在使用安企CMS(AnQiCMS)管理网站内容时,在线留言功能无疑是与访客互动、收集反馈或潜在客户信息的重要途径。除了基本的姓名、联系方式和留言内容,很多时候我们还需要收集更具体、个性化的信息,例如“您的项目预算”、“感兴趣的服务类型”或“期望联系时间”等。安企CMS提供了灵活的自定义留言字段功能,让我们可以轻松实现这些需求。那么,如何在网站前台页面上获取并优雅地显示这些自定义的留言表单字段呢?

这通常涉及到模板文件的修改,通过运用安企CMS内置的模板标签,我们可以将后台定义的自定义字段呈现在用户面前。核心在于理解 guestbook 标签的工作原理及其返回的数据结构。

利用 guestbook 标签获取自定义字段

要显示自定义的留言表单字段,首先需要在你的留言页面模板中(通常是 guestbook/index.html 或你自定义的留言模板文件)使用 guestbook 标签。这个标签会获取你在安企CMS后台“功能管理” -> “网站留言”中配置的所有自定义表单字段。

标签的使用方式非常简洁:

{% guestbook fields %}
    {# 你的表单字段渲染逻辑将在这里 #}
{% endguestbook %}

在这里,fields 是一个由 guestbook 标签创建的变量,它是一个包含所有自定义表单字段信息的数组。接下来,我们就可以遍历这个 fields 数组,动态地渲染出每个表单字段。

理解表单字段的数据结构并动态渲染

fields 数组中的每一个元素都代表一个自定义字段,我们称之为 item。每个 item 都包含了一些关键属性,帮助我们决定如何渲染它:

  • item.Name: 这是字段的显示名称,也就是用户在表单上看到的标签文本,比如“您的称呼”、“留言主题”等。
  • item.FieldName: 这是表单字段的唯一标识符,将作为 HTML 输入框的 name 属性值,在表单提交时,后台会根据这个名称来接收数据。
  • item.Type: 这是字段的类型,决定了它应该渲染成哪种 HTML 输入元素,例如 text(单行文本)、number(数字)、textarea(多行文本)、radio(单选)、checkbox(多选)或 select(下拉选择)。
  • item.Required: 一个布尔值,指示该字段是否为必填项。
  • item.Content: 对于 textnumbertextarea 类型的字段,这通常是它们的默认值或提示文本(placeholder)。
  • item.Items: 对于 radiocheckboxselect 类型的字段,这是一个数组,包含了所有可供选择的选项值。

有了这些信息,我们就可以在一个 for 循环中,根据 item.Type 的不同,使用 ifelif 语句来生成相应的 HTML 输入框。

下面是一个常用的代码示例,展示了如何遍历 fields 变量并动态渲染不同类型的自定义字段,同时包含了安企CMS留言表单默认所需的 user_namecontactcontent 字段:

<form method="post" action="/guestbook.html">
    <input type="hidden" name="return" value="html"> {# 可选:指定后台返回HTML或JSON #}

    {# 安企CMS留言表单默认字段 #}
    <div>
        <label for="user_name">您的称呼</label>
        <input type="text" id="user_name" name="user_name" required placeholder="请填写您的称呼" autocomplete="off">
    </div>
    <div>
        <label for="contact">联系方式</label>
        <input type="text" id="contact" name="contact" required placeholder="请填写您的手机号或微信" autocomplete="off">
    </div>
    <div>
        <label for="content">留言内容</label>
        <textarea id="content" name="content" required placeholder="请填写您的留言内容" rows="5"></textarea>
    </div>

    {# 动态渲染自定义字段 #}
    {% guestbook fields %}
        {% for item in fields %}
            <div>
                <label for="{{item.FieldName}}">{{item.Name}}</label>
                {% if item.Type == "text" or item.Type == "number" %}
                    <input type="{{item.Type}}" id="{{item.FieldName}}" name="{{item.FieldName}}" {% if item.Required %}required{% endif %} placeholder="{{item.Content}}" autocomplete="off">
                {% elif item.Type == "textarea" %}
                    <textarea id="{{item.FieldName}}" name="{{item.FieldName}}" {% if item.Required %}required{% endif %} placeholder="{{item.Content}}" rows="3"></textarea>
                {% elif item.Type == "radio" %}
                    {% for val in item.Items %}
                        <label>
                            <input type="{{item.Type}}" name="{{item.FieldName}}" value="{{val}}" {% if item.Required and loop.first %}required{% endif %}> {{val}}
                        </label>
                    {% endfor %}
                {% elif item.Type == "checkbox" %}
                    {% for val in item.Items %}
                        <label>
                            <input type="{{item.Type}}" name="{{item.FieldName}}[]" value="{{val}}" {% if item.Required and loop.first %}required{% endif %}> {{val}}
                        </label>
                    {% endfor %}
                {% elif item.Type == "select" %}
                    <select id="{{item.FieldName}}" name="{{item.FieldName}}" {% if item.Required %}required{% endif %}>
                        {% for val in item.Items %}
                            <option value="{{val}}">{{val}}</option>
                        {% endfor %}
                    </select>
                {% endif %}
            </div>
        {% endfor %}
    {% endguestbook %}

    <div>
        <button type="submit">提交留言</button>
        <button type="reset">重置</button>
    </div>
</form>

在上面的代码中,我们首先硬编码了安企CMS默认会处理的 user_namecontactcontent 字段。随后,通过 {% guestbook fields %} 标签获取自定义字段,并通过一个 for 循环遍历 fields 数组。在循环内部,我们利用 if/elif 结构根据 item.Type 的值来渲染不同类型的表单元素。例如,textnumber 类型使用 <input type="text/number">textarea 类型使用 <textarea>。对于 radiocheckboxselect 类型,我们还会进一步遍历 item.Items 数组来生成各自的选项。

需要注意的是,checkbox 类型的 name 属性通常需要加上 [] 后缀(如 name="FieldName[]"),以便在提交表单时能够接收到多个选中值。此外,item.Required 属性被用来添加 HTML5 的 required 属性,实现简单的客户端验证。

表单提交注意事项

留言表单的 action 属性应指向 /guestbook.html,并且 method 必须是 post。除了自定义字段,请确保页面中包含了 user_namecontactcontent 这三个安企CMS默认的留言字段,即使你希望它们是隐藏的或通过其他方式预填。如果缺少这些核心字段,留言可能无法成功提交。你也可以添加一个隐藏字段 <input type="hidden" name="return" value="html"> 来控制后端处理完留言后是返回 HTML 页面还是 JSON 数据。

通过上述方法,你可以根据后台配置,灵活地在前端页面上展示和收集各种自定义留言信息,极大地增强了网站与访客互动的功能性和数据收集能力。


常见问题 (FAQ)

  1. 我在安企CMS后台配置了自定义留言字段,但前台页面上没有显示,这是为什么? 这通常是因为你还没有在网站的留言模板文件中添加或正确使用 {% guestbook fields %} 标签来动态渲染这些字段。安企CMS后台的自定义字段配置只是定义了字段的结构和属性,但不会自动将它们插入到前端页面。你需要手动编辑留言页面对应的模板文件(例如 template/你的模板名/guestbook/index.html),并按照文章中的示例代码,使用 guestbook 标签遍历并渲染这些字段。

  2. 我的留言表单提交后,自定义字段的数据没有保存,或者保存到后台的数据不正确,该如何排查? 首先,请确保你的表单 action 属性指向了 /guestbook.html 并且 methodpost。其次,检查每个自定义字段的 HTML inputtextareaselect 标签的 name 属性值是否与安企CMS后台自定义字段设置中的 FieldName 完全一致(包括大小写)。对于多选字段(checkbox),确保其 name 属性使用了 [] 后缀(例如 name="your_custom_field_name[]")。此外,也要确认 user_namecontactcontent 这三个安企CMS默认要求的字段已经正确提交。

  3. 如果我只想显示后台自定义字段中的某几个,而不是全部,可以怎么操作? 当然可以。文章中提供的代码是一个动态渲染所有字段的通用示例。如果你只想显示特定的几个自定义字段,你可以选择不使用 for 循环遍历 fields 数组,而是直接根据后台定义的 item.FieldName 来硬编码你需要的字段。例如,如果你有一个 项目预算 的自定义字段,其 FieldNameproject_budget,你可以直接在模板中这样写:

    {% guestbook fields %} {# 仍然需要此标签来获取所有字段信息 #}
        {# 假设你知道 project_budget 字段在 fields 数组中的位置或其 FieldName #}
        {# **做法是过滤 fields 数组或者直接使用已知 FieldName 查找 #}
        {% set project_budget_field = null %}
        {% for item in fields %}
            {% if item.FieldName == "project_budget" %}
                {% set project_budget_field = item %}
                {% break %} {# 找到后退出循环 #}
            {% endif %}
        {% endfor %}
    
    
        {% if project_budget_field %}
            <div>
                <label for="{{project_budget_field.FieldName}}">{{project_budget_field.Name}}</label>
                <input type="{{project_budget_field.Type}}" id="{{project_budget_field.FieldName}}" name="{{project_budget_field.FieldName}}" {% if project_budget_field.Required %}required{% endif %} placeholder="{{project_budget_field.Content}}">
            </div>
        {% endif %}
    {% endguestbook %}
    

    这种方式虽然稍微复杂一点,但提供了最大的灵活性,让你只显示或自定义特定字段的渲染方式。