Works with the Form plugin
This commit is contained in:
		
							parent
							
								
									6ce186584e
								
							
						
					
					
						commit
						5f50c08970
					
				
					 8 changed files with 221 additions and 404 deletions
				
			
		| 
						 | 
					@ -45,9 +45,9 @@ For example, in Antimatter, in `templates/item.html.twig`:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The comment form will appear to the blog post items.
 | 
					The comment form will appear to the blog post items.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Enable the Captcha anti-spam filter
 | 
					# Enabling Recaptcha
 | 
				
			||||||
 | 
					
 | 
				
			||||||
To reduce spam in your comments, enable the Google Recaptcha integration we added. Copy the plugin's `comments.yaml` to `user/config/plugins/comments.yaml` and enable `use_captcha`. Also add the Google Recaptcha API keys to allow it to work correctly.
 | 
					The plugin comes with Recaptcha integration. To make it work, add your own Recaptcha `site` and `secret` keys the the plugin yaml config file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Where are the comments stored?
 | 
					# Where are the comments stored?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -61,7 +61,7 @@ Further improvements to the comments visualization will be added in the next rel
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Email notifications
 | 
					# Email notifications
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Upon receiving a comment, if `enable_email_notifications` is enabled, the Comments plugin will send an email to the `notifications_email_to` address set in the plugin options.
 | 
					The plugin interacts with the Email plugin to send emails upon receiving a comment.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Things still missing
 | 
					# Things still missing
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -105,6 +105,33 @@
 | 
				
			||||||
        <p class="center">Showing <span class="totalRetrieved">{{grav.twig.comments.totalRetrieved}}</span> comments of <span class="totalAvailable">{{grav.twig.comments.totalAvailable}}</span></p>
 | 
					        <p class="center">Showing <span class="totalRetrieved">{{grav.twig.comments.totalRetrieved}}</span> comments of <span class="totalAvailable">{{grav.twig.comments.totalAvailable}}</span></p>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <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"><strong>Page</strong>: {{page.lastCommentDate}}</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 %}
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{% endblock %}
 | 
					{% endblock %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										31
									
								
								blueprints.yaml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								blueprints.yaml
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,31 @@
 | 
				
			||||||
 | 
					name: Comments
 | 
				
			||||||
 | 
					version: 0.1.0
 | 
				
			||||||
 | 
					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 status
 | 
				
			||||||
 | 
					      highlight: 1
 | 
				
			||||||
 | 
					      default: 0
 | 
				
			||||||
 | 
					      options:
 | 
				
			||||||
 | 
					        1: Enabled
 | 
				
			||||||
 | 
					        0: Disabled
 | 
				
			||||||
 | 
					      validate:
 | 
				
			||||||
 | 
					        type: bool
 | 
				
			||||||
							
								
								
									
										104
									
								
								comments.php
									
										
									
									
									
								
							
							
						
						
									
										104
									
								
								comments.php
									
										
									
									
									
								
							| 
						 | 
					@ -23,9 +23,27 @@ class CommentsPlugin extends Plugin
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return [
 | 
					        return [
 | 
				
			||||||
            'onPluginsInitialized' => ['onPluginsInitialized', 0],
 | 
					            'onPluginsInitialized' => ['onPluginsInitialized', 0],
 | 
				
			||||||
 | 
					            'onFormProcessed' => ['onFormProcessed', 0],
 | 
				
			||||||
 | 
					            'onPageInitialized' => ['onPageInitialized', 0],
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Initialize form if the page has one. Also catches form processing if user posts the form.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function onPageInitialized()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        /** @var Page $page */
 | 
				
			||||||
 | 
					        $page = $this->grav['page'];
 | 
				
			||||||
 | 
					        if (!$page) {
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $header = $page->header();
 | 
				
			||||||
 | 
					        $header->form = $this->grav['config']->get('plugins.comments.form');
 | 
				
			||||||
 | 
					        $page->header($header);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public function onPluginsInitialized()
 | 
					    public function onPluginsInitialized()
 | 
				
			||||||
| 
						 | 
					@ -36,15 +54,7 @@ class CommentsPlugin extends Plugin
 | 
				
			||||||
                'onTwigTemplatePaths' => ['onTwigTemplatePaths', 0],
 | 
					                '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();
 | 
					            $this->grav['twig']->comments = $this->fetchComments();
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -74,8 +84,23 @@ class CommentsPlugin extends Plugin
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function addComment()
 | 
					    /**
 | 
				
			||||||
 | 
					     * 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 = !empty($_POST) ? $_POST : [];
 | 
					                $post = !empty($_POST) ? $_POST : [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                $lang = filter_var(urldecode($post['lang']), FILTER_SANITIZE_STRING);
 | 
					                $lang = filter_var(urldecode($post['lang']), FILTER_SANITIZE_STRING);
 | 
				
			||||||
| 
						 | 
					@ -84,20 +109,9 @@ class CommentsPlugin extends Plugin
 | 
				
			||||||
                $name = filter_var(urldecode($post['name']), FILTER_SANITIZE_STRING);
 | 
					                $name = filter_var(urldecode($post['name']), FILTER_SANITIZE_STRING);
 | 
				
			||||||
                $email = filter_var(urldecode($post['email']), FILTER_SANITIZE_STRING);
 | 
					                $email = filter_var(urldecode($post['email']), FILTER_SANITIZE_STRING);
 | 
				
			||||||
                $title = filter_var(urldecode($post['title']), FILTER_SANITIZE_STRING);
 | 
					                $title = filter_var(urldecode($post['title']), FILTER_SANITIZE_STRING);
 | 
				
			||||||
 | 
					                /** @var Language $language */
 | 
				
			||||||
        if ($this->config->get('plugins.comments.use_captcha')) {
 | 
					                $language = $this->grav['language'];
 | 
				
			||||||
            //Validate the captcha
 | 
					                $lang = $language->getLanguage();
 | 
				
			||||||
            $recaptchaResponse = filter_var(urldecode($post['recaptchaResponse']), FILTER_SANITIZE_STRING);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            $url = 'https://www.google.com/recaptcha/api/siteverify?secret=';
 | 
					 | 
				
			||||||
            $url .= $this->config->get('plugins.comments.recatpcha_secret');
 | 
					 | 
				
			||||||
            $url .= '&response=' . $recaptchaResponse;
 | 
					 | 
				
			||||||
            $response = json_decode(file_get_contents($url), true);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if ($response['success'] == false) {
 | 
					 | 
				
			||||||
                throw new \RuntimeException('Error validating the Captcha');
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                $filename = DATA_DIR . 'comments';
 | 
					                $filename = DATA_DIR . 'comments';
 | 
				
			||||||
                $filename .= ($lang ? '/' . $lang : '');
 | 
					                $filename .= ($lang ? '/' . $lang : '');
 | 
				
			||||||
| 
						 | 
					@ -127,41 +141,8 @@ class CommentsPlugin extends Plugin
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                $file->save(Yaml::dump($data));
 | 
					                $file->save(Yaml::dump($data));
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
        if (isset($this->grav['Email']) && $this->grav['config']->get('plugins.comments.enable_email_notifications')) {
 | 
					 | 
				
			||||||
            $this->sendEmailNotification(array(
 | 
					 | 
				
			||||||
                'title' => $title,
 | 
					 | 
				
			||||||
                'comment' => array(
 | 
					 | 
				
			||||||
                    'text' => $text,
 | 
					 | 
				
			||||||
                    'date' => gmdate('D, d M Y H:i:s', time()),
 | 
					 | 
				
			||||||
                    'author' => $name,
 | 
					 | 
				
			||||||
                    'email' => $email
 | 
					 | 
				
			||||||
                )
 | 
					 | 
				
			||||||
            ));
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					 | 
				
			||||||
        exit();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private function sendEmailNotification($comment) {
 | 
					 | 
				
			||||||
        /** @var Language $l */
 | 
					 | 
				
			||||||
        $l = $this->grav['language'];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $sitename = $this->grav['config']->get('site.title', 'Website');
 | 
					 | 
				
			||||||
        $from = $this->grav['config']->get('plugins.email.from', 'noreply@getgrav.org');
 | 
					 | 
				
			||||||
        $to = $this->grav['config']->get('plugins.email.email');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $subject = $l->translate(['PLUGIN_COMMENTS.NEW_COMMENT_EMAIL_SUBJECT', $sitename]);
 | 
					 | 
				
			||||||
        $content = $l->translate(['PLUGIN_COMMENTS.NEW_COMMENT_EMAIL_BODY', $sitename, $comment['title'], $comment['comment']['text'], $comment['comment']['author'], $comment['comment']['email']]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $twig = $this->grav['twig'];
 | 
					 | 
				
			||||||
        $body = $twig->processTemplate('email/base.html.twig', ['content' => $content]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $message = $this->grav['Email']->message($subject, $body, 'text/html')
 | 
					 | 
				
			||||||
            ->setFrom($from)
 | 
					 | 
				
			||||||
            ->setTo($to);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $sent = $this->grav['Email']->send($message);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private function getFilesOrderedByModifiedDate($path = '') {
 | 
					    private function getFilesOrderedByModifiedDate($path = '') {
 | 
				
			||||||
| 
						 | 
					@ -242,15 +223,8 @@ class CommentsPlugin extends Plugin
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $totalAvailable = count($comments);
 | 
					        $totalAvailable = count($comments);
 | 
				
			||||||
 | 
					 | 
				
			||||||
        $comments = array_slice($comments, $page * $number, $number);
 | 
					        $comments = array_slice($comments, $page * $number, $number);
 | 
				
			||||||
 | 
					 | 
				
			||||||
        $totalRetrieved = count($comments);
 | 
					        $totalRetrieved = count($comments);
 | 
				
			||||||
        $hasMore = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if ($totalAvailable > $totalRetrieved) {
 | 
					 | 
				
			||||||
            $hasMore = true;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return (object)array(
 | 
					        return (object)array(
 | 
				
			||||||
            "comments" => $comments,
 | 
					            "comments" => $comments,
 | 
				
			||||||
| 
						 | 
					@ -264,7 +238,7 @@ class CommentsPlugin extends Plugin
 | 
				
			||||||
     * Return the comments associated to the current route
 | 
					     * Return the comments associated to the current route
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    private function fetchComments() {
 | 
					    private function fetchComments() {
 | 
				
			||||||
        $lang = $this->grav['language']->getActive();
 | 
					        $lang = $this->grav['language']->getLanguage();
 | 
				
			||||||
        $filename = $lang ? '/' . $lang : '';
 | 
					        $filename = $lang ? '/' . $lang : '';
 | 
				
			||||||
        $filename .= $this->grav['uri']->path() . '.yaml';
 | 
					        $filename .= $this->grav['uri']->path() . '.yaml';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,68 @@
 | 
				
			||||||
enabled: true
 | 
					enabled: true
 | 
				
			||||||
use_captcha: false
 | 
					form:
 | 
				
			||||||
recatpcha_site_key: ''
 | 
					    name: comments
 | 
				
			||||||
recatpcha_secret: ''
 | 
					    fields:
 | 
				
			||||||
enable_email_notifications: false
 | 
					        - name: name
 | 
				
			||||||
notifications_email_to: 'noreply@getgrav.org'
 | 
					          label: Name
 | 
				
			||||||
 | 
					          placeholder: Enter your name
 | 
				
			||||||
 | 
					          autofocus: on
 | 
				
			||||||
 | 
					          autocomplete: on
 | 
				
			||||||
 | 
					          type: text
 | 
				
			||||||
 | 
					          validate:
 | 
				
			||||||
 | 
					            required: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        - name: email
 | 
				
			||||||
 | 
					          label: Email
 | 
				
			||||||
 | 
					          placeholder: Enter your email address
 | 
				
			||||||
 | 
					          type: email
 | 
				
			||||||
 | 
					          validate:
 | 
				
			||||||
 | 
					            required: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        - name: text
 | 
				
			||||||
 | 
					          label: Message
 | 
				
			||||||
 | 
					          placeholder: Enter your message
 | 
				
			||||||
 | 
					          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
 | 
				
			||||||
 | 
					        #   recatpcha_site_key: 6Lde4gwTAAAAAAZuv4z2AgVU6Xamn5twDYzQr8hv
 | 
				
			||||||
 | 
					        #   recaptcha_not_validated: 'Captcha not valid!'
 | 
				
			||||||
 | 
					        #   validate:
 | 
				
			||||||
 | 
					        #     required: true
 | 
				
			||||||
 | 
					        #   process:
 | 
				
			||||||
 | 
					        #     ignore: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    buttons:
 | 
				
			||||||
 | 
					        - type: submit
 | 
				
			||||||
 | 
					          value: Submit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    process:
 | 
				
			||||||
 | 
					        # - email:
 | 
				
			||||||
 | 
					        #     subject: "[Site Guestbook] {{ form.value.name|e }}"
 | 
				
			||||||
 | 
					        #     body: "{% include 'forms/data.html.twig' %}"
 | 
				
			||||||
 | 
					        # - captcha:
 | 
				
			||||||
 | 
					        #     recatpcha_secret: 6Lde4gwTAAAAAPpwVKuaYm53n2bWfFfxcDxSlI54
 | 
				
			||||||
 | 
					        - addComment:
 | 
				
			||||||
 | 
					        - message: Thank you for writing your comment!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,6 @@
 | 
				
			||||||
en:
 | 
					en:
 | 
				
			||||||
  PLUGIN_COMMENTS:
 | 
					  PLUGIN_COMMENTS:
 | 
				
			||||||
 | 
					    ADD_COMMENT: Add a comment
 | 
				
			||||||
    COMMENTS: Comments
 | 
					    COMMENTS: Comments
 | 
				
			||||||
    EMAIL_NOT_CONFIGURED: Email not configured
 | 
					    EMAIL_NOT_CONFIGURED: Email not configured
 | 
				
			||||||
    NEW_COMMENT_EMAIL_SUBJECT: 'New comment on %1$s'
 | 
					    NEW_COMMENT_EMAIL_SUBJECT: 'New comment on %1$s'
 | 
				
			||||||
| 
						 | 
					@ -11,6 +12,7 @@ en:
 | 
				
			||||||
    BY: by
 | 
					    BY: by
 | 
				
			||||||
it:
 | 
					it:
 | 
				
			||||||
  PLUGIN_COMMENTS:
 | 
					  PLUGIN_COMMENTS:
 | 
				
			||||||
 | 
					    ADD_COMMENT: Aggiungi un commento
 | 
				
			||||||
    COMMENTS: Commenti
 | 
					    COMMENTS: Commenti
 | 
				
			||||||
    EMAIL_NOT_CONFIGURED: Email non configurata
 | 
					    EMAIL_NOT_CONFIGURED: Email non configurata
 | 
				
			||||||
    NEW_COMMENT_EMAIL_SUBJECT: 'Nuovo commento su %1$s'
 | 
					    NEW_COMMENT_EMAIL_SUBJECT: 'Nuovo commento su %1$s'
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,194 +0,0 @@
 | 
				
			||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 | 
					 | 
				
			||||||
<html xmlns="http://www.w3.org/1999/xhtml">
 | 
					 | 
				
			||||||
<head>
 | 
					 | 
				
			||||||
    <meta name="viewport" content="width=device-width" />
 | 
					 | 
				
			||||||
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
 | 
					 | 
				
			||||||
    <title>Comments Email Template</title>
 | 
					 | 
				
			||||||
    <style>
 | 
					 | 
				
			||||||
        /* -------------------------------------
 | 
					 | 
				
			||||||
                GLOBAL
 | 
					 | 
				
			||||||
        ------------------------------------- */
 | 
					 | 
				
			||||||
        * {
 | 
					 | 
				
			||||||
            margin: 0;
 | 
					 | 
				
			||||||
            padding: 0;
 | 
					 | 
				
			||||||
            font-family: "Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif;
 | 
					 | 
				
			||||||
            font-size: 100%;
 | 
					 | 
				
			||||||
            line-height: 1.6;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        img {
 | 
					 | 
				
			||||||
            max-width: 100%;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        body {
 | 
					 | 
				
			||||||
            -webkit-font-smoothing: antialiased;
 | 
					 | 
				
			||||||
            -webkit-text-size-adjust: none;
 | 
					 | 
				
			||||||
            width: 100%!important;
 | 
					 | 
				
			||||||
            height: 100%;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        /* -------------------------------------
 | 
					 | 
				
			||||||
                ELEMENTS
 | 
					 | 
				
			||||||
        ------------------------------------- */
 | 
					 | 
				
			||||||
        a {
 | 
					 | 
				
			||||||
            color: #348eda;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        .btn-primary {
 | 
					 | 
				
			||||||
            text-decoration: none;
 | 
					 | 
				
			||||||
            color: #FFF;
 | 
					 | 
				
			||||||
            background-color: #348eda;
 | 
					 | 
				
			||||||
            border: solid #348eda;
 | 
					 | 
				
			||||||
            border-width: 10px 20px;
 | 
					 | 
				
			||||||
            line-height: 2;
 | 
					 | 
				
			||||||
            font-weight: bold;
 | 
					 | 
				
			||||||
            margin-right: 10px;
 | 
					 | 
				
			||||||
            text-align: center;
 | 
					 | 
				
			||||||
            cursor: pointer;
 | 
					 | 
				
			||||||
            display: inline-block;
 | 
					 | 
				
			||||||
            border-radius: 25px;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        .btn-secondary {
 | 
					 | 
				
			||||||
            text-decoration: none;
 | 
					 | 
				
			||||||
            color: #FFF;
 | 
					 | 
				
			||||||
            background-color: #aaa;
 | 
					 | 
				
			||||||
            border: solid #aaa;
 | 
					 | 
				
			||||||
            border-width: 10px 20px;
 | 
					 | 
				
			||||||
            line-height: 2;
 | 
					 | 
				
			||||||
            font-weight: bold;
 | 
					 | 
				
			||||||
            margin-right: 10px;
 | 
					 | 
				
			||||||
            text-align: center;
 | 
					 | 
				
			||||||
            cursor: pointer;
 | 
					 | 
				
			||||||
            display: inline-block;
 | 
					 | 
				
			||||||
            border-radius: 25px;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        .last {
 | 
					 | 
				
			||||||
            margin-bottom: 0;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        .first {
 | 
					 | 
				
			||||||
            margin-top: 0;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        .padding {
 | 
					 | 
				
			||||||
            padding: 10px 0;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        /* -------------------------------------
 | 
					 | 
				
			||||||
                BODY
 | 
					 | 
				
			||||||
        ------------------------------------- */
 | 
					 | 
				
			||||||
        table.body-wrap {
 | 
					 | 
				
			||||||
            width: 100%;
 | 
					 | 
				
			||||||
            padding: 20px;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        table.body-wrap .container {
 | 
					 | 
				
			||||||
            border: 1px solid #f0f0f0;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        /* -------------------------------------
 | 
					 | 
				
			||||||
                FOOTER
 | 
					 | 
				
			||||||
        ------------------------------------- */
 | 
					 | 
				
			||||||
        table.footer-wrap {
 | 
					 | 
				
			||||||
            width: 100%;
 | 
					 | 
				
			||||||
            clear: both!important;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        .footer-wrap .container p {
 | 
					 | 
				
			||||||
            font-size: 12px;
 | 
					 | 
				
			||||||
            color: #666;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        table.footer-wrap a {
 | 
					 | 
				
			||||||
            color: #999;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        /* -------------------------------------
 | 
					 | 
				
			||||||
                TYPOGRAPHY
 | 
					 | 
				
			||||||
        ------------------------------------- */
 | 
					 | 
				
			||||||
        h1, h2, h3 {
 | 
					 | 
				
			||||||
            font-family: "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
 | 
					 | 
				
			||||||
            color: #000;
 | 
					 | 
				
			||||||
            margin: 40px 0 10px;
 | 
					 | 
				
			||||||
            line-height: 1.2;
 | 
					 | 
				
			||||||
            font-weight: 200;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        h1 {
 | 
					 | 
				
			||||||
            font-size: 36px;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        h2 {
 | 
					 | 
				
			||||||
            font-size: 28px;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        h3 {
 | 
					 | 
				
			||||||
            font-size: 22px;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        p, ul, ol {
 | 
					 | 
				
			||||||
            margin-bottom: 10px;
 | 
					 | 
				
			||||||
            font-weight: normal;
 | 
					 | 
				
			||||||
            font-size: 14px;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        ul li, ol li {
 | 
					 | 
				
			||||||
            margin-left: 5px;
 | 
					 | 
				
			||||||
            list-style-position: inside;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        /* ---------------------------------------------------
 | 
					 | 
				
			||||||
                RESPONSIVENESS
 | 
					 | 
				
			||||||
                Nuke it from orbit. It's the only way to be sure.
 | 
					 | 
				
			||||||
        ------------------------------------------------------ */
 | 
					 | 
				
			||||||
        /* Set a max-width, and make it display as block so it will automatically stretch to that width, but will also shrink down on a phone or something */
 | 
					 | 
				
			||||||
        .container {
 | 
					 | 
				
			||||||
            display: block!important;
 | 
					 | 
				
			||||||
            max-width: 600px!important;
 | 
					 | 
				
			||||||
            margin: 0 auto!important; /* makes it centered */
 | 
					 | 
				
			||||||
            clear: both!important;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        /* Set the padding on the td rather than the div for Outlook compatibility */
 | 
					 | 
				
			||||||
        .body-wrap .container {
 | 
					 | 
				
			||||||
            padding: 20px;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        /* This should also be a block element, so that it will fill 100% of the .container */
 | 
					 | 
				
			||||||
        .content {
 | 
					 | 
				
			||||||
            max-width: 600px;
 | 
					 | 
				
			||||||
            margin: 0 auto;
 | 
					 | 
				
			||||||
            display: block;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        /* Let's make sure tables in the content area are 100% wide */
 | 
					 | 
				
			||||||
        .content table {
 | 
					 | 
				
			||||||
            width: 100%;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    </style>
 | 
					 | 
				
			||||||
</head>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<body bgcolor="#f6f6f6">
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<!-- body -->
 | 
					 | 
				
			||||||
<table class="body-wrap" bgcolor="#f6f6f6">
 | 
					 | 
				
			||||||
    <tr>
 | 
					 | 
				
			||||||
        <td></td>
 | 
					 | 
				
			||||||
        <td class="container" bgcolor="#FFFFFF">
 | 
					 | 
				
			||||||
            <div class="content">
 | 
					 | 
				
			||||||
                <table>
 | 
					 | 
				
			||||||
                    <tr>
 | 
					 | 
				
			||||||
                        <td>
 | 
					 | 
				
			||||||
                            {{ content }}
 | 
					 | 
				
			||||||
                        </td>
 | 
					 | 
				
			||||||
                    </tr>
 | 
					 | 
				
			||||||
                </table>
 | 
					 | 
				
			||||||
            </div>
 | 
					 | 
				
			||||||
        </td>
 | 
					 | 
				
			||||||
        <td></td>
 | 
					 | 
				
			||||||
    </tr>
 | 
					 | 
				
			||||||
</table>
 | 
					 | 
				
			||||||
<!-- /body -->
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<!-- footer -->
 | 
					 | 
				
			||||||
<table class="footer-wrap">
 | 
					 | 
				
			||||||
    <tr>
 | 
					 | 
				
			||||||
        <td></td>
 | 
					 | 
				
			||||||
        <td class="container">
 | 
					 | 
				
			||||||
            <div class="content">
 | 
					 | 
				
			||||||
                <table>
 | 
					 | 
				
			||||||
                    <tr>
 | 
					 | 
				
			||||||
                        <td align="center">
 | 
					 | 
				
			||||||
                            {{ 'PLUGIN_COMMENTS.EMAIL_FOOTER'|tu }}
 | 
					 | 
				
			||||||
                        </td>
 | 
					 | 
				
			||||||
                    </tr>
 | 
					 | 
				
			||||||
                </table>
 | 
					 | 
				
			||||||
            </div>
 | 
					 | 
				
			||||||
        </td>
 | 
					 | 
				
			||||||
        <td></td>
 | 
					 | 
				
			||||||
    </tr>
 | 
					 | 
				
			||||||
</table>
 | 
					 | 
				
			||||||
<!-- /footer -->
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
</body>
 | 
					 | 
				
			||||||
</html>
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,113 +1,28 @@
 | 
				
			||||||
{% set use_captcha = grav.config.plugins.comments.use_captcha %}
 | 
					<h3>{{'PLUGIN_COMMENTS.ADD_COMMENT'|t}}</h3>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<h3>Add a Comment</h3>
 | 
					<form name="{{ grav.config.plugins.comments.form.name }}"
 | 
				
			||||||
 | 
					      action="{{ uri.rootUrl ~ (grav.config.plugins.comments.form.action|default(page.route)) }}/processform:true"
 | 
				
			||||||
 | 
					      method="{{ grav.config.plugins.comments.form.method|upper|default('POST') }}">
 | 
				
			||||||
 | 
					{% for field in grav.config.plugins.comments.form.fields %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script>
 | 
					    {% set value = form.value(field.name) %}
 | 
				
			||||||
$(function() {
 | 
					    {% if field.evaluateDefault %}
 | 
				
			||||||
    function validateEmail(email) {
 | 
					        {% set value = evaluate(field.evaluateDefault) %}
 | 
				
			||||||
        var re = /^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i;
 | 
					 | 
				
			||||||
        return re.test(email);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    $(document).on('click tap', '.js__add-new-comment', function(event) {
 | 
					 | 
				
			||||||
        event.preventDefault();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        var text = $('.js__new-comment-text').val();
 | 
					 | 
				
			||||||
        var name = $('.js__new-comment-name').val();
 | 
					 | 
				
			||||||
        var email = $('.js__new-comment-email').val();
 | 
					 | 
				
			||||||
        var captcha = $('#g-recaptcha-response').val();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (text.length == 0 || email.length == 0 || name.length == 0) {
 | 
					 | 
				
			||||||
            $('.alert').html('Please fill all the fields');
 | 
					 | 
				
			||||||
            $('.alert-container').show();
 | 
					 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (!validateEmail(email)) {
 | 
					 | 
				
			||||||
            $('.alert').html('Please enter a valid email');
 | 
					 | 
				
			||||||
            $('.alert-container').show();
 | 
					 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        {% if use_captcha %}
 | 
					 | 
				
			||||||
        if (!captcha) {
 | 
					 | 
				
			||||||
            $('.alert').html("Error validating the security code");
 | 
					 | 
				
			||||||
            $('.alert-container').show();
 | 
					 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    {% endif %}
 | 
					    {% endif %}
 | 
				
			||||||
 | 
					    <div>
 | 
				
			||||||
 | 
					        {% include "forms/fields/#{field.type}/#{field.type}.html.twig" %}
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					{% endfor %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $.ajax({
 | 
					    <div class="buttons">
 | 
				
			||||||
            url: "{{ grav.uri.rootUrl }}/add-comment",
 | 
					    {% for button in grav.config.plugins.comments.form.buttons %}
 | 
				
			||||||
            data: {
 | 
					        <button class="button" type="{{ button.type|default('submit') }}">{{ button.value|default('Submit') }}</button>
 | 
				
			||||||
                text: $('.js__new-comment-text').val(),
 | 
					    {% endfor %}
 | 
				
			||||||
                name: $('.js__new-comment-name').val(),
 | 
					    </div>
 | 
				
			||||||
                email: $('.js__new-comment-email').val(),
 | 
					 | 
				
			||||||
                title: "{{ grav.page.header.title }}",
 | 
					 | 
				
			||||||
                lang: "{{ grav.language.getActive }}",
 | 
					 | 
				
			||||||
                path: "{{ grav.uri.path }}",
 | 
					 | 
				
			||||||
                {% if use_captcha %}recaptchaResponse: captcha{% endif %}
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            type: 'POST'
 | 
					 | 
				
			||||||
        })
 | 
					 | 
				
			||||||
        .success(function() {
 | 
					 | 
				
			||||||
            $('.alert-container').hide();
 | 
					 | 
				
			||||||
            window.location.reload();
 | 
					 | 
				
			||||||
        })
 | 
					 | 
				
			||||||
        .error(function() {
 | 
					 | 
				
			||||||
            $('.alert').html("Error while posting the comment");
 | 
					 | 
				
			||||||
            $('.alert-container').show();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
</script>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% if use_captcha %}
 | 
					 | 
				
			||||||
    <script src="https://www.google.com/recaptcha/api.js?onload=captchaOnloadCallback&render=explicit" async defer></script>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <script>
 | 
					 | 
				
			||||||
        $(function() {
 | 
					 | 
				
			||||||
            var captchaOnloadCallback = function captchaOnloadCallback() {
 | 
					 | 
				
			||||||
                grecaptcha.render('g-recaptcha', {
 | 
					 | 
				
			||||||
                    'sitekey': "{{grav.config.plugins.comments.recatpcha_site_key}}",
 | 
					 | 
				
			||||||
                    'callback': captchaValidatedCallback,
 | 
					 | 
				
			||||||
                    'expired-callback': captchaExpiredCallback
 | 
					 | 
				
			||||||
                });
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            var captchaValidatedCallback = function captchaValidatedCallback() {
 | 
					 | 
				
			||||||
            };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            var captchaExpiredCallback = function captchaExpiredCallback() {
 | 
					 | 
				
			||||||
                grecaptcha.reset();
 | 
					 | 
				
			||||||
            };
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    </script>
 | 
					 | 
				
			||||||
{% endif %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<div class="alert-container" style="display: none">
 | 
					 | 
				
			||||||
    <blockquote>
 | 
					 | 
				
			||||||
        <blockquote>
 | 
					 | 
				
			||||||
            <blockquote>
 | 
					 | 
				
			||||||
                <blockquote>
 | 
					 | 
				
			||||||
                    <p class="alert"></p>
 | 
					 | 
				
			||||||
                </blockquote>
 | 
					 | 
				
			||||||
            </blockquote>
 | 
					 | 
				
			||||||
        </blockquote>
 | 
					 | 
				
			||||||
    </blockquote>
 | 
					 | 
				
			||||||
</div>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<form>
 | 
					 | 
				
			||||||
    <textarea class="js__new-comment-text"></textarea>
 | 
					 | 
				
			||||||
    {{'PLUGIN_COMMENTS.NAME'|t}} <input type="text" class="js__new-comment-name" />
 | 
					 | 
				
			||||||
    {{'PLUGIN_COMMENTS.EMAIL'|t}} <input type="email" class="js__new-comment-email" />
 | 
					 | 
				
			||||||
    {% if use_captcha %}
 | 
					 | 
				
			||||||
        <div class="g-recaptcha" id="g-recaptcha"></div>
 | 
					 | 
				
			||||||
    {% endif %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <input type="submit" class="js__add-new-comment" />
 | 
					 | 
				
			||||||
</form>
 | 
					</form>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div class="alert">{{ form.message }}</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{% if grav.twig.comments|length %}
 | 
					{% if grav.twig.comments|length %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <h3>{{'PLUGIN_COMMENTS.COMMENTS'|t}}</h3>
 | 
					    <h3>{{'PLUGIN_COMMENTS.COMMENTS'|t}}</h3>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue