Twig html_attr_type 过滤器:将数组转换为符合 HTML 属性语法的专用值对象
后端【免费下载链接】TwigTwig, the flexible, fast, and secure template language for PHP项目地址https://gitcode.com/gh_mirrors/tw/Twig点击查看免费下载本文介绍 Twightml-extra包中的html_attr_type过滤器它把普通的 PHP 数组转换成实现了自定义渲染逻辑的属性值对象AttributeValueInterface让class、srcset、style这类有特殊分隔符规则的 HTML 属性能按语义正确地拼接与转义。读完本文你能掌握三种类型sst/cst/style的用法与适用场景、与html_attr/html_attr_merge的配合方式并能从源码层面理解其合并merge与省略omit机制用于生产级模板中安全、可组合地输出 HTML 属性。定位为特殊格式化规则的属性值提供类型标记html_attr_type过滤器自 Twig 3.24 引入见 CHANGELOG 中 3.24.0 条目 Add thehtml_attrfunction andhtml_attr_mergeas well ashtml_attr_typefilters的作用是把数组转换为专用属性值对象这些对象实现了自定义渲染逻辑。它专为配合 html_attr 函数 使用而设计用于那些属性值遵循特殊格式化规则的场景img {{ html_attr({ srcset: [small.jpg 480w, large.jpg 1200w]|html_attr_type(cst) }) }} {# 输出: img srcsetsmall.jpg 480w, large.jpg 1200w #} /code为什么需要这个过滤器因为html_attr对裸数组的默认处理是空格分隔见后文而srcset、sizes等属性要求逗号分隔style则要求声明串或属性-值对两种形态都可用。html_attr_type就是显式声明这个数组应该按哪种语法规则渲染的入口。前置条件安装 HtmlExtension该过滤器属于HtmlExtension不是 Twig 核心默认安装的。官方文档给出的安装步骤是$ composer require twig/html-extra在 Symfony 项目上再安装 twig/extra-bundle仓库内对应目录为 extra/twig-extra-bundle/以自动装配$ composer require twig/extra-bundle如果不是 Symfony 项目则需要手动把扩展注册到 Twig 环境use Twig\Extra\Html\HtmlExtension; $twig new \Twig\Environment(...); $twig-addExtension(new HtmlExtension());从源码看扩展的注册点非常直接HtmlExtension::getFilters() 返回了data_uri、html_attr_merge、html_attr_type三个过滤器getFunctions() 返回html_classes、html_cva、html_attr三个函数其中html_attr被标记为is_safe [html]且needs_environment true它需要环境来调用EscaperRuntime做转义。支持的三种类型空格分隔令牌列表sst用于期望空格分隔值的属性典型如class、aria-labelledby{% set classes [btn, btn-primary]|html_attr_type(sst) %} button {{ html_attr({class: classes}) }} Click me /button {# 输出: button classbtn btn-primaryClick me/button #}sst是默认类型当html_attr函数遇到一个数组值style属性除外时会自动按sst处理——无需显式调用html_attr_type(sst)。这一点在 HtmlExtension::htmlAttrValue() 中得到印证对于未实现AttributeValueInterface的可迭代值非style属性会直接包装为new SeparatedTokenList($value)其默认分隔符就是 。逗号分隔令牌列表cst用于期望逗号分隔值的属性典型如srcset、sizesimg {{ html_attr({ srcset: [image-1x.jpg 1x, image-2x.jpg 2x, image-3x.jpg 3x]|html_attr_type(cst), sizes: [(max-width: 600px) 100vw, 50vw]|html_attr_type(cst) }) }} {# 输出: img srcsetimage-1x.jpg 1x, image-2x.jpg 2x, image-3x.jpg 3x sizes(max-width: 600px) 100vw, 50vw #} /code内联样式style用于style属性同时支持两种输入形态关联数组属性-值对和数字索引数组CSS 声明串{# 关联数组 #} {% set styles {color: red, font-size: 14px}|html_attr_type(style) %} div {{ html_attr({style: styles}) }} Styled content /div {# 输出: div stylecolor: red; font-size: 14px;Styled content/div #} {# 数字索引数组 #} {% set styles [color: red, font-size: 14px]|html_attr_type(style) %} div {{ html_attr({style: styles}) }} Styled content /div {# 输出: div stylecolor: red; font-size: 14px;Styled content/div #} /code与sst类似style类型对style属性是自动的html_attr遇到style属性的数组值时会在 htmlAttrValue() 中自动包装为new InlineStyle($value)。显式调用html_attr_type(style)主要用于提前定型、或在html_attr_merge场景中获得确定的合并语义。InlineStyle::getValue() 对两种形态的处理逻辑值得注意键为数字时把值原样当作声明串拼上;键为字符串时输出name: value;。并且只有null、false、true、空串、空数组会被跳过——0、0.0、0是合法的 CSS 值会正常输出CHANGELOG 3.29.0 条目 Fixhtml_attrdroppingstyledeclarations whose value is0,0.0or0 正是修复了这一边界。参数说明参数说明value要转换的属性值序列可迭代或标量type属性类型取值之一sst默认空格分隔令牌列表、cst逗号分隔令牌列表、style内联 CSS从 HtmlExtension::htmlAttrType() 的实现看该函数是一个静态工厂用match语句做类型分派public static function htmlAttrType(mixed $value, string $type sst): AttributeValueInterface { return match ($type) { sst new SeparatedTokenList($value, ), cst new SeparatedTokenList($value, , ), style new InlineStyle($value), default throw new RuntimeError(\sprintf(Unknown attribute type %s The only supported types are sst, cst and style., $type)), }; }两个实现要点sst与cst本质是同一个类SeparatedTokenList仅分隔符不同 与, 传入未知类型会在运行时抛出RuntimeError错误信息中明确列出支持的三种类型。渲染与合并源码级机制值对象接口html_attr_type的返回值统一实现 AttributeValueInterfaceinterface AttributeValueInterface { /** * Returns the string representation of the attribute value. The returned value * will automatically be escaped for the HTML attribute context. */ public function getValue(): ?string; }接口文档明确了两点契约返回的字符串会被自动按 HTML 属性上下文转义返回null表示整个属性应被省略。在 htmlAttr() 中每个属性值经htmlAttrValue()解析后最终通过$runtime-escape($value)EscaperRuntime输出属性名则使用html_attr_relaxed策略保留:、、[、]以兼容 Vue/React 等前端框架属性名。省略语义SeparatedTokenList::getValue() 的省略规则很精细列表中过滤掉null与false后若为空返回null属性被整体省略true值不打印文本但会让属性得以保留用于布尔属性语义。与 html_attr_merge 的合并协作sst/cst/style值对象同时实现了 MergeableInterface提供mergeInto()与appendFrom()两个方法用于在 html_attr_merge 过滤器 合并多个属性数组时的自定义合并行为SeparatedTokenList::mergeInto()仅当两侧同为SeparatedTokenList且分隔符相同时按序拼接一侧是普通可迭代值也可拼分隔符不同如sst与cst混用会抛出RuntimeError防止产生语义错误的输出InlineStyle::mergeInto()两侧均为InlineStyle或普通可迭代值时按序拼接声明。html_attr本身就可以接收多个属性数组内部先走htmlAttrMerge再渲染因此html_attr_type转换后的值可以直接参与多来源合并。仓库的集成测试 html_attr.test 验证了这一点merging a comma separated token list value with more array values: img {{ html_attr({ srcset: [small.jpg 480w]|html_attr_type(cst) }, { srcset: [medium.jpg 800w, large.jpg 1200w] }) }} /期望输出同一 fixture 第 40 行img srcsetsmall.jpg 480w, medium.jpg 800w, large.jpg 1200w /即已定型为cst的右侧数组与后续普通数组合并后仍保持逗号分隔渲染。与其他 HTML 辅助 API 的关系API类型职责html_attr函数函数合并并渲染整个属性字符串负责转义html_attr_type文档过滤器把数组定型为sst/cst/style值对象html_attr_merge文档过滤器显式合并多个属性数组尊重MergeableInterfacehtml_classes函数函数仅处理 class 字符串/条件数组html_cva函数函数构建 Cva 组件base/variants/compoundVariants输出 class 串需要注意的边界html_attr_type只负责值对象定型不输出最终 HTML真正的属性拼接、转义与省略判断由html_attr完成。此外HtmlExtension::htmlAttrValue() 还处理了若干与类型无关的细节BackedEnum取 backing value、aria-*布尔值转true/false字符串、data-*非标量值 JSON 编码Stringable除外、布尔true渲染为attrXHTML 合规的空值默认。这些行为与html_attr_type配合使用时不会冲突但了解它们有助于排查模板输出。小结html_attr_type是 Twig HTML 属性体系中的类型标记过滤器用一行管道声明数组应该按sst空格、cst逗号还是styleCSS 声明渲染。它的价值在于——把分隔符语义固化到值对象上使多来源属性合并html_attr多参数或html_attr_merge时仍保持正确的格式化与可预期的省略行为且全程由EscaperRuntime保证属性上下文转义。实现集中在 extra/html-extra/ 的 HtmlExtension 与 HtmlAttr/ 三个类中行为基线由 Tests/Fixtures/html_attr.test 等集成测试锁定可作为改造或二次开发时的权威参照。赞分享后端【免费下载链接】TwigTwig, the flexible, fast, and secure template language for PHP项目地址https://gitcode.com/gh_mirrors/tw/Twig点击查看免费下载相关推荐es-toolkit 的 toPairsIn 详解将对象含继承属性转换为键值对数组es toolkit 的 toPairsIn 详解将对象含继承属性转换为键值对数组 toPairsIn 是 es toolkit 提供的 Lodash 兼前端后端es-toolkit/compat 的 toPairsIn将对象含继承属性转换为键值对数组的兼容性方案es toolkit/compat 的 toPairsIn将对象含继承属性转换为键值对数组的兼容性方案 toPairsIn 是 es toolkit 的前端后端es-toolkit/compat 的 fromPairs 函数将键值对数组转换为对象es toolkit/compat 的 fromPairs 函数将键值对数组转换为对象 fromPairs 是 es toolkit 兼容层 es tool前端后端上一篇从卡顿到丝滑PrimeVue TreeSelect组件在10万级数据下的性能优化实战下一篇彻底解决PrimeVue TreeTable行选择与展开冲突的3个实战方案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

