brain / assets
WordPress 资产助手。
Requires
- php: >= 8.0 < 8.4
Requires (Dev)
- brain/monkey: ^2.6.1
- inpsyde/php-coding-standards: ^2@dev
- inpsyde/wp-stubs-versions: dev-latest
- phpcompatibility/php-compatibility: ^10@dev
- phpunit/phpunit: ^9.6.16
- vimeo/psalm: ^5.22.0
This package is auto-updated.
Last update: 2024-08-30 19:39:32 UTC
README
Assets
类
这是一个 Composer 包,可用于在 WordPress 插件、主题和库中处理资产 URL,以及样式/脚本排队。
包 API 入口点是类 Brain\Assets\Assets
,因此首先要做的是获取其实例。
这可以通过一个静态构造函数来完成,根据库的使用位置选择几个可用的选项:在插件中、在主题中或库中。
use Brain\Assets\Assets; // For plugins. // First param is main plugin file,second optional param // is the subfolder in which assets files are saved. Assets::forPlugin(__FILE__, '/dist'); // For themes. // First param is the subfolder in which assets files are saved. Assets::forTheme('/dist'); // For child themes. // First param is the subfolder in which assets files are saved. Assets::forChildTheme('/dist'); // For libraries. // First param is the name of the library. // Second param is absolute path in which assets files are saved. // Third param is the absolute URL that points to the base path. Assets::forLibrary('my-lib', __DIR__ . '/dist', content_url('/vendor/acme/my-lib/dist'));
获取 Assets
实例后,可以调用两组方法
- 排队脚本和样式 的方法
- 获取资产 URL 的方法
排队资产
Assets
类的第一组方法可以用来排队样式和脚本,并作用于排队输出。例如
$assets = Assets::forPlugin(__FILE__, '/dist'); $assets->enqueueScript('my-script', strategy: 'async') ->useAsync() ->useAttribute('crossorigin', 'anonymous') ->localize('MyScriptData', ['foo' => 'bar']) ->prependInline("window.foo = 'Foo';"); $assets->enqueueStyle('my-alt-style') ->asAlternate() ->useAttribute("disabled", null) ->useAttribute("data-something", "Something") ->withTitle('my style') ->withCondition('lte IE 10') ->appendInline(".custom-color: #{$customColor}");
正确钩子
WordPress 要求使用正确的钩子(例如 wp_enqueue_scripts
或 admin_enqueue_scripts
)来排队资产,并且调用 Assets::enqueueStyle()
和 Assets::enqueueScript()
方法时也是如此。
Assets
的实例可以提前创建而不会出现任何问题,但实际的排队必须通过正确的钩子来完成。
WordPress 的依赖提取 Webpack 插件支持
WordPress 的 依赖提取 Webpack 插件(在使用 wp-scripts
时包含)生成一个名为 <asset name>.asset.php
的 PHP 文件,其中包含有关脚本依赖和版本的信息。要使用此文件,请使用 Assets::useDependencyExtractionData()
方法。
例如,使用以下代码
$assets = Assets::forTheme('/dist')->useDependencyExtractionData(); $assets->enqueueScript('main', strategy: 'async'); $assets->enqueueScript('secondary', strategy: Strategy::newDeferInFooter()); $assets->enqueueScript('head', strategy: Strategy::newInHead());
然后库将调用
wp_enqueue_script( 'my-theme-main', 'https://example.com/wp-content/themes/my-theme/dist/main.js?v=a29c9d677e174811e603', ['react', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-data'], null, ['in_footer' => false, 'strategy' => 'async'] ); wp_enqueue_script( 'my-theme-secondary', 'https://example.com/wp-content/themes/my-theme/dist/secondary.js?v=d1e2af1f57008411b820', ['wp-api-fetch', 'lodash'], null, ['in_footer' => true, 'strategy' => 'defer'] ); wp_enqueue_script( 'my-theme-head', 'https://example.com/wp-content/themes/my-theme/dist/head.js?v=2933858c47af52e33b8a', [], null, ['in_footer' => false] );
注册
除了 Assets::enqueueScript()
和 Assets::enqueueStyle()
之外,Assets
类还有 Assets::registerScript()
和 Assets::registerStyle()
,它们返回由“排队”方法返回的相同的 Enqueue
实例。该对象有一个 Enqueue::enqueue()
方法,可以用来在已注册的资产上调用 wp_enqueue_script()
/wp_enqueue_style()
。
值得注意的是,Enqueue
实例还有一个 Enqueue::dequeue()
方法,它只有在资产被排队时(无论是通过 Assets::enqueueStyle()
/Assets::enqueueSscript()
还是通过注册方法 + Enqueue::enqueue()
)才有效,就像 Enqueue::enqueue()
只在资产尚未排队时才有效。
优点
库的优点是显而易见的。只需通过从库传递一个脚本文件名,我们就可以获得
- 一个唯一的脚本 "handle",通过在主题名称前缀(对于插件将是相同的)
- 一个完整的 URL,包括缓存破坏查询变量,该 URL 使用由依赖提取 Webpack 插件确定的版本
- 依赖项,由依赖提取 Webpack 插件确定
- 排队 "策略"
这已经大大提高了开发体验,并减少了需要编写的代码量。
此外,它还允许我们
- 更改打印的
<link>
或<script>
标签的 HTML 属性(包括自定义属性); - 为脚本和样式表添加条件入队功能;
- 将本地化数据传递给脚本;
- 将内联代码前置或后置到标签中(对于CSS,仅支持"append");
清单文件
如果我们使用Webpack,并且使用了Webpack Manifest Plugin,我们将有一个包含未处理资产文件名称到已处理文件映射的manifest.json
文件。
当使用任何forPlugin
、forTheme
、forChildTheme
、forLibrary
方法实例化Assets
类时,库会自动识别“base”文件夹中的manifest.json
文件,如果找到,则用于解析完整URL。
清单+依赖提取Webpack插件
同时使用wp-scripts
(或仅使用"Dependency Extraction"插件)和Webpack清单,可以实现非常强大且简洁的工作流程。
Assets
类提供了一个Assets::registerAllFromManifest()
方法,正如其名称所暗示的,注册所有在manifest.json
中存在的CSS/JS资产。结合"Dependency Extraction"插件,它可以自动提供每个资产的依赖项和版本,我们可以通过一行代码自动注册所有资产。
Assets::registerAllFromManifest()
返回一个包含所有注册资产的Enqueue
实例的Collection
类,提供过滤它们和通过名称或句柄获取特定实例的方法。
对用于文件的名字有一些约定(例如,使用"-admin"后缀为后端资产,"-view"后缀为前端资产,"-block"后缀为与块相关的资产),可以编写如下代码:
$myAssets = Assets::forTheme('/dist')->useDependencyExtractionData()->registerAllFromManifest(); add_action('admin_enqueue_scripts'), fn () => $myAssets->keep('*-admin')->enqueue()); add_action('wp_enqueue_scripts'), fn () => $myAssets->keep('*-view')->enqueue());
这三行代码就足够注册可能很多资产,并正确地按URL、正确依赖和正确版本入队。.
带有"-block"后缀的资产在片段中未入队,因为我们可能希望在block.json
中使用它们的句柄,让WordPress在需要时入队它们。
关于Collection
对象更多
Collection
类提供了许多不同的方式来过滤资产。上述显示的Collection::keep()
方法不仅支持glob模式,还接受正则表达式,如$myAssets->keep('#foo-[a-z]+bar#')
或简单字符串,如$myAssets->keep('admin')
,在这种情况下,它使用str_contains()
进行过滤。
除了Collection::keep()
外,集合还提供Collection::discard()
(具有相似特性但范围相反)、Collection::filter()
(使用自定义回调进行过滤)以及基于类型进行过滤的方法,如Collection::cssOnly()
和Collection::jsOnly()
。
此外,该类提供通过句柄或文件名检索单个实例的方法,这对于精确注册特定资产非常有用。例如
$myAssets = Assets::forTheme('/dist')->useDependencyExtractionData()->registerAllFromManifest(); $myAssets->byName('main', 'js')->localize('MyData', $mainScriptData); add_action('wp_enqueue_scripts'), fn () => $myAssets->discard('*-admin')->enqueue());
请查阅Collection
源代码以了解该类提供的所有有用API。
检索注册/入队资产的集合
Assets
类提供了一个Assets::collection()
方法,该方法返回一个包含所有已入队/注册资产的Collection
实例。该集合允许我们对单个资产(通过Collection::oneByName()
或Collection::oneByHandle()
检索)或对全部或部分资产进行集体操作(使用Collection
提供的许多方法之一进行过滤,见上文)。
以下是一个示例,说明如何通过几行代码获取所有资产的"自动批量注册",这些代码在资产目录中循环文件
$assets = Assets::forTheme('/dist')->useDependencyExtractionData(); foreach (glob($assets->context()->basePath() . '*.{css,js}', GLOB_BRACE) as $file) { str_ends_with($file, '.css') ? $assets->registerStyle(basename($file, '.css')) : $assets->registerScript(basename($file, '.js')); } add_action('admin_enqueue_scripts'), fn () => $assets->collection()->keep('*-admin')->enqueue()); add_action('wp_enqueue_scripts'), fn () => $assets->collection()->keep('*-view')->enqueue());
请注意:由于Collection
具有不可变设计,不要存储Assets::collection()
的结果,而始终调用该方法以检索最新的集合。
调试
库有一个用于两种情况的"调试"状态标志
- 当为真时,确保在每个请求上使用新的"版本"参数为资产URL。
- 当启用最小化查找时(见下文),决定是否寻找资产的最小化版本(扩展名前有
.min
的版本)。
"调试"状态取决于 SCRIPT_DEBUG
常量的值,但可以通过以下方法设置:Assets::forceDebug()
和 Assets::forceNoDebug()
。
最小化文件解析
一些用于编译资产的方法定义了两个版本的文件,一个用于调试目的,另一个是带有 .min
后缀的"最小化"版本。例如,我们可能同时拥有 my-style.css
和 my-style.min.css
。
在这种情况下,可以指示库在"调试"为 false 时查找最小化文件。这是通过 Assets::tryMinUrls()
方法完成的。
例如
Assets::forPlugin(__FILE__, '/dist') ->tryMinUrls() ->enqueueStyle('my-style.css');
当"调试"为 false 时,上面的代码片段将搜索 my-style.min.css
,如果找到,则将其排队,如果未找到最小化文件,则回退到 my-style.css
。
如果最小化文件是资产构建管道创建的 唯一 文件,则可以像往常一样排队,将 .min
部分作为文件名的一部分。
Assets::forPlugin(__FILE__, '/dist')->enqueueStyle('my-style.min');
HTTP方案解析
当"Context" "secure" 状态启用时,此库强制使用 https
方案。这默认基于 WordPress 函数 is_ssl()
的结果。
可以使用 Assets::forceSecureUrls()
和 Assets::dontForceSecureUrls()
来禁用此功能。
禁用后,基础 URL 将按原样使用,这可能在 HTTPs 上下文中包含 https
,因为通过 forPlugin()
或 forTheme()
构造函数创建的 Assets
实例;然而,当使用 Assets::forLibrary()
然后在获取的实例上调用 dontForceSecureUrls()
时,所有资产使用的 HTTP 方案将由开发人员决定,并且仅取决于 $baseUrl
参数。
排队外部资产
使用 Assets::enqueueStyle()
和 Assets::enqueueScript()
时,需要传递要排队的资产文件名,库将解析完整 URL。
有时希望只是排队给定的完整 URL,例如位于 CDN(或任何非本地)的文件,这可以通过简单地调用 wp_enqueue_script
或 wp_enqueue_style
来轻松完成。
Assets
类提供了 enqueueExternalStyle()
和 enqueueExternalScript()
,可以用于几乎无处理的排队资产,然后可以使用库提供的"高级"方法。
例如
$assets->enqueueExternalScript('foo-js', 'https://cdn.example.com/foo.js?v=1.0') ->useDefer() ->useAttribute('data-id', 'foo-script') ->withCondition('lte IE 10') ->localize('MyScriptData', ['foo' => 'bar']) ->prependInline("window.foo = 'Foo';"); ->appendInline("delete window.foo;");
请注意,当使用这些方法时,库将排队资产而不会尝试附加任何缓存破坏查询变量(并且也阻止 WordPress 添加其版本),因为非本地资产 URL 通常包含作为 URL 部分的缓存变量。
库在给定 URL 上尝试的唯一处理是 调整方案:默认情况下,以 http://
开头的 URL 将转换为使用 https://
,如果 is_ssl()
为真。此处理也可以通过 Assets::dontForceSecureUrls()
禁用。
值得注意的是,使用以 //
(相对方案)开头的外部 URL 也会跳过任何方案处理。
获取 URL
除了排队资产外,库还提供了获取资产 URL 的方法,这些方法除了用于脚本和样式之外,对任何类型的资产都可能有用,如图像、视频、字体等。
以下是一个快速示例
$assets = Assets::forPlugin(__FILE__, '/dist'); $styleUrl = $assets->assetUrl('css/my-style.css'); $scriptUrl = $assets->assetUrl('js/my-script.js'); $imageUrl = $assets->assetUrl('images/foo.jpg'); $fontUrl = $assets->assetUrl('fonts/bar.eot'); $videoUrl = $assets->assetUrl('videos/baz.mp4');
在上述代码片段中,假设不同类型的资产(图像、视频、字体、CSS、JS)保存在主要资产文件夹的子文件夹中,在这种情况下是插件文件夹内的 /dist
。
如果是这种情况,可以指示 Assets
对象关于这些子文件夹的存在,然后使用特定类型的获取 URL 的方法。
$assets = Assets::forPlugin(__FILE__, '/dist') ->withCssFolder('/css') ->withJsFolder('/js') ->withImagesFolder('/images') ->withVideosFolder('/videos') ->withFontsFolder('fonts'); $styleUrl = $assets->cssUrl('my-style'); $scriptUrl = $assets->jsUrl('my-script'); $imageUrl = $assets->imgUrl('foo.jpg'); $fontUrl = $assets->fontUrl('bar.eot'); $videoUrl = $assets->videoUrl('baz.mp4');
这个最后的代码片段与前面的代码片段等效。但子文件夹在创建实例时设置一次,然后可以使用更简洁、更明确的获取 URL 的方法。
注意,对于JS和CSS文件,无需传递文件扩展名。
URL包含版本号
上述方法获取的所有URL都包含用于缓存破坏的查询变量。例如
print $assets->cssUrl('my-style'); // https://www.example.com/wp-content/themes/my-theme/dist/my-style.css?v=1708973312
要获取不带任何版本查询变量的URL,可以使用方法的“原始”版本
$assets->rawAssetUrl('my-style.css'); $assets->rawCssUrl('my-style'); $assets->rawJsUrl('my-script'); $assets->rawImgUrl('foo.jpg'); $assets->rawFontUrl('bar.eot'); $assets->rawVideoUrl('baz.mp4');
或者,可以通过调用Assets::dontAddVersion()
将整个Asset
实例配置为从不添加版本查询变量
print $assets->dontAddVersion()->cssUrl('my-style'); // https://www.example.com/wp-content/themes/my-theme/dist/my-style.css
需求
该库需要
- PHP 8.0+
- WordPress 6.3+.
在开发模式下安装时,需要以下包
- phpunit/phpunit (BSD-3-Clause)
- brain/monkey (MIT)
- inpsyde/php-coding-standards (MIT)
- phpcompatibility/php-compatibility (LGPL 3)
- vimeo/psalm (MIT)
- inpsyde/wp-stubs (MIT)
许可证
Brain Monkey是开源的,并使用MIT许可证发布。有关更多信息,请参阅LICENSE文件。