Drupal模板开发:自定义块动态传参与内容渲染实现方案咨询
可落地实现方案
按开发成本从低到高排序,优先选低代码方案即可满足需求。
方案1:视图块方案(零自定义代码,优先推荐)
- 先做存量内容收敛:所有样式、结构统一的区块对应内容,全部归并到单一对应内容类型,禁止为每个页面板块单独建内容类型。比如所有卡片式宣传位统一用
promo_card内容类型,仅保留通用字段:标题、配图、正文、跳转链接、可选样式配置项(如高亮标记、图标选择)。 - 新建视图(Views),展示类型选择「块」,筛选条件固定指定归并后的目标内容类型;在视图高级设置中开启暴露配置,支持放置块时手动勾选/筛选要展示的指定内容节点。
- 视图展示格式不要选默认的「字段」模式,切换为渲染实体,绑定提前配置好的专属视图模式(比如专门给区块嵌入场景用的
block_embed视图模式,提前配置好字段输出顺序、样式类),即可直接渲染完整内容详情,不会只输出内容链接。 - 统一的样式、JS逻辑直接写到主题全局资源中,通过视图块自带的自定义CSS类做作用域隔离,不需要为每个块单独绑定资源。
方案2:自定义块类型配置方案(低代码,灵活度更高)
实体引用字段默认只输出链接是字段显示配置未调整,按以下步骤修改即可实现完整内容渲染:
- 新建通用自定义块类型,添加实体引用字段(目标类型选内容节点,可配置支持按内容类型筛选可选值),额外加分类、样式配置类字段满足差异化配置需求。
- 进入自定义块类型的「显示管理」页面,找到实体引用字段,将字段格式从默认的「标签(带链接)」改为渲染的实体,视图模式选择提前配置好的
block_embed模式,保存后引用的内容就会按设定格式完整输出。 - 块的统一外层结构、样式类写到主题对应的块模板文件中,配套写好通用JS逻辑,所有同结构块复用这一套模板资源即可。
方案3:自定义块插件开发方案(适合复杂动态逻辑场景)
如果需要更复杂的筛选、交互逻辑,直接通过自定义块插件实现,动态传参的核心逻辑是通过块配置表单存储选中的内容ID,在渲染时加载对应实体调用原生渲染流程即可,核心代码框架如下:
<?php namespace Drupal\your_custom_module\Plugin\Block; use Drupal\Core\Block\BlockBase; use Drupal\Core\Form\FormStateInterface; use Drupal\node\Entity\Node; /** * 通用内容渲染块 * * @Block( * id = "common_content_render_block", * admin_label = @Translation("通用内容渲染块"), * ) */ class CommonContentRenderBlock extends BlockBase { /** * {@inheritdoc} */ public function defaultConfiguration() { return [ 'selected_nids' => [], 'target_content_type' => '', ]; } /** * {@inheritdoc} */ public function blockForm($form, FormStateInterface $form_state) { $form['target_content_type'] = [ '#type' => 'select', '#title' => $this->t('筛选内容类型'), '#options' => node_type_get_names(), '#default_value' => $this->configuration['target_content_type'], // 可加ajax逻辑实现选完内容类型后动态刷新可选内容列表 ]; $form['selected_nids'] = [ '#type' => 'entity_autocomplete', '#title' => $this->t('选择要渲染的内容'), '#target_type' => 'node', '#selection_settings' => [ 'target_bundles' => [$this->configuration['target_content_type']], ], '#tags' => TRUE, '#default_value' => $this->loadConfiguredNodes(), ]; return $form; } /** * {@inheritdoc} */ public function build() { $build = []; $selected_nids = array_column($this->configuration['selected_nids'], 'target_id'); $view_builder = \Drupal::entityTypeManager()->getViewBuilder('node'); foreach ($selected_nids as $nid) { $node = Node::load($nid); if ($node && $node->access('view')) { // 调用原生视图构建器,按指定视图模式渲染内容 $build['content_list'][] = $view_builder->view($node, 'block_embed'); } } // 附加块专属样式、JS库 $build['#attached']['library'][] = 'your_custom_module/common_block_assets'; return $build; } }
- 不要手动拼接字段HTML输出,全部复用Drupal实体渲染流程,后续内容字段调整不需要修改块代码,维护成本更低。
核心避坑规则
- 禁止为每个页面、每个板块单独创建内容类型、自定义块,所有结构样式一致的区块全部复用同一套配置,仅在放置块时选择不同内容做差异化,从根源上避免实体混乱。
- 样式、JS资源统一封装为库通过
#attached加载,不要重复为每个块实例嵌入相同资源,避免前端资源冗余。 - 内容渲染全部通过视图模式配置输出,不要在模板、块代码里硬编码字段结构,降低后续迭代成本。
内容的提问来源于stack exchange,提问作者Shuai Wang
相关产品推荐
相关产品推荐

