Going on with the Comments plugin
Added a frontend form, store comments under data/, basic visualization options
This commit is contained in:
parent
978abff176
commit
c18914d3e3
14
README.md
14
README.md
|
@ -1,4 +1,4 @@
|
||||||
# Grav Data Manager Plugin
|
# Grav Comments Plugin
|
||||||
|
|
||||||
The **Comments Plugin** for [Grav](http://github.com/getgrav/grav) adds the ability to add comments to pages, and moderate them.
|
The **Comments Plugin** for [Grav](http://github.com/getgrav/grav) adds the ability to add comments to pages, and moderate them.
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ The **Comments Plugin** for [Grav](http://github.com/getgrav/grav) adds the abil
|
||||||
|
|
||||||
# Installation
|
# Installation
|
||||||
|
|
||||||
The Data plugin is easy to install with GPM.
|
The Comments plugin is easy to install with GPM.
|
||||||
|
|
||||||
```
|
```
|
||||||
$ bin/gpm install comments
|
$ bin/gpm install comments
|
||||||
|
@ -16,10 +16,10 @@ Or clone from GitHub and put in the `user/plugins/comments` folder.
|
||||||
|
|
||||||
# TODO
|
# TODO
|
||||||
|
|
||||||
- Create inferface (with Form?) to allow people to submit a comment to a Page
|
- Validate comment, name and email on the frontend form
|
||||||
- Store and email the comment to the emails configured (default to all with admin.super)
|
- Add language file for the frontend
|
||||||
- Enable by default on all Pages
|
- Allow to moderate comments from the admin
|
||||||
|
- Email the comment to the site admins (default to all with admin.super, could be configured)
|
||||||
- Allow to enable on some taxonomies or page types only
|
- Allow to enable on some taxonomies or page types only
|
||||||
- Allow some pages to disable comments
|
- Allow some pages to disable comments
|
||||||
- Admin interface to moderate comments
|
- Better presentation of the comments in Antimatter and other default themes
|
||||||
- Add ACL permissions so users can moderate comments in admin
|
|
|
@ -1,7 +1,7 @@
|
||||||
---
|
---
|
||||||
title: Data Manager
|
title: Comments
|
||||||
|
|
||||||
access:
|
access:
|
||||||
admin.data-manager: true
|
admin.comments: true
|
||||||
admin.super: true
|
admin.super: true
|
||||||
---
|
---
|
||||||
|
|
|
@ -9,28 +9,33 @@
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<style>
|
|
||||||
.page-data ul { padding-left: 60px; display: block; list-style-type: square; }
|
|
||||||
.page-data ul li .row { padding-left: 0px }
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<div class="page-data">
|
<div class="page-data">
|
||||||
<div class="gpm gpm-themes">
|
<div class="gpm gpm-themes">
|
||||||
<h1>
|
<h1>
|
||||||
{{"PLUGIN_COMMENTS.COMMENTS"|e|tu}}
|
{{"PLUGIN_COMMENTS.COMMENTS"|e|tu}}
|
||||||
</h1>
|
</h1>
|
||||||
<div class="gpm gpm-themes themes card-row grid fixed-blocks pure-g">
|
|
||||||
<ul class="pages-list depth-0">
|
<table>
|
||||||
{% for item in grav.twig.comments %}
|
{% for file in grav.twig.files %}
|
||||||
<li class="page-item">
|
<tr data-gpm-plugin="#">
|
||||||
<div class="row">
|
<td class="gpm-name">
|
||||||
<a href="{{ item.route }}" class="page-edit">{{ item.content|e }}</a>
|
<!-- <i class="fa fa-fw fa-{{ plugin.icon }}"></i> -->
|
||||||
</div>
|
{{ file.fileName }}
|
||||||
</li>
|
{% if file.data.hasUnread %}<span class="gpm-version">Has {{file.data.unreadCount}} unread comments</span>{% endif %}
|
||||||
{% endfor %}
|
</td>
|
||||||
</ul>
|
<td class="gpm-actions">
|
||||||
</div>
|
<span class="gpm-details-expand"><i class="fa fa-chevron-down"></i></span>
|
||||||
|
</td>
|
||||||
|
<td class="gpm-details">
|
||||||
|
<div class="table-wrapper">
|
||||||
|
{% include 'partials/comments-list.html.twig' with { file: file } %}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
<table>
|
||||||
|
{% for comment in file.data.comments %}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
{{ comment.text }}
|
||||||
|
<br />
|
||||||
|
By {{ comment.author }} {{ comment.email }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
155
comments.php
155
comments.php
|
@ -6,6 +6,10 @@ use Grav\Common\Grav;
|
||||||
use Grav\Common\Page\Page;
|
use Grav\Common\Page\Page;
|
||||||
use Grav\Common\Page\Pages;
|
use Grav\Common\Page\Pages;
|
||||||
use Grav\Common\Plugin;
|
use Grav\Common\Plugin;
|
||||||
|
use RocketTheme\Toolbox\File\File;
|
||||||
|
use RocketTheme\Toolbox\Event\Event;
|
||||||
|
use Grav\Common\Filesystem\RecursiveFolderFilterIterator;
|
||||||
|
use Symfony\Component\Yaml\Yaml;
|
||||||
|
|
||||||
class CommentsPlugin extends Plugin
|
class CommentsPlugin extends Plugin
|
||||||
{
|
{
|
||||||
|
@ -22,32 +26,159 @@ class CommentsPlugin extends Plugin
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable search only if url matches to the configuration.
|
|
||||||
*/
|
*/
|
||||||
public function onPluginsInitialized()
|
public function onPluginsInitialized()
|
||||||
{
|
{
|
||||||
if (!$this->isAdmin()) {
|
if (!$this->isAdmin()) {
|
||||||
|
|
||||||
|
// //Site
|
||||||
|
// $this->enable([
|
||||||
|
// 'onPageProcessed' => ['onPageProcessed', 0],
|
||||||
|
// ]);
|
||||||
|
|
||||||
|
|
||||||
|
$this->enable([
|
||||||
|
'onTwigTemplatePaths' => ['onTwigTemplatePaths', 0],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->addCommentURL = $this->config->get('plugins.comments.addCommentURL', '/add-comment');
|
||||||
|
|
||||||
|
if ($this->addCommentURL && $this->addCommentURL == $this->grav['uri']->path()) {
|
||||||
|
$this->enable([
|
||||||
|
'onPagesInitialized' => ['addComment', 0]
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
$this->grav['twig']->comments = $this->fetchComments();
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
//Admin
|
||||||
|
$this->enable([
|
||||||
|
'onTwigTemplatePaths' => ['onTwigAdminTemplatePaths', 0],
|
||||||
|
'onAdminTemplateNavPluginHook' => ['onAdminTemplateNavPluginHook', 0],
|
||||||
|
'onDataTypeExcludeFromDataManagerPluginHook' => ['onDataTypeExcludeFromDataManagerPluginHook', 0],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->grav['twig']->files = $this->getFilesOrderedByModifiedDate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addComment()
|
||||||
|
{
|
||||||
|
$post = !empty($_POST) ? $_POST : [];
|
||||||
|
$filename = DATA_DIR . 'comments' . $post['path'] . '.yaml';
|
||||||
|
$file = File::instance($filename);
|
||||||
|
|
||||||
|
if (file_exists($filename)) {
|
||||||
|
$data = Yaml::parse($file->content());
|
||||||
|
|
||||||
|
$data['comments'][] = [
|
||||||
|
'text' => $post['text'],
|
||||||
|
'date' => gmdate('D, d M Y H:i:s', time()),
|
||||||
|
'author' => $post['name'],
|
||||||
|
'email' => $post['email']
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
$data = array(
|
||||||
|
'comments' => array([
|
||||||
|
'text' => $post['text'],
|
||||||
|
'date' => gmdate('D, d M Y H:i:s', time()),
|
||||||
|
'author' => $post['name'],
|
||||||
|
'email' => $post['email']
|
||||||
|
])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$file->save(Yaml::dump($data));
|
||||||
|
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getFilesOrderedByModifiedDate($path = '') {
|
||||||
|
$files = [];
|
||||||
|
$dirItr = new \RecursiveDirectoryIterator(DATA_DIR . 'comments' . $path, \RecursiveDirectoryIterator::SKIP_DOTS);
|
||||||
|
$filterItr = new RecursiveFolderFilterIterator($dirItr);
|
||||||
|
$itr = new \RecursiveIteratorIterator($filterItr, \RecursiveIteratorIterator::SELF_FIRST);
|
||||||
|
|
||||||
|
$itrItr = new \RecursiveIteratorIterator($dirItr, \RecursiveIteratorIterator::SELF_FIRST);
|
||||||
|
$filesItr = new \RegexIterator($itrItr, '/^.+\.yaml$/i');
|
||||||
|
|
||||||
|
foreach ($filesItr as $filepath => $file) {
|
||||||
|
$files[] = (object)array(
|
||||||
|
"modifiedDate" => $file->getMTime(),
|
||||||
|
"fileName" => $file->getFilename(),
|
||||||
|
"filePath" => $filepath,
|
||||||
|
"data" => Yaml::parse(file_get_contents($filepath))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($itr as $file) {
|
||||||
|
if ($file->isDir()) {
|
||||||
|
$this->getFilesOrderedByModifiedDate('/' . $file->getFilename());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Order files by last modified date
|
||||||
|
usort($files, function($a, $b) {
|
||||||
|
return !($a->modifiedDate > $b->modifiedDate);
|
||||||
|
});
|
||||||
|
|
||||||
|
return $files;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private function fetchComments() {
|
||||||
|
|
||||||
|
|
||||||
|
return $this->getFileContentFromRoute($this->grav['uri']->path() . '.yaml')['comments'];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// return [
|
||||||
|
// 'route' => 'comment-test-1',
|
||||||
|
// 'content' => 'A comment text'
|
||||||
|
// ];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a data file route, return the YAML content already parsed
|
||||||
|
*/
|
||||||
|
private function getFileContentFromRoute($fileRoute) {
|
||||||
|
|
||||||
|
//Single item details
|
||||||
|
$fileInstance = File::instance(DATA_DIR . 'comments/' . $fileRoute);
|
||||||
|
|
||||||
|
if (!$fileInstance->content()) {
|
||||||
|
//Item not found
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->enable([
|
return Yaml::parse($fileInstance->content());
|
||||||
'onTwigTemplatePaths' => ['onTwigTemplatePaths', 0],
|
}
|
||||||
'onAdminTemplateNavPluginHook' => ['onAdminTemplateNavPluginHook', 0],
|
|
||||||
'onDataTypeExcludeFromDataManagerPluginHook' => ['onDataTypeExcludeFromDataManagerPluginHook', 0],
|
|
||||||
]);
|
|
||||||
|
|
||||||
$comments[] = [
|
// /**
|
||||||
'route' => 'comment-test-1',
|
// */
|
||||||
'content' => 'A comment text'
|
// public function onPageProcessed(Event $e)
|
||||||
];
|
// {
|
||||||
|
// $page = $e['page'];
|
||||||
|
// $page->setRawContent('ss');
|
||||||
|
// }
|
||||||
|
|
||||||
$this->grav['twig']->comments = $comments;
|
/**
|
||||||
|
* Add templates directory to twig lookup paths.
|
||||||
|
*/
|
||||||
|
public function onTwigTemplatePaths()
|
||||||
|
{
|
||||||
|
$this->grav['twig']->twig_paths[] = __DIR__ . '/templates';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add plugin templates path
|
* Add plugin templates path
|
||||||
*/
|
*/
|
||||||
public function onTwigTemplatePaths()
|
public function onTwigAdminTemplatePaths()
|
||||||
{
|
{
|
||||||
$this->grav['twig']->twig_paths[] = __DIR__ . '/admin/templates';
|
$this->grav['twig']->twig_paths[] = __DIR__ . '/admin/templates';
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
<h3>Add a Comment</h3>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
jQuery(document).on('click tap', '.js__add-new-comment', function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
jQuery.ajax({
|
||||||
|
url: "{{ grav.uri.rootUrl }}/add-comment",
|
||||||
|
data: {
|
||||||
|
text: $('.js__new-comment-text').val(),
|
||||||
|
name: $('.js__new-comment-name').val(),
|
||||||
|
email: $('.js__new-comment-email').val(),
|
||||||
|
path: "{{ grav.uri.path }}"
|
||||||
|
},
|
||||||
|
type: 'POST'
|
||||||
|
})
|
||||||
|
.success(function() {
|
||||||
|
window.location.reload();
|
||||||
|
})
|
||||||
|
.error(function() {
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<form>
|
||||||
|
<textarea class="js__new-comment-text"></textarea>
|
||||||
|
|
||||||
|
Name: <input type="text" class="js__new-comment-name" />
|
||||||
|
<br>
|
||||||
|
Email: <input type="text" class="js__new-comment-email" />
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<input type="submit" class="js__add-new-comment" />
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<h3>Comments</h3>
|
||||||
|
|
||||||
|
<table>
|
||||||
|
{% for comment in grav.twig.comments|array_reverse %}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
{{ comment.text }}
|
||||||
|
<br />
|
||||||
|
Written on {{comment.date}} by {{comment.author}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
Loading…
Reference in New Issue