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.
 | 
			
		||||
 | 
			
		||||
# 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?
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -61,7 +61,7 @@ Further improvements to the comments visualization will be added in the next rel
 | 
			
		|||
 | 
			
		||||
# 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
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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>
 | 
			
		||||
    </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 %}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										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
 | 
			
		||||
							
								
								
									
										170
									
								
								comments.php
									
										
									
									
									
								
							
							
						
						
									
										170
									
								
								comments.php
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -23,9 +23,27 @@ class CommentsPlugin extends Plugin
 | 
			
		|||
    {
 | 
			
		||||
        return [
 | 
			
		||||
            '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()
 | 
			
		||||
| 
						 | 
				
			
			@ -36,15 +54,7 @@ class CommentsPlugin extends Plugin
 | 
			
		|||
                '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 {
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -74,94 +84,65 @@ class CommentsPlugin extends Plugin
 | 
			
		|||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function addComment()
 | 
			
		||||
    /**
 | 
			
		||||
     * Handle form processing instructions.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Event $event
 | 
			
		||||
     */
 | 
			
		||||
    public function onFormProcessed(Event $event)
 | 
			
		||||
    {
 | 
			
		||||
        $post = !empty($_POST) ? $_POST : [];
 | 
			
		||||
        $form = $event['form'];
 | 
			
		||||
        $action = $event['action'];
 | 
			
		||||
        $params = $event['params'];
 | 
			
		||||
 | 
			
		||||
        $lang = filter_var(urldecode($post['lang']), FILTER_SANITIZE_STRING);
 | 
			
		||||
        $path = filter_var(urldecode($post['path']), 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 ($this->config->get('plugins.comments.use_captcha')) {
 | 
			
		||||
            //Validate the captcha
 | 
			
		||||
            $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');
 | 
			
		||||
            }
 | 
			
		||||
        if (!$this->active) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $filename = DATA_DIR . 'comments';
 | 
			
		||||
        $filename .= ($lang ? '/' . $lang : '');
 | 
			
		||||
        $filename .= $path . '.yaml';
 | 
			
		||||
        $file = File::instance($filename);
 | 
			
		||||
        switch ($action) {
 | 
			
		||||
            case 'addComment':
 | 
			
		||||
                $post = !empty($_POST) ? $_POST : [];
 | 
			
		||||
 | 
			
		||||
        if (file_exists($filename)) {
 | 
			
		||||
            $data = Yaml::parse($file->content());
 | 
			
		||||
                $lang = filter_var(urldecode($post['lang']), FILTER_SANITIZE_STRING);
 | 
			
		||||
                $path = filter_var(urldecode($post['path']), 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);
 | 
			
		||||
                /** @var Language $language */
 | 
			
		||||
                $language = $this->grav['language'];
 | 
			
		||||
                $lang = $language->getLanguage();
 | 
			
		||||
 | 
			
		||||
            $data['comments'][] = [
 | 
			
		||||
                'text' => $text,
 | 
			
		||||
                'date' => gmdate('D, d M Y H:i:s', time()),
 | 
			
		||||
                'author' => $name,
 | 
			
		||||
                'email' => $email
 | 
			
		||||
            ];
 | 
			
		||||
        } else {
 | 
			
		||||
            $data = array(
 | 
			
		||||
                'title' => $title,
 | 
			
		||||
                'lang' => $lang,
 | 
			
		||||
                'comments' => array([
 | 
			
		||||
                    'text' => $text,
 | 
			
		||||
                    'date' => gmdate('D, d M Y H:i:s', time()),
 | 
			
		||||
                    'author' => $name,
 | 
			
		||||
                    'email' => $email
 | 
			
		||||
                ])
 | 
			
		||||
            );
 | 
			
		||||
                $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' => gmdate('D, d M Y H:i:s', time()),
 | 
			
		||||
                        'author' => $name,
 | 
			
		||||
                        'email' => $email
 | 
			
		||||
                    ];
 | 
			
		||||
                } else {
 | 
			
		||||
                    $data = array(
 | 
			
		||||
                        'title' => $title,
 | 
			
		||||
                        'lang' => $lang,
 | 
			
		||||
                        'comments' => array([
 | 
			
		||||
                            'text' => $text,
 | 
			
		||||
                            'date' => gmdate('D, d M Y H:i:s', time()),
 | 
			
		||||
                            'author' => $name,
 | 
			
		||||
                            'email' => $email
 | 
			
		||||
                        ])
 | 
			
		||||
                    );
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                $file->save(Yaml::dump($data));
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $file->save(Yaml::dump($data));
 | 
			
		||||
 | 
			
		||||
        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 = '') {
 | 
			
		||||
| 
						 | 
				
			
			@ -242,15 +223,8 @@ class CommentsPlugin extends Plugin
 | 
			
		|||
        });
 | 
			
		||||
 | 
			
		||||
        $totalAvailable = count($comments);
 | 
			
		||||
 | 
			
		||||
        $comments = array_slice($comments, $page * $number, $number);
 | 
			
		||||
 | 
			
		||||
        $totalRetrieved = count($comments);
 | 
			
		||||
        $hasMore = false;
 | 
			
		||||
 | 
			
		||||
        if ($totalAvailable > $totalRetrieved) {
 | 
			
		||||
            $hasMore = true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return (object)array(
 | 
			
		||||
            "comments" => $comments,
 | 
			
		||||
| 
						 | 
				
			
			@ -264,7 +238,7 @@ class CommentsPlugin extends Plugin
 | 
			
		|||
     * Return the comments associated to the current route
 | 
			
		||||
     */
 | 
			
		||||
    private function fetchComments() {
 | 
			
		||||
        $lang = $this->grav['language']->getActive();
 | 
			
		||||
        $lang = $this->grav['language']->getLanguage();
 | 
			
		||||
        $filename = $lang ? '/' . $lang : '';
 | 
			
		||||
        $filename .= $this->grav['uri']->path() . '.yaml';
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,68 @@
 | 
			
		|||
enabled: true
 | 
			
		||||
use_captcha: false
 | 
			
		||||
recatpcha_site_key: ''
 | 
			
		||||
recatpcha_secret: ''
 | 
			
		||||
enable_email_notifications: false
 | 
			
		||||
notifications_email_to: 'noreply@getgrav.org'
 | 
			
		||||
form:
 | 
			
		||||
    name: comments
 | 
			
		||||
    fields:
 | 
			
		||||
        - name: name
 | 
			
		||||
          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:
 | 
			
		||||
  PLUGIN_COMMENTS:
 | 
			
		||||
    ADD_COMMENT: Add a comment
 | 
			
		||||
    COMMENTS: Comments
 | 
			
		||||
    EMAIL_NOT_CONFIGURED: Email not configured
 | 
			
		||||
    NEW_COMMENT_EMAIL_SUBJECT: 'New comment on %1$s'
 | 
			
		||||
| 
						 | 
				
			
			@ -11,6 +12,7 @@ en:
 | 
			
		|||
    BY: by
 | 
			
		||||
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'
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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>
 | 
			
		||||
$(function() {
 | 
			
		||||
    function validateEmail(email) {
 | 
			
		||||
        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 %}
 | 
			
		||||
 | 
			
		||||
        $.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(),
 | 
			
		||||
                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>
 | 
			
		||||
    {% set value = form.value(field.name) %}
 | 
			
		||||
    {% if field.evaluateDefault %}
 | 
			
		||||
        {% set value = evaluate(field.evaluateDefault) %}
 | 
			
		||||
    {% endif %}
 | 
			
		||||
    <div>
 | 
			
		||||
        {% include "forms/fields/#{field.type}/#{field.type}.html.twig" %}
 | 
			
		||||
    </div>
 | 
			
		||||
{% endfor %}
 | 
			
		||||
 | 
			
		||||
    <input type="submit" class="js__add-new-comment" />
 | 
			
		||||
    <div class="buttons">
 | 
			
		||||
    {% for button in grav.config.plugins.comments.form.buttons %}
 | 
			
		||||
        <button class="button" type="{{ button.type|default('submit') }}">{{ button.value|default('Submit') }}</button>
 | 
			
		||||
    {% endfor %}
 | 
			
		||||
    </div>
 | 
			
		||||
</form>
 | 
			
		||||
 | 
			
		||||
<div class="alert">{{ form.message }}</div>
 | 
			
		||||
 | 
			
		||||
{% if grav.twig.comments|length %}
 | 
			
		||||
 | 
			
		||||
    <h3>{{'PLUGIN_COMMENTS.COMMENTS'|t}}</h3>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue