关于 craft-site
使用原生 Twig 和原子设计模式构建 Craft CMS 5 前端模板的技能,涵盖组件架构、路由、组合、主题与构建链,并指出相关任务所需的配套技能。
主要功能
- 01原子设计组件模式
- 02Twig 模板组合指导
- 03路由与模板架构
- 04Tailwind 与主题约定
- 05Vite 构建链参考指南
- 06Craft 插件集成参考
适用场景
- 01设计可复用的前端组件
- 02搭建 Craft 模板结构
- 03实现响应式图片处理
- 04配置缓存或多站点模板
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ michtio/ craftcms-claude-skills --skill craft-site安装后在 Claude Code 中输入/craft-site确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/atomic-design.mdatomic-patterns.mdauth-account.mdauth-flows.mdboilerplate-routing.mdcomponent-inventory.mdcomposition-patterns.mdelement-partials.mdexample-templates.mdfeeds.mdheadless.mdimage-presets.mdjavascript-boundaries.mdmulti-site-patterns.mdsearch.mdtailwind-conventions.mdtemplate-caching.mdthird-party-integration.mdtwig-collections.mdvite-buildchain.md详细介绍
Craft CMS 5 — 前端 Twig(原子设计)
适用于 Craft CMS 5 站点模板的原子设计系统模式。使用原生 Twig — 不依赖模块。适用于任何 Craft 5 项目。
此技能仅涵盖前端模板架构——组件设计、路由、组合、主题和构建链。关于扩展 Craft(插件、模块、PHP),请参阅 craftcms 技能。
配套技能 — 始终一并加载
触发此技能时,也要加载:
craft-twig-guidelines— Twig 编码规范:变量命名、空值处理、空白控制、include 隔离、Craft 辅助函数。编写任何 Twig 代码都必须加载。craft-content-modeling— 分区、条目类型、字段、Matrix、关系。决定要查询哪些内容或模板如何访问数据时必须加载。ddev— 所有命令都通过 DDEV 运行。运行 Vite、npm 和 Craft CLI 命令时必须加载。craft-cloud— 站点托管在 Craft Cloud 上时加载(通过仓库根目录中的craft-cloud.yaml或composer.json中的craftcms/cloud检测)。配置边缘静态缓存规则、在缓存页面中使用cloud.esi(...)动态岛、处理边缘图像转换限制,以及在可缓存页面中使用csrfInput()时必须加载。servd— 站点托管在 Servd 上时加载(通过仓库根目录中的servd.yaml或composer.json中的servd/craft-asset-storage检测)。配置 Servd 静态缓存、在缓存页面中使用{% dynamicInclude %}岛、以反向代理模式运行 Blitz,以及进行服务器外图像转换时必须加载。
文档
- Craft 中的 Twig:https://craftcms.com/docs/5.x/development/twig.html
- 模板标签:https://craftcms.com/docs/5.x/reference/twig/tags.html
- 模板函数:https://craftcms.com/docs/5.x/reference/twig/functions.html
- Twig 3 文档:https://twig.symfony.com/doc/3.x/
如果参考文件未涵盖足够细节,请使用 WebFetch 查阅具体文档页面。
常见陷阱(跨领域)
{% include %}缺少only— 环境变量会悄然泄漏进来。- 通过条件语句(
{% if variant == 'x' %})而非 extends/block 实现变体逻辑。 - 按父级上下文命名原子(
hero-button),而非按视觉样式命名(button--primary)。 - 将
utilities属性用作覆盖项 — 它只会追加。应通过具名插槽合并来覆盖。 - 在视图中执行查询 — 视图接收数据,不负责获取数据。
- 视图中的关系字段缺少
.eagerly()— 会导致 N+1 查询。 - 对未知区块类型的构建器缺少
devMode回退逻辑。 - 在
{% cache %}中放置 CSP nonce、csrfInput()、活动导航状态或语言切换器。首次渲染的内容会重放给所有人。请参阅template-caching.md。 - 硬编码 Tailwind 颜色(
bg-yellow-600),而非使用品牌令牌(bg-brand-accent)。 - 混用按钮和链接 — 按钮用于操作(根据属性解析为
<a>、<button>或<span>),链接用于导航(始终为<a>)。应将它们归入不同的原子类别。 - 在组件中放置跟踪/分析逻辑 — 应在视图/页面层通过数据属性解耦。
- 在 CP 之外编辑 YAML 后忘记执行
project-config/touch— Git 拉取、手动编辑和解决合并冲突都不会更新dateModified。运行ddev craft project-config/touch,然后运行ddev craft up;否则在其他环境中运行craft up时将检测不到更改。
参考文件
请根据任务阅读相关参考文件。通常需要结合多个文件。 任务示例:
- “构建新的卡片组件” → 读取
atomic-patterns.md+composition-patterns.md+component-inventory.md+tailwind-conventions.md - “为新项目设置模板结构” → 读取
boilerplate-routing.md+component-inventory.md - “为 Matrix 字段添加内容构建器” → 读取
boilerplate-routing.md+composition-patterns.md - “处理响应式图片” → 读取
image-presets.md+plugins/image-optimize.md - “使用
{% cache %}缓存导航栏/页脚” → 读取template-caching.md - “添加
{% cache %}后脚本被 CSP 阻止/nonce 不匹配” → 读取template-caching.md(CSP Nonces) - “上传后首次查看页面很慢/为什么图片 URL 是
generate-transform” → 读取image-presets.md(Transform Generation Timing)+plugins/image-optimize.md - “添加多品牌主题” → 读取
tailwind-conventions.md - “为某项功能选择 Alpine 还是 Vue” → 读取
javascript-boundaries.md - “组合 Tailwind 类且避免冲突” → 读取
tailwind-conventions.md+twig-collections.md - “了解原子设计方法论” → 读取
atomic-design.md - “在新的 Craft 项目中设置 Vite + Tailwind” → 读取
vite-buildchain.md - “排查生产环境中资源无法加载的原因” → 读取
vite-buildchain.md - “查找
craft.vite.*Twig 函数(asset、register、critical CSS)” → 读取plugins/vite.md - “在 Craft 项目中安装 GTM/分析工具/CMP” → 读取
third-party-integration.md - “无法覆盖插件的前端 CSS/插件样式优先于我的样式” → 读取
third-party-integration.md(Plugin CSS Loads After Yours) - “用自己的模板替换插件模板/插件小组件停止增强” → 读取
third-party-integration.md(Hand-Written Templates for Plugin Widgets) - “为某个分区配置 SEOMatic” → 读取
plugins/seomatic.md - “使用 Cloudflare 设置 Blitz 缓存” → 读取
plugins/blitz.md - “向页面添加表单” → 读取
plugins/formie.md - “使用嵌套条目配置 CKEditor” → 读取
plugins/ckeditor.md - “构建导航菜单” → 读取
plugins/navigation.md - “向组件添加链接字段” → 读取
plugins/hyper.md - “为站点设置重定向” → 读取
plugins/retour.md - “为条目添加周期性/重复日期” → 读取
plugins/timeloop.md - “创建 JSON API 端点” → 读取
plugins/element-api.md - “排查模板中的 N+1 查询” → 读取
plugins/elements-panel.md - “运行安全审计” → 读取
plugins/sherlock.md - “将 YouTube/Vimeo 视频嵌入为资源” → 读取
plugins/embedded-assets.md - “通过 SES 配置电子邮件投递” → 读取
plugins/amazon-ses.md+third-party-integration.md - “构建语言切换器” → 读取
multi-site-patterns.md - “在前端添加登录/注册功能” → 读取
auth-flows.md - “构建用户资料编辑页面” → 读取
auth-account.md - “设置密码重置流程” → 读取
auth-flows.md - “设置 hreflang 标签” → 读取
multi-site-patterns.md - “规划多语言站点架构” → 读取
multi-site-patterns.md - “无需 JavaScript 添加实时搜索” → 读取
plugins/sprig.md - “构建响应式筛选或加载更多功能” → 读取
plugins/sprig.md - “从外部 Feed 导入数据” → 读取
plugins/feed-me.md - “使用 Imager-X 设置响应式图片” → 读取
plugins/imager-x.md - “构建搜索页面” → 读取
search.md - “配置搜索设置” → 读取
search.md(Search Configuration) - “重建搜索索引” → 读取
search.md(Rebuilding) - “创建 RSS Feed” → 读取
feeds.md - “构建 XML 站点地图” → 读取
feeds.md(XML Sitemap) - “创建 JSON Feed” → 读取
feeds.md(JSON Feed) - “使用 Next.js 设置无头 Craft CMS” → 读取
headless.md - “修复 GraphQL 预览令牌” → 读取
headless.md - “从前端框架调用 Craft GraphQL API” → 读取
headless.md - “使用 entry.render() 构建可复用的卡片组件” → 读取
element-partials.md - “为条目设置 _partials/ 模板” → 读取
element-partials.md - “使用 partials 渲染 Matrix 块” → 读取
element-partials.md - “通过插件打包并安装示例模板(打包 + 安装命令)” → 读取
example-templates.md - “构建流畅的前端渲染/标签构建器(craft..thing().render())” → 读取
example-templates.md| 参考文档 | 范围 | |-----------|-------| |references/atomic-design.md| 方法论:Brad Frost 的原子设计原则、从 5 层压缩为 3 层、可组合性、与上下文无关的命名、分类难题、向下分解工作流。与技术无关。 | |references/atomic-patterns.md| 单个组件的构建:props/extends/block 模式、变体文件机制、按钮/链接/文本/图标原子组件的实现 | |references/composition-patterns.md| 组件组合:分子模式、有机体模式、结构嵌入模式、include/extends/embed 决策表、调用约定、创建新组件 | |references/component-inventory.md| 分类方法:决策树、命名约定、文件命名、props 设计、脚手架指南、层级晋升、审核清单 | |references/boilerplate-routing.md| 模板链:布局层级、Craft 区块模板路径、全局变量、路由器、视图、内容构建器、目录结构 | |references/tailwind-conventions.md| 类组合:命名键集合、标准键名、utilitiesprop、基于变体的暗色模式、间距偏好。假设使用 Tailwind CSS——请根据你的 CSS 框架调整这些模式。 | |references/vite-buildchain.md| Craft CMS Vite 配置:nystudio107 插件桥接、config/vite.php、vite.config.ts、craft.vite.script()、按页面条件加载、Tailwind v4 集成、DDEV 配置 | |references/image-presets.md| 图像处理:使用预设的单个原子组件、srcset/sizes、ImageOptimize 与 Craft Cloud、托管策略、转换生成时机(generateTransformsBeforePageLoad) | |references/template-caching.md|{% cache %}标签:缓存键(按 URL、globally、using key)、参数顺序、哪些内容可以或不可以放入缓存、CSP nonce、带活动状态的导航栏/页脚示例及置于外部的语言切换器、临时转换 URL、验证步骤 | |references/javascript-boundaries.md| JS 决策树:Twig → Alpine/DataStar → Vue、挂载点、数据传递、共存规则 | |references/twig-collections.md|collect()方法参考:创建、访问、转换、筛选、排序、切片、箭头函数 | |references/third-party-integration.md| 脚本加载顺序、CMP(UserCentrics/CookieBot)、GTM/sGTM 数据层、分析工具(Fathom/Plausible)、AWS SES 传输、n8n webhook、插件 CSS 层叠(在你编写的样式之后加载)及插件小部件的手写模板、Blitz 兼容性、完整 head 模板示例 | |references/multi-site-patterns.md| 语言切换器、hreflang 标签、站点架构(子目录/域名/子域名/多品牌)、跨站点查询、静态翻译、站点专属模板、多站点表单、站点检测 | |references/auth-flows.md| 前端身份验证表单:登录、注册、密码重置、设置新密码 | |references/auth-account.md| 账户管理:编辑个人资料、电子邮件验证、导航部分、访问控制标签、用户会话助手、GeneralConfig 身份验证设置 | |references/search.md| 搜索:语法、Twig 查询、配置、索引、重建、评分与排名 | |references/feeds.md| Feed:RSS 2.0、Atom、JSON Feed、XML 站点地图、自定义路由、日期筛选器 | |references/headless.md| 无头与混合模式:headlessMode、GraphQL API、CORS、预览令牌、Next.js/Nuxt/Astro 集成 | |references/element-partials.md| 元素部分模板:entry.render()、_partials/ 目录、模板查找、自定义变量、在部分模板中预加载 | |references/example-templates.md| 插件前端交付:Craft Commerce 风格的示例模板包(规范文件夹、_private/layouts/外壳、每页的{% extends %}/{% block main %}、index.twig重定向、支持重命名/--overwrite的安装控制台命令)、流畅的craft.<handle>.<thing>({...}).render()BaseTag 构建器、渐进增强规范 |
插件参考
各插件的配置、Twig API 和注意事项都记录在 craft-plugins 技能中(skills/craft-plugins/references/<plugin>.md)——集中存放在此处,方便后端、迁移和部署任务查阅,不只限于前端任务。
当前端任务涉及特定插件时——Formie 表单样式、SEOmatic 元数据、Blitz 缓存、Imager-X / ImageOptimize 转换、Sprig 组件、CKEditor、Hyper 链接、Navigation、Embedded Assets、Vite、Typogrify、Colour Swatches——请加载 craft-plugins 技能并打开相应的参考文档。
组件系统约定
所有项目采用统一的规范组件系统。原子组件与上下文无关——始终按视觉样式命名,绝不按父级命名。HTML 元素类型由 props 决定(url → <a>,type → <button>,默认 → <span>)。
外部链接检测根据 URL 推导,绝不作为 prop 传入。当 URL 为外部链接时,组件会自动应用 target="_blank"、rel="noopener noreferrer"、外部链接图标和仅供屏幕阅读器读取的文本。
FontAwesome 是通用图标系统。图标以 FA 类字符串传入。
视觉变体使用 extends/block——基础模板定义结构,变体覆盖类。绝不使用条件逻辑切换变体样式。对于带内容插槽的结构骨架,请使用 {% embed %}——参见 composition-patterns.md。
图像处理使用一个由配置驱动预设的原子组件,而不是针对不同上下文使用单独的变体文件。
CSS 与主题约定
本技能假设使用 Tailwind CSS 来展示类组合示例。请根据你的 CSS 框架调整这些模式——架构原则(命名键、叠加式工具类、语义化令牌)与框架无关。
类集合按样式关注点使用命名键——这是防止冲突的主要机制。utilities prop 用于叠加扩展,而非覆盖。通过命名插槽合并来覆盖特定关注点。
多品牌主题使用 CSS 自定义属性,并通过 <html> 上的 data-brand="{{ currentSite.handle }}" 激活。组件引用语义化 Tailwind 类(bg-brand-accent),由 CSS 变量解析。仅当品牌之间的 HTML 结构本身不同时,才在模板层覆盖品牌样式;颜色、字体或间距差异不适用。
令牌命名分为三层:基础值(--brand-{color}-{shade})、语义值(--brand-{purpose})和框架映射(--color-brand-{purpose})。
Tailwind v4 的级联层无法解决同一 utilities 层内的类冲突。仍需使用命名键集合。
路由约定
PHP 负责数据,Twig 负责呈现。视图通过 include 接收数据——绝不自行查询数据。
collect() 同时用于 props 和类的构建。通过 Craft 可在 Twig 中使用完整的 Collection API。
JS 的边界遵循决策树:默认使用 Twig → 用 Alpine/DataStar 管理 UI 状态 → 用 Vue 管理应用状态。