This commit is contained in:
Loïc Guibert
2022-09-30 20:02:02 +01:00
commit 66dafc36c3
2561 changed files with 454489 additions and 0 deletions

1
user/plugins/comments/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
.DS_Store

View File

@@ -0,0 +1,135 @@
# v1.2.8
## 09/10/2020
1. [](#improved)
* Improved some translations
1. [](#bugfix)
* Fix for PHP 7.4 [#81](https://github.com/getgrav/grav-plugin-comments/issues/81)
* Fix for allowing path in form submission [#86](https://github.com/getgrav/grav-plugin-comments/issues/86) [#80](https://github.com/getgrav/grav-plugin-comments/issues/80)
# v1.2.7
## 05/12/2017
1. [](#improved)
* Added Japanese translation
* Move captcha over email [#45](https://github.com/getgrav/grav-plugin-comments/issues/45)
1. [](#bugfix)
* Fix comment form processing
* Fix issue with scope for autofilled values
# v1.2.6
## 01/09/2017
1. [](#improved)
* Use existing `Utils::startsWith()` method
1. [](#bugfix)
* Fix [#41](https://github.com/getgrav/grav-plugin-comments/issues/41) using Comments in a Gantry-powered theme did not escape the comment form token correctly
# v1.2.5
## 09/16/2016
1. [](#bugfix)
* Fix [#37](https://github.com/getgrav/grav-plugin-comments/issues/37) showing comments older than one week in the "latest comments" view
# v1.2.4
## 09/15/2016
1. [](#bugfix)
* Fix missing Twig template error if route is excluded but twig is loaded
# v1.2.3
## 09/15/2016
1. [](#improved)
* Added Croatian translation
1. [](#bugfix)
* Fix [#35](https://github.com/getgrav/grav-plugin-comments/issues/35) Allow comments to work fine on Form 2.0 too
# v1.2.2
## 08/12/2016
1. [](#improved)
* Added Romanian translation
1. [](#bugfix)
* Fix issue in storing comments cache when cache is enabled [#33](https://github.com/getgrav/grav-plugin-comments/issues/33)
# v1.2.1
## 07/19/2016
1. [](#bugfix)
* Check if Login plugin is installed before checking for user object [#28](https://github.com/getgrav/grav-plugin-comments/issues/28)
# v1.2.0
## 07/14/2016
1. [](#improved)
* Prevent a missing template problem on ignored routes
* Allow to translate the comments form
* Added spanish and brazilian portuguese translations
* Enhanced german, russian and french translations
* Added cache for comments
* Handle logged in users by not requiring username/email
* Reset the comments form after a comment is submitted
# v1.1.4
## 02/05/2016
1. [](#improved)
* Added german and polish
* Avoid listening on onTwigTemplatePaths if not enabled
# v1.1.3
## 01/06/2016
1. [](#improved)
* Disable captcha by default, added instructions on how to enable it
1. [](#bugfix)
* Increase priority for onPageInitialized in the comments plugin over the form plugin one to prevent an issue when saving comments
# v1.1.2
## 12/11/2015
1. [](#improved)
Fix double escaping comments text and author
# v1.1.1
## 12/11/2015
1. [](#improved)
* Drop the autofocus on the comment form
1. [](#bugfix)
* Fix double encoding (#12)
# v1.1.0
## 11/24/2015
1. [](#new)
* Added french (@codebee-fr) and russian (@joomline) languages
* Takes advantage of the new nonce support provided by the Form plugin
1. [](#improved)
* Use date instead of gmdate to respect the server local time (thanks @bovisp)
* Now works with multilang (thanks @bovisp)
# v1.0.2
## 11/13/2015
1. [](#improved)
* Use nonce
1. [](#improved)
* Changed form action to work with multilang
# v1.0.1
## 11/11/2015
1. [](#improved)
* Use onAdminMenu instead of the deprecated onAdminTemplateNavPluginHook
1. [](#bugfix)
* Fix error when user/data/comments does not exist
# v1.0.0
## 10/21/2015
1. [](#new)
* Initial Release

View File

@@ -0,0 +1,74 @@
# Grav Comments Plugin
The **Comments Plugin** for [Grav](http://github.com/getgrav/grav) adds the ability to add comments to pages, and moderate them.
# Installation
The Comments plugin is easy to install with GPM.
```
$ bin/gpm install comments
```
Or clone from GitHub and put in the `user/plugins/comments` folder.
# Usage
Add `{% include 'partials/comments.html.twig' with {'page': page} %}` to the template file where you want to add comments.
For example, in Antimatter, in `templates/item.html.twig`:
```twig
{% embed 'partials/base.html.twig' %}
{% block content %}
{% if config.plugins.breadcrumbs.enabled %}
{% include 'partials/breadcrumbs.html.twig' %}
{% endif %}
<div class="blog-content-item grid pure-g-r">
<div id="item" class="block pure-u-2-3">
{% include 'partials/blog_item.html.twig' with {'blog':page.parent, 'truncate':false} %}
</div>
<div id="sidebar" class="block size-1-3 pure-u-1-3">
{% include 'partials/sidebar.html.twig' with {'blog':page.parent} %}
</div>
</div>
{% include 'partials/comments.html.twig' with {'page': page} %}
{% endblock %}
{% endembed %}
```
The comment form will appear on the blog post items matching the enabled routes.
To set the enabled routes, create a `user/config/plugins/comments.yaml` file, copy in it the contents of `user/plugins/comments/comments.yaml` and edit the `enable_on_routes` and `disable_on_routes` options according to your needs.
> Make sure you configured the "Email from" and "Email to" email addresses in the Email plugin with your email address!
# Enabling Recaptcha
The plugin comes with Recaptcha integration. To make it work, create a `user/config/plugins/comments.yaml` file, copy in it the contents of `user/plugins/comments/comments.yaml` and uncomment the captcha form field and the captcha validation process.
Make sure you add your own Recaptcha `site` and `secret` keys too.
# Where are the comments stored?
In the `user/data/comments` folder. They're organized by page route, so every page with a comment has a corresponding file. This enables a quick load of all the page comments.
# Visualize comments
When the plugin is installed and enabled, the `Comments` menu will appear in the Admin Plugin. From there you can see all the comments made in the last 7 days.
Further improvements to the comments visualization will be added in the next releases.
# Email notifications
The plugin interacts with the Email plugin to send emails upon receiving a comment. Configure the Email plugin correctly, setting its "Email from" and "Email to" email addresses.
# Things still missing
- Allow to delete comments from the Admin Plugin
- Ability to see all comments of a page in the Admin Plugin
- Ability to reply to a comment from the Admin Plugin
- Auto-fill the comment form when a user is logged in

View File

@@ -0,0 +1,7 @@
---
title: Comments
access:
admin.comments: true
admin.super: true
---

View File

@@ -0,0 +1,133 @@
{% extends 'partials/base.html.twig' %}
{% if admin.route %}
{% set context = admin.page(true) %}
{% endif %}
{% block titlebar %}
<h1><i class="fa fa-fw fa-file-text-o"></i> {{ "PLUGIN_COMMENTS.COMMENTS"|tu }}</h1>
{% endblock %}
{% block content %}
<style>
td.comments-actions {
flex: 0.1;
}
.pages-list .row {
padding-right: 1rem;
}
.comment-text {
line-height: 1.5rem;
display: inline-block;
}
.pages-list .row p.page-route {
margin: 0px 0 10px 0px;
}
th { background: #d9d9d9; }
.comment { flex: 3 }
.details { flex: 1.5 }
.center {
margin: 0 auto;
text-align: center;
display: block;
}
.button:active { margin: 0 auto;}
</style>
<script>
$(function() {
var currentPage = 0;
$(document).on('click tap', '.js__load-more', function(event) {
$.getJSON(window.location + '/page:' + (currentPage + 1))
.success(function(response) {
currentPage = parseInt(response.page);
response.comments.forEach(function(comment) {
$('.js__comments-container').append('<tr>' +
'<td class="e author">' + comment.author + '</td>' +
'<td class="v comment">' + comment.text + '</td>' +
'<td class="v details"><strong>Page</strong>: ' + comment.pageTitle + '<br>' +
'<strong>Date</strong>: ' + comment.date + '</td>' +
'</tr>');
})
var totalRetrieved = response.totalRetrieved * (parseInt(response.page) + 1);
$('.totalRetrieved').html(totalRetrieved);
$('.totalAvailable').html(response.totalAvailable);
if (totalRetrieved == response.totalAvailable) {
$('.js__load-more').hide();
}
})
.error(function() {
alert('Unexpected error');
});
});
});
</script>
<h1>Comments in the last 7 days</h1>
<div class="admin-block">
<table>
<tbody class="js__comments-container">
<tr class="h">
<th class="author">Author</th>
<th class="comment">Comment</th>
<th class="details">Details</th>
</tr>
{% for comment in grav.twig.comments.comments %}
<tr>
<td class="author">{{comment.author}}</td>
<td class="comment">{{comment.text}}</td>
<td class="details"><strong>Page</strong>: {{comment.pageTitle}}<br>
<strong>Date</strong>: {{comment.date}}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% if grav.twig.comments.totalRetrieved < grav.twig.comments.totalAvailable %}
<button type="button" class="button center js__load-more">
Load more
</button>
{% endif %}
<p class="center">Showing <span class="totalRetrieved">{{grav.twig.comments.totalRetrieved}}</span> comments of <span class="totalAvailable">{{grav.twig.comments.totalAvailable}}</span></p>
</div>
{% if grav.twig.pages %}
<h1>Recently commented pages</h1>
<div class="admin-block">
<table>
<tbody class="js__pages-container">
<tr class="h">
<th class="page">Page</th>
<th class="number-of-comments">Number of comments</th>
<th class="last-comment-date">Last commented on</th>
</tr>
{% for page in grav.twig.pages %}
<tr>
<td class="page">{{page.title}}</td>
<td class="number-of-comments">{{page.commentsCount}}</td>
<td class="last-comment-date">{{page.lastCommentDate}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endif %}
{% endblock %}

View File

@@ -0,0 +1,33 @@
name: Comments
type: plugin
slug: comments
version: 1.2.8
description: Adds a commenting functionality to your site
icon: comment
author:
name: Team Grav
email: devs@getgrav.org
url: http://getgrav.org
homepage: https://github.com/getgrav/grav-plugin-comments
keywords: guestbook, plugin
bugs: https://github.com/getgrav/grav-plugin-comments/issues
readme: https://github.com/getgrav/grav-plugin-comments/blob/develop/README.md
license: MIT
dependencies:
- form
- email
form:
validation: loose
fields:
enabled:
type: toggle
label: PLUGIN_ADMIN.PLUGIN_STATUS
highlight: 1
default: 0
options:
1: PLUGIN_ADMIN.ENABLED
0: PLUGIN_ADMIN.DISABLED
validate:
type: bool

View File

@@ -0,0 +1,435 @@
<?php
namespace Grav\Plugin;
use Grav\Common\Filesystem\Folder;
use Grav\Common\GPM\GPM;
use Grav\Common\Grav;
use Grav\Common\Page\Page;
use Grav\Common\Page\Pages;
use Grav\Common\Plugin;
use Grav\Common\Filesystem\RecursiveFolderFilterIterator;
use Grav\Common\User\User;
use Grav\Common\Utils;
use RocketTheme\Toolbox\File\File;
use RocketTheme\Toolbox\Event\Event;
use Symfony\Component\Yaml\Yaml;
class CommentsPlugin extends Plugin
{
protected $route = 'comments';
protected $enable = false;
protected $comments_cache_id;
/**
* @return array
*/
public static function getSubscribedEvents()
{
return [
'onPluginsInitialized' => ['onPluginsInitialized', 0]
];
}
/**
* Initialize form if the page has one. Also catches form processing if user posts the form.
*
* Used by Form plugin < 2.0, kept for backwards compatibility
*
* @deprecated
*/
public function onPageInitialized()
{
/** @var Page $page */
$page = $this->grav['page'];
if (!$page) {
return;
}
if ($this->enable) {
$header = $page->header();
if (!isset($header->form)) {
$header->form = $this->grav['config']->get('plugins.comments.form');
$page->header($header);
}
}
}
/**
* Add the comment form information to the page header dynamically
*
* Used by Form plugin >= 2.0
*/
public function onFormPageHeaderProcessed(Event $event)
{
$header = $event['header'];
if ($this->enable) {
if (!isset($header->form)) {
$header->form = $this->grav['config']->get('plugins.comments.form');
}
}
$event->header = $header;
}
public function onTwigSiteVariables() {
// Old way
$enabled = $this->enable;
$comments = $this->fetchComments();
$this->grav['twig']->enable_comments_plugin = $enabled;
$this->grav['twig']->comments = $comments;
// New way
$this->grav['twig']->twig_vars['enable_comments_plugin'] = $enabled;
$this->grav['twig']->twig_vars['comments'] = $comments;
}
/**
* Determine if the plugin should be enabled based on the enable_on_routes and disable_on_routes config options
*/
private function calculateEnable() {
$uri = $this->grav['uri'];
$disable_on_routes = (array) $this->config->get('plugins.comments.disable_on_routes');
$enable_on_routes = (array) $this->config->get('plugins.comments.enable_on_routes');
$path = $uri->path();
if (!in_array($path, $disable_on_routes)) {
if (in_array($path, $enable_on_routes)) {
$this->enable = true;
} else {
foreach($enable_on_routes as $route) {
if (Utils::startsWith($path, $route)) {
$this->enable = true;
break;
}
}
}
}
}
/**
* Frontend side initialization
*/
public function initializeFrontend()
{
$this->calculateEnable();
$this->enable([
'onTwigTemplatePaths' => ['onTwigTemplatePaths', 0],
]);
if ($this->enable) {
$this->enable([
'onFormProcessed' => ['onFormProcessed', 0],
'onFormPageHeaderProcessed' => ['onFormPageHeaderProcessed', 0],
'onPageInitialized' => ['onPageInitialized', 10],
'onTwigSiteVariables' => ['onTwigSiteVariables', 0]
]);
}
$cache = $this->grav['cache'];
$uri = $this->grav['uri'];
//init cache id
$this->comments_cache_id = md5('comments-data' . $cache->getKey() . '-' . $uri->url());
}
/**
* Admin side initialization
*/
public function initializeAdmin()
{
/** @var Uri $uri */
$uri = $this->grav['uri'];
$this->enable([
'onTwigTemplatePaths' => ['onTwigAdminTemplatePaths', 0],
'onAdminMenu' => ['onAdminMenu', 0],
'onDataTypeExcludeFromDataManagerPluginHook' => ['onDataTypeExcludeFromDataManagerPluginHook', 0],
]);
if (strpos($uri->path(), $this->config->get('plugins.admin.route') . '/' . $this->route) === false) {
return;
}
$page = $this->grav['uri']->param('page');
$comments = $this->getLastComments($page);
if ($page > 0) {
echo json_encode($comments);
exit();
}
$this->grav['twig']->comments = $comments;
$this->grav['twig']->pages = $this->fetchPages();
}
/**
*/
public function onPluginsInitialized()
{
if ($this->isAdmin()) {
$this->initializeAdmin();
} else {
$this->initializeFrontend();
}
}
/**
* Handle form processing instructions.
*
* @param Event $event
*/
public function onFormProcessed(Event $event)
{
$form = $event['form'];
$action = $event['action'];
$params = $event['params'];
if (!$this->active) {
return;
}
switch ($action) {
case 'addComment':
$post = isset($_POST['data']) ? $_POST['data'] : [];
$path = $this->grav['uri']->path();
$lang = filter_var(urldecode($post['lang']), FILTER_SANITIZE_STRING);
$text = filter_var(urldecode($post['text']), FILTER_SANITIZE_STRING);
$name = filter_var(urldecode($post['name']), FILTER_SANITIZE_STRING);
$email = filter_var(urldecode($post['email']), FILTER_SANITIZE_STRING);
$title = filter_var(urldecode($post['title']), FILTER_SANITIZE_STRING);
if (isset($this->grav['user'])) {
$user = $this->grav['user'];
if ($user->authenticated) {
$name = $user->fullname;
$email = $user->email;
}
}
/** @var Language $language */
$language = $this->grav['language'];
$lang = $language->getLanguage();
$filename = DATA_DIR . 'comments';
$filename .= ($lang ? '/' . $lang : '');
$filename .= $path . '.yaml';
$file = File::instance($filename);
if (file_exists($filename)) {
$data = Yaml::parse($file->content());
$data['comments'][] = [
'text' => $text,
'date' => date('D, d M Y H:i:s', time()),
'author' => $name,
'email' => $email
];
} else {
$data = array(
'title' => $title,
'lang' => $lang,
'comments' => array([
'text' => $text,
'date' => date('D, d M Y H:i:s', time()),
'author' => $name,
'email' => $email
])
);
}
$file->save(Yaml::dump($data));
//clear cache
$this->grav['cache']->delete($this->comments_cache_id);
break;
}
}
private function getFilesOrderedByModifiedDate($path = '') {
$files = [];
if (!$path) {
$path = DATA_DIR . 'comments';
}
if (!file_exists($path)) {
Folder::mkdir($path);
}
$dirItr = new \RecursiveDirectoryIterator($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');
// Collect files if modified in the last 7 days
foreach ($filesItr as $filepath => $file) {
$modifiedDate = $file->getMTime();
$sevenDaysAgo = time() - (7 * 24 * 60 * 60);
if ($modifiedDate < $sevenDaysAgo) {
continue;
}
$files[] = (object)array(
"modifiedDate" => $modifiedDate,
"fileName" => $file->getFilename(),
"filePath" => $filepath,
"data" => Yaml::parse(file_get_contents($filepath))
);
}
// Traverse folders and recurse
foreach ($itr as $file) {
if ($file->isDir()) {
$this->getFilesOrderedByModifiedDate($file->getPath() . '/' . $file->getFilename());
}
}
// Order files by last modified date
usort($files, function($a, $b) {
return !($a->modifiedDate > $b->modifiedDate);
});
return $files;
}
private function getLastComments($page = 0) {
$number = 30;
$files = [];
$files = $this->getFilesOrderedByModifiedDate();
$comments = [];
foreach($files as $file) {
$data = Yaml::parse(file_get_contents($file->filePath));
for ($i = 0; $i < count($data['comments']); $i++) {
$commentTimestamp = \DateTime::createFromFormat('D, d M Y H:i:s', $data['comments'][$i]['date'])->getTimestamp();
$data['comments'][$i]['pageTitle'] = $data['title'];
$data['comments'][$i]['filePath'] = $file->filePath;
$data['comments'][$i]['timestamp'] = $commentTimestamp;
}
if (count($data['comments'])) {
$comments = array_merge($comments, $data['comments']);
}
}
// Order comments by date
usort($comments, function($a, $b) {
return !($a['timestamp'] > $b['timestamp']);
});
$totalAvailable = count($comments);
$comments = array_slice($comments, $page * $number, $number);
$totalRetrieved = count($comments);
return (object)array(
"comments" => $comments,
"page" => $page,
"totalAvailable" => $totalAvailable,
"totalRetrieved" => $totalRetrieved
);
}
/**
* Return the comments associated to the current route
*/
private function fetchComments() {
$cache = $this->grav['cache'];
//search in cache
if ($comments = $cache->fetch($this->comments_cache_id)) {
return $comments;
}
$lang = $this->grav['language']->getLanguage();
$filename = $lang ? '/' . $lang : '';
$filename .= $this->grav['uri']->path() . '.yaml';
$data = $this->getDataFromFilename($filename);
$comments = isset($data['comments']) ? $data['comments'] : null;
//save to cache if enabled
$cache->save($this->comments_cache_id, $comments);
return $comments;
}
/**
* Return the latest commented pages
*/
private function fetchPages() {
$files = [];
$files = $this->getFilesOrderedByModifiedDate();
$pages = [];
foreach($files as $file) {
$pages[] = [
'title' => $file->data['title'],
'commentsCount' => count($file->data['comments']),
'lastCommentDate' => date('D, d M Y H:i:s', $file->modifiedDate)
];
}
return $pages;
}
/**
* Given a data file route, return the YAML content already parsed
*/
private function getDataFromFilename($fileRoute) {
//Single item details
$fileInstance = File::instance(DATA_DIR . 'comments/' . $fileRoute);
if (!$fileInstance->content()) {
//Item not found
return;
}
return Yaml::parse($fileInstance->content());
}
/**
* Add templates directory to twig lookup paths.
*/
public function onTwigTemplatePaths()
{
$this->grav['twig']->twig_paths[] = __DIR__ . '/templates';
}
/**
* Add plugin templates path
*/
public function onTwigAdminTemplatePaths()
{
$this->grav['twig']->twig_paths[] = __DIR__ . '/admin/templates';
}
/**
* Add navigation item to the admin plugin
*/
public function onAdminMenu()
{
$this->grav['twig']->plugins_hooked_nav['PLUGIN_COMMENTS.COMMENTS'] = ['route' => $this->route, 'icon' => 'fa-file-text'];
}
/**
* Exclude comments from the Data Manager plugin
*/
public function onDataTypeExcludeFromDataManagerPluginHook()
{
$this->grav['admin']->dataTypesExcludedFromDataManagerPlugin[] = 'comments';
}
}

View File

@@ -0,0 +1,77 @@
enabled: true
enable_on_routes:
- '/blog'
disable_on_routes:
- /blog/blog-post-to-ignore
- /ignore-this-route
#- '/blog/daring-fireball-link'
form:
name: comments
fields:
- name: name
label: PLUGIN_COMMENTS.NAME_LABEL
placeholder: PLUGIN_COMMENTS.NAME_PLACEHOLDER
autocomplete: on
type: text
validate:
required: true
- name: email
label: PLUGIN_COMMENTS.EMAIL_LABEL
placeholder: PLUGIN_COMMENTS.EMAIL_PLACEHOLDER
type: email
validate:
required: true
- name: text
label: PLUGIN_COMMENTS.MESSAGE_LABEL
placeholder: PLUGIN_COMMENTS.MESSAGE_PLACEHOLDER
type: textarea
validate:
required: true
- name: date
type: hidden
process:
fillWithCurrentDateTime: true
- name: title
type: hidden
evaluateDefault: grav.page.header.title
- name: lang
type: hidden
evaluateDefault: grav.language.getLanguage
- name: path
type: hidden
evaluateDefault: grav.uri.path
# - name: g-recaptcha-response
# label: Captcha
# type: captcha
# recaptcha_site_key: e32iojeoi32jeoi32jeoij32oiej32oiej3
# recaptcha_not_validated: 'Captcha not valid!'
# validate:
# required: true
# process:
# ignore: true
buttons:
- type: submit
value: PLUGIN_COMMENTS.SUBMIT_COMMENT_BUTTON_TEXT
process:
# - captcha:
# recaptcha_secret: ej32oiej23oiej32oijeoi32jeio32je
- email:
subject: PLUGIN_COMMENTS.EMAIL_NEW_COMMENT_SUBJECT
body: "{% include 'forms/data.html.twig' %}"
- addComment:
- message: PLUGIN_COMMENTS.THANK_YOU_MESSAGE
- reset: true

View File

@@ -0,0 +1,276 @@
en:
PLUGIN_COMMENTS:
ADD_COMMENT: Add a comment
COMMENTS: Comments
EMAIL_NOT_CONFIGURED: Email not configured
NEW_COMMENT_EMAIL_SUBJECT: 'New comment on %1$s'
NEW_COMMENT_EMAIL_BODY: '<p>A new comment was made on %1$s by %3$s (%4$s).</p><p>Page: %2$s</p><p>Text: %5$s</p>'
EMAIL_FOOTER: ''
NAME: Name:
EMAIL: Email:
WRITTEN_ON: Written on
BY: by
NAME_LABEL: "Name"
NAME_PLACEHOLDER: "Enter your name"
EMAIL_LABEL: "Email"
EMAIL_PLACEHOLDER: "Enter your email address"
MESSAGE_LABEL: "Comment"
MESSAGE_PLACEHOLDER: "Enter your comment"
SUBMIT_COMMENT_BUTTON_TEXT: "Submit"
EMAIL_NEW_COMMENT_SUBJECT: "[New Comment] from {{ form.value.name|e }}"
THANK_YOU_MESSAGE: "Thank you for writing your comment!"
de:
PLUGIN_COMMENTS:
ADD_COMMENT: Kommentar hinzufügen
COMMENTS: Kommentare
EMAIL_NOT_CONFIGURED: Email nicht konfiguriert
NEW_COMMENT_EMAIL_SUBJECT: 'Neuer Kommentar für %1$s'
NEW_COMMENT_EMAIL_BODY: '<p>Ein neuer Kommentar am %1$s von %3$s (%4$s).</p><p>Seite: %2$s</p><p>Text: %5$s</p>'
EMAIL_FOOTER: ''
NAME: Name:
EMAIL: Email:
WRITTEN_ON: geschrieben am
BY: von
NAME_LABEL: "Name"
NAME_PLACEHOLDER: "Namen eingeben"
EMAIL_LABEL: "Email"
EMAIL_PLACEHOLDER: "Email-Adresse eingeben"
MESSAGE_LABEL: "Kommentar"
MESSAGE_PLACEHOLDER: "Kommentar eingeben"
SUBMIT_COMMENT_BUTTON_TEXT: "Absenden"
EMAIL_NEW_COMMENT_SUBJECT: "[Neuer Kommentar] von {{ form.value.name|e }}"
THANK_YOU_MESSAGE: "Vielen Dank für den Kommentar!"
es:
PLUGIN_COMMENTS:
ADD_COMMENT: Agregar un comentario
COMMENTS: Comentarios
EMAIL_NOT_CONFIGURED: El Email no está configurado
NEW_COMMENT_EMAIL_SUBJECT: 'Nuevo comentario en %1$s'
NEW_COMMENT_EMAIL_BODY: '<p>Un nuevo comentario se hizo en %1$s por %3$s (%4$s).</p><p>Page: %2$s</p><p>Text: %5$s</p>'
EMAIL_FOOTER: ''
NAME: Nombre:
EMAIL: Email:
WRITTEN_ON: Escrito en
BY: por
NAME_LABEL: "Nombre"
NAME_PLACEHOLDER: "Escriba su nombre"
EMAIL_LABEL: "Email"
EMAIL_PLACEHOLDER: "Escriba su email"
MESSAGE_LABEL: "Comentario"
MESSAGE_PLACEHOLDER: "Escriba su comentario"
SUBMIT_COMMENT_BUTTON_TEXT: "Enviar"
EMAIL_NEW_COMMENT_SUBJECT: "[Nuevo comentario] de {{ form.value.name|e }}"
THANK_YOU_MESSAGE: "Gracias por escribir su comentario!"
fr:
PLUGIN_COMMENTS:
ADD_COMMENT: Ajouter un commentaire (en travaux)
COMMENTS: Commentaires (en travaux)
EMAIL_NOT_CONFIGURED: E-mail non configuré
NEW_COMMENT_EMAIL_SUBJECT: 'Nouveau commentaire sur %1$s'
NEW_COMMENT_EMAIL_BODY: '<p>Un nouveau commentaire a été publié sur %1$s par %3$s (%4$s).</p><p>Page : %2$s</p><p>Texte : %5$s</p>'
EMAIL_FOOTER: ''
NAME: Nom :
EMAIL: E-mail :
WRITTEN_ON: Écrit le
BY: par
NAME_LABEL: "Nom"
NAME_PLACEHOLDER: "Indiquez votre nom"
EMAIL_LABEL: "E-mail"
EMAIL_PLACEHOLDER: "Indiquez votre adresse e-mail"
MESSAGE_LABEL: "Commentaire"
MESSAGE_PLACEHOLDER: "Rédigez votre commentaire"
SUBMIT_COMMENT_BUTTON_TEXT: "Envoyer"
EMAIL_NEW_COMMENT_SUBJECT: "[Nouveau commentaire] de {{ form.value.name|e }}"
THANK_YOU_MESSAGE: "Merci d'avoir rédigé votre commentaire !"
hr:
PLUGIN_COMMENTS:
ADD_COMMENT: Dodaj komentar
COMMENTS: Komentari
EMAIL_NOT_CONFIGURED: Email adresa nije podešena
NEW_COMMENT_EMAIL_SUBJECT: 'Novi komentar na %1$s'
NEW_COMMENT_EMAIL_BODY: '<p>Novi komentar je napisan na %1$s od %3$s (%4$s).</p><p>Stranica:: %2$s</p><p>Tekst: %5$s</p>'
EMAIL_FOOTER: ''
NAME: Ime:
EMAIL: Email:
WRITTEN_ON: Napisano je na
BY: od
NAME_LABEL: "Ime"
NAME_PLACEHOLDER: "Unesite ime"
EMAIL_LABEL: "Email adresa"
EMAIL_PLACEHOLDER: "Unesite email adresu"
MESSAGE_LABEL: "Komentar"
MESSAGE_PLACEHOLDER: "Unesite komentar"
SUBMIT_COMMENT_BUTTON_TEXT: "Pošalji"
EMAIL_NEW_COMMENT_SUBJECT: "[Novi komentar] od {{ form.value.name|e }}"
THANK_YOU_MESSAGE: "Hvala Vam što ste napisali svoj komentar!"
it:
PLUGIN_COMMENTS:
ADD_COMMENT: Aggiungi un commento
COMMENTS: Commenti
EMAIL_NOT_CONFIGURED: Email non configurata
NEW_COMMENT_EMAIL_SUBJECT: 'Nuovo commento su %1$s'
NEW_COMMENT_EMAIL_BODY: '<p>Un nuovo commento è stato postato su %1$s da %3$s (%4$s).</p><p>Pagina: %2$s</p><p>Testo: %5$s</p>'
EMAIL_FOOTER: ''
NAME: Nome:
EMAIL: Email:
WRITTEN_ON: Scritto il
BY: da
NAME_LABEL: "Nome"
NAME_PLACEHOLDER: "Inserisci il tuo nome"
EMAIL_LABEL: "Email"
EMAIL_PLACEHOLDER: "Inserisci il tuo indirizzo email"
MESSAGE_LABEL: "Messaggio"
MESSAGE_PLACEHOLDER: "Inserisci il tuo commento"
SUBMIT_COMMENT_BUTTON_TEXT: "Invia"
EMAIL_NEW_COMMENT_SUBJECT: "[Nuovo commento] da {{ form.value.name|e }}"
THANK_YOU_MESSAGE: "Grazie per il tuo commento!"
ja:
PLUGIN_COMMENTS:
ADD_COMMENT: コメントする
COMMENTS: コメント
EMAIL_NOT_CONFIGURED: メールアドレスが設定さていません
NEW_COMMENT_EMAIL_SUBJECT: '%1$sの新しいコメント'
NEW_COMMENT_EMAIL_BODY: '<p>%1$sに新しいコメントが%3$sから(%4$s)に書かれました。</p><p>ページ : %2$s</p><p>内容 : %5$s</p>'
EMAIL_FOOTER: ''
NAME: 名前 :
EMAIL: メールアドレス :
WRITTEN_ON: 投稿日時
BY: By
NAME_LABEL: "名前"
NAME_PLACEHOLDER: "名前を入力してください"
EMAIL_LABEL: "メールアドレス"
EMAIL_PLACEHOLDER: "メールアドレスを入力してください"
MESSAGE_LABEL: "コメント"
MESSAGE_PLACEHOLDER: "コメントを入力してください"
SUBMIT_COMMENT_BUTTON_TEXT: "送信"
EMAIL_NEW_COMMENT_SUBJECT: "[新しいコメント] {{ form.value.name|e }}から"
THANK_YOU_MESSAGE: "コメントありがとうございます!"
nl:
PLUGIN_COMMENTS:
ADD_COMMENT: Reageer
COMMENTS: Reacties
EMAIL_NOT_CONFIGURED: Email niet geconfigureerd
NEW_COMMENT_EMAIL_SUBJECT: 'Nieuwe reactie op %1$s'
NEW_COMMENT_EMAIL_BODY: '<p>Er is een nieuwe reactie gemaakt op %1$s door %3$s (%4$s).</p><p>Pagina: %2$s</p><p>Tekst: %5$s</p>'
EMAIL_FOOTER: ''
NAME: 'Naam:'
EMAIL: 'Email:'
WRITTEN_ON: 'Geschreven op'
BY: 'door'
NAME_LABEL: "Naam"
NAME_PLACEHOLDER: "Vul je naam in"
EMAIL_LABEL: "Email"
EMAIL_PLACEHOLDER: "Vul je emailadres in"
MESSAGE_LABEL: "Reactie"
MESSAGE_PLACEHOLDER: "Vul je reactie in"
SUBMIT_COMMENT_BUTTON_TEXT: "Verstuur"
EMAIL_NEW_COMMENT_SUBJECT: "[Nieuwe reactie] van {{ form.value.name|e }}"
THANK_YOU_MESSAGE: "Bedankt voor je reactie!"
pl:
PLUGIN_COMMENTS:
ADD_COMMENT: Dodaj komentarz
COMMENTS: Komentarzy
EMAIL_NOT_CONFIGURED: Email jest nie skofigurowany
NEW_COMMENT_EMAIL_SUBJECT: 'Nowy komentarz %1$s'
NEW_COMMENT_EMAIL_BODY: '<p>Pojawił się nowy komentarz, napisany %1$s przez %3$s (%4$s).</p><p>Strona: %2$s</p><p>Treść: %5$s</p>'
EMAIL_FOOTER: ''
NAME: Imię:
EMAIL: Email:
WRITTEN_ON: Napisany przez
BY: przez
ru:
PLUGIN_COMMENTS:
ADD_COMMENT: Добавить комментарий
COMMENTS: Комментарии
EMAIL_NOT_CONFIGURED: Email не настроен
NEW_COMMENT_EMAIL_SUBJECT: 'Новый комментарий к %1$s'
NEW_COMMENT_EMAIL_BODY: '<p>Новый комментарий на %1$s от %3$s (%4$s).</p><p>Страница: %2$s</p><p>Текст: %5$s</p>'
EMAIL_FOOTER: ''
NAME: Имя:
EMAIL: Email:
WRITTEN_ON: Написан в
BY: от
NAME_LABEL: "Имя"
NAME_PLACEHOLDER: "Введите свое имя"
EMAIL_LABEL: "Email"
EMAIL_PLACEHOLDER: "Введите свой email адрес"
MESSAGE_LABEL: "Комментарий"
MESSAGE_PLACEHOLDER: "Введите свой комментарий"
SUBMIT_COMMENT_BUTTON_TEXT: "Отправить"
EMAIL_NEW_COMMENT_SUBJECT: "[Новый комментарий] от {{ form.value.name|e }}"
THANK_YOU_MESSAGE: "Благодарим за ваш комментарий!"
pt-br:
PLUGIN_COMMENTS:
ADD_COMMENT: Escreva um comentário
COMMENTS: Comentários
EMAIL_NOT_CONFIGURED: E-mail não configurado
NEW_COMMENT_EMAIL_SUBJECT: 'Novo comentário em %1$s'
NEW_COMMENT_EMAIL_BODY: '<p>Um novo comentário foi feito em %1$s por %3$s (%4$s).</p><p>Página: %2$s</p><p>Texto: %5$s</p>'
EMAIL_FOOTER: ''
NAME: Name:
EMAIL: Email:
WRITTEN_ON: Publicado em
BY: por
NAME_LABEL: "Nome"
NAME_PLACEHOLDER: "Escreva seu nome"
EMAIL_LABEL: "E-mail"
EMAIL_PLACEHOLDER: "Escreva seu e-mail. Ex.: seunome@provedor.com.br"
MESSAGE_LABEL: "Comentário"
MESSAGE_PLACEHOLDER: "Escreva seu comentário"
SUBMIT_COMMENT_BUTTON_TEXT: "Enviar"
EMAIL_NEW_COMMENT_SUBJECT: "[Novo comentário] de {{ form.value.name|e }}"
THANK_YOU_MESSAGE: "Obrigada por enviar seu comentário!"
ro:
PLUGIN_COMMENTS:
ADD_COMMENT: 'Adăugați un comentariu'
COMMENTS: 'Comentarii'
EMAIL_NOT_CONFIGURED: 'Adresa de email nu este configurată'
NEW_COMMENT_EMAIL_SUBJECT: 'Comentariu nou pentru %1$s'
NEW_COMMENT_EMAIL_BODY: '<p>Un nou comentariu a fost adăugat la %1$s de către %3$s (%4$s).</p><p>Pagină: %2$s</p><p>Text: %5$s</p>'
EMAIL_FOOTER: ''
NAME: 'Nume:'
EMAIL: 'Adresă de email:'
WRITTEN_ON: 'Scris în data de'
BY: 'de către'
NAME_LABEL: "Numele"
NAME_PLACEHOLDER: "Introduceți numele Dvs."
EMAIL_LABEL: "Email"
EMAIL_PLACEHOLDER: "Introduceți adresa Dvs. de email"
MESSAGE_LABEL: "Comentariu"
MESSAGE_PLACEHOLDER: "Scrieți comentariul Dvs."
SUBMIT_COMMENT_BUTTON_TEXT: "Trimiteți"
EMAIL_NEW_COMMENT_SUBJECT: "[Comentariu nou] from {{ form.value.name|e }}"
THANK_YOU_MESSAGE: "Vă mulțumim pentru comentariu!"
no:
PLUGIN_COMMENTS:
ADD_COMMENT: Skriv en kommentar
COMMENTS: Kommentarer
EMAIL_NOT_CONFIGURED: Epost er ikke konfigurert
NEW_COMMENT_EMAIL_SUBJECT: 'Ny kommentar på %1$s'
NEW_COMMENT_EMAIL_BODY: '<p>En ny kommentar er skrevet på %1$s av %3$s (%4$s).</p><p>Side: %2$s</p><p>Tekst: %5$s</p>'
EMAIL_FOOTER: ''
NAME: Navn:
EMAIL: Epost:
WRITTEN_ON: Skrevet på
BY: av
NAME_LABEL: "Navn"
NAME_PLACEHOLDER: "Skriv ditt navn"
EMAIL_LABEL: "Epost"
EMAIL_PLACEHOLDER: "Skriv din epost adresse"
MESSAGE_LABEL: "Kommentar"
MESSAGE_PLACEHOLDER: "Skriv din kommentar"
SUBMIT_COMMENT_BUTTON_TEXT: "Send"
EMAIL_NEW_COMMENT_SUBJECT: "[Ny kommentar] fra {{ form.value.name|e }}"
THANK_YOU_MESSAGE: "Takk for din kommentar!"

View File

@@ -0,0 +1,60 @@
{% if enable_comments_plugin %}
{% set scope = scope ?: 'data.' %}
<h3>{{'PLUGIN_COMMENTS.ADD_COMMENT'|t}}</h3>
<form name="{{ grav.config.plugins.comments.form.name }}"
action="{{ grav.config.plugins.comments.form.action ? base_url ~ grav.config.plugins.comments.form.action : page.url }}"
method="{{ grav.config.plugins.comments.form.method|upper|default('POST') }}">
{% for field in grav.config.plugins.comments.form.fields %}
{% set value = form.value(field.name) %}
{% if field.evaluateDefault %}
{% set value = evaluate(field.evaluateDefault) %}
{% endif %}
{% if config.plugins.login.enabled and grav.user.authenticated %}
{% if field.name == 'name' %}
<input type="hidden" name="{{ (scope ~ field.name)|fieldName }}" value="{{grav.user.fullname}}">
{% elseif field.name == 'email' %}
<input type="hidden" name="{{ (scope ~ field.name)|fieldName }}" value="{{grav.user.email}}">
{% else %}
<div>
{% include "forms/fields/#{field.type}/#{field.type}.html.twig" %}
</div>
{% endif %}
{% else %}
<div>
{% include "forms/fields/#{field.type}/#{field.type}.html.twig" %}
</div>
{% endif %}
{% endfor %}
{% include "forms/fields/formname/formname.html.twig" %}
<div class="buttons">
{% for button in grav.config.plugins.comments.form.buttons %}
<button class="button" type="{{ button.type|default('submit') }}">{{ button.value|t|default('Submit') }}</button>
{% endfor %}
</div>
{{ nonce_field('form', 'form-nonce')|raw }}
</form>
<div class="alert">{{ form.message }}</div>
{% if grav.twig.comments|length %}
<h3>{{'PLUGIN_COMMENTS.COMMENTS'|t}}</h3>
<table>
{% for comment in comments|array_reverse %}
<tr>
<td>
{{comment.text}}
<br />
{{'PLUGIN_COMMENTS.WRITTEN_ON'|t}} {{comment.date|e}} {{'PLUGIN_COMMENTS.BY'|t}} {{comment.author}}
</td>
</tr>
{% endfor %}
</table>
{% endif %}
{% endif %}