淘小兔

在Drupal8中,CSS和JS通过加载模块和主题的系统加载,组件库(asset libraries)。

Drupal用一个高级的原则:CSS/JS 只有在你告知Drupal加载时才被加载。Drupal不会在所有页面加载全部的CSS/JS,因为这样不利于前端性能。

与Drupal 7的不同

主要4点:

  1. 不再有THEME.info 文件,但是有包含相同内容的THEME.info.yml 文件
  2. Stylessheets属性不再存在于THEME.info.yml文件,因为现在只使用库了(stylesheets-override 和 stylesheets-remove 依然存在并和原来一样工作)
  3. Scripts 属性也不存在于THEME.info.yml文件,因为现在只使用库了
  4. 只有页面需要的JS会被加入到该页面。 因为,Drupal默认不需要给不登陆的用户分享大部分JS。这意味着jQuery不会自动被所有页面加载(link is external)
  5. jQuery或其他JS(已经在组件库中定义了),你需要用“在需要的组件库声明需求”的方式告诉Drupal。

过程

通常步骤:

  1. 保存CSS/JS文件
  2. 定义一个包含CSS和JS文件的库
  3. 将这个库附到钩子函数中一个呈递的数组中

但是,在主题中,第三部有另一个方法,主题可以选择加载任意数量的组件库在所有的页面中

定义库

要定义一个库,往主题文件夹中加入 *.libraries.yml 文件。(如果你的主题名是fluffiness, 那么文件名应该是fluffiness.libraries.yml)每个库都是包含CSS/JS详细信息的一个目录,例如:

cuddly-slider:  version: 1.x  css:    theme:      css/cuddly-slider.css: {}  js:    js/cuddly-slider.js: {}

但是,记住Drupal8不再默认对所有页面加载jQuery,只是在需要的时候加载。 因此,我们必须声明我们主题的cuddly-slider库声明了对包含jQuery的库的需求。这不是一个模块或主题分享jQuery,而是 Drupal的核心core/jQuery是我们需要声明的需求。(这是一个跟着/和库名的扩展命名,所以,如果有其他库想依赖我们cuddly- slider这个库,它必须要声明对fluffiness/cuddly-slider的需求。因为fluffiness是我们的主题名)这个例子中,假设JS (cuddly-slider.js)是位于你主题的js子文件夹中。你也可以从外部链接引入JS, CSS 和其他可能。详细信息在https://www.drupal.org/node/2274843(link is external) 或 https://www.drupal.org/node/2201089(link is external) 

所以,要确保jQuery在js/cuddly-slider.js中可用,我们需要更新代码:

cuddly-slider:  version: 1.x  css:    theme:      css/cuddly-slider.css: {}  js:    js/cuddly-slider.js: {}  dependencies:    - core/jquery

当然,一个库可以只包含CSS组件,或JS组件。绝大多数主题都会想要一个global-styling组件库,为了需要被全范围加载的CSS (比如,应用主题的所有页 – 通常是整个站点,出了管理员页面):

global-styling:  version: 1.x  css:    theme:      css/layout.css: {}      css/style.css: {}      css/colors.css: {}      css/print.css: { media: print }

当然,如你所期望,CSS在这里的顺序也是它们被加载的顺序

在Drupal 7中,你需要指出媒体属性(screen,print,all)作为stylesheets属性的子键值,现在,对任意CSS组件,你可以把它定义成一个值,例如:

css/print.css: { media: print }

给页面附加库

根据你需要加载的组件,你会想用不同的方式附加相关的组件库。毕竟,一些组件库所有页面都需要,一些只被少数需要,还有一些被大多数但不是全部需要。

附加到所有页面

要为所有使用你主题的页面附加库,需要在你主题的*.info.yml文件中声明它,在libraires键值的下面:

name: Exampletype: themecore: 8.xlibraries:  - fluffiness/cuddly-slider

你想列多少库就可以列多少库,它们都会在每一页被加载。

然后,清除缓存让Drupal加载新信息

为一个子集的页面附加库

