欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

宁皓网 Drupal 8:主题 有大用

Drupal 8 主题的开发。

仓库:https://github.com/ninghao/drupal-8-dev-theme-demo
分支:一开始用 theme-start 分支,以后的代码在 theme-finish 这个分支上

1)Drupal 主题

了解 Drupal 主题最好的地方就去查看一下 Drupal 默认使用的主题 .. 先打开 Appearance .. 在这里你可以设置 Drupal 的前台还有后台使用的主题 ..

默认的前台主题就是这个 Bartik .. 后台主题是 Seven ..

打开这个前台主题的 Settings ... 可以设置一下这个主题的一些显示 .. 再回到编辑器 ... 核心自带的主题是在 core .. themes 这个目录的下面 .. bartik 就是默认的前台主题 .

每个主题都会放在各自的目录的下面 .. Drupal 会寻找主题目录下的这个 .info.yml 文件 .. 它里面描述了这个主题,比如主题的名字 .. 类型 ... base theme 表示它使用的基础主题 ..

也就是一个主题可以基于另一个主题来设计.. 这个 classy 也是核心自带的一个主题,我们自己创建的主题也可以基于这个主题来创建 ..

libraries 里面描述了使用的资源库 .. 这个 .libraries.yml 文件里面定义的就是主题使用的资源库 .. 宁皓网有课程专门介绍了这个资源库的使用 ..

每个资源库里都可以描述一下它使用的 css,js,还有它依赖的一些东西 ..

regions 下面定义的是主题里使用的区域 ... 我们可以把一些区块放到主题里面定义的区域上来显示 ..

你需要在主题的模板文件里去主设置让这些区域在哪里显示 ..

主题的模板文件可以放在 templates 目录的下面 .. 页面上不同部分的显示会由各自的模板文件来控制 .. 一般模块都会提供自己要使用的模板文件,如果你想覆盖模块自己的模板文件,你可以把这些模板文件复制一份,然后放到这个 templates 目录的下面 .. 再去按自己的需求去修改它们就行了 ..

先打开 page.html.twig 这个模板文件看一下 .. 它是页面默认使用的整体的模板文件 .. 这里你会看到一些 page. 开头的东西,它们就是在这里要显示的区域 ... 这些区域的名字就是在 .info.yml 里面定义好的 ..

如果你想在主题里去实施一些 Drupal 提供的 API .. 可以把它们放到 .theme 这个文件里 ..

2)打开主题调试功能

Drupal 页面的显示会受到一些模板文件的控制,在不同的地方可能会用到不同的模板文件,如果你需要修改某个地方的显示,你需要找到这个模板文件,复制一份,把它放到自己的主题目录的templates下面 .. 这些模板文件需要使用一种特定的命名规则 ..

知道什么地方用了哪个模板文件,我们可以打开一个调试功能 .. 在 drupal 目录下面的 sites/default 这个目录的里面,有一个 default.services.yml ... 我们需要复制一份这个文件 ...

这里我先去修改一个权限 ... 回到终端 .. 我的位置是在 sites 这个目录的下面 .. 注意它里面的 default 这个目录现在没有写入权限 ... 用一下 chmod 给目录的拥有者添加一个写入的权限 .. 有了写入权限以后,再回到编辑器 ..

复制一份这个 default.services.yml 文件 ... 名字是 services.yml ..

再用编辑器打开这个文件 .. 在 twig.config 这个区域的下面,找到 debug ... 现在它是 false ,我们把它修改成 true . 这样就会打开 twig 的调试功能 ..

再去清空一下 Drupal 的缓存 ... 配置 ... 性能 ... 清空所有的缓存 ...

再回到前台页面 .. 现在网站用的是 Drupal 的默认的主题 .. 打开浏览器的开发者工具 .. Elements ..

点一下这个选择元素工具 .. 选择你想要了解的地方 ... 比如选中这个搜索区块 .. 打开了调试功能以后,会在源代码这里显示一些注释 .. 这些注释可以帮助我们理解这个地方跟主题相关的一些信息 ..

3)理解模板文件

这个搜索区块,它的 Theme Hook 是 block ,说明这个地方是 Drupal 的一个区块 .. File Name Suggestions 下面会列出一些可能的模板文件的名字 ..

也就是如果你想修改这个搜索框的模板,你可以使用这里列出的这些名字作为这个模板文件的名字 .. 最上面的这个名字应该是最具体的 .. block 是区块,bartik search 表示的应该是这个具体的搜索区块的机器名 .. bartik 是我们当前使用的这个主题的名字 ..