SPL 迁移到 Axiom APL 实战指南:基于 spl-to-apl 技能的完整查询翻译手册

SPL 迁移到 Axiom APL 实战指南:基于 spl-to-apl 技能的完整查询翻译手册

后端前端AI 技能AI 插件搜索引擎 【免费下载链接】clawhub Skill Plugin Registry for OpenClaw 项目地址: https://gitcode.com/gh_mirrors/mo/clawhub 点击查看 免费下载 本指南围绕本仓库 .agents/skills/spl-to-apl/ 目录下的 SPL→APL 翻译技能展开&#xff…

2026/9/25 7:51:10 阅读更多 →
通信驱动的CRM工作台:DeskcommCRM设计思路与落地实践

通信驱动的CRM工作台:DeskcommCRM设计思路与落地实践

最近大半年我在推进一个项目,内部代号 DeskcommCRM,聊的人不多,但用起来确实和传统 CRM 是两个思路。它不是那种把客户信息塞进数据库就完事的系统,而是把“客户关系”这件事重新拉回到桌面上——电话、邮件、会话、跟进记录&…

2026/9/25 7:51:10 阅读更多 →
安卓逆向助手:抓包脱壳反编译全流程脚本化实战

安卓逆向助手:抓包脱壳反编译全流程脚本化实战

简介:安卓逆向助手是一款面向Android应用开发者与安全研究人员的图形化逆向工具,旨在降低APK反编译与分析门槛,让初学者也能快速理解应用内部结构。它集成dex2jar、JD-GUI、apktool、baksmali等常用组件,支持一键将Dalvik字节码转…

2026/9/25 7:51:10 阅读更多 →

最新新闻

多协议支持实战:用 LiteLLM 让一个模型同时讲 OpenAI、Responses 和 Anthropic 三种“方言”并接入 TaoToken

多协议支持实战:用 LiteLLM 让一个模型同时讲 OpenAI、Responses 和 Anthropic 三种“方言”并接入 TaoToken

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/25 8:22:38 阅读更多 →
LibreChat:多模型统一自托管AI聊天平台部署指南

LibreChat:多模型统一自托管AI聊天平台部署指南

我是在整理自托管服务清单时注意到 LibreChat 的,一开始没当回事,后来发现身边好几个搞技术朋友都在用,才认真研究了一下。这个项目本质上是一个开源的 AI 聊天客户端,但它解决了一个挺麻烦的问题:不同 AI 模型散落在各…

2026/9/25 8:22:38 阅读更多 →
vinext 兼容性压力测试实战:用 pages-router-complex 演练大型 Pages Router 企业应用迁移

