Merge https://github.com/codeshell/grav-plugin-comments into develop
This commit is contained in:
commit
be0eca0ff5
|
@ -1,6 +1,6 @@
|
|||
# Grav Comments Plugin \[Fork\]
|
||||
|
||||
This plugin adds support for displaying pingbacks, toggling the display of pingbacks. I'm not yet sure how pingbacks work, so this may not include support for adding new pingbacks; if it won't take too much work I'll add more support for them. Also added support for user entered URLs, though I haven't gotten the form input to show up yet.
|
||||
This plugin adds support for displaying pingbacks, toggling the display of pingbacks. I'm not yet sure how pingbacks work, so this may not include support for adding new pingbacks though I attempted to patch the php file so it could work in theory; if it won't take too much work I'll add more support for them. Also added support for user entered URLs, though I haven't gotten the form input to show up yet.
|
||||
|
||||
This fork adds support for Akismet, which is now basically working. Consider it alpha. Also has admin panel functionality, can toggle it, add api key, shows error on comment page if api key doesn't match site. Going to add amin panel checkbox for recaptcha.
|
||||
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
===============================================================================================================================
|
||||
Comments Plugin Styles
|
||||
===============================================================================================================================
|
||||
*/
|
||||
|
||||
.comment {
|
||||
margin-top: 0px;
|
||||
width:100%;
|
||||
}
|
||||
.comment:first-child {
|
||||
margin-top: 0px;
|
||||
}
|
||||
.comment,
|
||||
.comment-body {
|
||||
zoom: 1;
|
||||
}
|
||||
.comment-body {
|
||||
overflow: hidden;
|
||||
margin-left: 10px;
|
||||
}
|
||||
.comment-object {
|
||||
display: block;
|
||||
}
|
||||
.comment-right,
|
||||
.comment > .pull-right {
|
||||
padding-left: 10px;
|
||||
}
|
||||
.comment-left,
|
||||
.comment > .pull-left {
|
||||
padding-right: 10px;
|
||||
}
|
||||
.comment-middle {
|
||||
vertical-align: middle;
|
||||
}
|
||||
.comment-bottom {
|
||||
vertical-align: bottom;
|
||||
}
|
||||
.comment-heading {
|
||||
margin-top: 0px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.comment-meta {
|
||||
font-size: small;
|
||||
}
|
||||
.comment-text {
|
||||
clear: both;
|
||||
}
|
||||
.comment-list {
|
||||
padding-left: 0px;
|
||||
list-style: none;
|
||||
}
|
||||
.comment-flag-new {
|
||||
background-color: lightcyan;
|
||||
}
|
||||
.comment-wrapper {
|
||||
display: -webkit-box;
|
||||
display: -moz-box;
|
||||
display: -ms-flexbox;
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
}
|
||||
.comment-avatar {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin-left: -10px;
|
||||
margin-right:5px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
/*.comment-thread-line:hover {
|
||||
border-left:3px solid #1BB3E9;
|
||||
}*/
|
||||
.comment-thread-top {
|
||||
margin-top:20px;
|
||||
}
|
||||
.comment-thread {
|
||||
float: left;
|
||||
border-left:3px solid #444;
|
||||
margin-left:10px;
|
||||
}
|
||||
.comment-footer {
|
||||
font-size: small;
|
||||
}
|
||||
.comment-reply {
|
||||
display: inline;
|
||||
}
|
|
@ -0,0 +1,216 @@
|
|||
function escapeRegExp(str) {
|
||||
return str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
|
||||
}
|
||||
jQuery(document).ready(function() {
|
||||
var commentForm = $('#comments-form'); //$(document).find('.comments-form').first();
|
||||
var commentSection = $('#comments-section'); //$(document).find('.comments').first();
|
||||
var commentAlert = $('#comments-alert'); //$(document).find('.alert').first();
|
||||
|
||||
//hide form, show link
|
||||
commentForm.hide();
|
||||
$(document).find('.comment-add-new').show();
|
||||
|
||||
//show comment form above comments section (new comment thread)
|
||||
$('body').on('click', '.comment-add-new', function(e) {
|
||||
e.preventDefault();
|
||||
if ($(this).prev().filter('#comments-form').length > 0) {
|
||||
//form is already in the right place.
|
||||
//just make sure it is visible.
|
||||
commentForm.show();
|
||||
return;
|
||||
}
|
||||
commentForm.hide(); //hide it to make sure that it is not shown after move to make "show" transition work.
|
||||
$(this).before(commentForm);
|
||||
commentForm.show('slow');
|
||||
commentAlert.empty().slideUp();
|
||||
});
|
||||
|
||||
//show comment form below selected comment (reply to existing comment)
|
||||
$('body').on('click', '.comment-add-reply', function(e) {
|
||||
e.preventDefault();
|
||||
var comment = $(this).closest('.comment');
|
||||
if (comment.find('#comments-form').length > 0) {
|
||||
//form is already in the right place.
|
||||
//just make sure it is visible.
|
||||
commentForm.show();
|
||||
return;
|
||||
}
|
||||
commentForm.hide();
|
||||
comment.find('.comment-body').last().append(commentForm);
|
||||
commentForm.show('slow');
|
||||
commentAlert.empty().slideUp();
|
||||
});
|
||||
|
||||
//delete comment (authorized user only)
|
||||
$('body').on('click', '.comment-delete', function(e) {
|
||||
e.preventDefault();
|
||||
var comment = $(this).closest('.comment');
|
||||
var id = parseInt(comment.attr('data-id'), 10);
|
||||
var level = parseInt(comment.attr('data-level'), 10);
|
||||
var nonce = commentForm.find("input[name='form-nonce']").val();
|
||||
if (comment.next().filter(".comment[data-level='" + (level + 1) + "']").length > 0) {
|
||||
alert('Deletion not allowed. There are replies to this comment. Please delete them first.');
|
||||
return;
|
||||
}
|
||||
var url = commentForm.attr("action");
|
||||
var posting = $.post(url, {
|
||||
action: 'delete',
|
||||
id: id,
|
||||
nonce: nonce
|
||||
}, null, 'json');
|
||||
// Register events to ajax call
|
||||
posting.done(function(response) {
|
||||
|
||||
//make sure that commentForm is definitely not within the deleted DOM part.
|
||||
//hide
|
||||
//temporary move it outside the comment selected for deletion. (this definitely exists, not taking any chances here)
|
||||
//finally move back to start of commentSection. (preferred target)
|
||||
//Hint: Don't forget commentAlert as it is not inside the form.
|
||||
commentAlert.empty().hide();
|
||||
commentForm.hide();
|
||||
comment.before(commentForm);
|
||||
comment.before(commentAlert);
|
||||
commentSection.prepend(commentAlert);
|
||||
commentSection.prepend(commentForm);
|
||||
//remove the comment and all content from DOM.
|
||||
//detach would be a soft delete but as there is no reason to reuse the deleted comment, means should not be provided.
|
||||
comment.remove();
|
||||
});
|
||||
posting.fail(function(status, error, title) {
|
||||
//alert('error');
|
||||
//console.log("Response Data (fail)", JSON.parse(JSON.stringify(status)));
|
||||
commentForm.after(commentAlert);
|
||||
commentAlert.show();
|
||||
commentAlert.empty().append("<p>Error: </p>");
|
||||
commentAlert.append("<p>" + JSON.stringify(status) + "</p>");
|
||||
commentAlert.append("<p>" + JSON.stringify(error) + "</p>");
|
||||
commentAlert.append("<p>" + JSON.stringify(title) + "</p>");
|
||||
});
|
||||
posting.always(function() {
|
||||
//alert("finished, be it successful or not");
|
||||
});
|
||||
});
|
||||
|
||||
// Attach a submit handler to the form
|
||||
$(commentForm).on('submit', function(event) {
|
||||
event.preventDefault();
|
||||
// Get form data:
|
||||
var data = $(this).serialize();
|
||||
//console.log("Form Data (submit)", JSON.parse(JSON.stringify(data)));
|
||||
var url = $(this).attr("action");
|
||||
//var url = '/nested-comments';
|
||||
var parent = 0;
|
||||
var ownLevel = 0;
|
||||
if ($(this).parents('.comment').length > 0) {
|
||||
parent = $(this).closest('.comment').attr('data-id');
|
||||
ownLevel = parseInt($(this).closest('.comment').attr('data-level'), 10) + 1;
|
||||
}
|
||||
|
||||
// Send the data using post
|
||||
//var posting = $.post(url, { parent: parent, data: data }, null, 'json');
|
||||
var posting = $.post(url, data + '&parent=' + parent, null, 'json');
|
||||
|
||||
// Register events to ajax call
|
||||
posting.done(function(response) {
|
||||
//alert('success');
|
||||
//console.log("Response Data (done)", JSON.parse(JSON.stringify(response)));
|
||||
//response = JSON.parse(response); //not needed, post was done using json
|
||||
commentForm.after(commentAlert);
|
||||
if (!response.status) {
|
||||
//should not trigger at all, if all bad requests return the right http status code
|
||||
//i.e. <> 200 success => thus triggering posting.fail()
|
||||
//leave this check just in case
|
||||
commentAlert.stop().css('opacity', 1).text('Error: ' + response.message).fadeIn(30).fadeOut(5000);
|
||||
return;
|
||||
}
|
||||
if (response.status) {
|
||||
commentAlert.css('color', 'green').empty().append(document.createTextNode(response.message)).fadeIn(30);
|
||||
/*var newMedia = "<div class='comment comment-level-{{comment.level|e}} comment-flag-new' data-level='{{comment.level}}' data-id='{{comment.id}}' >" +
|
||||
"<div class='comment-left'>" +
|
||||
"<img class='comment-object' src='https://www.gravatar.com/avatar/{{comment.email|trim|lower|md5}}?d=identicon' alt='user icon'>" +
|
||||
"</div>" +
|
||||
"<div class='comment-body'>" +
|
||||
"<div class='comment-heading'>" +
|
||||
"<div class='comment-title'><h4>{{comment.title}}</h4></div>" +
|
||||
"<div class='comment-reply'><a class='comment-add-reply' href='#'><i class='fa fa-reply' title='{{'PLUGIN_COMMENTS.ADD_REPLY'|t}}'></i> {{'PLUGIN_COMMENTS.REPLY'|t}}</a></div>" +
|
||||
"<div class='comment-meta'>{{'PLUGIN_COMMENTS.WRITTEN_ON'|t}} {{comment.date|e}} {{'PLUGIN_COMMENTS.BY'|t}} {{comment.author}}</div>" +
|
||||
"</div>" +
|
||||
"<div class='comment-text' >" +
|
||||
"{{comment.text}}" +
|
||||
"</div>" +
|
||||
"{{nested}}" +
|
||||
"</div>" +
|
||||
"</div>";*/
|
||||
var newMedia = `<div id="comment-{{comment.id}}" class="comment comment-level-{{comment.level|e}}" data-id="{{comment.id}}" itemtype="http://schema.org/UserComments">
|
||||
<header class="comment-heading">
|
||||
<img class="comment-avatar" src="https://www.gravatar.com/avatar/{{comment.email|trim|lower|md5}}?size=20&d=identicon" alt="user icon">
|
||||
<span class="comment-meta">
|
||||
{% if comment.site %}
|
||||
<a href="{{comment.site}}">{{comment.author}}</a>
|
||||
{% else %}
|
||||
{{comment.author}}
|
||||
{% endif %}
|
||||
<a href="{{uri.url(true)}}#comment-{{comment.id}}" title="Link to this comment" itemprop="url">
|
||||
<time class="comment-date" datetime="{{comment.date|e}}" itemprop="commentTime">
|
||||
{{comment.date|nicetime(false)}}
|
||||
</time>
|
||||
</a>
|
||||
</span>
|
||||
</header>
|
||||
<div class="comment-body">
|
||||
<div class="comment-text" >
|
||||
{{comment.text}}
|
||||
</div>
|
||||
{{nested}}
|
||||
<div class="comment-footer">
|
||||
<span class="comment-reply">
|
||||
{% if grav.twig.commenting_enabled %}
|
||||
<a class="comment-add-reply" href="#"><i class="fa fa-reply" title="{{'PLUGIN_COMMENTS.ADD_REPLY'|t}}"></i> {{'PLUGIN_COMMENTS.REPLY'|t}}</a>
|
||||
{% endif %}
|
||||
{% if grav.user.access.admin.super %}
|
||||
<a class="comment-delete" href="#"><i class="fa fa-trash" title="{{'PLUGIN_COMMENTS.DELETE_COMMENT'|t}}"></i> {{'PLUGIN_COMMENTS.DELETE'|t}}</a>
|
||||
{% endif %}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
newMedia = newMedia.replace(new RegExp(escapeRegExp("{{comment.id}}"), 'g'), response.data.id);
|
||||
newMedia = newMedia.replace(new RegExp(escapeRegExp("{{comment.level|e}}"), 'g'), ownLevel);
|
||||
newMedia = newMedia.replace(new RegExp(escapeRegExp("{{comment.level}}"), 'g'), ownLevel);
|
||||
newMedia = newMedia.replace(new RegExp(escapeRegExp("{{comment.email|trim|lower|md5}}"), 'g'), response.data.hash);
|
||||
newMedia = newMedia.replace(new RegExp(escapeRegExp("{{parent}}"), 'g'), response.data.parent);
|
||||
newMedia = newMedia.replace(new RegExp(escapeRegExp("{{comment.title}}"), 'g'), response.data.title);
|
||||
newMedia = newMedia.replace(new RegExp(escapeRegExp("{{comment.text}}"), 'g'), response.data.text);
|
||||
newMedia = newMedia.replace(new RegExp(escapeRegExp("{{comment.author}}"), 'g'), response.data.name);
|
||||
newMedia = newMedia.replace(new RegExp(escapeRegExp("{{comment.site}}"), 'g'), response.data.site);
|
||||
newMedia = newMedia.replace(new RegExp(escapeRegExp("{{comment.date|e}}"), 'g'), response.data.date);
|
||||
newMedia = newMedia.replace(new RegExp(escapeRegExp("{{nested}}"), 'g'), '');
|
||||
newMedia = newMedia.replace(new RegExp(escapeRegExp("{{'PLUGIN_COMMENTS.ADD_REPLY'|t}}"), 'g'), response.data.ADD_REPLY);
|
||||
newMedia = newMedia.replace(new RegExp(escapeRegExp("{{'PLUGIN_COMMENTS.REPLY'|t}}"), 'g'), response.data.REPLY);
|
||||
newMedia = newMedia.replace(new RegExp(escapeRegExp("{{'PLUGIN_COMMENTS.WRITTEN_ON'|t}}"), 'g'), response.data.WRITTEN_ON);
|
||||
if ($("div[data-id='" + response.data.parent + "']").length > 0) {
|
||||
$("div[data-id='" + response.data.parent + "']").first().after(newMedia);
|
||||
} else {
|
||||
$("#comments").prepend(newMedia);
|
||||
}
|
||||
}
|
||||
setTimeout(function() {
|
||||
commentForm.slideUp();
|
||||
commentAlert.fadeOut(5000);
|
||||
}, 5000);
|
||||
});
|
||||
posting.fail(function(status, error, title) {
|
||||
//alert('error');
|
||||
//console.log("Response Data (fail)", JSON.parse(JSON.stringify(status)));
|
||||
commentForm.after(commentAlert);
|
||||
commentAlert.show();
|
||||
commentAlert.empty().append("<p>Error: </p>");
|
||||
commentAlert.append("<p>" + JSON.stringify(status) + "</p>");
|
||||
commentAlert.append("<p>" + JSON.stringify(error) + "</p>");
|
||||
commentAlert.append("<p>" + JSON.stringify(title) + "</p>");
|
||||
});
|
||||
posting.always(function() {
|
||||
//alert("finished, be it successful or not");
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
namespace Grav\Plugin;
|
||||
|
||||
class Comment
|
||||
{
|
||||
private $id = 0;
|
||||
private $value = array();
|
||||
private $parent = null;
|
||||
private $children = array();
|
||||
|
||||
public function __construct($id, $content) {
|
||||
$this->id = $id;
|
||||
$this->value = $content;
|
||||
}
|
||||
|
||||
public function addItem($obj, $key = null) {
|
||||
}
|
||||
|
||||
public function deleteItem($key) {
|
||||
}
|
||||
|
||||
public function getItem($key) {
|
||||
}
|
||||
|
||||
public function getContent($level = 0) {
|
||||
$this->value['level'] = $level;
|
||||
$comments[] = $this->value;
|
||||
|
||||
foreach($this->children as $child) {
|
||||
//$comments[] = $child->getContent($level + 1); //produces nested result array.
|
||||
$comments = array_merge($comments, $child->getContent($level + 1)); //produces flat result array.
|
||||
}
|
||||
return $comments;
|
||||
}
|
||||
|
||||
public function setParent($parent) {
|
||||
$this->parent = $parent;
|
||||
}
|
||||
public function addSubComment($obj) {
|
||||
$this->children[] = $obj;
|
||||
}
|
||||
|
||||
}
|
816
comments.php
816
comments.php
File diff suppressed because it is too large
Load Diff
|
@ -3,14 +3,13 @@ pingbacks: true
|
|||
commenting: true
|
||||
akismet_enabled: true
|
||||
warning_message: ""
|
||||
|
||||
built_in_css: true
|
||||
ajax_callback: /nested-comments
|
||||
enable_on_routes:
|
||||
- '/blog'
|
||||
|
||||
disable_on_routes:
|
||||
- /blog/blog-post-to-ignore
|
||||
- /ignore-this-route
|
||||
|
||||
form:
|
||||
name: comments
|
||||
fields:
|
||||
|
@ -29,9 +28,9 @@ form:
|
|||
validate:
|
||||
required: true
|
||||
|
||||
- name: blah
|
||||
- name: site
|
||||
label: PLUGIN_COMMENTS.SITE_LABEL
|
||||
placeholder: "https://leetnightshade.com"
|
||||
placeholder:
|
||||
type: text
|
||||
validate:
|
||||
required: false
|
||||
|
@ -48,10 +47,6 @@ form:
|
|||
process:
|
||||
fillWithCurrentDateTime: true
|
||||
|
||||
- name: title
|
||||
type: hidden
|
||||
evaluateDefault: grav.page.header.title
|
||||
|
||||
- name: lang
|
||||
type: hidden
|
||||
evaluateDefault: grav.language.getLanguage
|
||||
|
|
|
@ -1,13 +1,22 @@
|
|||
de:
|
||||
PLUGIN_COMMENTS:
|
||||
ADD_NEW: Kommentar hinzufügen
|
||||
ADD_REPLY: Auf Kommentar antworten
|
||||
ADD_COMMENT: Kommentar hinzufügen
|
||||
AKISMET: Akismet
|
||||
AKISMET_KEY_API: Akismet API Key
|
||||
AKISMET_SITE_OVERRIDE: Akismet Site Override
|
||||
DELETE_COMMENT: Kommentar löschen
|
||||
REPLY: Antworten
|
||||
DELETE: Löschen
|
||||
SUCCESS: "Der Kommentar wurde erfolgreich gespeichert."
|
||||
COMMENTS: Kommentare
|
||||
COMMENTS_NESTED: Nested Comments
|
||||
COMMENTS_NONE: There are no comments yet.
|
||||
COMMENTS_PINGBACKS: Pingbacks
|
||||
COMMENTS_STATS: Kommentare
|
||||
RECENT_COMMENTS: Neue Kommentare
|
||||
RECENT_PAGES: Kommentierte Seiten
|
||||
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>'
|
||||
|
@ -30,14 +39,23 @@ de:
|
|||
|
||||
en:
|
||||
PLUGIN_COMMENTS:
|
||||
ADD_NEW: Add a comment
|
||||
ADD_REPLY: Reply to comment
|
||||
ADD_COMMENT: Add a comment
|
||||
AKISMET: Akismet
|
||||
AKISMET_KEY_API: Akismet API Key
|
||||
AKISMET_SITE_OVERRIDE: Akismet Site Override
|
||||
DELETE_COMMENT: Delete comment
|
||||
REPLY: Reply
|
||||
DELETE: Delete
|
||||
SUCCESS: "Comment has been saved successfully."
|
||||
COMMENTS: Comments
|
||||
COMMENTS_NESTED: Nested Comments
|
||||
COMMENTS_NONE: There are no comments yet.
|
||||
COMMENTS_PINGBACKS: Pingbacks
|
||||
COMMENTS_STATS: Comments
|
||||
RECENT_COMMENTS: Recent comments
|
||||
RECENT_PAGES: Commented pages
|
||||
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>'
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
<form id="comments-form" name="{{ grav.config.plugins.comments.form.name }}" class="comments-form"
|
||||
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('comments', 'form-nonce')|raw }}
|
||||
</form>
|
||||
|
||||
<div id="comments-alert" class="alert">{{ form.message }}</div>
|
|
@ -1,135 +1,67 @@
|
|||
{% if grav.twig.enable_comments_plugin %}
|
||||
{% set scope = scope ?: 'data.' %}
|
||||
<section id="comments-section">
|
||||
<h2>{{'PLUGIN_COMMENTS.COMMENTS'|t}}</h2>
|
||||
|
||||
{% if grav.twig.pingbacks_enabled %}
|
||||
{% if grav.twig.pingbacks|length %}
|
||||
{% set comments_visible = false %}
|
||||
{% for pingback in grav.twig.pingbacks %}
|
||||
{% if pingback.approved == "true" %}
|
||||
{% set comments_visible = true %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% if comments_visible %}
|
||||
<h3>{{'PLUGIN_COMMENTS.COMMENTS_PINGBACKS'|t}}</h3>
|
||||
|
||||
<table>
|
||||
{% for pingback in grav.twig.pingbacks %}
|
||||
{% if pingback.approved == "true" %}
|
||||
<tr>
|
||||
<td>
|
||||
<article id="pingback-{{loop.index0}}" class="pingback" itemtype="http://schema.org/UserComments">
|
||||
<header class="pingback-meta">
|
||||
<span class="pingback-author" itemprop="author" itemscope itemtype="http://schema.org/Person">
|
||||
{{'PLUGIN_COMMENTS.BY'|t}}
|
||||
<span itemprop="name">
|
||||
{% if pingback.site %}
|
||||
<a href="{{pingback.site}}">{{pingback.author}}</a>
|
||||
{% else %}
|
||||
{{pingback.author}}
|
||||
{% endif %}
|
||||
</span>
|
||||
</span>
|
||||
<a href="{{uri.url(true)}}#pingback-{{loop.index0}}" title="Link to this pingback" itemprop="url">
|
||||
<time class="pingback-date" datetime="{{pingback.date|e}}" itemprop="commentTime">
|
||||
{{pingback.date|nicetime(false)}}
|
||||
</time>
|
||||
</a>
|
||||
</header>
|
||||
<div class="pingback-content" itemprop="commentText">
|
||||
{{pingback.text}}
|
||||
</div>
|
||||
</article>
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</table
|
||||
{% endif %}
|
||||
</table>
|
||||
{% if grav.twig.commenting_enabled %}
|
||||
<a class="comment-add-new" href="#"><i class="fa fa-plus" title="{{'PLUGIN_COMMENTS.ADD_NEW'|t}}"></i> {{'PLUGIN_COMMENTS.ADD_NEW'|t}}</a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if grav.twig.commenting_enabled %}
|
||||
<h3>{{'PLUGIN_COMMENTS.ADD_COMMENT'|t}}</h3>
|
||||
{% include 'partials/comments.form.html.twig' %}
|
||||
|
||||
<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>
|
||||
{% endif %}
|
||||
|
||||
{% if grav.twig.comments|length %}
|
||||
|
||||
<h3>{{'PLUGIN_COMMENTS.COMMENTS'|t}}</h3>
|
||||
|
||||
<table class="comments">
|
||||
{% set comments_visible = false %}
|
||||
{% for comment in grav.twig.comments %}
|
||||
{% if comment.approved == "true" %}
|
||||
{% set comments_visible = true %}
|
||||
<tr>
|
||||
<td>
|
||||
<article id="comment-{{loop.index0}}" class="comment" itemtype="http://schema.org/UserComments">
|
||||
<header class="comment-meta">
|
||||
<span class="comment-author" itemprop="author" itemscope itemtype="http://schema.org/Person">
|
||||
<img class="comment-avatar" itemprop="image" src="https://www.gravatar.com/avatar/{{comment.email|ltrim()|rtrim()|md5}}?size=30&d=identicon">
|
||||
{{'PLUGIN_COMMENTS.BY'|t}}
|
||||
<span itemprop="name">
|
||||
{% if comment.site %}
|
||||
<a href="{{comment.site}}">{{comment.author}}</a>
|
||||
{% else %}
|
||||
{{comment.author}}
|
||||
{% endif %}
|
||||
</span>
|
||||
</span>
|
||||
<a href="{{uri.url(true)}}#comment-{{loop.index0}}" title="Link to this comment" itemprop="url">
|
||||
<div id="comments" class="row comments">
|
||||
{% if grav.twig.comments|length %}
|
||||
{% set comments_visible = false %}
|
||||
{% for comment in grav.twig.comments %}
|
||||
{% if comment.approved == "true" %}
|
||||
<div class="comment-wrapper">
|
||||
{% set comments_visible = true %}
|
||||
{% for level in range(0, comment.level|e) %}
|
||||
{% if level == comment.level|e %}
|
||||
<div id="thread-{{level}}" class="comment-thread-top comment-thread">
|
||||
</div>
|
||||
{% else %}
|
||||
<div id="thread-{{level}}" class="comment-thread">
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<div id="comment-{{comment.id}}" class="comment comment-level-{{comment.level|e}}" data-id="{{comment.id}}" itemtype="http://schema.org/UserComments">
|
||||
<header class="comment-heading">
|
||||
<img class="comment-avatar" src="https://www.gravatar.com/avatar/{{comment.email|trim|lower|md5}}?size=20&d=identicon" alt="user icon">
|
||||
<span class="comment-meta">
|
||||
{% if comment.site %}
|
||||
<a href="{{comment.site}}">{{comment.author}}</a>
|
||||
{% else %}
|
||||
{{comment.author}}
|
||||
{% endif %}
|
||||
<a href="{{uri.url(true)}}#comment-{{comment.id}}" title="Link to this comment" itemprop="url">
|
||||
<time class="comment-date" datetime="{{comment.date|e}}" itemprop="commentTime">
|
||||
{{comment.date|nicetime(false)}}
|
||||
</time>
|
||||
</a>
|
||||
</span>
|
||||
</header>
|
||||
<div class="comment-content" itemprop="commentText">
|
||||
{{comment.text}}
|
||||
<div class="comment-body">
|
||||
<div class="comment-text" >
|
||||
{{comment.text}}
|
||||
</div>
|
||||
{{nested}}
|
||||
<div class="comment-footer">
|
||||
<span class="comment-reply">
|
||||
{% if grav.twig.commenting_enabled %}
|
||||
<a class="comment-add-reply" href="#"><i class="fa fa-reply" title="{{'PLUGIN_COMMENTS.ADD_REPLY'|t}}"></i> {{'PLUGIN_COMMENTS.REPLY'|t}}</a>
|
||||
{% endif %}
|
||||
{% if grav.user.access.admin.super %}
|
||||
<a class="comment-delete" href="#"><i class="fa fa-trash" title="{{'PLUGIN_COMMENTS.DELETE_COMMENT'|t}}"></i> {{'PLUGIN_COMMENTS.DELETE'|t}}</a>
|
||||
{% endif %}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if not comments_visible %}
|
||||
<tr>
|
||||
|
@ -138,6 +70,6 @@
|
|||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</table>
|
||||
{% endif %}
|
||||
</div>
|
||||
</section>
|
||||
{% endif %}
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
{# you may set options when using this partial. Example: include 'partials/recentcomments.html.twig' with {'limit': 5, 'pages_limit': 3} #}
|
||||
{% if grav.twig.enable_comments_plugin %}
|
||||
<h1>{{'PLUGIN_COMMENTS.COMMENTS_STATS'|t}}</h1>
|
||||
{% set stats = recent_comments(limit|default(5), pages_limit|default(3)) %}
|
||||
{% if stats.global_stats.active_entries %}
|
||||
<i class="fa fa-comments" title="active_entries"></i> {{stats.global_stats.active_entries}}
|
||||
(<i class="fa fa-trash" title="deleted_entries"></i> {{stats.global_stats.deleted_entries}})
|
||||
- <i class="fa fa-comment" title="active_comments"></i>{{stats.global_stats.active_comments}}
|
||||
(<i class="fa fa-trash" title="deleted_comments"></i> {{stats.global_stats.deleted_comments}})
|
||||
- <i class="fa fa-commenting" title="active_replies"></i>{{stats.global_stats.active_replies}}
|
||||
(<i class="fa fa-trash" title="deleted_replies"></i> {{stats.global_stats.deleted_replies}})
|
||||
- <i class="fa fa-files-o" title="pages_with_active_entries"></i> {{stats.global_stats.pages_with_active_entries}}
|
||||
{% endif %}
|
||||
{% for key, entry in stats.pages %}
|
||||
{% if loop.first %}
|
||||
<h2>{{'PLUGIN_COMMENTS.RECENT_PAGES'|t}} (limit {{stats.options.pages_limit}})</h2>
|
||||
<ul class="fa-ul">
|
||||
{% endif %}
|
||||
<li><i class="fa-li fa fa-file" title="{{entry.route}}"></i>
|
||||
{% if entry.route %}
|
||||
<a href="{{entry.route}}#comments">
|
||||
{% endif %}
|
||||
{{entry.active_entries}}
|
||||
{% if entry.route %}
|
||||
</a>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% if loop.last %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% for key, entry in stats.comments %}
|
||||
{% if loop.first %}
|
||||
<h2>{{'PLUGIN_COMMENTS.RECENT_COMMENTS'|t}} (limit {{stats.options.comments_limit}})</h2>
|
||||
<ul class="fa-ul">
|
||||
{% endif %}
|
||||
{% set entry_icon = 'fa-comment' %}
|
||||
{% if not empty(entry.parent) %}
|
||||
{% set entry_icon = 'fa-commenting' %}
|
||||
{% endif %}
|
||||
<li><i class="fa-li fa {{entry_icon}}" title="{{key}}: {{entry.id}}, {{entry.parent}}"></i>
|
||||
{% if entry.route %}
|
||||
<a href="{{entry.route}}#comments">
|
||||
{% endif %}
|
||||
{{entry.date}}, {{entry.author}}, {{entry.text|truncate(15)}}
|
||||
{% if entry.route %}
|
||||
</a>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% if loop.last %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
Loading…
Reference in New Issue