下面的这个名字的前面是个小差号 .. 说明这是当前使用的这个地方的模板文件 .. 这个建议的模板文件名字列表,越往下就越广泛一些 .. 比如最后的这个 block.html.twig .. 它应该是所有的区块使用的模板文件 ... 这个模板文件一般就是模块本身提供的.. 这里应该就是 block 这个模块提供的模板文件 ..

最上面的这个 block--bartik-search.html.twig ,这个模板文件会是单独为这个特定的区块准备的 ... 也就是最上面的模板文件的名字是最具体的,在我们的主题里使用这个文件,不会影响其它的区块的显示 .. 最底下的这个模板文件的名字是最广泛的 .. 使用并且修改它应该会影响到其它的同类 ... 这里就是其它的 block 的显示 ...

这个要 Begin output ,会告诉你这块输出具体使用的模板文件的位置 .. 下面的 End Output ,意思就是这个模板文件输出的内容到这里就结束了 ..

回到编辑器 .. 现在你知道了自己要修改的模板文件,我们可以直接搜索一下它 ... command + p ... 输入文件名字的关键词 ..

这里给我们找到了两个 block--search-form 这个模板文件,一个是 bartik 主题的 ... 一个是 classy 主题的 ...

先打开上面这个 .. 这里的代码就是 bartik 这个主题为搜索区块准备的一个模板文件 ..

注意这个模板文件的上面还用了一个 extends ,表示继承 ... 它继承了 classy 主题的这个模板文件 ... 再去搜索一下 ... 找到 classy 主题下面的 block--search-form 这个模板文件 ...

这里的代码控制了刚才我们在浏览器上看到的那个搜索区块的显示 .. 我们可以做个小实验.. 去掉这组 h2 标签 ...

回到 Drupal ... 配置 .. 性能 ... 清空一下缓存 ..

再回到这个前台页面 .. 注意这个搜索区块的标题 ... 刷新一下 ... 你会发现刚才显示在这里的标题就不见了 ... 因为我们修改了影响这个区块显示的模板文件 ..

不过一般我们不能直接去修改模板文件 ... 特别是 Drupal 的核心自带的东西 ... 我们需要复制要修改的模板文件,然后把它们放在自己的主题目录的下面 ...

4)自定义主题

我们自己设计的主题可以放在 themes 这个目录的下面 ... 回到终端 .. 进入到 themes 这个目录的下面 ...先去克隆一个小仓库 ...

分支是 theme-start ... 仓库是 github 上的 ninghao,名字是 drupal-8-dev-theme-demo .. 放到 ninghao 这个目录的下面 ..

git clone -b theme-start git@github.com:ninghao/drupal-8-dev-theme-demo ninghao

现在 themes 下面会有一个 ninghao,它现在是一个基本的主题 ... 定义了几个区域 ... 使用了几个资源库 ..

这些资源库是在 libraries 里面定义的 .. 回到 Drupal 网站 ... 打开 Appearance .. 找到 ninghao 这个主题 ...

install and set as default .. 安装并设置为默认 ..

回到前台页面 ... 现在你看到的就是这个主题的样子 .. 再打开 Configuration .. 找到 Performance ...

去掉 Aggregate CSS files ... 还有 Aggregate JavaScript files ... 去掉它们以后 Drupal 就不会再合并压缩 css 还有 js 文件了 ... 再保存一下配置 ..

然后回到前台页面 ...

5)禁用缓存

在开发的时候我们可以暂时禁用掉 Drupal 的缓存,这样就不需要每次有点修改就去重建一下 Drupal 的缓存了 ... 在 drupal 的 sites 目录下有个 example.settings.local.php .. 复制一下这个文件 ... 把它放到 sites/default/ 这个目录的下面 .. 重命名为 settings.local.php ..

如果你看到 Permission denied ... 这是因为 default 这个目录没有写入的权限 .. 我们暂时行给这个目录的拥有者添加一个写入权限 ...

然后重新再执行一下这个复制 ..

回到编辑器 .. 先打开 sites/default .. settings.php ... 浏览到文件的底部 .. 取消这个 include 注释 ... 这样 drupal 就会加载 settings.local.php 这个配置文件里,在这个文件里我们可以去做一些自定义的设置 ..

打开这个文件 .. 搜索一下 container ...

这行代码会帮助我们启用本地的开发服务 .. 在 sites 目录的下面,找到这个 development.services.yml ... 在这个文件里定义了一个 null cache ... 也就是一个假的缓存 ...

再回到这个文件 .. 搜索一下 cache ... 取消这行代码的注释 ... 这样会禁用掉 drupal 的 render 缓存 ...

再取消注释这行代码 ... 它会禁用掉 drupal 的 dynamic page cache ...

再看一下这个文件 ... 这里有个开启或禁用 css ,js 合并压缩的功能 .. FALSE 表示不使用合并压缩 ... 设置成 TRUE 就表示要去压缩还有合并 css,js 文件 ...

然后我们再打开 default 目录下的 services.yml ... 搜索一下 twig.config ... 之前我们已经打开了调试的功能 ..

再把这个 auto_reload 设置成 true .. 然后把下面的 cache 设置成 false ... 表示不使用缓存 ..

现在我们再对模块或者主题的修改,在预览的时候,就不需要先去重建 Drupal 的缓存了 ...

Twig
6)模板文件覆盖

现在我想修改一下整个页面的布局 ... 先查看一下页面元素 ... 浏览一下 ... 你会发现这个带 layout-container 类的元素就是整个页面的包装 ... 在它的上面会显示这块内容是哪个模板文件输出的 .. 这里就是 classy 主题下面的 page.html.twig 这个模板文件,因为我的主题使用了这个主题作为一个基主题,所以默认会使用这个基主题下面的模板文件 ..

回到编辑器,搜索一下 page.html.twig .. 找到 classy 下面的 page 模板 ...

你会发现,这里有一个带 layout-container 类的包装 .. 如果你想修改这个模板,可以复制一份,把它放到我们自己的主题的下面 .. 或者我们也可以直接去创建一个新的 page 模板 ..

先找到我们自己的主题 .. 在它的下面新建一个目录,名字是 templates ,在这个目录的下面,创建一个 page.html.twig 文件 ..

重建一下 Drupal 的缓存 ...

回到前台页面,刷新一下 ... 现在页面上就不会显示内容了 .. 也就是 Drupal 现在会使用我们自己创建的页面模板 ...

7)输出内容

现在这里显示的是一个空白的页面 ... 这是因为在我的主题里,page 模板里面没有任何的内容 ... 在这个模板文件里,我们再去添加点东西 ... 添加一个包装 .. 加上 ui container 这两个 css 类 ..

在这个包装里我们可以输出点东西 .. 要输出的东西可以放到两组大括号 .. 这是 twig 模块引擎使用的输出内容的形式 ... 比如我要输出页面的 content 这个区域 ... page.content ..

这个 content 是我在主题的 info.yml 文件里定义的一个区域的名字 ... 用户在管理界面上可以把指定的区块放到这个区域上显示 .. 如果放在 content 这个区域上显示,那么要显示的内容就会出现在这个带 ui container 类的包装里面 ..

回到前台的页面 ... 刷新一下 ... 现在页面上会显示在 content 区域上要显示的内容 ...

回到这个 page 模板 ... 再添加一个要输出的东西 ... 这回我们输出 header 这个区域上的内容 ... 这个区域也是我在 info.yml 文件里定义的 ..

回到前台 .. 刷新 ... 这里又会出现一些东西 ... 它们就是在 header 这个区域上要显示的一些区块 ...

再打开后台的管理界面 .. Structure ... 找到 Block layout ... 在这里可以管理要显示的区块 ..

你会发现,在 header 这个区域的上面,有一些要显示的区块 .. 我们可以去掉一些要显示的区块 ... 只留下这个 Site branding 区块 ...

保存一下 ... 回到前台页面 ... 刷新 .. 现在这里就剩下这个标志了 ... 在这个标志的下面会有一个网站的名字 .. 再回到区块 .. 配置一下 Site branding 区块 .. 去掉 Site name ... 网站的名字 ... 还有 Site slogan ... 网站的标语 ..

保存 ...

再去预览一下 .. 现在页面上的在 header 区域上的 Site branding 区块就只会显示网站的标志了 ...

8)设置,输出,调试变量

在 twig 模板里面,要执行一段代码可以使用这样的形式 .. 一个大括号 .. 里面加上一个百分号 ... 结束的地方是一个百分号 .. 再关上这个大括号 ...

设置一个变量可以用 set ... string 等于 hello .. string 是一个变量,它的值是 hello ... 打算输出这个变量,可以使用两组大括号 ... 里面加上变量的名字 ...

回到前台页面 ... 在页面上会显示一个 hello ... 它就是我们在模板里面设置的 string 这个变量的值 ...

有时候我们需要检查变量里的东西 ... 可以用 dump 这个函数 ..

两组大括号 ... 输出 dump 检查的结果 .. 可以看一下上面设置的 string 这个变量 .. 这里会告诉我们 string 变量里的内容 ... 就是一个简单的字符串 ..

在输出 dump 结果的周围可以加上一组 pre 标签 ... 这样输出的内容会保留里面的格式 ...

在不同的模板文件里,我们可以使用 Drupal ... 或者 Drupal 的模块提供的一些变量 .. 可以先打开核心自己的 classy 主题里的 page.html.twig 这个模板文件 ..

在它的注释里 ... 会告诉我们一些可以使用的变量 .. 比如 logged_in ... 它可以判断当前的用户是不是已经登录了 .. 回到我们自己的模板文件 ... 把 logged_in 的值 dump 到屏幕上看一下 ...

这里显示的是 true ... 说明当前访问这个页面的用户已经登录了 ...

这个 is_admin ... 可以判断用户是不是管理员 ... 我们把它的值也输出到屏幕上检查一下 ...

结果是 false ... 意思就是当前登录的用户并不是网站的管理员 ..

再打开一个用管理员身份登录的页面 ... 这里显示的 is_admin 的值是 true ... 说明当前登录的用户是管理员 ..

9)控制流

现在我要判断一些条件以后再输出一些内容 .. 可以使用 twig 里的条件控制 .. 大括号 .. 百分号 .. 里面用一个 if ... 判断一下 is_admin ... 看看是不是管理员 ..

结束的地方用一下 endif ... 它也要在一组大括号百分号里面 ...

它们中间这块就是在要判断的条件是真的时候要输出的东西 ... 一个包装 ... 加上几个 css 类 ... 输出的内容是上面定义的 string 这个变量的值 ...

回到前台页面 .. 现在登录的这个用户是管理员 .. 所以会显示这个 hello ... 再打开一个使用不是管理员身份登录的页面 ... 在这个页面上,并不会显示那个 hello ..

再去试一下循环 ... 先设置一个变量 .. 名字是 users ... 它的值是一个数组 ... 里面有两个用户 ...

大括号,百分号 ... 用一个 for 循环 ... user in users ... 结束的地方用一下 endfor .. 中间是每次迭代的时候要做的事情 ... 我们可以输出这个 user ...

回到前台再去预览一下 ... 在这里会显示我们设置的那个数组里的每个项目 ...

10)twig 的过滤器

Twig 里面的 Filters,也就是过滤器 .. 一般我们可以使用它们可以去修改变量 ... twig 模板引擎本身定义了一些可以使用的过滤器,你可以在 twig 的官方网站找到它们
( https://twig.sensiolabs.org/doc/2.x/filters/index.html )
.. 一般过滤器的名字就解释了它到底可以做什么 ..另外 Drupal 也给我们提供了一些专门的过滤器 ...

先看一个 Twig 本身提供的过滤器 .. 在这个模板文件里有一组数组 ... 就是这个 users ... 我现在想输出一个 json 格式的数据 .. 两组花括号 .. 里面加上 users 这个变量 .. 后面是一个竖线 ... 然后是要使用的过滤器的名字,这里我需要的是 json_encode ...

回到前台 ... 这里给我们输出的就是一个 json 格式的数据 ..

现在我想合并这个数组 ... 可以用一下 join 这个过滤器 .. 有些过滤器支持一些参数,比如这个 join ,可以给它提供一个分隔符 ... 用一下逗号 .. 再回到前台 ...

输出的就是合并了 users 里面的项目之后的结果 ... 每个项目的中间用了一个逗号分隔了一下 ..

再看一下 Drupal 提供的过滤器 .. 添加一个按钮 ... 加上两个 css 类 ... 这个按钮上的文字我想可以在不同语言的下面使用不同的版本 .. 两组大括号 .. 文字是 Submit .. 表示提交 ... 后面应用一个 t 过滤器 ... 它表示这个字符串可以被翻译 ..

回到前台 ... 现在我的界面上的语言是英文,按钮上显示的文字是 submit .. 配置 ... 语言 ... 把我之前添加的中文简体设置成网站默认的语言 ... 保存一下 ..

再回到前台页面 ... 现在这个按钮上显示的文字会是中文的 提交 ... 因为我的网站里已经包含了 Submit 这个字符串的中文翻译 ... 所以切换成中文以后,就会自动使用这个中文翻译 ... 如果这个字符串没有中文翻译,你可以在网站的翻译界面上去手工的翻译一下这个英文的字符串 ...

11)twig 模板里的函数

twig 模板引擎里定义了一些函数,比如之前我们用过 dump 这个函数 ... 再用一下它 ... 把当前登录的用户 dump 到屏幕上检查一下 ... 周围用一组 pre 标签 .

页面上显示的就是 user 里的内容 ...

Drupal 也提供了一些可以在 twig 模板里使用的函数 .. 比如 path,可以根据提供给它的路由的名字还有参数给我们生成一个相对的地址 ...

添加一个链接 .. 链接的地址用一下 path 这个函数 .. 路由的名字是 entity.user.canonical[kəˈnɑ:nɪkl]... 参数是 user 的 user.id ...

链接上的文字是 Profile .. 让这个字符串可以被翻译 ...

<a href="{{ path('entity.user.canonical',{'user': user.id} ) }}" class="ui button">
    {{ 'Profile'|t }}
</a>

回到前台 .. 页面上会显示一个链接 ... 点一下它 ... 可以打开当前登录的用户的个人档案页面 ...

再去添加一个链接 ... 复制一下 ... 路由的名字是 entity.user.edit_form ... 生成的这个链接可以编辑当前登录用户...
 

<a href="{{ path('entity.user.edit_form',{'user': user.id} ) }}" class="ui button">
    {{ 'Edit'|t }}
</a>

再去预览一下 ... 点一下 Edit ... 打开的就是编辑我的个人档案的页面 ...

12)预处理

在 Drupal 要把输出的内容交给模板显示之前,我们有机会再处理一下这些数据,可以通过一些预处理的钩子函数 ... 一般这些函数的名字里都有一个 preprocess ... 具体要使用哪些 preprocess ,要看你想要修改的东西 ... 可以在 Drupal 的 api 网站上去搜索一下...

https://api.drupal.org/api/drupal

这些东西我们可以放在主题的 theme 文件里 ... 找到我们自己的主题 ... 创建一个文件,名字是 ninghao.theme .. ninghao 是我的主题的名字 ..

添加一个 php 的开始标记 ... 比如我想在页面的 body 标记上添加一个自定义的 css 类 .. 这里用一下 preprocess_html ... 定义一个函数 ... 先加上主题的名字 ... 后面是 preprocess_html ..

它接收一个引用传递的 variables 参数 .. 它里面会有很多东西,你可以在里面找到自己需要的东西,再去修改一下 .. 这里我们一般会借助两个模块 ... 先去安装一下它们 ... 下载一下 devel 这个模块 ...
drush dl devel --select .
 

Choose one of the available releases for devel:
 [0]  :  Cancel
 [1]  :  8.x-1.x-dev  -  2017-Apr-10  -  Development
 [2]  :  8.x-1.0-rc1  -  2017-Jan-19  -  Supported, Recommended

然后选择 1


.. 下载比较新的开发版 ..

它里面会包含几个模块 ... 我们要启动一下 devel 模块,还有 kint 这个模块 ..

drush en devel kint

The following extensions will be enabled: devel, kint
Do you really want to continue? (y/n): y
 
 

启动以后,会提示我们 kint 模块有一个 access kint 权限,也就是你想让普通用户看到 kint 的调试信息,你需要给它们设置一下这个权限 ..

People ... Permissions .. 搜索一下 kint ... 我为登录的用户分配一下可以访问 kint 的权限 ... 保存一下 ..

回到模板的 theme 文件 ... 用一下kint ... 去输出 variables 里的东西 ...
 


function ninghao_preprocess_html(&$variables){ 
  kint($variables);  
  //$variables['attributes']['class'][]='dark'; 
}

到前台去预览一下 ... 如果看不到输出的调试信息 ... 可以再去重建一下 Drupal 的缓存 .. 再回过来 .. 刷新 ..

这里输出的就是使用 kint 输出的调试信息 ... 现在你就可以一层一层的去检查输出到屏幕上的变量里的值了 ... 再回到这个 theme 文件 ... 我要添加一个 css 类 ... 可以这样 ..

$variables['attributes']['class'][] = 'dark';

再到前台看一下 ... 检查一下页面元素 ... 找到 body 这个元素 ... 你会看到它上面会有一个我们在主题里使用的预处理函数,添加的一个 css 类 .. 就是这个 dark ...

来自  https://ninghao.net/course/4397

普通分类: