{literal}会阻止smarty解析变量,导致含{$theme}等动态路径的失效;正确做法是仅对纯静态代码用{literal},动态路径应直接写在标签内让smarty解析。

Smarty中用{literal}包裹<link>标签会失效?
直接在Smarty模板里写<link rel="stylesheet" href="style.css">通常能工作,但一旦CSS路径含Smarty变量(比如{$theme}/main.css)或模板开启了auto_escape,就可能被转义或解析错误。根本原因不是{literal}本身有问题,而是它会原样输出内容——连里面的{$var}也不解析,导致动态路径失效。
正确做法是:不用{literal}包裹整个<link>,只对需要字面量处理的片段用。动态路径必须让Smarty解析:
- 路径含变量时,写成
<link rel="stylesheet" href="css/%7B%24theme%7D/main.css"> - 若
href值来自PHP传入的变量(如$smarty->assign('css_url', '/assets/app.css');),用<link rel="stylesheet" href="%7B%24css_url%7D"> - 避免在
{literal}里放{$xxx},否则变量不会被替换
使用{html_css}函数时提示undefined function
{html_css}不是Smarty内置函数,是PEAR的HTML_Template_Smarty扩展或某些老项目自定义的插件。Smarty 3/4 默认不提供这个函数,直接调用会报错。
替代方案更可控:
- 手动写
<link>标签(推荐,简单明确) - 自己注册一个简单插件:
function smarty_function_html_css($params, $template) { $href = isset($params['href']) ? $params['href'] : ''; return '<link rel="stylesheet" href="'%20.%20htmlspecialchars(%24href)%20.%20'">'; }然后在模板中用{html_css href="/css/base.css"} - 如果项目已用Assetic等资源管理工具,CSS应由后端生成最终路径,Smarty只负责输出变量
在{include}子模板里引入CSS,样式不生效
HTML规范要求<link>必须在内,而Smarty的{include}常被用在区域。把<link>塞进{include file='sidebar.tpl'}里,浏览器会忽略它,控制台还可能报“Resource interpreted as Stylesheet but transferred with MIME type text/html”。
解决思路不是硬塞,而是分层处理:
- 主模板
layout.tpl保留结构,用{block name="styles"}{/block} - 子模板用
{extends file="layout.tpl"}{block name="styles"}<link rel="stylesheet" href="%7B%24css_path%7D">{/block} - 或者PHP层提前收集所有CSS路径,统一赋值给
$smarty->assign('page_css', [...]),主模板循环输出
开发环境正常,上线后CSS 404?
常见原因是路径拼接出错,尤其当Smarty模板部署在子目录(如https://example.com/shop/)而CSS路径写成href="css/main.css",实际请求的是/css/main.css而非/shop/css/main.css。
关键检查点:
- 确认
href是绝对路径(以/开头)还是相对路径;相对路径基于当前URL,不是模板文件位置 - 用
{$base_url}或{$request_uri}等变量构造路径,例如href="{$base_url}/css/main.css" - 查看浏览器开发者工具Network面板,看CSS请求的真实URL和状态码,比猜更有用
- 注意Apache/Nginx是否重写了静态资源路径,有时CSS请求被路由规则捕获并返回404
路径问题永远比语法问题更隐蔽,上线前务必用真实URL打开页面,别只信本地测试结果。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











