路由链接 Url

路由链接 Url

{url} 是 DouPHP 模板生成链接的标准方式,也是最常用的核心标签。它把「点分路由键 + 参数」编译为全局 route() 调用,自动拼出符合当前站点 URL 规则(含伪静态 / 多语言前缀)的完整链接。

你在默认主题里随处可见它,例如搜索表单(theme/default/inc/header.tpl):

<form method="get" action="{url link='search'}">

一、语法

{url link="路由键" [params=$数组] [page=$页码] [options=$选项] [nofilter] k1=$v1 k2=$v2 ...}

二、保留属性

属性 必需 说明
link 是 点分路由键,如 'article.show'、'admin.user.edit'
params 否 路由参数数组(与内联属性合并)
page 否 分页页码,并入 options.page
options 否 路由选项数组(如 query、lang)
nofilter 否 裸词标志(或 nofilter=true),关闭自动 HTML 转义

三、编译行为(重点)

{url} 由 UrlTagCompiler 编译为对全局 route() 的调用,其签名为:

route($route, array $params = array(), array $options = array())

编译规则逐条如下:

  1. link 必需:缺失时编译期报 missing 'link' attribute in url tag;link 作为 route() 的第一个参数(强制转字符串)。
  2. page 并入 options:若写了 page=...,会被放进 options['page']。
  3. 非保留内联属性合并进 params:除 link / params / page / options / nofilter 五个保留属性外,其余内联属性会被 array_merge 进 params,作为路由参数。
  4. 自动转义:开启 escapeHtml 且未加 nofilter 时,对 route() 结果再做一次 htmlspecialchars;否则直接输出。

举例,下面两个写法等价:

{url link='article.show' id=$article.id}
{url link='article.show' params=['id' => $article.id]}

前者把内联属性 id 自动并入 params,更简洁,是推荐写法。

四、路由键约定表

link 是一个点分的路由键,常见约定如下(具体以站点已启用的模块为准):

页面类型 路由键形式 典型参数 示例
模块列表页 模块 — {url link='article'}
内容详情页 模块.show id {url link='article.show' id=$article.id}
分类列表页 模块.category category_id {url link='article.category' category_id=$cat.cat_id}
单页详情 page.show / page.detail slug {url link='page.detail' slug='agreement'}
功能动作 模块.动作 视动作而定 {url link='search'}、{url link='captcha'}
多级动作 模块.子域.动作 视动作而定 {url link='order.cart.store'}
后台链接 admin.模块.动作 id / page 等 {url link='admin.user.edit' id=$user.id}

五、真实示例(取自默认主题与现网)

{* 基础:模块列表页、搜索、验证码 *} 
<a href="{url link='article'}">更多文章</a>
<form method="get" action="{url link='search'}">
<img src="{url link='captcha'}" alt="验证码">

{* 带路径 / 查询参数(内联属性自动并入 params) *}
<a href="{url link='article.show' id=$article.id}">{$article.title}</a>
<a href="{url link='order.user.show' order_sn=$order.order_sn}">{$order.order_sn}</a>

{* 单页:用 slug 定位 *}
<a href="{url link='page.detail' slug='agreement'}">用户协议</a>

{* 带分页:page 并入 options *}
<a href="{url link='admin.weixin.media.subscribe' id=$media.id page=$page}">订阅</a>

{* 裸词参数值(非变量) *}
<a href="{url link='admin.ai.daily_stats' date_range=today}">今日</a>

{* 在 JS / onclick 中拼接 *}
<a href="javascript:;" onclick="douConfirm('{url link='order.user.cancel' order_sn=$order.order_sn token=$token}', '确认取消?')">取消</a>

六、参数值的形态

内联属性的值可以是:

  • 变量 / 属性路径:id=$article.id、order_sn=$order.order_sn;
  • 带引号的字符串字面量:slug='agreement';
  • 裸词:date_range=today(不带引号的字面值)。

七、自动转义与 nofilter

  • 前台默认 escapeHtml = false,{url} 结果原样输出;
  • 若开启了全局转义,{url} 结果会被 htmlspecialchars(URL 中的 & 会被转成 &amp;,这在 HTML 属性里恰恰是正确的);
  • 需要原样输出(如拼进 JS 字符串且不希望被转义)时,追加 nofilter:
<script>var api = "{url link='favorites.user.store' nofilter}";</script>

八、与旧式 {$url.xxx} 的兼容

早期模板里常见 {$url.xxx} 形式的链接变量,由框架注入的兼容映射提供。新模板一律推荐用 {url link='...'} 标准写法:它不依赖预注入的变量、支持任意参数与分页、与路由系统保持一致。旧式写法仅作为存量模板的兼容保留。

添加日期: