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

这里的技术是共享的

You are here

宁皓网 Drupal 8 开发:区块

学一下 Drupal 8 的区块接口,在我们的模块里使用代码来创建区块,顺便了解一下 Drupal 8 的插件。

代码仓库:https://github.com/ninghao/drupal-8-dev-module-demo
 

创建区块
1)创建区块

Block 是区块,我们可以把它放在主题里定义的某个区域上显示内容 .. 在 Drupal 8 里面,Block 可以作为一种插件,在我们的自定义模块里面可以包含一些使用代码定义好的区块。

先找到我们自己创建的这个模块,在它的 src 目录下面创建一个新的目录,名字是 Plugin ,我们可以把模块提供的一些插件放到这个目录的下面,在它的下面再创建一个 Block 目录,这里可以存储区块 .. 每个区块单独放在一个类里面,比如创建一个 NinghaoDemoBlock.php ..

这个文件的名字就是在这个文件里定义的类的名字 .. 创建它的目录结构也要使用这样的形式,也就是 src/Plugin/Block ..

添加一个 php 的开始标记 .. 再用一个 namespace 定义一个命名空间 .. 我这里就是 Drupal\ninghao_demo\Plugin\Block;

区块的类需要继承 Drupal 的 BlockBase .. 这个类实施了 BlockPluginInterface 这个接口 .. 我们先去使用一下这个 BlockBase .. use Drupal\Core\Block\BlockBase;

下面再给这个区块添加一块注释 .. Drupal 会用到这个注释里面的内容来理解这个区块 .. 先输入一个 Provides a 'Demo' Block

中间空一行 .. 再用一个 @Block .. 在括号里面需要再输入一些跟这个区块相关的东西 .. 先是 id .. 它的值就是这个区块的 id 号 .. 逗号分隔一下 .. 另起一行 .. 再输入一个 admin_label .. 它的值是这个区块的管理标题 .. 先用一个 @Translation .. 告诉 Drupal 它里面的字符可以被翻译成多个语言的版本 ..

最后再添加一个 category .. 设置一下这个区块的分类 ... Custom 表示自定义 .. 这个字符也是可被翻译的字符 ..

下面我们再去定义这个区块类 ... 名字是 NinghaoDemoBlock .. 让它继承 BlockBase .. 因为这个 BlockBase 类实施了 BlockPluginInterface 这个接口,所以在这个类里面,我们需要提供 BlockPluginInterface 里面的方法 ..

添加一个公开的方法 .. 名字是 build .. 它可以返回区块的内容 .. 这里直接使用一个可被显示的数组 .. 里面添加一个 #markup 属性 .. 它的值是一个用 t 函数处理的字符串 ..

现在我们就在自己创建的模块里面添加了一个区块插件 .. 这个区块上的内容就是这个 hello ..

保存一下 ... 再去重建一下 Drupal 的缓存 ...

2)显示区块

下面我们去使用一下自己定义好的这个区块 .. 回到 Drupal 的管理界面 .. 打开 结构 .. 区块 .. 这里显示的就是在主题上定义好的一些区域,还有在这些区域上面显示的区块 ..

注意这里有个标签,可以切换不同的主题 .. 现在我用的就是 Drupal 默认的主题 .. 如果你不确定这些区域在主题的什么地方,可以点一下这个 演示区域 ..

这样会直接在前台页面上显示这些区域在页面上的位置 .. 比如我想把自己创建的区块放在 Footer first 这个位置上 .. 找到这个区域 .. 点一下 放置区块 ..

在这个可用的区块列表里面,你可以找到我们自己创建的 Demo 这个区块 .. 点一下放置区块 .. 去掉 显示标题 .. 再保存一下 ..

现在这个 footer first 区域上面会有一个叫 Demo 的区块 ..

再点一下保存 ..

回到前台页面 .. 在这个主题的 footer first 区域上,会显示我们自己在模块里用代码定义的一个区块 ...

3)区块配置

在区块里面可以包含一些配置的选项,也就是我们可以为在模块里定义的区块添加一个配置用的表单,用户可以使用这个配置表单,它们在上面填写的数据,我们可以在区块里用到。

比如我们页面上显示的这个 hello 就是我们自己创建的一个区块,下面我们给这个区块添加一个文本框,让用户可以配置一下区块,在上面输入文字 .. 然后我们可以根据用户输入的内容去显示这个区块 ..

打开这个区块的文件 .. 先在这个类里面,用一下 Drupal\Core\Form\FormStateInterface .. 这样在类里面的其它地方,我们就可以直接使用这个类的名字了 .. 不需要指定它的这个具体的位置 ..

然后在这个类里面,再添加一个方法 .. 名字是 defaultConfigguration .. 它可以返回配置选项的一些默认的值 .. 是一个数组 .. 比如我们一会儿要添加一个叫 name 的配置选项 .. 先把它的值设置成一个空白 ..

再去添加一个方法 ... 名字是 blockForm .. 在这个方法里可以去创建配置用的表单 .. 方法支持一个 $form 参数 .. 还有一个 $form_state .. 它属于 FormStateInterface ..

给这个表单添加一个元素 .. 名字可以是 name .. 再配置一下它 .. 这个表单元素的类型是 textfield .. 文本框 .. 再设置一下它的标签 .. 用一个 #title .. 标签上的文字是 姓名 .. 再给这个字段添加一个默认的值 .. 它的值可以使用 $this->configuration .. 配置选项的名字是 name ..

配置好以后返回这个 $form ..

4)保存与使用区块的配置

下面我们可以再用一个方法去处理一下表单的提交 .. 方法的名字是 blockSubmit .. 里面有一个 $form 参数 .. 还有一个 $form_state ...

提交表单的时候,我们可以把用户在 name 这个表单元素里填写的内容保存到名字是 name 的这个配置选项里面 .. $this->configuration['name'] .. 去设置一下它的值 .. 用户填写的内容可以在 $form_state 里面得到 .. 用一下它的 getValue 方法 .. 去得到 name 这个元素的值 ..

我们可以在区块里面,用一下这个配置选项里的内容 .. 找到 build 这个方法 .. 在这个 hello 后面 .. 添加一个 @name .. 然后在这个 t 方法的第二个参数里面,设置一下这个 @name 表示的东西 .. 它的值是一个数组 .. 添加一个 @name .. 对应的值就是名字是 name 的这个配置选项 ...

保存一下 ... 再去重建一下 Drupal 的缓存 .. 回到 Drupal .. 打开 结构 .. 区块 .. 找到我们自定义的这个 demo 区块 .. 配置一下它 .. 你会看到,现在这个区块的配置界面上会显示我们给它添加的这个姓名文本框 ..

输入姓名 .. 再保存一下 .. 这样这个字段的值会放到 name 这个配置选项里保存 .. 回到 Drupal 的前台页面 .. 现在你会发现,这个区块里面,会包含用户在这个区块的配置表单里填写的东西 ...

再回到这个区块的配置界面 .. 找到 Footer second 这个区域 .. 放置区块 .. 搜索一下 demo 这个区块 .. 再输入一个姓名 .. 比如 小雪 ..

保存区块 .. 回到前台页面 .. 刷新一下 .. 现在这个 Footer first 还有 Footer second 区域上显示的都是我们自己定义的 demo 这个区块 .. 不过这两个区块里面使用的配置是不一样的 ..

权限
5)权限

在区块的配置界面,我们可以配置一下这个区块在哪里可以显示 .. 或者在什么页面上隐藏它 .. 使用代码我们也可以去设置区块的显示或者隐藏 ..

这里我们可以先打开核心里的 BlockBase 这个类去看一下 .. 在 core .. lib.. Drupal .. Core 这个目录的下面,找到 Block .. 打开它下面的 BlockBase.php .. 在这个文件里定义的类就是我们在自己的区块类里继承的那个类 ..

这里有一个 blockAccess 方法,它的作用就是判断区块是不是要显示 .. 默认它使用了 AccessResult 的 allowed 方法,意思就是允许显示区块 ..

这个 AccessResult 可以返回检查权限的结果 .. 我们可以去看一下它 .. 在这个类的上面可以看到这个 AccessResult 的位置 .. 在 core .. lib .. Drupal .. Core 的下面, 找到 Access .. 打开 AccessResult.php

这里有一些方法 .. neutral .. allowed .. forbidden .. 还有一些方法可以判断一些条件 .. 比如 allowedIf .. 也就是给这个方法的条件如果是返回真 .. 就允许 .. 下面还有一下 forbiddenIf .. 意思就是给它的条件返回真 .. 就去禁止 ..

我们也可以判断用户拥有的权限来决定允许或者禁止 .. 可以使用下面的 allowedIfHasPermission .. 还有一个 allowedIfHasPermissions .. 区别就是,下面的方法可以判断用户拥有的多个权限 ..

6)使用权限

下面我们在自己的区块插件里使用一下权限 .. 复制一下 BlockBase.php 里面的这个 blockAccess 方法 .. 把它粘贴到我们自己的类里面 ..

这个方法里用到了核心的 AccountInterface .. 还有 AccessResult .. 所以在我们定义的类的一开始去使用一下它们 ..

一个是 AccountInterface .. 它是在 Drupal\Core\Session\AccountInterface .. 还有一个就是 AccessResult .. 它在 Drupal\Core\Access 的下面 ..

在这个 blockAccess 的方法里面,我们可以去做一些判断 .. 然后再决定返回什么东西 .. 比如现在返回的是 AccessResult::allowed() .. 这样这个区块就可以显示 .. 这次我们把它改成 forbidden ..

保存一下 .. 回到前台页面 .. 注意我们自己定义的这个区块的显示 .. 刷新一下 .. 这个区块就不见了 .. 回到这个区块类 .. 再试一下 allowedIf ..

我们可以设置一个条件给这个方法 .. 比如我想判断一下当前用户是不是匿名用户 .. 如果是就允许显示这个区块 .. 在 AcceountInterface 里面有一个 isAnonymous 方法,如果用户是匿名用户,这个方法会返回 TRUE ..

使用一下 $account 的 isAnonymous 方法 .. 因为 $account 是 AccountInterface 的一个实例,所以我们可以使用这个方法 ..

保存 .. 再去重建一下 Drupal 的缓存 .. 回到前台页面 .. 现在登录的用户的身份是管理员 .. 刷新一下 .. 这里仍然没有显示我们自定义的区块 ..

再试一下 .. 用一下匿名用户去访问一下这个页面 .. 在这个页面上会显示我们定义的区块 .. 因为当前用户是一个匿名用户 ...

Hooks
7)使用 hook 修改区块

使用 hook,我们可以修改区块,可以是核心自带的区块,或者其它模块里面定义的区块。 比如我想在所有的区块元素上面添加一个 css 类 .. 可以使用 hook_block_view_alter 这个 hook ..

在我们自己定义的模块里面,打开它的 .module 文件 .. 在这里可以去实施一下想要使用的 hook .. 定义一个函数 .. 名字可以先用模块的名字,我这里就是 ninghao_demo .. 然后是 hook 的名字 .. block_view_alter .. 它里面有两个参数 .. 一个是用引用方式传递过来的 build .. 它是一个数组 .. 还有一个参数是 block .. 它属于 \Drupal\Core\Block\BlockPluginInterface 这个接口 ..

在这个函数里面,我们可以去做一些判断来决定要修改的区块是哪些 .. 它的 block 参数里面就是区块的相关信息 .. 这里我想在所有的区块上面添加一个 css 类 .. 可以这样 .. $build .. 设置一下它的 #attributes ,里面的 class ... 在这个数组里面添加一个新的项目 .. 等号的右边就是项目的值 .. 也就是我们要添加的 css 类 ..

比如我想添加一个叫 item 的 css 类 .. 保存一下 .. 再去重建一下 Drupal 的缓存 .. 回到前台页面 .. 刷新 .. 检查一下页面 .. 选中一个区块 .. 找到这个区块的包装元素 .. 你会看到它上面会有一个名字是 item 的 css 类 ...

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

 
普通分类: