mirror of
https://github.com/Oreolek/ifhub.club.git
synced 2024-07-05 16:04:24 +03:00
Доработка комментариев
* Удален экшн ActionComments (функционал будет перенесен в активность) * Добавлен компонент comment * Доработан js код комментариев + оформлен как jQuery Widget * Fixes #466 При ajax подгрузке комментов не работает голосование
This commit is contained in:
parent
e6a92aaa98
commit
130dcac352
|
@ -523,6 +523,7 @@ $config['head']['default']['js'] = array(
|
||||||
"___path.application.web___/frontend/common/js/userfeed.js",
|
"___path.application.web___/frontend/common/js/userfeed.js",
|
||||||
"___path.application.web___/frontend/common/js/activity.js",
|
"___path.application.web___/frontend/common/js/activity.js",
|
||||||
"___path.application.web___/frontend/common/js/toolbar.js",
|
"___path.application.web___/frontend/common/js/toolbar.js",
|
||||||
|
"___path.application.web___/frontend/common/js/toolbar.comments.js",
|
||||||
"___path.application.web___/frontend/common/js/topic.js",
|
"___path.application.web___/frontend/common/js/topic.js",
|
||||||
"___path.application.web___/frontend/common/js/admin.js",
|
"___path.application.web___/frontend/common/js/admin.js",
|
||||||
"___path.application.web___/frontend/common/js/userfield.js",
|
"___path.application.web___/frontend/common/js/userfield.js",
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -466,10 +466,11 @@ return array(
|
||||||
* Комментарии
|
* Комментарии
|
||||||
*/
|
*/
|
||||||
'comments' => array(
|
'comments' => array(
|
||||||
'comments_declension' => 'комментарий;комментария;комментариев',
|
'comments_declension' => '%%count%% комментарий;%%count%% комментария;%%count%% комментариев',
|
||||||
'count_new' => 'Число новых комментариев',
|
'count_new' => 'Число новых комментариев',
|
||||||
'title' => 'Комментарии',
|
'title' => 'Комментарии',
|
||||||
'subscribe' => 'Подписаться на новые комментарии',
|
'subscribe' => 'Подписаться',
|
||||||
|
'unsubscribe' => 'Отписаться',
|
||||||
|
|
||||||
// Комментарий
|
// Комментарий
|
||||||
'comment' => array(
|
'comment' => array(
|
||||||
|
|
|
@ -5,18 +5,25 @@
|
||||||
{extends 'layouts/layout.base.tpl'}
|
{extends 'layouts/layout.base.tpl'}
|
||||||
|
|
||||||
{block 'layout_content'}
|
{block 'layout_content'}
|
||||||
|
{* Топик *}
|
||||||
{include 'topics/topic.tpl'}
|
{include 'topics/topic.tpl'}
|
||||||
{include 'comments/comment_tree.tpl'
|
|
||||||
|
{* Комментарии *}
|
||||||
|
{include 'components/comment/comment-list.tpl'
|
||||||
|
sClasses = 'js-comments-topic'
|
||||||
iTargetId = $oTopic->getId()
|
iTargetId = $oTopic->getId()
|
||||||
iAuthorId = $oTopic->getUserId()
|
iAuthorId = $oTopic->getUserId()
|
||||||
|
aComments = $aComments
|
||||||
sAuthorNotice = $aLang.topic_author
|
sAuthorNotice = $aLang.topic_author
|
||||||
sTargetType = 'topic'
|
sTargetType = 'topic'
|
||||||
iCountComment = $oTopic->getCountComment()
|
iCountComment = $oTopic->getCountComment()
|
||||||
sDateReadLast = $oTopic->getDateRead()
|
sDateReadLast = $oTopic->getDateRead()
|
||||||
bForbidNewComment = $oTopic->getForbidComment()
|
bForbidAdd = $oTopic->getForbidComment()
|
||||||
sNoticeNotAllow = $aLang.topic_comment_notallow
|
sNoticeNotAllow = $aLang.topic_comment_notallow
|
||||||
sNoticeCommentAdd = $aLang.topic_comment_add
|
sNoticeCommentAdd = $aLang.topic_comment_add
|
||||||
bAllowSubscribe = true
|
bAllowSubscribe = true
|
||||||
oSubscribeComment = $oTopic->getSubscribeNewComment()
|
oSubscribeComment = $oTopic->getSubscribeNewComment()
|
||||||
aPagingCmt = $aPagingCmt}
|
aPagingCmt = $aPagingCmt
|
||||||
|
bShowVote = true
|
||||||
|
bShowFavourite = true}
|
||||||
{/block}
|
{/block}
|
|
@ -1,7 +0,0 @@
|
||||||
{extends file='layouts/layout.base.tpl'}
|
|
||||||
|
|
||||||
{block name='layout_page_title'}{$aLang.comments_all}{/block}
|
|
||||||
|
|
||||||
{block name='layout_content'}
|
|
||||||
{include file='comments/comment_list.tpl'}
|
|
||||||
{/block}
|
|
|
@ -13,11 +13,14 @@
|
||||||
/**
|
/**
|
||||||
* Блок со списком комментариев
|
* Блок со списком комментариев
|
||||||
*/
|
*/
|
||||||
.comments { margin-bottom: 30px; }
|
.comments { }
|
||||||
|
|
||||||
.comments-header { margin-bottom: 20px; }
|
.comments-header { margin-bottom: 20px; }
|
||||||
.comments-title { font-size: 24px; margin-bottom: 5px; }
|
.comments-title { font-size: 24px; margin-bottom: 5px; }
|
||||||
|
|
||||||
|
.comments-actions { padding: 0; background-color: transparent; }
|
||||||
|
|
||||||
|
.comment-list { margin-bottom: 30px; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Вспомогательный блок-обертка
|
* Вспомогательный блок-обертка
|
||||||
|
@ -28,7 +31,7 @@
|
||||||
/**
|
/**
|
||||||
* Предпросмотр текста комментария
|
* Предпросмотр текста комментария
|
||||||
*/
|
*/
|
||||||
.comment-preview { padding: 15px; margin: 0 0 10px 0; border: 1px solid #eee; }
|
.comment-preview { padding: 15px; margin: 10px 0 10px 0; border: 1px solid #eee; }
|
||||||
.comment-wrapper .comment-preview { margin-left: 25px; }
|
.comment-wrapper .comment-preview { margin-left: 25px; }
|
||||||
|
|
||||||
|
|
||||||
|
@ -45,66 +48,108 @@
|
||||||
*/
|
*/
|
||||||
.comment {
|
.comment {
|
||||||
min-height: 48px;
|
min-height: 48px;
|
||||||
padding: 10px 10px 10px 68px;
|
padding: 15px 15px 15px 80px;
|
||||||
|
margin-bottom: 2px;
|
||||||
position: relative;
|
position: relative;
|
||||||
border-top: 1px solid #eee;
|
background: #fafafa;
|
||||||
background: #fff;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.comment.comment-self { background: #c5f7ea; }
|
.comment--self { background: #c5f7ea; }
|
||||||
|
|
||||||
.comment.comment-new { background: #fbfba8; }
|
.comment--new { background: #fbfba8; }
|
||||||
|
|
||||||
.comment.comment-current { background: #a5e7fa; }
|
.comment--current { background: #a5e7fa; }
|
||||||
|
|
||||||
.comment.comment-bad { opacity: 0.3; filter: alpha(opacity=30); }
|
.comment--bad { opacity: 0.3; filter: alpha(opacity=30); }
|
||||||
.comment.comment-bad:hover { opacity: 1; filter: alpha(opacity=100); }
|
.comment--bad:hover { opacity: 1; filter: alpha(opacity=100); }
|
||||||
|
|
||||||
.comment.comment-deleted { background: #efd5d5; }
|
.comment.comment--deleted { background: #efd5d5; }
|
||||||
.ls-user-role-not-admin .comment.comment-deleted { padding: 10px 15px; min-height: 0; background: #f7f7f7; color: #888; }
|
.ls-user-role-not-admin .comment.comment--deleted {
|
||||||
|
padding: 10px 15px;
|
||||||
|
min-height: 0;
|
||||||
|
background: #f7f7f7;
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
|
|
||||||
.comment.comment-list-item { margin-bottom: 20px; }
|
.comment.comment-list-item { margin-bottom: 20px; }
|
||||||
.comment.comment-list-item .vote .vote-up,
|
.comment.comment-list-item .vote .vote-up,
|
||||||
.comment.comment-list-item .vote .vote-down { display: none; }
|
.comment.comment-list-item .vote .vote-down { display: none; }
|
||||||
|
|
||||||
/* Аватар */
|
/* Аватар */
|
||||||
.comment-avatar { position: absolute; top: 10px; left: 10px; }
|
.comment-avatar {
|
||||||
|
position: absolute;
|
||||||
|
top: 15px;
|
||||||
|
left: 15px;
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
border-radius: 50%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.comment-avatar img { width: 50px; height: 50px; }
|
||||||
|
|
||||||
/* Информация */
|
/* Информация */
|
||||||
.comment-info { padding: 0 70px 0 0; margin-bottom: 10px; line-height: 1.3em; position: relative; overflow: hidden; }
|
.comment-info { padding: 0 70px 0 0; margin-bottom: 15px; line-height: 1.3em; position: relative; }
|
||||||
.comment-info li { float: left; margin-right: 10px; }
|
.comment-info li { float: left; margin-right: 10px; }
|
||||||
.comment-info a { text-decoration: none; }
|
.comment-info a { text-decoration: none; }
|
||||||
.comment-date a { color: #999; border-color: #999; }
|
|
||||||
.comment-info .vote { position: absolute; top: 0; right: 0; margin: 0; }
|
|
||||||
.comment-scroll-to-child { display: none; }
|
|
||||||
.comment-username { font-weight: bold; }
|
|
||||||
.comment-username-author { background: #2891D3; padding: 0 3px; }
|
|
||||||
.comment-username-author a { color: #fff; }
|
|
||||||
|
|
||||||
/* Содержимое комментария */
|
/* Логин */
|
||||||
.comment-content.text { font-size: 13px; }
|
.comment-info .comment-username { float: none; font: 20px/1.3em "Open Sans", sans-serif; margin-bottom: 5px; }
|
||||||
|
|
||||||
|
/* Избранное */
|
||||||
|
.comment-favourite {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
width: 50px;
|
||||||
|
top: 65px;
|
||||||
|
left: -65px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comment-favourite.favourite--added,
|
||||||
|
.comment-favourite.favourite--has-counter,
|
||||||
|
.comment:hover .comment-favourite { display: block; }
|
||||||
|
|
||||||
|
/* Дата */
|
||||||
|
.comment-date a { color: #999; }
|
||||||
|
.comment-date a:hover { color: #777; }
|
||||||
|
|
||||||
|
/* Голосование */
|
||||||
|
.comment-vote { position: absolute; top: 0; right: 0; margin: 0; }
|
||||||
|
|
||||||
|
.comment-vote.vote--not-voted.vote--count-zero { display: none; }
|
||||||
|
.comment:hover .comment-vote { display: block; }
|
||||||
|
|
||||||
|
/* Прокрутка к дочернему комментарию */
|
||||||
|
.comment-scroll-to { cursor: pointer; }
|
||||||
|
.comment-scroll-to-child { display: none; }
|
||||||
|
|
||||||
|
/* Текст комментария */
|
||||||
|
.comment-content.text { font-size: 13px; line-height: 1.7em; }
|
||||||
.comment-content.text blockquote { background: #fff; border-color: #ccc; padding: 5px 10px; margin-bottom: 5px; }
|
.comment-content.text blockquote { background: #fff; border-color: #ccc; padding: 5px 10px; margin-bottom: 5px; }
|
||||||
|
|
||||||
/* Кнопки */
|
/* Действия */
|
||||||
.comment-actions { margin-top: 10px; }
|
.comment-actions li { float: left; margin: 10px 10px 0 0; }
|
||||||
.comment-actions li { display: inline; margin-right: 10px; }
|
|
||||||
|
|
||||||
/* Сворачивание */
|
/* Сворачивание */
|
||||||
.comment-fold { background: #CBCBF3; }
|
.comment-fold { background: #CBCBF3; display: none; }
|
||||||
.comment-fold.open { background: transparent; }
|
.comment-fold.open { background: transparent; }
|
||||||
|
|
||||||
|
/* Информация о редактировании */
|
||||||
|
.comment-edit-info { margin-top: 10px; font-size: 11px; opacity: .5; }
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Форма комментирования
|
* Форма комментирования
|
||||||
*
|
*
|
||||||
* @template comments/comment.form.tpl
|
* @template comments/comment.form.tpl
|
||||||
*/
|
*/
|
||||||
.comment-form { padding: 15px; background: #fafafa; }
|
.comment-form { padding: 15px; margin-bottom: 2px; background: #fafafa; }
|
||||||
.comment-form textarea { height: 150px; }
|
.comment-form textarea { height: 150px; }
|
||||||
|
|
||||||
.comment-wrapper .comment-form { margin-left: 25px; }
|
.comment-wrapper .comment-form { margin-left: 25px; }
|
||||||
|
|
||||||
.comment-reply-root { font-size: 20px; margin-bottom: 15px; }
|
.comment-reply-root { font-size: 20px; margin-bottom: 0; }
|
||||||
|
.comment-reply-root + .comment-form { margin-top: 15px; }
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -98,18 +98,6 @@ jQuery(document).ready(function($){
|
||||||
$(window)._scrollable();
|
$(window)._scrollable();
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Toolbar
|
|
||||||
*/
|
|
||||||
$('.js-toolbar').toolbar({
|
|
||||||
target: '.grid-role-wrapper',
|
|
||||||
offsetX: 20
|
|
||||||
});
|
|
||||||
|
|
||||||
ls.toolbar.topic.init(); // Тул-бар топиков
|
|
||||||
ls.toolbar.up.init(); // Кнопка "UP"
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Code highlight
|
* Code highlight
|
||||||
*/
|
*/
|
||||||
|
@ -137,7 +125,33 @@ jQuery(document).ready(function($){
|
||||||
/**
|
/**
|
||||||
* Comments
|
* Comments
|
||||||
*/
|
*/
|
||||||
ls.comments.init();
|
$('.js-comments-topic').lsComments({
|
||||||
|
urls: {
|
||||||
|
add: aRouter['blog'] + 'ajaxaddcomment/',
|
||||||
|
load: aRouter['blog'] + 'ajaxresponsecomment/'
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.js-comments-talk').lsComments({
|
||||||
|
urls: {
|
||||||
|
add: aRouter['talk'] + 'ajaxaddcomment/',
|
||||||
|
load: aRouter['talk'] + 'ajaxresponsecomment/'
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toolbar
|
||||||
|
*/
|
||||||
|
$('.js-toolbar').toolbar({
|
||||||
|
target: '.grid-role-wrapper',
|
||||||
|
offsetX: 20
|
||||||
|
});
|
||||||
|
|
||||||
|
ls.toolbar.topic.init(); // Тул-бар топиков
|
||||||
|
ls.toolbar.up.init(); // Кнопка "UP"
|
||||||
|
|
||||||
|
$('.js-toolbar-comments').lsToolbarComments();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -217,10 +231,12 @@ jQuery(document).ready(function($){
|
||||||
});
|
});
|
||||||
|
|
||||||
// Голосование за комментарий
|
// Голосование за комментарий
|
||||||
$('.js-vote-comment').vote({
|
$('.js-vote-comment').livequery(function () {
|
||||||
urls: {
|
$(this).vote({
|
||||||
vote: aRouter['ajax'] + 'vote/comment/'
|
urls: {
|
||||||
}
|
vote: aRouter['ajax'] + 'vote/comment/'
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
{extends file='blocks/block.aside.base.tpl'}
|
{extends file='blocks/block.aside.base.tpl'}
|
||||||
|
|
||||||
{block name='block_title'}<a href="{router page='comments'}" title="{$aLang.block_stream_comments_all}">{$aLang.block_stream}</a>{/block}
|
{block name='block_title'}<a href="{router page='stream'}">{$aLang.stream_menu}</a>{/block}
|
||||||
{block name='block_type'}stream{/block}
|
{block name='block_type'}stream{/block}
|
||||||
{block name='block_class'}block-nopadding{/block}
|
{block name='block_class'}block-nopadding{/block}
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,11 @@
|
||||||
<a href="{if Config::Get('module.comment.nested_per_page')}{router page='comments'}{else}{$oTopic->getUrl()}#comment{/if}{$oComment->getId()}">{$oTopic->getTitle()|escape:'html'}</a>
|
<a href="{if Config::Get('module.comment.nested_per_page')}{router page='comments'}{else}{$oTopic->getUrl()}#comment{/if}{$oComment->getId()}">{$oTopic->getTitle()|escape:'html'}</a>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<time datetime="{date_format date=$oComment->getDate() format='c'}">{date_format date=$oComment->getDate() hours_back="12" minutes_back="60" now="60" day="day H:i" format="j F Y, H:i"}</time> |
|
<time datetime="{date_format date=$oComment->getDate() format='c'}">
|
||||||
{$oTopic->getCountComment()} {$oTopic->getCountComment()|declension:$aLang.comments.comments_declension}
|
{date_format date=$oComment->getDate() hours_back="12" minutes_back="60" now="60" day="day H:i" format="j F Y, H:i"}
|
||||||
|
</time> |
|
||||||
|
|
||||||
|
{lang name='comments.comments_declension' count=$oTopic->getCountComment() plural=true}
|
||||||
</p>
|
</p>
|
||||||
</li>
|
</li>
|
||||||
{/foreach}
|
{/foreach}
|
||||||
|
@ -29,5 +32,5 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<footer class="block-footer">
|
<footer class="block-footer">
|
||||||
<a href="{router page='comments'}">{$aLang.block_stream_comments_all}</a> | <a href="{router page='rss'}allcomments/">RSS</a>
|
<a href="{router page='rss'}allcomments/">RSS</a>
|
||||||
</footer>
|
</footer>
|
|
@ -19,8 +19,11 @@
|
||||||
<a href="{$oTopic->getUrl()}">{$oTopic->getTitle()|escape:'html'}</a>
|
<a href="{$oTopic->getUrl()}">{$oTopic->getTitle()|escape:'html'}</a>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<time datetime="{date_format date=$oTopic->getDate() format='c'}">{date_format date=$oTopic->getDateAdd() hours_back="12" minutes_back="60" now="60" day="day H:i" format="j F Y, H:i"}</time> |
|
<time datetime="{date_format date=$oTopic->getDate() format='c'}">
|
||||||
{$oTopic->getCountComment()} {$oTopic->getCountComment()|declension:$aLang.comments.comments_declension}
|
{date_format date=$oTopic->getDateAdd() hours_back="12" minutes_back="60" now="60" day="day H:i" format="j F Y, H:i"}
|
||||||
|
</time> |
|
||||||
|
|
||||||
|
{lang name='comments.comments_declension' count=$oTopic->getCountComment() plural=true}
|
||||||
</p>
|
</p>
|
||||||
</li>
|
</li>
|
||||||
{/foreach}
|
{/foreach}
|
||||||
|
@ -28,5 +31,5 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<footer class="block-footer">
|
<footer class="block-footer">
|
||||||
<a href="{router page='index'}new/">{$aLang.block_stream_topics_all}</a> | <a href="{router page='rss'}new/">RSS</a>
|
<a href="{router page='rss'}new/">RSS</a>
|
||||||
</footer>
|
</footer>
|
|
@ -1,35 +0,0 @@
|
||||||
{**
|
|
||||||
* Форма комментирования
|
|
||||||
*
|
|
||||||
* @param integer $iTargetId
|
|
||||||
* @param string $sTargetType
|
|
||||||
*
|
|
||||||
* @styles css/comments.css
|
|
||||||
*}
|
|
||||||
|
|
||||||
{* Подключение редактора *}
|
|
||||||
|
|
||||||
|
|
||||||
{* Форма *}
|
|
||||||
<form method="post" class="comment-form js-comment-form" enctype="multipart/form-data" data-target-id="{$iTargetId}" data-target-type="{$sTargetType}">
|
|
||||||
{hook run='form_add_comment_begin'}
|
|
||||||
|
|
||||||
{* Текст комментария *}
|
|
||||||
{include 'components/editor/editor.tpl' sSet='light' sName='comment_text' sId='form_comment_text' bShowHelp=false sMediaTargetType='comment'}
|
|
||||||
|
|
||||||
{hook run='form_add_comment_end'}
|
|
||||||
|
|
||||||
{* Скрытые поля *}
|
|
||||||
{include 'components/field/field.hidden.tpl' sName='reply' sValue='0' sId='form_comment_reply'}
|
|
||||||
{include 'components/field/field.hidden.tpl' sName='cmt_target_id' sValue=$iTargetId}
|
|
||||||
|
|
||||||
{* Кнопки создания *}
|
|
||||||
{include 'components/button/button.tpl' sName='submit_comment' sText=$aLang.common.add sMods='primary' sClasses='js-comment-form-submit'}
|
|
||||||
|
|
||||||
{* Кнопки редактирования *}
|
|
||||||
{include 'components/button/button.tpl' sName='submit_comment' sType='button' sText=$aLang.common.save sMods='primary' sClasses='js-comment-form-update-submit hide'}
|
|
||||||
{include 'components/button/button.tpl' sName='submit_comment' sType='button' sText=$aLang.common.cancel sClasses='js-comment-form-update-cancel fl-r hide'}
|
|
||||||
|
|
||||||
{* Общие кнопки *}
|
|
||||||
{include 'components/button/button.tpl' sText=$aLang.common.preview_text sType='button' sClasses='js-comment-form-preview'}
|
|
||||||
</form>
|
|
|
@ -1,130 +0,0 @@
|
||||||
{**
|
|
||||||
* Комментарий
|
|
||||||
*
|
|
||||||
* @param boolean bAllowNewComment true если разрешно добавлять новые комментарии
|
|
||||||
* @param boolean bOneComment
|
|
||||||
* @param boolean bNoCommentFavourites true если не нужно выводить кнопку добавления в избранное
|
|
||||||
* @param integer iAuthorId ID автора топика
|
|
||||||
* @param boolean bList true если комментарий выводится в списках (например на странице Избранные комментарии)
|
|
||||||
*
|
|
||||||
* @styles css/comments.css
|
|
||||||
*}
|
|
||||||
|
|
||||||
{$oUser = $oComment->getUser()}
|
|
||||||
|
|
||||||
|
|
||||||
{* Выводим ссылки на блог и топик в котором находится комментарий (только в списках) *}
|
|
||||||
{if $bList}
|
|
||||||
{$oTopic = $oComment->getTarget()}
|
|
||||||
{$oBlog = $oTopic->getBlog()}
|
|
||||||
|
|
||||||
<div class="comment-path">
|
|
||||||
<a href="{$oBlog->getUrlFull()}" class="comment-path-blog">{$oBlog->getTitle()|escape}</a> →
|
|
||||||
<a href="{$oTopic->getUrl()}">{$oTopic->getTitle()|escape}</a>
|
|
||||||
<a href="{$oTopic->getUrl()}#comments">({$oTopic->getCountComment()})</a>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
|
|
||||||
{* Комментарий *}
|
|
||||||
<section data-id="{$oComment->getId()}" id="comment{$oComment->getId()}" class="js-comment comment open
|
|
||||||
{if ! $bList}
|
|
||||||
{if $oComment->isBad()}
|
|
||||||
comment-bad
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
{if $oComment->getDelete()}
|
|
||||||
comment-deleted
|
|
||||||
{elseif $oUserCurrent and $oComment->getUserId() == $oUserCurrent->getId()}
|
|
||||||
comment-self
|
|
||||||
{elseif $sDateReadLast <= $oComment->getDate()}
|
|
||||||
comment-new
|
|
||||||
{/if}
|
|
||||||
{else}
|
|
||||||
comment-list-item
|
|
||||||
{/if}">
|
|
||||||
{if ! $oComment->getDelete() or ($oUserCurrent and $oUserCurrent->isAdministrator())}
|
|
||||||
{* Аватар пользователя *}
|
|
||||||
<a href="{$oUser->getUserWebPath()}">
|
|
||||||
<img src="{$oUser->getProfileAvatarPath(48)}" alt="{$oUser->getDisplayName()}" class="comment-avatar" />
|
|
||||||
</a>
|
|
||||||
|
|
||||||
{* Информация *}
|
|
||||||
<ul class="comment-info">
|
|
||||||
{* Автор комментария *}
|
|
||||||
<li class="comment-username {if $iAuthorId == $oUser->getId()}comment-username-author{/if}" title="{if $sAuthorNotice}{$sAuthorNotice}{/if}">
|
|
||||||
<a href="{$oUser->getUserWebPath()}">{$oUser->getDisplayName()}</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
{* Дата *}
|
|
||||||
<li class="comment-date">
|
|
||||||
<a href="{if Config::Get('module.comment.use_nested')}{router page='comments'}{else}#comment{/if}{$oComment->getId()}" class="link-dotted" title="{$aLang.comments.comment.url}">
|
|
||||||
<time datetime="{date_format date=$oComment->getDate() format='c'}">{date_format date=$oComment->getDate() hours_back="12" minutes_back="60" now="60" day="day H:i" format="j F Y, H:i"}</time>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
{* Прокрутка к родительскии/дочернии комментариям *}
|
|
||||||
{if ! $bList and $oComment->getPid()}
|
|
||||||
<li class="comment-scroll-to comment-scroll-to-parent js-comment-scroll-to-parent" title="{$aLang.comments.comment.scroll_to_parent}" data-id="{$oComment->getId()}" data-parent-id="{$oComment->getPid()}">↑</li>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
<li class="comment-scroll-to comment-scroll-to-child js-comment-scroll-to-child" title="{$aLang.comments.comment.scroll_to_child}">↓</li>
|
|
||||||
|
|
||||||
{* Голосование *}
|
|
||||||
{if $oComment->getTargetType() != 'talk'}
|
|
||||||
<li>{include 'components/vote/vote.tpl' sClasses='js-vote-comment' oObject=$oComment bIsLocked=($oUserCurrent && $oUserCurrent->getId() == $oUser->getId())}</li>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
{* Избранное *}
|
|
||||||
{if $oUserCurrent and ! $bNoCommentFavourites}
|
|
||||||
<li>{include 'components/favourite/favourite.tpl' sClasses='js-favourite-comment' oObject=$oComment}</li>
|
|
||||||
{/if}
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
|
|
||||||
{* Текст комментария *}
|
|
||||||
<div id="comment_content_id_{$oComment->getId()}" class="comment-content text">
|
|
||||||
{$oComment->getText()}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{* Информация о редактировании *}
|
|
||||||
{if $oComment->getDateEdit()}
|
|
||||||
<div>
|
|
||||||
{$aLang.comments.comment.edit_info}: {date_format date=$oComment->getDateEdit() hours_back="12" minutes_back="60" now="60" day="day H:i" format="j F Y, H:i"}
|
|
||||||
{if $oComment->getCountEdit()>1}
|
|
||||||
({$oComment->getCountEdit()} {$oComment->getCountEdit()|declension:$aLang.common.times_declension})
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
{* Кнопки ответа, удаления и т.д. *}
|
|
||||||
{if $oUserCurrent}
|
|
||||||
<ul class="comment-actions">
|
|
||||||
{if ! $bList and ! $oComment->getDelete() and ! $bAllowNewComment}
|
|
||||||
<li><a href="#" class="link-dotted js-comment-reply" data-id="{$oComment->getId()}">{$aLang.comments.comment.reply}</a></li>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
<li class="link-dotted comment-fold js-comment-fold open" data-id="{$oComment->getId()}" style="display: none"><a href="#">{$aLang.comments.folding.fold}</a></li>
|
|
||||||
|
|
||||||
{if $oComment->IsAllowEdit()}
|
|
||||||
<li>
|
|
||||||
<a href="#" class="link-dotted js-comment-update" data-id="{$oComment->getId()}">
|
|
||||||
{$aLang.common.edit}
|
|
||||||
{if $oComment->getEditTimeRemaining()}
|
|
||||||
(<span class="js-comment-update-timer" data-seconds="{$oComment->getEditTimeRemaining()}"></span>)
|
|
||||||
{/if}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
{if $oComment->IsAllowDelete()}
|
|
||||||
<li><a href="#" class="link-dotted js-comment-remove" data-id="{$oComment->getId()}">{($oComment->getDelete()) ? $aLang.comments.comment.restore : $aLang.common.remove}</a></li>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
{hook run='comment_action' comment=$oComment}
|
|
||||||
</ul>
|
|
||||||
{/if}
|
|
||||||
{else}
|
|
||||||
{$aLang.comments.comment.deleted}
|
|
||||||
{/if}
|
|
||||||
</section>
|
|
|
@ -1,11 +0,0 @@
|
||||||
{**
|
|
||||||
* Список комментариев
|
|
||||||
*
|
|
||||||
* @styles css/comments.css
|
|
||||||
*}
|
|
||||||
|
|
||||||
{foreach $aComments as $oComment}
|
|
||||||
{include file='comments/comment.tpl' bList=true}
|
|
||||||
{/foreach}
|
|
||||||
|
|
||||||
{include 'components/pagination/pagination.tpl' aPaging=$aPaging}
|
|
|
@ -1,86 +0,0 @@
|
||||||
{**
|
|
||||||
* Пагинация комментариев
|
|
||||||
*
|
|
||||||
* @styles assets/css/common.css
|
|
||||||
*}
|
|
||||||
|
|
||||||
{if $aPagingCmt and $aPagingCmt.iCountPage>1}
|
|
||||||
{if $aPagingCmt.sGetParams}
|
|
||||||
{$sGetSep = '&'}
|
|
||||||
{else}
|
|
||||||
{$sGetSep = '?'}
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
<nav class="pagination pagination-comments js-pagination" role="navigation">
|
|
||||||
<ul class="pagination--list">
|
|
||||||
{if $aPagingCmt.iPrevPage}
|
|
||||||
<li class="pagination--item pagination--prev">
|
|
||||||
<a class="pagination--item-inner pagination--item-link js-pagination-prev"
|
|
||||||
href="{$aPagingCmt.sGetParams}{$sGetSep}cmtpage={$aPagingCmt.iPrevPage}"
|
|
||||||
title="{$aLang.paging_previos}">← {$aLang.paging_previos}</a>
|
|
||||||
</li>
|
|
||||||
{else}
|
|
||||||
<li class="pagination--item pagination--prev">
|
|
||||||
<span class="pagination--item-inner pagination--item-text">← {$aLang.paging_previos}</span>
|
|
||||||
</li>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
|
|
||||||
{if $aPagingCmt.iNextPage}
|
|
||||||
<li class="pagination--item pagination--next">
|
|
||||||
<a class="pagination--item-inner pagination--item-link js-pagination-next"
|
|
||||||
href="{$aPagingCmt.sGetParams}{$sGetSep}cmtpage={$aPagingCmt.iNextPage}"
|
|
||||||
title="{$aLang.paging_next}">{$aLang.paging_next} →</a>
|
|
||||||
</li>
|
|
||||||
{else}
|
|
||||||
<li class="pagination--item pagination--next">
|
|
||||||
<span class="pagination--item-inner pagination--item-text">{$aLang.paging_next} →</span>
|
|
||||||
</li>
|
|
||||||
{/if}
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<ul class="pagination--list">
|
|
||||||
{if Config::Get('module.comment.nested_page_reverse')}
|
|
||||||
{if $aPagingCmt.iCurrentPage > 1}
|
|
||||||
<li class="pagination--item"><a class="pagination--item-inner pagination--item-link" href="{$aPagingCmt.sGetParams}{$sGetSep}cmtpage=1">{$aLang.paging_first}</a></li>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
|
|
||||||
{foreach $aPagingCmt.aPagesLeft as $iPage}
|
|
||||||
<li class="pagination--item"><a class="pagination--item-inner pagination--item-link" href="{$aPagingCmt.sGetParams}{$sGetSep}cmtpage={$iPage}">{$iPage}</a></li>
|
|
||||||
{/foreach}
|
|
||||||
|
|
||||||
<li class="pagination--item active"><span class="pagination--item-inner pagination--item-text">{$aPagingCmt.iCurrentPage}</span></li>
|
|
||||||
|
|
||||||
{foreach $aPagingCmt.aPagesRight as $iPage}
|
|
||||||
<li class="pagination--item"><a class="pagination--item-inner pagination--item-link" href="{$aPagingCmt.sGetParams}{$sGetSep}cmtpage={$iPage}">{$iPage}</a></li>
|
|
||||||
{/foreach}
|
|
||||||
|
|
||||||
|
|
||||||
{if $aPagingCmt.iCurrentPage < $aPagingCmt.iCountPage}
|
|
||||||
<li class="pagination--item"><a class="pagination--item-inner pagination--item-link" href="{$aPagingCmt.sGetParams}{$sGetSep}cmtpage={$aPagingCmt.iCountPage}" title="{$aLang.paging_last}">{$aLang.paging_last}</a></li>
|
|
||||||
{/if}
|
|
||||||
{else}
|
|
||||||
{if $aPagingCmt.iCurrentPage < $aPagingCmt.iCountPage}
|
|
||||||
<li class="pagination--item"><a class="pagination--item-inner pagination--item-link" href="{$aPagingCmt.sGetParams}{$sGetSep}cmtpage={$aPagingCmt.iCountPage}">{$aLang.paging_last}</a></li>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
|
|
||||||
{foreach $aPagingCmt.aPagesRight as $iPage}
|
|
||||||
<li class="pagination--item"><a class="pagination--item-inner pagination--item-link" href="{$aPagingCmt.sGetParams}{$sGetSep}cmtpage={$iPage}">{$iPage}</a></li>
|
|
||||||
{/foreach}
|
|
||||||
|
|
||||||
<li class="pagination--item active"><span class="pagination--item-inner pagination--item-text">{$aPagingCmt.iCurrentPage}</span></li>
|
|
||||||
|
|
||||||
{foreach $aPagingCmt.aPagesLeft as $iPage}
|
|
||||||
<li class="pagination--item"><a class="pagination--item-inner pagination--item-link" href="{$aPagingCmt.sGetParams}{$sGetSep}cmtpage={$iPage}">{$iPage}</a></li>
|
|
||||||
{/foreach}
|
|
||||||
|
|
||||||
|
|
||||||
{if $aPagingCmt.iCurrentPage > 1}
|
|
||||||
<li class="pagination--item"><a class="pagination--item-inner pagination--item-link" href="{$aPagingCmt.sGetParams}{$sGetSep}cmtpage=1">{$aLang.paging_first}</a></li>
|
|
||||||
{/if}
|
|
||||||
{/if}
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
{/if}
|
|
|
@ -1,104 +0,0 @@
|
||||||
{**
|
|
||||||
* Комментарии
|
|
||||||
*
|
|
||||||
* @styles css/comments.css
|
|
||||||
*}
|
|
||||||
|
|
||||||
{* Добавляем в тулбар кнопку обновления комментариев *}
|
|
||||||
{add_block group='toolbar' name='toolbar/toolbar.comment.tpl'
|
|
||||||
aPagingCmt = $aPagingCmt
|
|
||||||
iTargetId = $iTargetId
|
|
||||||
sTargetType = $sTargetType
|
|
||||||
iMaxIdComment = $iMaxIdComment}
|
|
||||||
|
|
||||||
|
|
||||||
{hook run='comment_tree_begin' iTargetId=$iTargetId sTargetType=$sTargetType}
|
|
||||||
|
|
||||||
|
|
||||||
{**
|
|
||||||
* Комментарии
|
|
||||||
*}
|
|
||||||
<div class="comments js-comments" id="comments">
|
|
||||||
{**
|
|
||||||
* Хидер
|
|
||||||
*}
|
|
||||||
{if ! $bForbidNewComment || ( $bForbidNewComment && $iCountComment )}
|
|
||||||
<header class="comments-header">
|
|
||||||
<h3 class="comments-title js-comments-title">{$iCountComment} {$iCountComment|declension:$aLang.comments.comments_declension}</h3>
|
|
||||||
|
|
||||||
{* Подписка на комментарии *}
|
|
||||||
{if $bAllowSubscribe and $oUserCurrent}
|
|
||||||
<p><label class="comments-subscribe">
|
|
||||||
<input
|
|
||||||
type="checkbox"
|
|
||||||
id="comment_subscribe"
|
|
||||||
class="input-checkbox"
|
|
||||||
onchange="ls.subscribe.toggle('{$sTargetType}_new_comment','{$iTargetId}','',this.checked);"
|
|
||||||
{if $oSubscribeComment and $oSubscribeComment->getStatus()}checked{/if}>
|
|
||||||
{$aLang.comments.subscribe}
|
|
||||||
</label></p><br>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
{* Свернуть/развернуть все *}
|
|
||||||
<a href="#" class="link-dotted js-comments-fold-all">{$aLang.comments.folding.fold_all}</a> |
|
|
||||||
<a href="#" class="link-dotted js-comments-unfold-all">{$aLang.comments.folding.unfold_all}</a>
|
|
||||||
</header>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
{**
|
|
||||||
* Комментарии
|
|
||||||
*}
|
|
||||||
{$iCurrentLevel = -1}
|
|
||||||
{$iMaxLevel = Config::Get('module.comment.max_tree')}
|
|
||||||
|
|
||||||
{foreach $aComments as $oComment}
|
|
||||||
{$iCommentLevel = $oComment->getLevel()}
|
|
||||||
|
|
||||||
{if $iCommentLevel > $iMaxLevel}
|
|
||||||
{$iCommentLevel = $iMaxLevel}
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
{if $iCurrentLevel > $iCommentLevel}
|
|
||||||
{section name=closelist1 loop=$iCurrentLevel - $iCommentLevel + 1}</div>{/section}
|
|
||||||
{elseif $iCurrentLevel == $iCommentLevel && ! $oComment@first}
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
<div class="comment-wrapper js-comment-wrapper" data-id="{$oComment->getId()}">
|
|
||||||
|
|
||||||
{include './comment.tpl'}
|
|
||||||
|
|
||||||
{$iCurrentLevel = $iCommentLevel}
|
|
||||||
|
|
||||||
{if $oComment@last}
|
|
||||||
{section name=closelist2 loop=$iCurrentLevel + 1}</div>{/section}
|
|
||||||
{/if}
|
|
||||||
{/foreach}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
{**
|
|
||||||
* Пагинация
|
|
||||||
*}
|
|
||||||
{include './comment_pagination.tpl' aPagingCmt=$aPagingCmt}
|
|
||||||
|
|
||||||
{hook run='comment_tree_end' iTargetId=$iTargetId sTargetType=$sTargetType}
|
|
||||||
|
|
||||||
|
|
||||||
{**
|
|
||||||
* Форма добавления комментария
|
|
||||||
*}
|
|
||||||
{if $bForbidNewComment}
|
|
||||||
{include 'components/alert/alert.tpl' sMods='info' mAlerts=$sNoticeNotAllow}
|
|
||||||
{else}
|
|
||||||
{if $oUserCurrent}
|
|
||||||
{* Ссылка открывающая форму *}
|
|
||||||
<h4 class="comment-reply-root js-comment-reply js-comment-reply-root" data-id="0">
|
|
||||||
<a href="#" class="link-dotted">{$sNoticeCommentAdd}</a>
|
|
||||||
</h4>
|
|
||||||
|
|
||||||
{include './comment.form.tpl'}
|
|
||||||
{else}
|
|
||||||
{include 'components/alert/alert.tpl' sMods='info' mAlerts=$aLang.comments.alerts.unregistered}
|
|
||||||
{/if}
|
|
||||||
{/if}
|
|
|
@ -105,7 +105,10 @@
|
||||||
{* Не показываем если комментирование запрещено и кол-во комментариев равно нулю *}
|
{* Не показываем если комментирование запрещено и кол-во комментариев равно нулю *}
|
||||||
{if $bTopicList && ( ! $oTopic->getForbidComment() || ( $oTopic->getForbidComment() && $oEntry->getCountComment() ) )}
|
{if $bTopicList && ( ! $oTopic->getForbidComment() || ( $oTopic->getForbidComment() && $oEntry->getCountComment() ) )}
|
||||||
<li class="topic-info-item topic-info-item-comments">
|
<li class="topic-info-item topic-info-item-comments">
|
||||||
<a href="{$oEntry->getUrl()}#comments" title="{$aLang.topic_comment_read}">{$oEntry->getCountComment()} {$oEntry->getCountComment()|declension:$aLang.comments.comments_declension}</a>
|
<a href="{$oEntry->getUrl()}#comments" title="{$aLang.topic_comment_read}">
|
||||||
|
{lang name='comments.comments_declension' count=$oEntry->getCountComment() plural=true}
|
||||||
|
</a>
|
||||||
|
|
||||||
{if $oEntry->getCountCommentNew()}<span>+{$oEntry->getCountCommentNew()}</span>{/if}
|
{if $oEntry->getCountCommentNew()}<span>+{$oEntry->getCountCommentNew()}</span>{/if}
|
||||||
</li>
|
</li>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
{**
|
||||||
|
* Форма комментирования
|
||||||
|
*
|
||||||
|
* @param integer $iTargetId
|
||||||
|
* @param string $sTargetType
|
||||||
|
* @param string $sClasses Дополнительные классы
|
||||||
|
* @param string $sAttributes Атрибуты
|
||||||
|
* @param string $sMods Модификаторы
|
||||||
|
* @param string $sEditorSet (light) Стиль редактора
|
||||||
|
*
|
||||||
|
* @styles css/comments.css
|
||||||
|
*}
|
||||||
|
|
||||||
|
{* Название компонента *}
|
||||||
|
{$sComponent = 'comment-form'}
|
||||||
|
|
||||||
|
{* Переменные *}
|
||||||
|
{$iTargetId = $smarty.local.iTargetId}
|
||||||
|
{$sTargetType = $smarty.local.sTargetType}
|
||||||
|
|
||||||
|
|
||||||
|
{* Форма *}
|
||||||
|
<form method = "post"
|
||||||
|
class = "{$sComponent} {mod name=$sComponent mods=$sMods} {$smarty.local.classes} js-comment-form"
|
||||||
|
enctype = "multipart/form-data"
|
||||||
|
data-target-id = "{$iTargetId}"
|
||||||
|
data-target-type = "{$sTargetType}"
|
||||||
|
{$smarty.local.sAttributes}>
|
||||||
|
|
||||||
|
{block 'comment-form'}
|
||||||
|
{hook run='comment-form-begin'}
|
||||||
|
|
||||||
|
{block 'comment-form-fields'}
|
||||||
|
{* Скрытые поля *}
|
||||||
|
{include 'components/field/field.hidden.tpl' sName='reply' sValue='0' sId='form_comment_reply'}
|
||||||
|
{include 'components/field/field.hidden.tpl' sName='cmt_target_id' sValue=$iTargetId}
|
||||||
|
|
||||||
|
{* Текст комментария *}
|
||||||
|
{include 'components/editor/editor.tpl'
|
||||||
|
sSet = $smarty.local.sEditorSet|default:'light'
|
||||||
|
sName = 'comment_text'
|
||||||
|
sInputClasses = 'js-comment-form-text'
|
||||||
|
bShowHelp = false
|
||||||
|
sMediaTargetType = 'comment'}
|
||||||
|
{/block}
|
||||||
|
|
||||||
|
{hook run='comment-form-end'}
|
||||||
|
|
||||||
|
{**
|
||||||
|
* Кнопки
|
||||||
|
*}
|
||||||
|
|
||||||
|
{* Кнопка добавления *}
|
||||||
|
{include 'components/button/button.tpl' sName='submit_comment' sText=$aLang.common.add sMods='primary' sClasses='js-comment-form-submit'}
|
||||||
|
|
||||||
|
{* Кнопки редактирования *}
|
||||||
|
{include 'components/button/button.tpl' sName='submit_comment' sType='button' sText=$aLang.common.save sMods='primary' sClasses='js-comment-form-update-submit hide'}
|
||||||
|
{include 'components/button/button.tpl' sName='submit_comment' sType='button' sText=$aLang.common.cancel sClasses='js-comment-form-update-cancel fl-r hide'}
|
||||||
|
|
||||||
|
{* Кнопка превью текста *}
|
||||||
|
{include 'components/button/button.tpl' sText=$aLang.common.preview_text sType='button' sClasses='js-comment-form-preview'}
|
||||||
|
{/block}
|
||||||
|
</form>
|
|
@ -0,0 +1,102 @@
|
||||||
|
{**
|
||||||
|
* Комментарии
|
||||||
|
*
|
||||||
|
* @param string $sTargetType
|
||||||
|
* @param integer $iTargetId
|
||||||
|
* @param array $aComments
|
||||||
|
* @param boolean $bForbidAdd
|
||||||
|
* @param string $sHeading
|
||||||
|
* @param integer $iCountComment
|
||||||
|
* @param boolean $bAllowSubscribe
|
||||||
|
*
|
||||||
|
* @styles css/comments.css
|
||||||
|
*}
|
||||||
|
|
||||||
|
{block 'comment-list-options'}
|
||||||
|
{$iTargetId = $smarty.local.iTargetId}
|
||||||
|
{$sTargetType = $smarty.local.sTargetType}
|
||||||
|
{$iCountComment = $smarty.local.iCountComment}
|
||||||
|
{/block}
|
||||||
|
|
||||||
|
{add_block group='toolbar' name='toolbar/toolbar.comment.tpl' target='.js-comment'}
|
||||||
|
|
||||||
|
<div class="comments js-comments {$smarty.local.sClasses}"
|
||||||
|
id="comments"
|
||||||
|
data-target-type="{$sTargetType}"
|
||||||
|
data-target-id="{$iTargetId}"
|
||||||
|
data-comment-last-id="{$iMaxIdComment}">
|
||||||
|
{**
|
||||||
|
* Заголовок
|
||||||
|
*}
|
||||||
|
<header class="comments-header">
|
||||||
|
<h3 class="comments-title js-comments-title">
|
||||||
|
{lang name='comments.comments_declension' count=$iCountComment plural=true}
|
||||||
|
</h3>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
|
||||||
|
{**
|
||||||
|
* Экшнбар
|
||||||
|
*}
|
||||||
|
|
||||||
|
{* Свернуть/развернуть все комментарии *}
|
||||||
|
{$aItems = [ [ 'classes' => 'js-comments-fold-all-toggle', 'text' => $aLang.comments.folding.fold_all ] ]}
|
||||||
|
|
||||||
|
{* Подписка на комментарии *}
|
||||||
|
{if $bAllowSubscribe and $oUserCurrent}
|
||||||
|
{* Подписан пользователь на комментарии или нет *}
|
||||||
|
{$bIsSubscribed = $oSubscribeComment && $oSubscribeComment->getStatus()}
|
||||||
|
|
||||||
|
{$aItems[] = [
|
||||||
|
'classes' => "comments-subscribe js-comments-subscribe {if $bIsSubscribed}active{/if}",
|
||||||
|
'attributes' => "data-type=\"{$sTargetType}\" data-target-id=\"{$iTargetId}\"",
|
||||||
|
'text' => ( $bIsSubscribed ) ? $aLang.comments.unsubscribe : $aLang.comments.subscribe
|
||||||
|
]}
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{* TODO: Добавить хук *}
|
||||||
|
|
||||||
|
{include 'components/actionbar/actionbar.tpl' aItems=$aItems sClasses='comments-actions'}
|
||||||
|
|
||||||
|
|
||||||
|
{**
|
||||||
|
* Комментарии
|
||||||
|
*}
|
||||||
|
<div class="comment-list js-comment-list" data-target-type="{$sTargetType}" data-target-id="{$iTargetId}">
|
||||||
|
{include './comment-tree.tpl'
|
||||||
|
aComments = $smarty.local.aComments
|
||||||
|
bForbidAdd = $bForbidAdd
|
||||||
|
bShowFavourite = $smarty.local.bShowFavourite
|
||||||
|
bShowVote = $smarty.local.bShowVote}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
{**
|
||||||
|
* TODO: Пагинация
|
||||||
|
*}
|
||||||
|
{*include 'comments/comment_pagination.tpl' aPagingCmt=$aPagingCmt*}
|
||||||
|
|
||||||
|
|
||||||
|
{**
|
||||||
|
* Форма добавления комментария
|
||||||
|
*}
|
||||||
|
|
||||||
|
{* Проверяем запрещено комментирование или нет *}
|
||||||
|
{if $bForbidAdd}
|
||||||
|
{include 'components/alert/alert.tpl' sMods='info' mAlerts=$sNoticeNotAllow}
|
||||||
|
|
||||||
|
{* Если разрешено то показываем форму добавления комментария *}
|
||||||
|
{else}
|
||||||
|
{if $oUserCurrent}
|
||||||
|
{* Кнопка открывающая форму *}
|
||||||
|
<h4 class="comment-reply-root js-comment-reply js-comment-reply-root" data-id="0">
|
||||||
|
<a href="#" class="link-dotted">{$sNoticeCommentAdd}</a>
|
||||||
|
</h4>
|
||||||
|
|
||||||
|
{* Форма добавления комментария *}
|
||||||
|
{include './comment-form.tpl' sTargetType=$sTargetType iTargetId=$iTargetId}
|
||||||
|
{else}
|
||||||
|
{include 'components/alert/alert.tpl' sMods='info' mAlerts=$aLang.comments.alerts.unregistered}
|
||||||
|
{/if}
|
||||||
|
{/if}
|
||||||
|
</div>
|
|
@ -0,0 +1,62 @@
|
||||||
|
{**
|
||||||
|
* Дерево комментариев
|
||||||
|
*
|
||||||
|
* @component comment
|
||||||
|
* @styles css/comments.css
|
||||||
|
* @scripts js/comments.js
|
||||||
|
*
|
||||||
|
* @param array $aComments Комментарии
|
||||||
|
* @param string $sClasses Дополнительные классы
|
||||||
|
* @param string $sAttributes Атрибуты
|
||||||
|
* @param string $sMods
|
||||||
|
* @param boolean $bShowVote (true) Показывать или нет голосование
|
||||||
|
* @param boolean $bShowReply (true) Показывать или нет кнопку Ответить
|
||||||
|
* @param integer $iAuthorId
|
||||||
|
* @param string $sDateReadLast
|
||||||
|
*}
|
||||||
|
|
||||||
|
{* Текущая вложенность *}
|
||||||
|
{$iCurrentLevel = -1}
|
||||||
|
|
||||||
|
{* Максимальная вложенность *}
|
||||||
|
{$iMaxLevel = $smarty.local.iMaxLevel|default:Config::Get('module.comment.max_tree')}
|
||||||
|
|
||||||
|
{* Добавляем возможность переопределить стандартный шаблон комментария *}
|
||||||
|
{$sTemplate = $smarty.local.template|default:'./comment.tpl'}
|
||||||
|
|
||||||
|
{* Построение дерева комментариев *}
|
||||||
|
{foreach $smarty.local.aComments as $oComment}
|
||||||
|
{* Ограничиваем вложенность комментария максимальным значением *}
|
||||||
|
{$iCommentLevel = ( $oComment->getLevel() > $iMaxLevel ) ? $iMaxLevel : $oComment->getLevel()}
|
||||||
|
|
||||||
|
{* Закрываем блоки-обертки *}
|
||||||
|
{if $iCurrentLevel > $iCommentLevel}
|
||||||
|
{section closewrappers1 loop=$iCurrentLevel - $iCommentLevel + 1}</div>{/section}
|
||||||
|
{elseif $iCurrentLevel == $iCommentLevel && ! $oComment@first}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{* Устанавливаем текущий уровень вложенности *}
|
||||||
|
{$iCurrentLevel = $iCommentLevel}
|
||||||
|
|
||||||
|
{* Вспомогательный блок-обертка *}
|
||||||
|
<div class="comment-wrapper js-comment-wrapper" data-id="{$oComment->getId()}">
|
||||||
|
|
||||||
|
{* Комментарий *}
|
||||||
|
{include "$sTemplate"
|
||||||
|
oComment = $oComment
|
||||||
|
bShowVote = $smarty.local.bShowVote
|
||||||
|
bShowReply = ! $smarty.local.bForbidAdd
|
||||||
|
bShowFavourite = $smarty.local.bShowFavourite
|
||||||
|
sDateReadLast = $sDateReadLast
|
||||||
|
bIsHidden = $oComment->getDelete()
|
||||||
|
bShowScroll = true
|
||||||
|
bShowEdit = true}
|
||||||
|
|
||||||
|
{* Закрываем блоки-обертки после последнего комментария *}
|
||||||
|
{if $oComment@last}
|
||||||
|
{section closewrappers2 loop=$iCurrentLevel + 1}</div>{/section}
|
||||||
|
{/if}
|
||||||
|
{foreachelse}
|
||||||
|
{include 'components/alert/alert.tpl' sMods='empty' mAlerts=$aLang.common.empty}
|
||||||
|
{/foreach}
|
|
@ -0,0 +1,190 @@
|
||||||
|
{**
|
||||||
|
* Комментарий
|
||||||
|
*
|
||||||
|
* @component comment
|
||||||
|
* @styles css/comments.css
|
||||||
|
* @scripts js/comments.js
|
||||||
|
*
|
||||||
|
* @param object $oComment Комментарий
|
||||||
|
* @param string $sClasses Дополнительные классы
|
||||||
|
* @param string $sAttributes Атрибуты
|
||||||
|
* @param string $sMods Модификаторы
|
||||||
|
* @param boolean $bShowVote (true) Показывать или нет голосование
|
||||||
|
* @param boolean $bShowReply (true) Показывать или нет кнопку Ответить
|
||||||
|
* @param integer $iAuthorId
|
||||||
|
* @param string $sDateReadLast
|
||||||
|
*}
|
||||||
|
|
||||||
|
{* Название компонента *}
|
||||||
|
{$sComponent = 'comment'}
|
||||||
|
|
||||||
|
{* Переменные *}
|
||||||
|
{$oComment = $smarty.local.oComment}
|
||||||
|
{$sMods = $smarty.local.sMods}
|
||||||
|
{$bShowEdit = $smarty.local.bShowEdit|default:true}
|
||||||
|
{$bIsHidden = $smarty.local.bIsHidden}
|
||||||
|
{$oUser = $oComment->getUser()}
|
||||||
|
{$iCommentId = $oComment->getId()}
|
||||||
|
|
||||||
|
{* Получаем ссылку на комментарий *}
|
||||||
|
{* TODO: Вынести в бэкенд *}
|
||||||
|
{$sPermalink = ( Config::Get('module.comment.use_nested') ) ? "{router page='comments'}{$iCommentId}" : "#comment{$iCommentId}"}
|
||||||
|
|
||||||
|
{**
|
||||||
|
* Добавляем модификаторы
|
||||||
|
*}
|
||||||
|
|
||||||
|
{* Комментарий с отрицательным рейтингом *}
|
||||||
|
{if $smarty.local.bShowVote && $oComment->isBad()}
|
||||||
|
{$sMods = "$sMods bad"}
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{* Автор комментария является автором объекта к которому оставлен комментарий *}
|
||||||
|
{if $smarty.local.iAuthorId == $oUser->getId()}
|
||||||
|
{$sMods = "$sMods author"}
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{* Комментарий удален *}
|
||||||
|
{if $bIsHidden}
|
||||||
|
{$sMods = "$sMods deleted"}
|
||||||
|
|
||||||
|
{* Комментарий текущего залогиненого пользователя *}
|
||||||
|
{elseif $oUserCurrent && $oComment->getUserId() == $oUserCurrent->getId()}
|
||||||
|
{$sMods = "$sMods self"}
|
||||||
|
|
||||||
|
{* Непрочитанный комментарий *}
|
||||||
|
{elseif $smarty.local.sDateReadLast && strtotime($smarty.local.sDateReadLast) <= strtotime($oComment->getDate())}
|
||||||
|
{$sMods = "$sMods new"}
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
|
||||||
|
{**
|
||||||
|
* Комментарий
|
||||||
|
* Атрибут id используется для ссылки на комментарий через хэш в урл #comment123
|
||||||
|
*}
|
||||||
|
<section class = "{$sComponent} {mod name=$sComponent mods=$sMods} {$smarty.local.sClasses} open js-{$sComponent}"
|
||||||
|
id = "comment{$iCommentId}"
|
||||||
|
data-id = "{$iCommentId}"
|
||||||
|
{$smarty.local.sAttributes}>
|
||||||
|
|
||||||
|
{* Показываем удаленные комментарии только администраторам *}
|
||||||
|
{if ! $bIsHidden || ( $oUserCurrent && $oUserCurrent->isAdministrator() )}
|
||||||
|
{* Аватар пользователя *}
|
||||||
|
<a href="{$oUser->getUserWebPath()}" class="{$sComponent}-avatar">
|
||||||
|
<img src="{$oUser->getProfileAvatarPath(64)}" alt="{$oUser->getDisplayName()}" />
|
||||||
|
</a>
|
||||||
|
|
||||||
|
{* Информация *}
|
||||||
|
<ul class="{$sComponent}-info clearfix">
|
||||||
|
{* Автор комментария *}
|
||||||
|
<li class="{$sComponent}-username">
|
||||||
|
<a href="{$oUser->getUserWebPath()}">
|
||||||
|
{$oUser->getDisplayName()}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
{* Дата добавления комментария *}
|
||||||
|
{* Так же является ссылкой на комментарий *}
|
||||||
|
<li class="{$sComponent}-date">
|
||||||
|
<a href="{$sPermalink}" title="{$aLang.comments.comment.url}">
|
||||||
|
<time datetime="{date_format date=$oComment->getDate() format='c'}">
|
||||||
|
{date_format date=$oComment->getDate() hours_back="12" minutes_back="60" now="60" day="day H:i" format="j F Y, H:i"}
|
||||||
|
</time>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
{* Прокрутка к родительскому комментарию *}
|
||||||
|
{if $smarty.local.bShowScroll}
|
||||||
|
{if $oComment->getPid()}
|
||||||
|
<li class = "{$sComponent}-scroll-to {$sComponent}-scroll-to-parent js-comment-scroll-to-parent"
|
||||||
|
title = "{$aLang.comments.comment.scroll_to_parent}"
|
||||||
|
data-id = "{$iCommentId}"
|
||||||
|
data-parent-id = "{$oComment->getPid()}">↑</li>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{* Прокрутка к дочернему комментарию *}
|
||||||
|
<li class = "{$sComponent}-scroll-to {$sComponent}-scroll-to-child js-comment-scroll-to-child"
|
||||||
|
title = "{$aLang.comments.comment.scroll_to_child}">↓</li>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{* Голосование *}
|
||||||
|
{if $smarty.local.bShowVote}
|
||||||
|
<li>
|
||||||
|
{* Блокируем голосование для гостей или если залогиненый пользователь является автором комментария*}
|
||||||
|
{include 'components/vote/vote.tpl'
|
||||||
|
sClasses = "{$sComponent}-vote js-vote-{$sComponent}"
|
||||||
|
oObject = $oComment
|
||||||
|
bIsLocked = ($oUserCurrent && $oUserCurrent->getId() == $oUser->getId())}
|
||||||
|
</li>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{* Избранное *}
|
||||||
|
{if $oUserCurrent && $smarty.local.bShowFavourite}
|
||||||
|
<li>
|
||||||
|
{include 'components/favourite/favourite.tpl' sClasses='comment-favourite js-favourite-comment' oObject=$oComment}
|
||||||
|
</li>
|
||||||
|
{/if}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
{* Текст комментария *}
|
||||||
|
<div class="{$sComponent}-content text">
|
||||||
|
{$oComment->getText()}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{* Информация о редактировании *}
|
||||||
|
{if $oComment->getDateEdit()}
|
||||||
|
<div class="{$sComponent}-edit-info">
|
||||||
|
{$aLang.comments.comment.edit_info}:
|
||||||
|
|
||||||
|
<span class="{$sComponent}-edit-info-time js-{$sComponent}-edit-time">
|
||||||
|
{date_format date=$oComment->getDateEdit() hours_back="12" minutes_back="60" now="60" day="day H:i" format="j F Y, H:i"}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
{if $oComment->getCountEdit() > 1}
|
||||||
|
({$oComment->getCountEdit()} {$oComment->getCountEdit()|declension:$aLang.common.times_declension})
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{* Действия *}
|
||||||
|
<ul class="comment-actions clearfix">
|
||||||
|
{* Ответить *}
|
||||||
|
{if $oUserCurrent && ! $bIsHidden && $smarty.local.bShowReply|default:true}
|
||||||
|
<li>
|
||||||
|
<a href="#" class="link-dotted js-comment-reply" data-id="{$iCommentId}">{$aLang.comments.comment.reply}</a>
|
||||||
|
</li>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{* Сворачивание *}
|
||||||
|
<li class="comment-fold js-comment-fold open" data-id="{$iCommentId}">
|
||||||
|
<a href="#" class="link-dotted">{$aLang.comments.folding.fold}</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
{* Редактировать *}
|
||||||
|
{if $smarty.local.bShowEdit && $oUserCurrent && $oComment->IsAllowEdit()}
|
||||||
|
<li>
|
||||||
|
<a href="#" class="link-dotted js-comment-update" data-id="{$iCommentId}">
|
||||||
|
{$aLang.common.edit}
|
||||||
|
|
||||||
|
{* Отображение времени отведенного для редактирования *}
|
||||||
|
{* Используется плагин jquery.timers *}
|
||||||
|
{if $oComment->getEditTimeRemaining()}
|
||||||
|
(<span class="js-comment-update-timer" data-seconds="{$oComment->getEditTimeRemaining()}">...</span>)
|
||||||
|
{/if}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{* Удалить *}
|
||||||
|
{if $oUserCurrent && $oComment->IsAllowDelete()}
|
||||||
|
<li>
|
||||||
|
<a href="#" class="link-dotted js-comment-remove" data-id="{$iCommentId}">
|
||||||
|
{( $bIsHidden ) ? $aLang.comments.comment.restore : $aLang.common.remove}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{/if}
|
||||||
|
</ul>
|
||||||
|
{else}
|
||||||
|
{$aLang.comments.comment.deleted}
|
||||||
|
{/if}
|
||||||
|
</section>
|
|
@ -0,0 +1,40 @@
|
||||||
|
{**
|
||||||
|
* Тестирование компонента comment
|
||||||
|
*}
|
||||||
|
|
||||||
|
{extends 'layouts/layout.base.tpl'}
|
||||||
|
|
||||||
|
{block 'layout_options'}
|
||||||
|
{$bNoSidebar = true}
|
||||||
|
{/block}
|
||||||
|
|
||||||
|
{block 'layout_page_title'}
|
||||||
|
Component <span>comment</span>
|
||||||
|
{/block}
|
||||||
|
|
||||||
|
{block 'layout_content'}
|
||||||
|
{function test_heading}
|
||||||
|
<br><h3>{$text}</h3>
|
||||||
|
{/function}
|
||||||
|
|
||||||
|
{* Полная версия *}
|
||||||
|
{test_heading text='Default'}
|
||||||
|
|
||||||
|
<div class="comments js-comments" id="comments">
|
||||||
|
<div class="comment-wrapper js-comment-wrapper" data-id="{$comment1->getId()}">
|
||||||
|
{include 'components/comment/comment.tpl'
|
||||||
|
oComment = $comment1
|
||||||
|
bShowVote = true
|
||||||
|
sDateLastRead = '2014-01-01 00:00:00'}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="comment-wrapper js-comment-wrapper" data-id="{$comment2->getId()}">
|
||||||
|
{include 'components/comment/comment.tpl'
|
||||||
|
comment = $comment2
|
||||||
|
bShowVote = true
|
||||||
|
sDateLastRead = '2014-01-01 00:00:00'}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{include 'comments/comment.form.tpl'}
|
||||||
|
</div>
|
||||||
|
{/block}
|
|
@ -11,7 +11,7 @@
|
||||||
{block 'layout_head' append}
|
{block 'layout_head' append}
|
||||||
<script>
|
<script>
|
||||||
ls.lang.load({json var = $aLangJs});
|
ls.lang.load({json var = $aLangJs});
|
||||||
ls.lang.load({lang_load name="comments.comments_declension, comments.folding.unfold, comments.folding.fold, poll.notices.error_answers_max, blog.blog, favourite.add, favourite.remove, geo_select_city, geo_select_region, blog.add.fields.type.note_open, blog.add.fields.type.note_close, common.success.add, common.success.remove"});
|
ls.lang.load({lang_load name="comments.comments_declension, comments.unsubscribe, comments.subscribe, comments.folding.unfold, comments.folding.fold, comments.folding.unfold_all, comments.folding.fold_all, poll.notices.error_answers_max, blog.blog, favourite.add, favourite.remove, geo_select_city, geo_select_region, blog.add.fields.type.note_open, blog.add.fields.type.note_close, common.success.add, common.success.remove"});
|
||||||
|
|
||||||
ls.registry.set('comment_max_tree', {json var=Config::Get('module.comment.max_tree')});
|
ls.registry.set('comment_max_tree', {json var=Config::Get('module.comment.max_tree')});
|
||||||
ls.registry.set('block_stream_show_tip', {json var=Config::Get('block.stream.show_tip')});
|
ls.registry.set('block_stream_show_tip', {json var=Config::Get('block.stream.show_tip')});
|
||||||
|
|
Loading…
Reference in a new issue