在 Drupal 8 主题中添加样式表 (CSS) 和 JavaScript (JS)
本指南适用于主题。关于模块的说明,请参见 《在 Drupal 8 模块中添加样式表 (CSS) 和 JavaScript (JS)》。
在 Drupal 8 中,样式表 (CSS) 和 JavaScript (JS) 的加载通过相同的系统来完成,无论是模块(代码)还是主题,一切都依赖于 资源库 (libraries)。
为明确起见,这些说明仅适用于主题,不适用于模块。
Drupal 的高级原则:资源 (CSS 或 JS) 只有在你明确告诉 Drupal 需要加载时才会加载。Drupal 不会在每个页面上加载所有资源,因为那会降低界面性能。
与 Drupal 7 的区别
与 Drupal 7 相比,有六个重要的区别:
- 文件
THEME.info.yml取代了THEME.info文件(包含相同的数据)。 THEME.info中用于添加 CSS 的stylesheets属性被移除,改为使用*.libraries.yml文件,其中 * 是主题或模块的名称。THEME.info中用于添加 JS 的scripts属性也被移除,改为使用*.libraries.yml。- 只有页面需要的 CSS、JS 才会被加载。例如,jQuery 不再自动加载,除非在
*.libraries.yml中明确声明。如果你的主题需要 jQuery 或其他资源在所有页面中加载,请在*.libraries.yml中添加,并在THEME.info.yml中启用该库。 - 在 Drupal 7 中,库需要通过
hook_library_info()定义。在 Drupal 8 中改为使用*.libraries.yml文件。 - 在 Drupal 8 中,
drupal_add_css()、drupal_add_js()和drupal_add_library()被移除,改为使用#attached
流程
加载 CSS 或 JS 资源的步骤:
- 将 CSS 或 JS 保存到文件中,并遵循 命名和文件结构规范。
- 定义“库 (library)”,在你的主题中注册这些 CSS/JS 文件。
- 将库 附加到所有页面,或仅附加到 特定 Twig 模板,或通过预处理函数的渲染元素针对特定页面。
定义库
在主题文件夹的 *.libraries.yml 文件中定义所有资源库。如果你的主题名为 fluffiness,文件应命名为 fluffiness.libraries.yml。每个“库”是一个条目,列出 CSS 和 JS 文件,例如:
# fluffiness.libraries.yml
cuddly-slider:
version: 1.x
css:
theme:
css/cuddly-slider.css: {}
js:
js/cuddly-slider.js: {}
此示例中,JavaScript 文件 cuddly-slider.js 和 CSS 文件 cuddly-slider.css 分别放在主题的 js 和 css 目录下。
注意:该示例仅展示了一个 CSS 和一个 JS 文件的添加。实际上,在定义库时有更多选项可用,详见 “定义库:参数和细节”。
在库中包含 jQuery
请记住,Drupal 8 默认不会在所有页面加载 jQuery。如果 cuddly-slider 依赖 jQuery,则必须声明对核心 jQuery 库的依赖。核心库通过 core/jquery 提供。依赖声明格式为 扩展名/库名,例如:
# fluffiness.libraries.yml
cuddly-slider:
version: 1.x
css:
theme:
css/cuddly-slider.css: {}
js:
js/cuddly-slider.js: {}
dependencies:
- core/jquery
将库附加到所有页面
大多数主题会有一个全局资源库 global-styling(用于每个页面加载的 CSS 文件),也可以有一个 global-scripts(用于每个页面加载的 JS 文件)。
# fluffiness.libraries.yml
global-styling:
version: 1.x
css:
theme:
css/layout.css: {}
css/style.css: {}
css/colors.css: {}
global-scripts:
version: 1.x
js:
js/navmenu.js: {}
要使其在所有页面可用,需要在主题的 info.yml 文件中声明:
# fluffiness.info.yml name: Fluffiness type: theme description: 'A cuddly theme that offers extra fluffiness.' core: 8.x libraries: - fluffiness/global-styling - fluffiness/global-scripts base theme: classy regions: header: Header content: Content sidebar_first: 'Sidebar first' footer: Footer
通过 Twig 模板附加库
你可以在 Twig 模板文件中使用 attach_library() 附加资源库:
{{ attach_library('fluffiness/cuddly-slider') }}
<div>Some fluffy markup {{ message }}</div>
为部分页面附加库
有时你只希望库在特定页面加载,例如某个区块或某种节点类型。
你可以在主题的 .theme 文件中实现 THEME_preprocess_HOOK() 函数,其中 THEME 替换为你的主题机读名,HOOK 替换为主题 hook 名。例如,为维护页面添加 JS:
function fluffiness_preprocess_maintenance_page(&$variables) {
$variables['#attached']['library'][] = 'fluffiness/cuddly-slider';
}
注意! 在此类情况下,需要声明合适的缓存元数据。例如,为特定路由加载库:
function fluffiness_preprocess_page(&$variables) {
$variables['page']['#cache']['contexts'][] = 'route';
$route = "entity.node.preview";
if (\Drupal::routeMatch()->getRouteName() === $route) {
$variables['#attached']['library'][] = 'fluffiness/node-preview';
}
}