墨迹语 CMS

v1.0.0 使用说明

模板基础语法

墨迹语 CMS 使用自定义模板引擎,语法简洁易用。本文档介绍模板的基础语法规则。

变量输出

转义变量(推荐用于文本内容)

语法:{$变量名}

  • 自动对输出内容进行 HTML 转义(htmlspecialchars)
  • 防止 XSS 攻击
  • 推荐用于用户输入的文本、标题、描述等内容
<h2>{$article.title}</h2>
<p>作者:{$article.author_name}</p>
<span>{$category.name}</span>

不转义变量(用于 HTML 内容)

语法:{!$变量名}

  • 直接输出变量内容,不做任何转义
  • 用于已经是 HTML 的内容(如富文本编辑器输出)
  • 用于可信任的内容片段
<div class="content">
    {!$article.content}
</div>
⚠️ 警告:仅对完全可控的内容使用不转义变量,避免 XSS 漏洞!

变量与路径访问

当变量是数组或对象时,可以通过点号(.)访问其键值,支持无限层级深度访问。

语法:{$变量.属性1.属性2...}

<div class="deep-data">
    <h3>{$deep.level1.level2.level3}</h3>
</div>

条件判断

简单条件与复合逻辑

语法:{if $condition1 && $condition2}...{/if}

{if $article.thumb && $article.is_featured}
<div class="featured-image">
    <img src="{$article.thumb}" alt="精选图片">
</div>
{/if}

比较运算符

支持 ==!=<><=>=

现在支持逻辑运算符 && (AND) 和 || (OR)。

{if $article.status == 'published' && $article.views > 1000}
<span class="popular-tag">热门发布</span>
{/if}

嵌套判断

支持多层嵌套 if,解析引擎会自动处理配对关系。

{if $is_admin}
    {if $is_active}
        管理员在线
    {else}
        管理员封禁中
    {/if}
{/if}

循环语法

语法:{loop $数组名 $项目名}...{/loop}

嵌套循环示例

{loop $categories $cat}
<div class="category-block">
    <h2>{$cat.name}</h2>
    <ul>
        {loop $cat.items $item}
        <li>{$item.name} - {$item.price}元</li>
        {/loop}
    </ul>
</div>
{/loop}
{loop $articles $article}
<div class="article-item">
    <h3>{$article.title}</h3>
    <p>{$article.description}</p>
    <time>{$article.published_at}</time>
</div>
{/loop}

循环中的条件

{loop $articles $article}
<div class="article">
    <h3>{$article.title}</h3>
    
    {if $article.thumb}
    <img src="{$article.thumb}">
    {/if}
    
    {if $article.status == 'published'}
    <span class="status">已发布</span>
    {/if}
</div>
{/loop}

模板包含

语法:{include file="模板文件路径"}

{include file="common/header.html"}
{include file="common/footer.html"}

函数调用标签

系统提供了多个全局函数,可以直接在模板中调用。

获取栏目信息

<!-- 获取栏目名称 -->
{get_catname(3)}

<!-- 获取栏目链接 -->
<a href="{get_category(3, 'pclink')}">{get_category(3, 'catname')}</a>

<!-- 在循环中使用 -->
{loop $data $v}
    <p>栏目:{get_catname($v.category_id)}</p>
{/loop}

获取单页内容

<!-- 获取栏目ID为1的单页内容,限制300字 -->
{page_content(1, 300)}

<!-- 不过滤HTML标签 -->
{page_content(1, 300, false)}

图片处理

<!-- 自动处理空值,返回默认图片 -->
<img src="{get_thumb($v.thumb)}" alt="{$v.title}">

<!-- 自定义默认图片 -->
<img src="{get_thumb($v.thumb, '/public/images/custom-default.jpg')}">

字符串处理

<!-- 带颜色的标题 -->
{title_color($v.title, '#ff0000')}

<!-- 字符串截取 -->
{str_cut($v.description, 120)}

<!-- 日期格式化(推荐使用) -->
{template_date('Y-m-d', $v.inputtime)}
{template_date('Y-m-d H:i:s', $v.updatetime)}

业务标签({m:xxx} 格式)

用于获取动态内容,可缓存

内容列表标签 {m:lists}

<!-- 基本用法:显示1号栏目的10篇文章 -->
{m:lists field="id,title,thumb,url,description,inputtime,views" catid="1" limit="10"}
{loop $data $v}
    <div class="article-item">
        <a href="{$v.url}">
            <img src="{get_thumb($v.thumb)}" alt="{$v.title}">
        </a>
        <h3><a href="{$v.url}">{$v.title}</a></h3>
        <p>{$v.description}</p>
        <span>{template_date('Y-m-d', $v.inputtime)}</span>
        <span>浏览量:{$v.views}</span>
    </div>
{/loop}

常用参数

  • field - 字段列表,如 "id,title,thumb,url,description,inputtime"
  • catid - 栏目ID(支持多个,用逗号分隔,如 "1,3,6")
  • limit - 限制条数(默认20)
  • order - 排序规则(默认 "inputtime DESC")
  • thumb - 是否只调用带缩略图(1=是,0=否)
  • flag - 内容属性(1=置顶,4=推荐)
  • cache - 缓存时间(秒),0表示不缓存

排序示例

<!-- 按更新时间降序(推荐使用 updatetime) -->
{m:lists field="id,title,url" order="updatetime DESC" limit="10"}

<!-- 按发布时间降序(推荐使用 inputtime) -->
{m:lists field="id,title,url" order="inputtime DESC" limit="10"}

<!-- 随机排序 -->
{m:lists field="id,title,url" order="RAND()" limit="10"}

调用推荐/置顶内容

<!-- 推荐文章 -->
{m:lists field="id,title,thumb,url" flag="4" limit="6"}

<!-- 置顶文章 -->
{m:lists field="id,title,thumb,url" flag="1" limit="5"}

栏目导航标签 {m:nav}

<!-- 显示顶级栏目 -->
{m:nav field="id,name,slug,pclink" limit="20"}
{loop $data $v}
    <li>
        <a href="{$v.pclink}">{$v.name}</a>
    </li>
{/loop}

友情链接标签 {m:link}

<!-- 显示友情链接 -->
{m:link limit="10"}
{loop $data $v}
    <a href="{$v.url}" target="_blank">{$v.name}</a>
{/loop}

全站最新更新标签 {m:all} - SEO 链轮核心功能

🎯 SEO 链轮功能:这是实现 SEO 链轮的核心标签!{m:all} 可以获取所有分站的最新文章,并自动生成包含完整域名和协议的外链 URL,实现分站之间的互相链接。

核心特性

  • 跨分站获取:获取所有分站(包括主站)的最新文章,不进行分站过滤
  • 自动生成外链:自动为每篇文章生成完整的 URL(包含协议和域名)
  • 智能域名识别:根据文章的 branch_id 自动识别并生成对应分站的完整 URL
  • SEO 链轮支持:通过在不同分站之间互相链接,形成链轮结构,提升 SEO 效果

基本用法

<!-- 获取所有分站的最新文章(自动生成完整外链) -->
{m:all field="id,title,url,inputtime" limit="10"}
{loop $data $v}
    <li>
        <a href="{$v.url}" target="_blank">{$v.title}</a>
        <span>{template_date('Y-m-d', $v.inputtime)}</span>
    </li>
{/loop}

URL 生成示例

系统会根据文章的 branch_id 自动生成对应的完整 URL:

  • 主站文章https://www.mojiyu999.com/article/123.html
  • 分站文章https://beijing.mojiyu999.com/wuxing/3_126.html
  • 其他分站https://shanghai.mojiyu999.com/bazi/1_92.html

SEO 链轮应用场景

<!-- 场景1:侧边栏显示其他分站的最新内容 -->
<div class="sidebar-links">
    <h3>相关站点最新内容</h3>
    {m:all field="id,title,url" order="inputtime DESC" limit="20"}
    {loop $data $v}
        <a href="{$v.url}" target="_blank" rel="nofollow">{$v.title}</a>
    {/loop}
</div>

<!-- 场景2:随机链轮(每次刷新显示不同的外链) -->
{m:all field="id,title,url" order="RAND()" limit="15"}
{loop $data $v}
    <a href="{$v.url}" target="_blank">{$v.title}</a>
{/loop}

<!-- 场景3:热门内容链轮(按浏览量排序) -->
{m:all field="id,title,url,views" order="views DESC" limit="10"}
{loop $data $v}
    <div class="hot-link">
        <a href="{$v.url}" target="_blank">{$v.title}</a>
        <span>浏览量:{$v.views}</span>
    </div>
{/loop}

参数说明

参数 类型 默认值 说明
field 字符串 id,title,thumb,description,inputtime 字段列表,推荐包含 id,title,url,inputtime
order 字符串 inputtime DESC 排序规则(支持 inputtime DESCviews DESCRAND() 等)
limit 整数 20 限制数量(建议 10-30 个,避免过度优化)

SEO 链轮使用建议

  1. 分散放置:在网站的不同位置(侧边栏、底部、相关文章区域)使用 {m:all} 标签
  2. 合理数量:建议每个页面显示 10-30 个外链,避免过度优化
  3. 随机排序:可以结合 order="RAND()" 实现随机链轮效果,每次访问显示不同的链接
  4. 自然展示:将外链自然地融入内容中,避免明显的链轮痕迹
  5. 定期更新:通过 order="inputtime DESC" 确保链接内容是最新的

与其他标签的区别

标签 获取范围 URL 格式 用途
{m:lists} 当前分站 相对路径(如 /article/123.html 站内内容展示
{m:all} 所有分站 完整 URL(如 https://beijing.mojiyu999.com/wuxing/3_126.html SEO 链轮、跨站链接
⚠️ 注意事项:
  • {m:all} 标签会查询所有分站的文章,性能开销较大,建议合理使用 limit 参数
  • 生成的 URL 包含完整域名,适合用于外链和 SEO 链轮,不适合站内导航
  • 建议在侧边栏、底部等位置使用,避免在主要内容区域过度使用

PHP代码块

可以在模板中直接执行PHP代码,用于复杂逻辑处理。

语法:{php PHP代码}

<!-- 定义变量 -->
{php $category = get_category(3);}
{if $category}
    <p>栏目名称:{$category.name}</p>
    <p>栏目链接:{$category.pclink}</p>
{/if}

<!-- 获取所有栏目 -->
{php $allCategories = get_category(0);}
{loop $allCategories $cat}
    <a href="{$cat.pclink}">{$cat.name}</a>
{/loop}
⚠️ 警告:PHP代码块中的变量定义会影响到后续的模板解析,请谨慎使用。

PHP内置函数支持

系统支持在模板中直接使用常用的PHP内置函数。

日期时间函数

<!-- 格式化日期(推荐使用 template_date,更安全) -->
{template_date('Y-m-d', $v.inputtime)}
{template_date('Y-m-d H:i:s', $v.updatetime)}

<!-- 使用PHP内置函数(需要时间戳) -->
{date('Y-m-d', $v.inputtime)}
{date('Y-m-d H:i:s', $v.inputtime)}
{date('m-d', $v.inputtime)}

<!-- 时间戳转换 -->
{strtotime('2026-01-15 11:52:30')}

<!-- 获取当前时间戳 -->
{time()}

字符串函数

<!-- 字符串长度 -->
{strlen($v.title)}

<!-- 转大写 -->
{strtoupper($v.title)}

<!-- 转小写 -->
{strtolower($v.title)}

<!-- 字符串替换 -->
{str_replace('old', 'new', $v.title)}

其他常用函数

<!-- 数字格式化 -->
{number_format($v.views, 0)}

<!-- URL编码 -->
{urlencode($v.title)}

<!-- MD5加密 -->
{md5($v.password)}

特殊变量

BASE_URL

自动注入的全局变量,表示网站的基础 URL:

<a href="{$BASE_URL}/articles">文章列表</a>
<img src="{$BASE_URL}/images/logo.png">

限制和约束

变量命名规范

  • 变量名只能包含字母、数字、下划线
  • 变量名开头必须是字母或下划线
  • 支持多层级点号访问,如 $a.b.c.d

注意事项

  • ❌ 不支持在模板中直接进行数学运算(如 {$a + $b}
  • ❌ 不支持三元运算符
  • ✅ 支持 Url:: 类方法调用