During the template development process of AnQiCMS, we often encounter a frustrating situation: the page display does not meet expectations, and the data of a variable cannot be output correctly.At this time, we urgently need a 'sharp eye' to see through the real data type and internal structure of the template variables.AnQiCMS's powerful Django-like template engine is flexible, but if you cannot clearly understand the 'true face' of variables during debugging, the efficiency will be greatly reduced.

Luckyly, AnQiCMS provides us with a series of practical tools to help us delve deeply into template variables.This is like adding a 'debug mode' to your template, allowing you to clearly see the data hidden behind each variable.

Discover the 'secret weapon' of variables:dumpFilter

Among many debugging tools,dumpThe filter is undoubtedly our preferred 'secret weapon' for checking variable data types and structures.It can print the complete structure, data type, and current value of any variable in the form of a Go language struct.This helps us understand complex data objects (such as fromarchiveDetailorcategoryListdata obtained with such tags is particularly useful.

Imagine that you have obtained a document from the background and assigned it toarchivea variable. You may only know that it hasTitle/ContentSuch a field, but what fields are inside it?ImagesIs it a string or an array?CreatedTimeIs it a timestamp or a formatted date string? These questions,dumpcan give you the answer.

You just need to use it like this in the template:

{# 假设我们有一个名为 'archive' 的文档变量 #}
<pre>
  {{ archive|dump }}
</pre>

{# 或者你可能在循环中,想查看每个 'item' 的详细信息 #}
{% archiveList archives with type="list" limit="1 %}
  {% for item in archives %}
    <pre>
      {{ item|dump }}
    </pre>
  {% endfor %}
{% endarchiveList %}

When you visit the page, the browser will display something like this output (the specific content depends on your data):

&models.Archive{Id:1, Title:"AnQiCMS模板调试指南", SeoTitle:"", Link:"/article/1.html", Keywords:"AnQiCMS,模板,调试", Description:"本文将详细介绍如何在AnQiCMS模板中调试...", Content:"<p>正文内容...</p>", ContentTitles:[], ModuleId:1, CategoryId:10, CanonicalUrl:"", UserId:1, ParentId:0, Price:0.00, Stock:0, ReadLevel:0, OriginUrl:"", Views:123, Flag:"c", Images:["https://en.anqicms.com/uploads/image1.webp", "https://en.anqicms.com/uploads/image2.webp"], Logo:"https://en.anqicms.com/uploads/thumb1.webp", Thumb:"https://en.anqicms.com/uploads/thumb1_s.webp", CommentCount:5, CreatedTime:1678886400, UpdatedTime:1678972800, Category:..., Tags:[], Params:{...}}

We can clearly see from this outputarchiveIs amodels.ArchiveA type of structure that includesId(integer),Title(string),Images(string array),CreatedTimeTimestamps and their corresponding values. This is much more efficient than blind guessing.

In-depth analysis:stringformatAnd type detection.

dumpThe filter is powerful, but sometimes we may not need such detailed information, just want to quickly understand the type of variables, or view the structure in the form of Go language source code fragments. At this time,stringformatThe filter combined with specific formatting symbols can be put to good use.

  • To check the variable type: use%T

    If you only care about the data type of a variable and do not want to see its value,stringformat:"%T"It is the perfect tool.

    {# 查看文档标题的类型 #}
    <p>文档标题类型:{{ archive.Title|stringformat:"%T" }}</p>
    
    
    {# 查看图片列表的类型 #}
    <p>图片列表类型:{{ archive.Images|stringformat:"%T" }}</p>
    
    
    {# 查看创建时间的类型 #}
    <p>创建时间类型:{{ archive.CreatedTime|stringformat:"%T" }}</p>
    

    The output might be:

    文档标题类型:string
    图片列表类型:[]string
    创建时间类型:int64
    
  • View the structure and values in Go language source code: Use%#v

    If you want the output to be closer to the Go language struct initialization code,stringformat:"%#v"It will be very helpful. It will output Go source code snippets with field names and values, usually moredumpconcise, and still retains the structural information.

    <pre>
      {{ archive|stringformat:"%#v" }}
    </pre>
    

    It will be output:

    main.Archive{Id:1, Title:"AnQiCMS模板调试指南", ..., Images:[]string{"https://en.anqicms.com/uploads/image1.webp", "https://en.anqicms.com/uploads/image2.webp"}, ...}
    

    This isdumpSimilar, but the format is different, sometimes it is easier to read.

An auxiliary tool: makes debugging more convenient.

Except for the powerful filters mentioned above, there are also some other tools and techniques that can provide convenience during debugging:

  1. lengthFilter: Check the size of the set

    When you want to know if an array (slice) or string is empty, or how many elements it contains,lengthfilters are very useful.

    {# 检查文档标题长度 #}
    <p>标题长度:{{ archive.Title|length }}</p>
    
    
    {# 检查图片列表包含的图片数量 #}
    <p>图片数量:{{ archive.Images|length }}</p>
    
    
    {# 结合 if 语句判断是否有图片 #}
    {% if archive.Images|length > 0 %}
      <p>文档包含图片。</p>
    {% else %}
      <p>文档不包含图片。</p>
    {% endif %}
    
  2. joinandsplitFilter: visualize array content

    IfdumpThe array content is a bit hard to read, you can try usingjoinConcatenating array elements into a string, or usingsplitSplitting the string into an array to check.

    {# 将图片数组用逗号连接起来显示 #}
    <p>所有图片路径:{{ archive.Images|join:", " }}</p>
    
  3. stampToDateLabel: Timestamp Translator

    In AnQiCMS, the time field (such asCreatedTime/UpdatedTime) usually exists in the form of a 10-digit Unix timestamp. If you output it directly{{ archive.CreatedTime }}It shows a series of numbers, not the date format we are accustomed to.stampToDateThe tag is designed for this, it can convert timestamps into a readable date format.

    {# 将时间戳转换为“年-月-日 时:分:秒”格式 #}
    <p>发布时间:{{ stampToDate(archive.CreatedTime, "2006-01-02 15:04:05") }}</p>
    

    This can help you confirm whether the value of the time field is correct.

  4. ifLogical judgment label: Quick condition check

    BasicifThe statement is also very useful during debugging, which can be used to check if a variable exists, whether it is a specific value, or whether it is empty.

    {% if archive %}
      <p>archive 变量存在且非空。</p>
    {% endif %}
    
    
    {% if archive.AuthorName == "AnQiCMS团队" %}
      <p>作者是 AnQiCMS团队。</p>
    {% endif %}
    
  5. setorwithTag: Isolation and Naming Variables

    In complex templates, variables may be deeply nested or have long names. You can usesetorwithCreate a temporary variable, simplify the debugging process, or save the result of an expression for subsequent checking.

    {# 创建一个临时变量来存储文档的第一张图片 #}
    {% set firstImage = archive.Images|first %}
    <p>第一张图片路径:{{ firstImage|dump }}</p>
    
    
    {# 或者在局部作用域内定义变量 #}
    {% with tempTitle = archive.Title %}
      <p>临时标题:{{ tempTitle|dump }}</p>
    {% endwith %}
    

Actual debugging workflow suggestion

When you encounter a problem in the AnQiCMS template, you can try the following debugging steps:

  1. Locate the problem area:Determine which variable may have caused the incorrect output.
  2. InsertdumpFilter:Insert temporarily next to the variable you suspect{{ 变量名|dump }}and<pre>Wrapped in tags to clearly display on the page
  3. Analysis output:Checkdumpoutput to understand the accurate type and internal of the variable