When building a website, maintaining a unified page style and clear structure is crucial for improving user experience and development efficiency. AnQiCMS provides a powerful and flexible template engine, which draws on the excellent ideas of Django templates, especiallyextendsThe use of tags makes this goal within reach.
The cornerstone of a unified style: basic layout template
Imagine your website as a meticulously designed building, with each room uniquely decorated, but with unified load-bearing walls, roofs, and foundations. In the AnQiCMS template system, this "foundation" is what we have.Basic Layout Templateusually namedbase.html.
thisbase.htmlThe file carries the most core and universal structure of the website, such as HTML document type declaration,<head>The area (including character sets, SEO meta information, common CSS styles, and JavaScript library links), the website header (Logo, main navigation), footer (copyright information, contact information), and other shared public elements on all pages.
Inbase.htmlThrough, we use{% block 标签名 %}{% endblock %}such a structure to define the area available for sub-templates to override. For example, a typicalbase.htmlmay contain severalblock:
{% block title %}: is used to define the page title.{% block head_extra %}: is used in<head>Add the CSS or JS specific to the current page area.{% block header %}: Used for the header content of the website.{% block content %}: This is the most core area, carrying the unique content of each page.{% block footer %}For website footer.
By this means,base.htmlLike a skeleton, it builds a unified appearance and behavior framework for all pages.
Examplebase.htmlStructure:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
{# 使用 AnQiCMS 的 TDK 标签获取页面标题、关键词和描述 #}
<title>{% tdk with name="Title" siteName=true %}</title>
<meta name="keywords" content="{% tdk with name="Keywords" %}">
<meta name="description" content="{% tdk with name="Description" %}">
{# 规范链接,有利于SEO #}
{%- tdk canonical with name="CanonicalUrl" %}
{%- if canonical %}
<link rel="canonical" href="{{canonical}}" />
{%- endif %}
{# 使用 AnQiCMS 的 system 标签获取模板静态文件地址,确保正确引用CSS #}
<link rel="stylesheet" href="{% system with name="TemplateUrl" %}/css/main.css">
{% block head_extra %}{% endblock %} {# 预留给子模板添加额外样式或脚本 #}
</head>
<body>
<header class="site-header">
<div class="container">
<a href="{% system with name="BaseUrl" %}" class="logo">
<img src="{% system with name="SiteLogo" %}" alt="{% system with name="SiteName" %}">
</a>
<nav class="main-nav">
{# 使用 AnQiCMS 的 navList 标签动态生成主导航 #}
{% navList navs %}
<ul>
{% for item in navs %}
<li class="{% if item.IsCurrent %}active{% endif %}">
<a href="{{ item.Link }}">{{item.Title}}</a>
{% if item.NavList %}
<ul class="sub-nav">
{% for subItem in item.NavList %}
<li><a href="{{ subItem.Link }}">{{subItem.Title}}</a></li>
{% endfor %}
</ul>
{% endif %}
</li>
{% endfor %}
</ul>
{% endnavList %}
</nav>
</div>
</header>
<main class="site-main">
<div class="container">
{% block content %}{% endblock %} {# 页面主体内容区域 #}
</div>
</main>
<footer class="site-footer">
<div class="container">
<p>{% system with name="SiteCopyright" %}</p>
<p>{% system with name="SiteIcp" %}</p>
{# 友情链接也可以在这里通过 linkList 标签动态调用 #}
{% linkList friendLinks %}
{% if friendLinks %}
<div class="friend-links">
{% for item in friendLinks %}
<a href="{{item.Link}}" {% if item.Nofollow == 1 %} rel="nofollow"{% endif %} target="_blank">{{item.Title}}</a>
{% endfor %}
</div>
{% endif %}
{% endlinkList %}
</div>
</footer>
{# 通用JavaScript文件引用 #}
<script src="{% system with name="TemplateUrl" %}/js/jquery.min.js"></script>
<script src="{% system with name="TemplateUrl" %}/js/common.js"></script>
{% block body_extra %}{% endblock %} {# 预留给子模板添加页面底部脚本 #}
</body>
</html>
Please note, in the abovebase.htmlIn Chinese, we used various tags provided by AnQiCMS, such assystemto obtain the website name, Logo and template pathtdkfor SEO information,navListandlinkListUsed to dynamically generate navigation and friendship links. Even in the basic layout, it fully gives full play to the dynamic management capabilities of CMS.
Inheritance and content customization: flexible application of child templates
Nowbase.htmlThis unified skeleton, all other page templates, such as the homepageindex.html, article detail pagearchive/detail.htmldo not need to rewrite those common HTML structures. They only need to be used in the first line of the file{% extends 'base.html' %}Tags to declare inheritance relationships.
Then, these child templates can optionally overridebase.htmldefined inblockArea. The unoverriddenblockArea will remainbase.htmlWith the default content inside.
Exampleindex.html(Home template) How to inheritbase.html:
{% extends 'base.html' %} {# 声明继承 base.html,必须是文件第一行 #}
{% block title %} {# 覆盖 base.html 中的 title block #}
<title>{% system with name="SiteName" %} - 专注于提供高效的企业级CMS解决方案</title>
{% endblock %}
{% block head_extra %} {# 在 head_extra block 中添加首页特有的 CSS #}
<link rel="stylesheet" href="{% system with name="TemplateUrl" %}/css/home.css">
{% endblock %}
{% block content %} {# 覆盖 base.html 中的 content block,添加首页特有内容 #}
<section class="hero-banner">
<h1>欢迎使用 AnQiCMS</h1>
<p>高效、可定制、易扩展的内容管理系统</p>
<a href="/about-us.html" class="btn btn-primary">了解更多</a>
</section>
<section class="latest-articles">
<h2>最新文章</h2>
{# 使用 AnQiCMS 的 archiveList 标签获取最新文章列表 #}
{% archiveList archives with type="list" moduleId="1" order="id desc" limit="5" %}
<ul>
{% for item in archives %}
<li>
<h3><a href="{{item.Link}}">{{item.Title}}</a></h3>
<p>{{item.Description|truncatechars:100}}</p>
<span>发布于:{{stampToDate(item.CreatedTime, "2006-01-02")}}</span>
</li>
{% empty %}
<li>暂无文章</li>
{% endfor %}
</ul>
{% endarchiveList %}
</section>
{% endblock %}
{% block body_extra %} {# 添加首页底部所需的JS #}
<script src="{% system with name="TemplateUrl" %}/js/home-animations.js"></script>
{% endblock %}
As you can see,index.htmlFocus on filling in your unique content without concerning<head>/header/footerThe structure of these common parts greatly improves the efficiency and readability of template writing.
Examplearchive/detail.html(Article detail page template) How to inheritbase.html:
{% extends 'base.html' %}
{% block title %} {# 覆盖标题,显示文章标题 #}
<title>{% archiveDetail with name="Title" %} - {% system with name="SiteName" %}</title>
{% endblock %}
{% block content %} {# 覆盖内容,显示文章详情 #}
{% archiveDetail article with name="all" %} {# 获取当前文章的所有字段 #}
<article class="article-detail">
<h1>{{article.Title}}</h1>
<div class="article-meta">
<span>分类:<a href="{% categoryDetail with name='Link' id=article.CategoryId %}">{% categoryDetail with name='Title' id=article.CategoryId %}</a></span>
<span>发布日期:{{stampToDate(article.CreatedTime, "2006-01-02 15:04")}}</span>
<span>浏览量:{{article.Views}}</span>
</div>
<div class="article-body">
{{article.Content|safe}} {# 文章内容通常需要使用 safe 过滤器以防止HTML转义 #}
</div>
<div class="article-tags">
{# 获取文章的标签 #}
{% tagList tags with itemId=article.Id limit="10" %}
{% for item in tags %}
<a href="{{item.Link}}">{{item.Title}}</a>
{% endfor %}
{% endtagList %}
</div>
<div class="article-navigation">
{% prevArchive prev %}
<p>上一篇:{% if prev %}<a href="{{prev.Link}}">{{prev.Title}}</a>{% else %}没有了{% endif %}</p>
{% endprevArchive %}
{% nextArchive next %}
<p>下一篇:{% if next %}<a href="{{next.Link}}">{{next.Title}}</a>{% else %}没有了{% endif %}</p>
{% endnextArchive %}
</div>
</article>
<section class="related-articles">
<h2>相关文章</h2>
{# 获取相关文章列表 #}
{% archiveList relatedArchives with type="related" limit="5" %}
<ul>
{% for item in relatedArchives %}
<li><a href="{{item.Link}}">{{item.Title}}</a></li>
{% endfor %}
</ul>
{% endarchiveList %}
</section>
{% endblock %}
In the article detail page, we usedarchiveDetailto get the details of the current article,tagListto display the article tags,prevArchiveandnextArchiveTo provide navigation to the previous/next article, as well asarchiveListTo display related articles.
The advantages are self-evident
ByextendsTags andblockMechanism, the template making of AnQiCMS brings many benefits:
- Uniform style, strong brand consistency: All pages share the same header, footer and basic layout, ensuring the overall visual style and brand image consistency of the website.
- Significantly improved development efficiency:Developers do not need to rewrite the common parts of each page, just focus on the content and layout of specific pages. This greatly reduces redundant code and shortens the development cycle.
- Easier to maintain laterWhen the website design needs to be adjusted (such as changing the navigation structure or footer content), simply modify
base.htmlA place, all pages inheriting it will be automatically updated, greatly reducing maintenance costs. - The template structure is clear and easy to understand.: The relationship between parent and child templates is clear, each template performs its own duties, making the template code easier to read and manage.
- Highly flexible and scalable: Pass
blockMechanism, child templates can cover or extend any area of the parent template as needed, providing infinite possibilities for customization.
AnQiCMS this template inheritance design pattern not only maintains the high visual consistency of the website, but also fundamentally improves the development and management efficiency of website templates, allowing content operators and developers to focus on their respective areas of expertise.
Frequently Asked Questions (FAQ)
1. How should I operate if I need to use different basic layouts for different areas of the website (such as the product center and news center)?
You canbase.htmlAbove, create more 'intermediate layer' basic templates. For example, you can have a generalbase.htmlDefined the most global HTML structure and common resources. Then, you can createproduct_base.htmlandnews_base.htmlThey allextends 'base.html'And define the unique sidebars, sub-navigation, or specific blocks for the product center and news center respectively. Finally, the product detail page and news detail page are defined separately.extends 'product_base.html'andnews_base.html'This enables multi-level template inheritance, meeting the layout needs of complex websites.
2. In the child template, in addition to overridingblockI can also retain the parent templateblockDo you want to add content on this basis?
Of course you can. You can override the parent template in the child template.blockwhen you{{ block.super }}variables to refer to the corresponding in the parent template.blockThe original content. This allows you to be in theblockabove and below of it