在安企CMS的强大功能背后,模板的灵活运用是提升效率、保证网站一致性的关键。作为一名资深的网站运营专家,我深知在日常工作中,我们总是希望能“事半功倍”。今天,我们就来深入探讨一个能极大提升模板开发与维护效率的话题:如何在安企CMS模板中定义和使用可重复利用的自定义函数或代码片段,尤其是像循环渲染文章列表项这样的常见场景。
为什么我们需要可重复使用的代码片段?
在数字时代,内容为王,而内容的展示形式则千变万化。一个企业官网可能需要在首页展示最新的新闻文章,在侧边栏推荐热门产品,在特定分类页显示相关文章列表,甚至在网站的其他角落嵌入不同的内容模块。如果我们每次遇到相似的展示需求都重写一遍代码,那将是时间和精力的巨大浪费。
更重要的是,重复代码会带来一系列维护难题:样式或结构稍有变动,就需要修改多处;代码逻辑不一致,可能导致用户体验参差不齐;开发效率低下,也拖慢了网站迭代的速度。而通过定义可重复使用的代码片段,我们可以轻松实现代码的一致性、可维护性、开发效率提升以及更顺畅的更新迭代。这正是我们常说的“DRY”(Don’t Repeat Yourself)原则在模板开发中的实践。
安企CMS采用类似Django模板引擎的语法,这为我们提供了非常友好的方式来实现代码重用,主要体现在include、extends和macro这三个标签上。
核心重用机制:include与extends
在安企CMS中,最直接的代码重用方式莫过于使用include标签。它允许我们将一个HTML代码片段(例如页头、页脚、侧边栏或导航菜单)抽离成独立的文件,然后在需要的地方简单地引用。这样,无论多少页面需要这些公共元素,我们只需在一个地方维护代码,大大简化了更新工作。
例如,我们通常会将网站的头部(header.html)和底部(footer.html)抽离出来,然后在每个页面中像这样引入:
{# 引入网站头部 #}
{% include "partial/header.html" %}
{# 页面主体内容 #}
<main>
<!-- 这里是页面的具体内容 -->
</main>
{# 引入网站底部 #}
{% include "partial/footer.html" %}
如果这个partial/header.html需要一些动态数据,例如当前页面的标题,我们可以通过with参数传递:
{% include "partial/header.html" with page_title="关于我们" %}
而extends标签则提供了一种更宏观的代码重用策略,它允许我们定义一个“母版”或“骨架”模板,其他页面模板可以继承这个骨架。骨架模板中会定义一些block区域,子模板可以重写这些区域来填充自己的内容。这就像制作PPT的母版一样,主题和布局是固定的,内容则可以根据需要自定义。
一个典型的base.html骨架可能包含页头、导航、侧边栏、页脚,以及一个名为content的主内容区域:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>{% block title %}默认标题 - {% system with name="SiteName" %}{% endblock %}</title>
{# 其他公共CSS和JS文件 #}
</head>
<body>
{% include "partial/header.html" %}
<div class="container">
{% block content %}
<!-- 默认内容或为空 -->
{% endblock %}
</div>
{% include "partial/footer.html" %}
</body>
</html>
然后,一个具体页面,比如文章列表页article/list.html,就可以继承这个base.html并填充自己的内容:
{% extends 'base.html' %}
{% block title %}文章列表 - {% system with name="SiteName" %}{% endblock %}
{% block content %}
<div class="article-list">
<h1>最新文章</h1>
<!-- 这里将是文章列表的具体渲染逻辑 -->
</div>
{% endblock %}
通过extends,我们确保了所有页面的整体结构和通用元素保持一致,而只需关注每个页面的独特内容部分。
定义可复用代码函数:macro标签的艺术
虽然include和extends在结构层面提供了强大的重用能力,但当我们面临更细粒度的、带有参数的动态内容渲染需求时,macro标签就显得尤为重要。macro可以被理解为模板中的“函数”,它接受参数,并根据这些参数渲染出特定的HTML片段。这对于循环渲染列表项这类场景来说,简直是量身定制。
想象一下,我们需要在网站的不同位置(例如首页的“最新文章”区块、分类页的文章列表、搜索结果页)展示文章列表。每篇文章的显示格式可能包含标题、简介、发布时间、缩略图等,而且这些格式在不同区块下可能略有差异,或者需要在某些情况下隐藏特定元素。如果我们在每个列表循环中都编写一遍复杂的HTML结构,那将非常冗长且难以维护。
这时,macro就能大显身手了。我们可以定义一个宏,专门负责渲染单个文章列表项:
首先,我们可以在一个独立的模板文件(比如macros/article_items.html)中定义这个宏:
{# macros/article_items.html #}
{% macro render_article_item(article, show_thumbnail=true, custom_class='') %}
<li class="article-item {{ custom_class }}">
{% if show_thumbnail and article.Thumb %}
<a href="{{ article.Link }}" class="article-thumb">
<img src="{{ article.Thumb }}" alt="{{ article.Title }}">
</a>
{% endif %}
<div class="article-content">
<h3 class="article-title"><a href="{{ article.Link }}">{{ article.Title }}</a></h3>
<p class="article-description">{{ article.Description|truncatechars:100 }}</p>
<div class="article-meta">
<span>发布日期:{{ stampToDate(article.CreatedTime, "2006-01-02") }}</span>
<span>浏览量:{{ article.Views }}</span>
</div>
</div>
</li>
{% endmacro %}
在这个宏中,render_article_item接受三个参数:
article:要渲染的文章对象,通常是archiveList循环中的item。show_thumbnail:一个布尔值,默认为true,用于控制是否显示文章缩略图。custom_class:一个字符串,默认为空,允许我们为列表项添加自定义CSS类。
定义好宏之后,我们就可以在任何需要渲染文章列表的地方,先导入这个宏,然后在一个archiveList循环中调用它。
例如,在首页的“最新文章”区块中:
{# index.html 或其他需要用到宏的模板 #}
{% import "macros/article_items.html" as article_macros %}
<div class="latest-articles">
<h2>最新文章</h2>
<ul>
{% archiveList archives with type="list" moduleId="1" limit="5" %}
{% for item in archives %}
{{ article_macros.render_article_item(item, show_thumbnail=true, custom_class='latest-item') }}
{% empty %}
<li>暂无最新文章。</li>
{% endfor %}
{% endarchiveList %}
</ul>
</div>
而在侧边栏的“热门推荐”中,我们可能不希望显示缩略图,并使用不同的样式:
<div class="hot-recommendations">
<h3>热门推荐</h3>
<ul>
{% archiveList hot_articles with type="list" moduleId="1" flag="c" order="views desc" limit="3" %}
{% for item in hot_articles %}
{{ article_macros.render_article_item(item, show_thumbnail=false, custom_class='hot-item') }}
{% empty %}
<li>暂无热门推荐。</li>
{% endfor %}
{% endarchiveList %}
</ul>
</div>
可以看到,通过macro,我们成功将复杂的列表项渲染逻辑封装起来,并能通过参数灵活控制其显示行为。这不仅让模板代码更加整洁,也使得修改或扩展文章列表的显示样式变得轻而易举。
灵活的变量与数据传递:with和set
在利用include、extends