drupal8 Adding stylesheets(css)and JavsScript(js)
更新:HHH   时间:2023-1-7


参考地址:https://www.drupal.org/docs/8/theming-drupal-8/adding-stylesheets-css-and-javascript-js-to-a-drupal-8-theme
In Drupal8,stylesheets(css)and javasctipt(js)are loaded through the same system for modules(code) and themes,for everying:asset libraries.
在drupal8中加载样式和javascript,对于module和theme通过相同的系统,使用一切资产库
Drupal use a high-level principle:assets(css or js)are still only loaded if you tell drupal it should load them.Drupal does not load every assets on every page,because it slows down front-end performance.
drupal使用高层原则:资产(css或js)只有在你告诉drupal的时候才会加载。drupal不会加载所有资源在页面,这样会降低前段性能。

Differences from drupal7

Only css,js that is required on a page will be loaded.jquery ,for example is no longer automatically loaded unless explicity specified in .libraries.yml.if your theme requires jquery or other assets you want to load on all pages,add theme in .libraries.yml.
css,js被需要的时候才加载到页面,例如jquery不在自动加载,除非在。libaries.yml中明确指定。如果您的主题需要jquery或其他资源加载到所有的页面,将它们添加到.libraries.yml.

The process

  1. 保存css或js文件到一个文件中,使用适当的命名约定和文档结构
  2. 定义一个“库”,它可以同时包含css和js文件
  3. “attach”库到所有的页面,到特定的Twig模板,到一个渲染的元素通过预处理函数中。

    Defining a library

    Define all of you asset libraries in a*.libraries.yml file in you theme folder.如果我们的主题名称是fluffiness,则文件名为fluffiness.libraries.yml.在文件中的每个“库”都是一个详细的css和js文件条目,like this:

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

    在这个例子中,cuddly-slider.js文件位于你主题目录下的js目录中。
    记住,drupal8不在默认加载jQuery到所有的页面。因此,如果cuddly-slider需要jQuery,我们必须定义依赖到核心库(Drupal core provides jQuery ,not a module or theme).定义依赖库使用扩展名后面跟斜线/,跟库名,在这个例子里是core/jquery.如果其他的库需要cuddly-slider,它应该定义为fulffiness/cuddly-slider.不能将单独的文件声明为依赖库。
    我们更新上面:

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

    大多数主题将使用一个global-stying资源库,CSS文件被加载到每个页面上当主题处于激活状态。

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

    我们看到media属性可以作为值被定义在css资源声明的结尾。

    Asset loading order 加载顺序

    正如你期望的那样,文件列出的顺序是它们的加载顺序。默认,所有js资源加载在页脚footer中。
    对于重要的UI元素使用了js的,不能被显示,除非相应的js被运行,如果需要可以被加载到页面header中。like this:

    js-header:
    header: true
    js:
    header.js: {}

    设置header属性为true,表示该库中javascript资源位于重要路径中,并且应该从header中加载。

    CSS properties

    以下属性是可选的

属性 说明 示例 补充
browses 基于浏览器加载 {IE: 'lte IE 9','!IE':false}
group 按组进行资源汇总。默认是SMACS组 很少使用 /
media 媒介类型 {media: print}
minified 资源是否已经压缩,默认false {type:external,minified:true} /
preprocess 资源是否聚合,默认true {preprocess: false} /
type 资源来源,默认file {type:external,minified:true} /
weight 调整相对其他资源的顺序(在相同的S'MASC组内),默认0;-50到50之间 {weight:1} /

JS properties

下面属性是可选的

属性 说明 示例
attributes 附加额外属性 {type: external,attributes: {async: true}}
browsers 基于浏览器有条件的加载 {IE: 'lte IE 9','!IE': false}
preprocess 资源是否聚合,默认true {preprocess: true}
type 资源来源,默认 file {type: external,minified: true}
weight 在相同的组内,调整行对其他资源的顺序(setting,library,default,theme) {weigth: 1}

Overriding and extending libraries 覆盖和扩展库

我们必须到.info.yml中来覆盖.libraries.yml中定义的库。我们既可以使用libraries-override覆盖,也可以使用libraries-extend来扩展。我们添加到*。info.yml的覆盖将被子主题继承。
libraries-override
需要使用覆盖时的逻辑:

  1. Use the original module(or core) namespace for the library name.
  2. Use the path of the most recent override as the key.
  3. That path should be the full path to the file.
    Example
    libraries-override:
    contextual/drupal.contextual-links:
    css:
      component:
        /core/themes/stable/css/contextual/contextual.module.css: false

    contexttual/drupal.contextual-links 是核心库的命名空间,同时/core/themes/stable/css/contextual/contextual.module.css是要覆盖核心库的全路径,这里使用false进行覆盖
    这里需要注意的是css: 和 component: 反应了被覆盖库的结构,最后一行是实际文件系统路径。
    这里需要注意的是,当被覆盖的文件结构发生变化,则会破会上面的路径,这里建议使用stream wrappers.
    下面是使用librares-override的一些方式

    libraries-override:
    #替换整个库
    core/drupal.collapse: mytheme/collapse
    #替换一个资源
    subtheme/library:
    css:
      theme:
        css/layout.css: css/my-layout.css
    #替换覆盖stable中的资源
    contextual/drupal.contextual-toolbar:
    css:
      component:
        /core/themes/stable/css/contextual/contextual.toolbar.css: css/contextual/toolbar.css
    #替换一个核心模块的js资源
    toolbar/toolbar:
    js:
      js/views/BodyVisualView.js: js/views/BodyVisualView.js
    #移除一个资源
    drupal/dialog:
    css:
      theme:
        dialog.theme.css: false
    #移除整个库
    core/modernizr: false

    libraries-extend
    这对于中主题中对某些组件进行不同的设计是完美的,同时不会应用到全局css中,即自定义组建外观,而无需在每个页面上加载css

    #扩展drupal.user库,从d8dev的baidu-map库添加资源
    libraries-extend:
    fulffiness/drupal.user:
    - d8dev/baidu-map #主题名|模块名/库名

    Attaching libraries to page(s) 添加库到页面

    我们加载的某些库可能并不是所有页面都需要。为了获得更快的性能,请不要在没有使用库的地方加载它们。以下是如何选择性加载库的示例

    Attaching a library via a Twig templage 通过Twig模板加载库

    attach_library()函数可以在任何*.html.twig使用,如:

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

    Attaching a library to all pages:

    要将库添加到使用主题的所哟页面,请在主题的*.info.yml文件中的libraries关键字生命如下:

    name: Example
    type: theme
    core: 8.x
    libraries:
    - fulffiness/cuddly-slider

    在编辑.info.yml或者.libraries.yml文件后,记得要清除缓存

    Attaching a library to a subset of pages

    在某些情况下,您不需要您的库对所有页面有效,只适用于页面的子集。例如:只显示某个区块时,或在显示某个节点类型时
    主题可以通过在THEMENAME.theme文件(在主题的根目录下)中实现THEME_preprocess_HOOK()函数来实现,使用主题的机器名替换“THEME”,使用主题钩子名称的机器名替换“HOOK”.
    例如,如果你想把JavaScript附件到maintenance page(maintenance-page.html.twig),那么“HOOK”部分就是“maintenance_page”,函数看起来如下:

    <?php
    function fulffiness_preprocess_maintenance_page(&$variables){
    $variables['#attached']['library'][] = 'fulffiness/cuddly-slider';
    }

    你可以为其他主题钩子做类似的事情,当然你的函数也可以有逻辑,比如监测在“block”钩子中预处理那个区块,“node”钩子中处理是那个节点类型。
    重要提示!在这种情况下,您需要指定与您的条件相对应的缓存性元数据!最常见的例子,基于当前路径由附加某个库的情况:

    <?php
    function fulffiness_preprocess_page(&$variables){
    $variables['page']['#cache']['context'][] = 'route';
    if(\Drupal::routeMatch()->getRouteName() === 'entity.node.preview'){
        $variables['#attached']['library'][] = 'fulffiness/mode-preview';
    }
    }

    Attaching configurable JavaScript 添加可配置的js

    在某些情况下,您可能需要将JavsScript添加到依赖于一些计算PHP信息的页面上。
    In this case,create a JavaScript file,define and attach a library just like before,but also attach JavaScript setting and have that JavsScript file read those settings, via drupalSettings. However,to make drupalSettings available to our JavaScript file, we have to do the same works as we had to do make jQuery available:we have to declare a dependency on it.
    这样就变成:

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

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

    这里的‘bar’是一个计算的值(注意清除缓存)
    然后cuddly-slider.js可以访问drupalSettings.fluffiness.cuddlySlider.foo( and it will === 'bar' ):

    (function($,Drupal,drupalSettings){
    'use strict';
    Drupal.hehaviors.mybehaviror = {
        console.log( drupalSettings.fulffiness.cuddlySlider.foo );
    }
    })(jQuery,Drupal,drupalSettings);

    Adding attribrutes to script elements 为script标签添加属性

    Example:

https://maps.googleapis.com/maps/api/js?key=myownapikey&signed_in=true&libraries=drawing&callback=initMap:
  type: external
  attributes:
    defer: true
    async: true
    data-test:map-link

结果为:


<script src="https://maps.googleapis.com/maps/api/js?key=myownapikey&signed_in=true&libraries=drawing&callback=initMap" async defer data-test="map-link"></script>

CDN/externally hosted libraries CDN/外部托管库

你可能希望使用外部CDN上的JavaScript-如网页字体库通常使用URL。这可以通过声明为外部库(type:external)来完成。

angular.angularjs:
  remote: https://github.com/angular
  version: 1.4.4
  license:
    name: MIT
    url: https://github.com/angular/angular.js/blob/master/LICENSE
    gpl-compatible: true
  js:
    https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular.min.js: { type: external, minified: true }

Inline JavaScript

(不推荐使用内联样式,故没有主要测试)

内联JavsScript是非常不鼓励的。建议将内联js放在一个文件中。这样可以缓存js,也可以被删除和检查。

Inline JavsScript that generates markup

你想把它们放在一个自定义的区块或一个Twig模板中
Example:


<script type="text/javascript"><!--
ad_client_id = "some identifier"
ad_width = 160;
ad_height = 90;
//--></script>
<script type="text/javascript" src="http://adserver.com/ad.js"></script>

Inline JavaScript that affects the entire page

Using any inline JavsScript is highly discouraged.

Inline JavaScript that is in integration module 内嵌在集成模块中

Differences with Drupal7

  1. hook_library_info()被替换为*.libraries.yml
  2. 在drupal8中drupal_add_css()、drupal_add_js()、drupal_add_library()被移除,推荐使用#attached

上面是结合本人自己的理解整理的,如有错误请多多指教;其中也有些不甚明了的地方,请给予指正。

返回web开发教程...