vinext 兼容性压力测试实战:用 pages-router-complex 演练大型 Pages Router 企业应用迁移

后端Web框架SSR 【免费下载链接】vinext Vite plugin that reimplements the Next.js API surface — deploy anywhere 项目地址: https://gitcode.com/gh_mirrors/vi/vinext 点击查看 免费下载 导读:pages-router-complex 是 vinext(基于 V…

2026/9/25 8:22:38 阅读更多 →
BentoML 流式响应实战:LLM 文本流、音频字节流与服务端流式实现解析

BentoML 流式响应实战:LLM 文本流、音频字节流与服务端流式实现解析

模型推理服务人工智能后端大模型MLOpsLLMOps 【免费下载链接】BentoML The easiest way to serve AI apps and models - Build Model Inference APIs, Job queues, LLM apps, Multi-model pipelines, and more! 项目地址: https://gitcode.com/gh_mirrors/be/BentoM…

2026/9/25 8:22:38 阅读更多 →
Hugo Blox Builder 简历页实战:用 resume 系列 Blox 组装 Experience / Skills / Awards / Languages 履历页面

Hugo Blox Builder 简历页实战:用 resume 系列 Blox 组装 Experience / Skills / Awards / Languages 履历页面

静态站点前端开发工具 【免费下载链接】kit 🧱 Describe your site, AI builds it, you own it as Markdown. Snap together Tailwind blocks like Lego — landing pages, blogs, portfolios, docs & more. No AI slop. Free to deploy anywhere 👇…

2026/9/25 8:22:38 阅读更多 →
React.cache() 请求内去重指南:服务端认证与数据库查询的 RSC 性能优化(mediago Vercel React 最佳实践)

React.cache() 请求内去重指南:服务端认证与数据库查询的 RSC 性能优化(mediago Vercel React 最佳实践)

音视频桌面应用后端 【免费下载链接】mediago 跨平台视频提取工具:支持流媒体下载、视频下载、m3u8 下载及 B站视频下载,提供 Windows 和 Mac 桌面客户端。Cross-platform video extraction tool: Supports streaming download, video download, m3u8 do…

2026/9/25 8:21:38 阅读更多 →

日新闻

AI元人文:从工具使用到思维重构的深度探索

AI元人文:从工具使用到思维重构的深度探索

最近半年我一直在琢磨一件事:AI元人文到底是什么?说白了,就是“用元视角重新审视人与AI的关系”,也在“探索AI如何反向逼着我们发现自己的思考边界”。标题里的“元探索”,在我看就是一层套一层的追问——当你用AI解决…

2026/9/25 0:00:41 阅读更多 →
Python+CNN车牌识别实战:从数据预处理到模型训练与部署

Python+CNN车牌识别实战:从数据预处理到模型训练与部署

简介:基于Python与卷积神经网络的车牌识别项目,面向计算机视觉初学者及智能交通开发者,目标是帮助用户掌握从数据预处理、模型构建到实际部署的完整流程。压缩包共25个文件,包含jpg/png图像样本、py训练脚本、md说明文档、dat数据…

2026/9/25 0:00:41 阅读更多 →
Vim基础操作全攻略:保存退出、模式切换与高频命令实战

Vim基础操作全攻略:保存退出、模式切换与高频命令实战

1. 项目概述1.1 核心需求解析今天聊聊Vim。写这个题目的原因是:几乎每个后端开发者、运维人员、数据工程师某天都会遇到一个场景——深夜加班,服务器登录界面只有黑底白字,编辑器只有vi/vim,你必须在五分钟内完成一次配置修改并保…

2026/9/25 0:00:41 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/24 14:34:13 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/24 9:10:42 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/24 14:33:56 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/24 12:50:34 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/24 14:33:48 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/24 12:49:17 阅读更多 →