During the development and maintenance of website templates, we often encounter situations where a page element does not display as expected, or data seems missing or incorrectly formatted.This allows for a clear view of the structure and specific values of variables within the template, which becomes the key to quickly locating issues.For users of AnQiCMS, the system provides powerful and convenient debugging tools to help us easily "see through" template data.

Why do we need to debug template variables?

In AnQiCMS templates, data is passed through variables. These variables may come from system configuration, article content, category information, or within the template through various tags (such asarchiveList/categoryDetailThe value is dynamically retrieved. When the page rendering occurs an exception, directly checking the actual values and data structure of these variables can help us:

  1. Confirm whether the data exists:Whether the variable has successfully retrieved the data?
  2. Verify the content of the data:Is the retrieved data the expected content?
  3. Understand the data structure:If a variable is a complex object or list, what fields does it contain? Are the field names correct?

Mastering variable debugging techniques can significantly improve our efficiency in solving template problems.

core tools:dumpFilter

The template engine of AnQiCMS supports rich filters, among which the most direct and powerful variable debugging tool isdumpFilter.dumpThe filter can output the complete data structure of any variable and its current value in a clear and readable format.

Usage:

You just need to add it after any variable you want to check.|dumpIt is. For example:

{# 检查整个 archives 变量的结构和值 #}
{{ archives|dump }}

{# 检查单个 item 变量的结构和值 #}
{{ item|dump }}

When you add this code to the template and refresh the page, it will output content similar to the following (the specific content depends on the type of variable):

&models.Archive{Id:1, Title:"我的第一篇文章", Description:"这是一篇测试文章。", CreatedTime:1678886400, ...}

This output clearly demonstratesitemis amodels.Archivethe object of this type, listing all its fields (such asId,Title,Description,CreatedTimeThe current values of ()are crucial for understanding the structure of the data object passed to the template.

Understanding data structure and delving deeper layer by layer

dumpThe filter can display the full picture of variables at once, but in actual debugging, we often need to combine our understanding of different data types with some auxiliary skills.

  1. Basic Variables (strings, numbers, booleans):For simple variables, use directly:{{ 变量名 }}You can view its value. If it appears blank, it may indicate that the variable is undefined or the value is null.

  2. Object (struct) properties:Most of the data in AnQiCMS (such as articles, categories, users, etc.) is passed in the form of structured objects. If you passdumpa variable through a filterarchiveis an article object, and it has aTitleattribute, you can directly access it through{{ archive.Title }}to display the article title.

  3. Lists and Arrays:When a variable is a list or array containing multiple elements (for examplearchiveListreturnedarchives), we need to use{% for %}a loop to iterate over each element. Inside the loop, each element is also used todumpFilter:

    {% archiveList articles with type="list" limit="3" %}
        {% for article in articles %}
            {# 在循环内部,检查每个 article 对象的结构和值 #}
            {{ article|dump }}
            <h3>{{ article.Title }}</h3>
            <p>{{ article.Description }}</p>
        {% endfor %}
    {% endarchiveList %}
    

    So, you can check each article object in the list one by one, ensuring its data integrity and correctness.

  4. Processing HTML content:safeFilterWhile debugging article content (archive.Content) or classification description (category.DescriptionWhen a variable of this kind may contain HTML tags, you might find that the output is the HTML source code rather than the rendered content.This is because the AnQiCMS template engine, for safety (to prevent XSS attacks), defaults to escaping all variable outputs.safeFilter:

    {# 确保文章内容被正确渲染为 HTML #}
    <div>{{ archive.Content|safe }}</div>
    

    When debugging, ifdumpthe output content includes HTML tags, but{{ archive.Content }}what you see is the source code instead|safethen that is your solution.

Practical Skills and Scene Applications

ExceptdumpandsafeFilter, some practical tips can make your debugging process more efficient:

  • Isolation and Focus: Using{% set %}or{% with %}When you need to debug a deeply nested or computationally generated variable, you can use{% set %}or{% with %}Extract the tag into a temporary variable for easier checking.

    {% set myArticle = archives|first %} {# 获取列表的第一个元素并赋值给 myArticle #}
    {{ myArticle|dump }} {# 调试这个临时变量 #}
    
    
    {% with debugTitle = archive.Title %}
        <p>调试标题: {{ debugTitle }}</p>
    {% endwith %}
    
  • Check if the variable exists:{% if %}Before trying to output a variable, first use{% if 变量名 %}Judging is a good habit. This can avoid template rendering errors caused by variables being empty or not existing, especially when debugging variables that may occasionally be empty.

    {% if archive.Author %}
        <p>作者:{{ archive.Author }}</p>
    {% else %}
        <p>作者信息缺失。</p>
    {% endif %}
    
  • Output a specific attribute:IfdumpThe output information is too much, you just want to quickly confirm a specific attribute (such as the Link), output directly{{ item.Link }}will bedumpthe wholeitemMore concise.

  • Temporary comment code:{# #}or{% comment %}During the debugging process, it is often necessary to temporarily disable certain code blocks. Use{# 这是单行注释 #}or{% comment %} 这里可以注释多行代码 {% endcomment %}It can avoid the trouble of deleting and restoring code.

  • Combined with other filters:

    • |length:Check the length of a list or string. For example{{ archives|length }}Can tell you how many articles are in the list.
    • |join:Join the elements of an array or list into a string with a specified separator for easy viewing of all elements. For example{{ categories|join:", "|safe }}.
    • |stringformat:Format numbers and strings output, especially useful when precise control of the number of digits displayed is required.

Case Demonstration: InsightarchiveListof the data

Suppose you are developing a list page for articles, but the page does not display any articles, or the article titles are incorrect.

Your template code might look something like this:

{% archiveList articles with type="page" limit="10" %}
    {% for post in articles %}
        <div class="article-item">
            <h2><a href="{{ post.Link }}">{{ post.Title }}</a></h2>
            <p>{{ post.Description }}</p>
        </div>
    {% empty %}
        <p>目前还没有文章。</p>
    {% endfor %}
{% endarchiveList %}

Debugging steps:

  1. Check if the entire list variable exists and has the correct structure:In{% archiveList %}after the label, but{% for %}insert before the loop{{ articles|dump }}.

    {% archiveList articles with type="page" limit="10" %}
        {{ articles|dump }} {# 临时插入这行 #}
        {% for post in articles %}
            {# ... #}
        {% endfor %}
    {% endarchiveList %}
    

    refresh the page, and viewarticlesif there is any data. IfdumpIt means that there is no output or the output is empty,archiveListThe label may not have retrieved the data (check),type/limit/categoryIdwhether the parameters are correct), or,articlesthe variable name is incorrect.

  2. Check the structure of the individual list element:IfarticlesThe variable has data, but inside the looppost.Titleorpost.LinkIf it doesn't feel right, thendumpFilter