Effectively integrate and display comment lists in Anqi CMS, which is crucial for enhancing website user interaction, active community atmosphere, and obtaining valuable user feedback.As an experienced CMS website operation personnel, I know that high-quality content cannot be separated from the active participation of users.AnQi CMS provides powerful and flexible template tags, allowing us to easily implement this feature on the website front-end.

Overview of comment feature and template file organization

The AnQi CMS is built with a comment management feature, allowing website administrators to review, reply to, and manage user comments.To integrate the comment list on the website front end, we first need to understand the recommended position in the template structure.According to the template production agreement of AnQi CMS, the comment list page is usually stored incomment/list.htmlIn such a path. Of course, you can also directly introduce the comment list code snippet in other template files such as the article detail page according to your actual needs.

Display comment list:commentListThe use of tags

Anqi CMS passedcommentListTemplate tags to render comment content. This tag has high flexibility and can retrieve and display comments based on different parameters.

To usecommentListTag, you need to be in a{% commentList comments with ... %}Define a variable in the code block (for examplecommentsThen proceedforLoop through the variable to display the details of each comment.

commentListThe tag supports the following key parameters:

  • archiveId: This is the ID of the document to which the comment belongs. Usually, we dynamically obtain the ID of the current article on the article detail page and use it asarchiveIdthe value.
  • order: Used to specify the sorting method of comments, for exampleid desc(Sorted in descending order by ID, i.e., the latest comments first) orid asc(Sorted in ascending order by ID).
  • limit: Control the number of comments displayed. If you only want to display the latest N comments, you can uselimit="N". It also supportsoffsetpattern, such aslimit="2,10"to get 10 comments starting from the second one.
  • type: Define the type of comment list. Whentype="list"it will directly display the specified number of comments. Whentype="page"it indicates that you want the comment list to have pagination functionality, at which point you need to work withpaginationTags are used together.
  • siteIdWhen your safe CMS deploys multiple sites, you can use this parameter to specify the site ID to retrieve comments.In most cases, there is no need to manually set, the system will automatically identify the current site.

InforIn the loop, each comment data is displayed in the form ofitemVariables, including such asId(Comment ID),UserName(Name of the commenter),Content(Comment content),CreatedTime(Comment Time),Status(Review Status),ParentIf this is a reply, it includes parent comment information fields. When displaying user submitted content, in order to prevent XSS attacks, it is necessary to use|safefilter for output.

Here is a basic comment list code example, which is usually placed at the bottom of the article detail page:

<div class="comments-section">
    <h3>用户评论</h3>
    {% commentList comments with archiveId=archive.Id type="list" limit="6" %}
        {% for item in comments %}
            <div class="comment-item">
                <div class="comment-meta">
                    <span class="username">
                        {% if item.Status != 1 %}
                            (审核中){{item.UserName|truncatechars:6}}
                        {% else %}
                            {{item.UserName}}
                        {% endif %}
                    </span>
                    {% if item.Parent %}
                        <span class="reply-to">回复 
                            {% if item.Parent.Status != 1 %}
                                (审核中){{item.Parent.UserName|truncatechars:6}}
                            {% else %}
                                {{item.Parent.UserName}}
                            {% endif %}
                        </span>
                    {% endif %}
                    <span class="time">{{stampToDate(item.CreatedTime, "2006-01-02 15:04")}}</span>
                </div>
                <div class="comment-content">
                    {% if item.Parent %}
                        <blockquote class="reply-quote">
                            {% if item.Parent.Status != 1 %}
                                该内容正在审核中:{{item.Parent.Content|truncatechars:9|safe}}
                            {% else %}
                                {{item.Parent.Content|truncatechars:100|safe}}
                            {% endif %}
                        </blockquote>
                    {% endif %}
                    {% if item.Status != 1 %}
                        该内容正在审核中:{{item.Content|truncatechars:9|safe}}
                    {% else %}
                        {{item.Content|safe}}
                    {% endif %}
                </div>
                <div class="comment-actions" data-id="{{item.Id}}" data-user="{{item.UserName}}">
                    <a class="action-btn vote-comment" data-id="praise">赞(<span class="vote-count">{{item.VoteCount}}</span>)</a>
                    <a class="action-btn reply-comment" data-id="reply">回复</a>
                </div>
            </div>
        {% endfor %}
        {% empty %}
            <p class="no-comments">目前还没有评论,快来发表您的看法吧!</p>
    {% endcommentList %}
</div>

If you have a large number of comments and want to implement pagination, you cantypethe parameter topage,and cooperatepaginationTags to generate pagination links:

<div class="comments-section">
    <h3>用户评论</h3>
    {% commentList comments with archiveId=archive.Id type="page" limit="10" %}
        {# 评论列表内容与上方示例类似 #}
        {% for item in comments %}
            {# ... 显示评论内容 ... #}
        {% endfor %}
    {% endcommentList %}

    <div class="pagination-container">
        {% pagination pages with show="5" %}
            <ul class="pagination-list">
                <li class="page-item {% if pages.FirstPage.IsCurrent %}active{% endif %}"><a href="{{pages.FirstPage.Link}}">{{pages.FirstPage.Name}}</a></li>
                {% if pages.PrevPage %}
                    <li class="page-item"><a href="{{pages.PrevPage.Link}}">{{pages.PrevPage.Name}}</a></li>
                {% endif %}
                {% for item in pages.Pages %}
                    <li class="page-item {% if item.IsCurrent %}active{% endif %}"><a href="{{item.Link}}">{{item.Name}}</a></li>
                {% endfor %}
                {% if pages.NextPage %}
                    <li class="page-item"><a href="{{pages.NextPage.Link}}">{{pages.NextPage.Name}}</a></li>
                {% endif %}
                <li class="page-item {% if pages.LastPage.IsCurrent %}active{% endif %}"><a href="{{pages.LastPage.Link}}">{{pages.LastPage.Name}}</a></li>
            </ul>
        {% endpagination %}
    </div>
</div>

Comment submission form: Implement user comment feature

Users usually submit comments through an HTML form. This form needs to submit data to the Anqi CMS.comment/publishInterface. The form must includearchive_id/user_nameandcontentfields, among whichparent_idused to reply to a specific comment.

<div class="comment-form-section">
    <h3>发表评论</h3>
    <form method="post" action="/comment/publish" class="comment-submit-form">
        <input type="hidden" name="return" value="html"> {# 可选,指定后端返回HTML或JSON #}
        <input type="hidden" name="archive_id" value="{% archiveDetail with name="Id" %}"> {# 假设在文章详情页,archive.Id 可用 #}
        <input type="hidden" name="parent_id" id="parent_comment_id" value=""> {# 回复时动态填充 #}

        <div class="form-group">
            <label for="comment-username">您的昵称:</label>
            <input type="text" id="comment-username" name="user_name" required placeholder="请输入您的昵称" autocomplete="off">
        </div>
        <div class="form-group">
            <label for="comment-content">评论内容:</label>
            <textarea id="comment-content" name="content" required rows="5" placeholder="请在此处输入您的评论"></textarea>
        </div>

        {# 验证码集成(如果启用) #}
        <div class="form-group captcha-group" style="display: flex; align-items: center;">
            <input type="hidden" name="captcha_id" id="captcha_id">
            <input type="text" name="captcha" required placeholder="请填写验证码" class="captcha-input">
            <img src="" id="get-captcha" class="captcha-image" title="点击刷新验证码">
        </div>
        
        <div class="form-actions">
            <button type="submit" class="submit-btn">提交评论</button>
            <button type="reset" class="reset-btn">重置</button>
        </div>
    </form>
</div>

<script>
// JavaScript 刷新验证码
document.getElementById('get-captcha').addEventListener("click", function () {
  fetch('/api/captcha')
    .then(response => response.json())
    .then(res => {
      document.getElementById('captcha_id').setAttribute("value", res.data.captcha_id);
      document.getElementById('get-captcha').setAttribute("src", res.data.captcha);
    }).catch(err => console.error('Error fetching captcha:', err));
});
document.getElementById('get-captcha').click(); // 页面加载时自动获取一次验证码

// JavaScript 处理回复功能
document.querySelectorAll('.reply-comment').forEach(button => {
    button.addEventListener('click', function() {
        const commentId = this.closest('.comment-actions').dataset.id;
        const userName = this.closest('.comment-actions').dataset.user;
        document.getElementById('parent_comment_id').value = commentId;
        document.getElementById('comment-content').value = `回复 @${userName}: `;
        document.getElementById('comment-content').focus();
    });
});
</script>

Comment like function: enhance interaction.

To further increase user interaction, you can add a like button to comments. This is usually done through JavaScript to/comment/praiseSend a POST request to implement the interface, the request body must include comments.id.

// 假设您已经使用了jQuery,或自行实现Ajax请求
$(document).on('click', '.vote-comment', function() {
  const $this = $(this);
  const commentId = $this.closest('.comment-actions').data("id");

  $.ajax({
    url: "/comment/praise",
    method: "POST",
    data: { id: commentId },
    dataType: "json",
    success: function(res) {
      if (res.code === 0) {
        $this.find(".vote-count").text(res.data.vote_count);
        alert(res.msg || "点赞成功!");
      } else {
        alert(res.msg || "点赞失败,请稍后再试。");
      }
    },
    error: function(xhr, status, error) {
      alert("网络错误,请检查您的连接。");
      console.error("点赞请求失败:", status, error);
    }
  });
});

Integrate captcha to prevent spam comments.

In order to effectively prevent spam comments and malicious screen scraping, AnQi CMS supports the integration of captcha function. Firstly, you need to go to the AnQi CMS backend's全局设置 -> 内容设置Enable Markdown editor (The document mentions that Captcha is related to Markdown editor, actually Captcha is an independent auxiliary comment function). In actual operation, the captcha function is usually in功能管理 -> 网站留言/内容评论In the relevant settings enable.

Once the background is enabled, you can add the HTML and JavaScript code for the captcha in the comment submission form, as shown in the previous form submission example. This includes a hiddencaptcha_idfield, a text box for entering a captcha and a button to display and refresh the captcha image<img>Label. JavaScript is responsible for retrieving and displaying the captcha image, as well as refreshing the captcha when the user clicks on the image.

By following these steps, you can build a feature-rich, interactive comment system for your secure CMS website, thereby attracting and retaining users better.


Frequently Asked Questions (FAQ)

1. Why is my comment list not displaying or why are comments not appearing after submission?

This usually has several reasons. First, make sure that your template code is used correctly.