在一些情况下,你不需要你的库被所有页面加载,而是只需要一部分(子集)页面加载。例如,你可以只需要你的库在某个特定区块(block)出现时或者某个特定节点类型显示时被激活。

一个主题可以通过在.theme文件中置入THEME_preprocess_HOOK()函数实现。需要用你的主题的机器名替换THEME和主题的钩子函数的机器名替换HOOK。

例如,如果你想给维护页附加JS,钩子部分就是maintenance_page,你的函数应该是这样:

<?phpfunction fluffiness_preprocess_maintenance_page(&$variables) {  $variables['#attached']['library'][] = 'fluffiness/cuddly-slider';}?>

你可以对其他主题的钩子做类似的事情,当然,你的函数也可以包含逻辑部分,例如,检测哪个区块被区块钩子预处理了,哪个节点类型被节点类型预处理了,等等。

在twig模板中附加库

你可以在twig模板中附加一个库,使用的是attach_library() 这个twig函数。

所以,在任何*.html.twig中:

{{ attach_library('fluffiness/cuddly-slider') }}<div>Some fluffy markup {{ message }}</div>

附加可设置的JS

在某些情况下,你可能希望根据一些PHP的计算信息来附加JS到页面上。

这 时,建立一个JS文件,像以前一样定义并附加一个库,但是也要附上JS设置并通过drupalSettings(Drupal 7的Drupal.settings的继承者)让JS读取这些设置。不过,要想让drupalSettings对我们的JS可用,我们需要做让 jQuery可用的同样工作:我们需要声明需求。

所以就变成了:

cuddly-slider:  version: 1.x  js:    js/cuddly-slider.js: {}  dependencies:    - core/jquery    - core/drupalSettings

<?phpfunction fluffiness_page_attachments_alter(&$page) {  $page['#attached']['library'][] = 'fluffiness/cuddly-slider';  $page['#attached']['drupalSettings']['fluffiness']['cuddlySlider']['foo'] = 'bar';}?>

“bar”是一些计算的值。

这样,cuddl-slider.js就可以访问drupalSettings.fluffiness.cuddlySlider.foo了,并===’bar’

内置JS

不鼓励内置JS,建议把需要内置的JS存到一个文件里,因为这样可以在客户端缓存JS,也可以审查JS。

内置生成附加物的JS

例如广告,社交媒体分享按钮,社交媒体插件。这些会用到内置JS。但是他们只是一类特定的内容/附加物,因为它们不装饰站点内容或让内容产生交互,而是用过JS从外部输入内容。

你需要这些或在一个自定义的区块中,或直接在Twig模板中。

例如:

<script type="text/javascript"><!--ad_client_id = "some identifier"ad_width = 160;ad_height = 90;//--></script><script type="text/javascript" src="/images/2021/07/19/03/2021071903512015330000.js"></script> <a class="twitter-timeline" href="https://twitter.com/wimleers" data-widget-id="307116909013368833">Tweets by @wimleers</a><script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+"://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>

影响整个页面的内置JS

例如: 分析插件,和分享的字体服务。影响整个页面的内置JS可以分为两种,前端设计或逻辑性的。

前端设计的情况下,JS属于主题。把JS直接放置到html.html.twig文件中。在字体的情况下,也允许将KS放置到对的地方会给你最好的终端用户体验,因为它允许你防止字体加载中的FOUT(未设计字体的闪现)

(更多内容在此:“Async Typekit & the Micro-FOUT”(link is external)

其他情况,JS属于模块,请看“Adding stylesheets (CSS) and JavaScript (JS) to a Drupal 8 module”(link is external)

Drupal 7的不同

  • 在Drupal 7中,库需要用hook_library_info()定义,这被*.libraries.yml文件取代。
  • 在Drupal 8中,drupal_add_css(), drupal_add_js(), 和drupal_add_library()被去除以支持#attached

 

原文链接:https://www.drupal.org/theme-guide/8/assets(link is external) 

下载仅供下载体验和测试学习,不得商用和正当使用。

下载体验

请输入密码查看内容!

如何获取密码?

 

点击下载