云客Drupal源码分析之块系统block

在drupal中系统流程指向一个控制器,通常控制器返回一个代表特定内容的渲染数组,那么还需要其他内容怎么办?这就是块系统要解决的,她让页面精彩纷呈,可展示多种信息或工具,如果没有她页面会非常单调,某种程度上说她是系统必须的,给各模块展示信息提供页面窗口。

从控制器返回的渲染数组说起:
一个渲染数组可以代表页面中的一部分,也可以是整个页面,在drupal中大多数时候控制器返回的渲染数组代表页面的一部分,这部分是请求的核心目标信息,被称为主内容main content,打开页面主要就是为了得到这个信息,在没有安装块block模块的情况下,页面只显示该信息,如果安装了块block模块,那么块模块会在主内容周围环绕其他信息,比如侧边栏、菜单栏、搜索栏等等;块模块将页面视为由多个区构成(区由主题来划分),这称为分区regions,每个分区中可以放置0个或多个块,每个块呈现一块信息,主内容一般放在主内容区中,要显示哪些信息块、怎么显示以及放在哪个区中显示是可以配置的,可在管理后台的区块配置(/admin/structure/block)中进行,这样就有了丰富多彩的页面了。
以上是宏观上的机制原理,在具体实现上当控制器返回渲染数组后,判断是否是一个局部信息(“#type”不为“page”),如果是那么将其作为主内容,然后派发“选择页面显示变体”事件,如果没有安装块模块,那么使用简单页面显示变体“simple_page”,此时只显示主内容,如果安装了块模块,那么将使用她提供的块页面显示变体“block_page”,该变体接收控制器返回的主内容渲染数组,然后将其和各种块内容组装为一个整页渲染数组(“#type”为“page”)并返回,此时已经得到整个页面的内容了,后续系统将继续执行占位替换、资源排序加载等等工作。
如果控制器直接返回了整页渲染数组,那么系统将跳过块模块的工作,直接继续后面的工作,那么控制器如何返回整页渲染数组呢?首先需要指定“#type”属性的值为“page”,其余部分可以是子元素(每个子元素对应一个分区的渲染数组,不必全部分区都要存在),或者可以是一个主题钩子,此时将钩子对应的模板内容渲染后作为整页内容,如果指定了钩子,那么代表分区渲染数组的子元素将失效,因此这两者是互斥的,除非在模板中使用了这些子元素(将整个数组作为上下文传递到模板中,并在模板中渲染了这些子元素)。
在块block模块中对各类信息块一直是操作的渲染数组,并不将其渲染成最终的html字符串,该渲染工作将在渲染整页渲染数组时在twig模板中进行(在模板中打印一个变量时,如果变量是数组那么将其当做渲染数组进行渲染输出,详见twig服务)

“选择页面显示变体”事件:
只要控制器返回的渲染数组不是整页渲染数组,那么html渲染器(服务id:main_content_renderer.html)将派发“选择页面显示变体”事件:render.page_display_variant.select,默认使用“simple_page”显示变体,但只要块block模块被安装了则将订阅她并无条件设置页面使用“block_page”显示变体
订阅器服务id:block.page_display_variant_subscriber
类:\Drupal\block\EventSubscriber\BlockPageDisplayVariantSubscriber

显示变体插件管理器:
页面显示变体是由显示变体插件管理器管理并实例化的:
服务id:plugin.manager.display_variant
类:Drupal\Core\Display\VariantManager
该插件管理器很简单,插件定义数据的修改钩子为“display_variant_plugin”,定义数据被缓存在“cache.discovery”缓存后端中。

自定义显示变体:
在模块的src/Plugin/DisplayVariant目录下,建立插件类,实现以下接口:
Drupal\Core\Display\VariantInterface
通常继承以下基类:
\Drupal\Core\Display\VariantBase
给出插件释文,清除缓存后插件将被自动收集
系统默认提供的简单页面变体是一个很好的参考:
\Drupal\Core\Render\Plugin\DisplayVariant\SimplePageVariant
请见该插件的实现

“block_page”显示变体:
这是块模块参与页面渲染流程的入口,插件id:block_page,插件类定义:
\Drupal\block\Plugin\DisplayVariant\BlockPageVariant
由于她实现了容器工厂插件接口,所以在插件管理器中将通过她的create静态方法来实例化(见本系列插件篇下集)
其build()方法返回整页渲染数组,每个子元素对应一个页面分区的渲染数组,以分区机器名作为子元素名,这里将其称为分区渲染数组,每个分区渲染数组包含1个或多子元素,每个子元素对应一个块的渲染数组;相反的,如果分区内一个块也没有,该整页渲染数组将不会包含该分区渲染数组。
在理解该显示变体的工作逻辑前,我们需要先了解块系统。

块系统概述:
一个drupal页面是由多个块构成的,每个块提供一块信息,通常主要区域显示控制器返回的主内容,该区域叫做主内容块,其周边分布着其他块,所有的块由块系统管理,块系统主要由块插件和块实体两大部分构成,块插件用于构建块的内容,块实体属于配置实体,用于提供前者的配置数据,如显示条件、分区位置、插件参数等,这两者有机结合形成了块

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值