timkelty / craftcms-classmate
HTML类辅助工具
Requires
- craftcms/cms: ^3.2.0
- illuminate/collections: ^8.22
Requires (Dev)
- codeception/codeception: ^3.1
- phpstan/phpstan: ^0.12.68
- vlucas/phpdotenv: ^3.0
README
Classmate旨在帮助HTML类组合,尤其与utility-first CSS框架,如Tailwind CSS搭配使用时非常有用。
在Classmate之前
template.twig
<h2 class="text-lg leading-6 font-medium text-gray-900 mb-3"> Some reusable heading… <a href="#" class="text-orange-600 hover:text-orange-900">A link</a> </h2>
在Classmate之后
template.twig
<h2 class="{{ classmate.get('myHeading').remove('text-gray-900').add('mb-3', 'text-gray-400') }" > Some reusable heading… <a href="#" class="{{ classmate.get('defaultLink') }}">A link</a> </h2>
classmate.json
{ "myHeading": "text-lg leading-6 font-medium text-gray-900", "defaultLink": "text-orange-600 hover:text-orange-900" }
为什么?
我对使用@apply
提取组件类的看法,可以由这篇推文很好地概括。
简而言之,我尽可能避免使用@apply
。
Classmate专门为单个元素组件(例如按钮、链接、标题)而创建,在这些组件中,将它们提取到模板部分可能很繁琐,同时仍然希望避免使用@apply
。
这与@apply有什么不同?我们不是只是把问题转移到了别处吗?
是的,也可能不是。确实,使用@apply
提取组件的实践与在Classmate JSON文件中定义类相似。然而,Classmate在后台(PHP)抽象化了定义,而@apply
作为前端构建的一部分进行了抽象。这种做法的优点是
- 没有组件类带来的额外CSS膨胀
- 没有增加
@apply
的编译时间 - 您生成的HTML保持全实用。对于新加入项目的开发者,尤其是如果他们已经熟悉Tailwind或任何框架,如果他们不需要解析一组组件类,那么加入项目会更容易。
- 错误更容易被发现。
- 使用提取的组件,可能会发生误用而未被察觉,例如在类属性中输入了拼写错误。在Classmate中,当类定义缺失时,开发者可以立即发现。
- 配置可以与前端JS共享。
配置
将./src/config.php
复制到<yourProject>/config/classmate.php
。
filePath
您的Classmate文件的位置。支持别名和环境变量。默认为@config/classmate.json
,但我建议您将其放置在与您的预编译前端资产相同的目录中,例如./src/css/classmate.json
如果您直接使用Tailwind或PurgeCSS,您还希望包含此路径。例如:
tailwind.config.js
module.exports = { purge: { content: [ "./src/**/*.css", "./src/**/*.js", "./templates/**/*.*", "./config/tailwind.json", ], options: { safelist: [], }, }, };
Classmate 文件
您的Classmate文件是一个包含单个对象的JSON文件。值可以是空格分隔的字符串或数组,也可以是两者的组合。
{ "heading1": "text-2xl font-bold", "heading2": ["text-lg", "font-bold"], "buttonBase": [ "text-center inline-flex items-center justify-center font-bold", "rounded-full" ], "buttonWhite": "bg-white text-gray-900", "buttonLg": "leading-none text-xl py-4 px-8", "buttonSm": "leading-none text-sm py-2 px-4", "centerX": "left-1/2 transform -translate-x-1/2", "centerY": "top-1/2 transform -translate-y-1/2" }
由于这只是一个JSON文件,它也很容易由JavaScript消费!
import classmate from "../../config/classmate.json"; document.querySelector("body").class = classmate.body;
使用方法
tag
函数
{{ tag('a', classmate.get('defaultLink').asAttributes({ text: 'A link' href: '#' })) }}
tag
标签
Craft 3.6+ 仅支持
{% tag('a', classmate.get('defaultLink').asAttributes({href: '#' })) %} A link {% endtag %}
attr
函数
<a {{ attr({ href: '#' class: classmate.get('defaultLink').asClasses() }) }}>A link</a>
attr
过滤器
{% set tag = '<a href="#">' %} {{ tag|attr({ class: classmate.get('defaultLink').asClasses() }) }}
类字符串
<a href="#" class="{{ classmate.get('defaultLink') }}">A link</a>
API
classmate
是一个链式API,在您的Twig模板中作为全局变量可用。
get(string ...$keys): Classmate
从您的Classmate文件中检索给定$keys
的类。多个键将从右至左合并。
{{ classmate.get('buttonBase', 'buttonLarge', 'buttonBlue') }}
asClasses(): array
检索一个类数组。移除重复和空值。
<div {{ attr({ class: classmate.get('foo').asClasses() }) }}">
asAttributes(iterable $attributes = []): array
检索一个与attr
兼容的可迭代对象,其中class
已合并到任何传递的$attributes
中。
<div {{ attr(classmate.get('foo').asAttributes({ id: 'buttonLarge' })) }}">
add(string ...$classes): 同学
向当前 ClassList
添加类。
{{ classmate.get('foo').add('mb-4') }}
remove(string ...$classes): 同学
从当前 ClassList
移除类。
{{ classmate.get('foo').remove('mb-4') }}
matching(string $pattern): 同学
过滤当前 ClassList
,保留与 $pattern
匹配的项。
{{ classmate.get('foo').matching('/^text-/') }}
notMatching(string $pattern): 同学
过滤当前 ClassList
,移除与 $pattern
匹配的项。
{{ classmate.get('foo').notMatching('/^mb-/') }}
replace(string $search, string $replace, bool $partial = false): 同学
将 $search
替换为 $replace
。将 $partial
设置为 true
以匹配部分字符串,否则仅替换完整匹配。
{{ classmate.get('foo').replace('text-red-500', 'text-red-100') }} {{ classmate.get('bar').replace('md:', 'lg:', true) }}
prepend(string $string): 同学
将 $string
预先添加到 ClassList
的每个项中。
{{ classmate.get('foo').prepend('md:') }}
append(string $string): 同学
将 $string
添加到 ClassList
的每个项中。
缓存
JSON 文件的检索被缓存,并且通过文件的修改来失效,因此你真的不需要过多担心失效。然而,你可以通过 CP 或 CLI 命令选择性地清除缓存。
./craft clear-caches/classmate-cache
需求
- Craft CMS 3.0+
- PHP 7.4+
安装
composer require timkelty/craftcms-classmate
路线图
如何在 CSS 中使用 Classmate 类?
你无法!……目前还不行。@markhuot 在这里提到了这一点:https://twitter.com/markhuot/status/1351605237736419329
可能的一个 Tailwind/Postcss 插件可以允许这样做
例如,你可以这样写
.prose a { @classmate foo, bar; }
……来获取与 classmate.get('foo', 'bar')
相同的类。
箭头函数
我很乐意允许使用箭头函数,但当前 Twig 不允许这样做。例如,对于我们的 matches
和 prepend
方法,我更愿意有
classmate.get('foo').filter(c => c starts with 'f') classmate.get('foo').filter(c => c matches '/^f/') classmate.get('foo').map(c => "md:#{c}")
虽然这适用于 Twig 的 map
、filter
和 reduce
过滤器,但在这里不起作用。参见 twigphp/Twig#3402
CP 设置
我并不真的想这样做,但如果有人想添加,我会很高兴接受 PR。