Drupal – Preprocess for View in Block
     发布在:PHP      浏览:27      评论:0 条评论

在 Drupal 中,经常使用 Views 来显示列表之类的数据,如新闻列表、Top10

但是实际在使用的时候,配置有点繁琐。于是就有了这样一个需求,假设有一个新闻列表 View (News List View),

希望将 View 绑定到 Block 中,并且在 Block 中有多个 Fields 可用于动态配置 News List 的显示数量、新闻类型等。

基于此,查阅相关资料,终于实现了这个功能。

创建模块

modules/custom 目录下创建自定义模块,这个就不细说了,可以看这里 《Drupal – 模块开发》

module 文件

modules/custom/custom_components 下面创建 custom_components.module 文件。

<?php
/**
 * @file
 * Primary module hooks for Custom COmponents module.
 */
use Durpal\views\Views;

/**
 * Implements hook_preprocess_block().
 */
function custom_components_preprocess_block(&$variables) {
    // For no entity blocks.
    $content = &$variables['content'];
    if (!isset($content['#block_content'])) return;

    $block = $content['#block_content'];
    $block_type = $block -> type -> getString();
    if ($block_type == 'news_block') {
        _preprocess_block_news_block($content, $block);
    }
}

/**
 * Preprocess News Block
 */
function _preprocess_block_news_block(&$content, $block) {
    // 注意:以下所有 field 字段名均根据实际情况来定
    $view = Views::getView('news_list');

    // 设置新闻条数 N
    $number = $block -> field_numbers_shown -> getValue();
    $view -> setItemsPerPage($number[0]['value']);

    // 设置 Contextual Filters
    $category = $block -> field_news_category -> getValue();
    $args = [];
    if (!empty($category)) {
        $args['field_news_category_target_id'] = $category[0]['target_id'];
    }
    $view -> setArguments($args);

    // 执行 View Query
    $view -> execute();

    // 添加自定义的一些 Query 条件
    $publishOptions = $block -> field_news_publish_options -> getValue();
    $publishOptions = array_column($publishOptions, 'value');
    _add_publish_filters_to_view($view, $publishOptions);

    if (!empty($view -> result)) {
        $view = $view -> render();
        $view = _add_weight_to_view($view, 1);
        $content[] = $view;
    }
}

/**
 * Add publish options filter to view.
 */
function _add_publish_filters_to_view(&$view, $options) {
    // 获取 View Query
    $query = $view -> getQuery();

    $preConditions = [
        'conditions' => [],
        'args' => [],
        'type' => 'OR',
    ];
    foreach ($options as $option) {
        array_push($preConditions['conditions'], [
            'field' => 'node_field_data.' . $options,
            'value' => '1',
            'operator' => '=',
        ]);
    }
    array_push($query -> where, $preConditions);

    $query -> build($view);
    $query -> execute($view);
}

/**
 * Add weight to view.
 */
function _add_weight_to_view($view, $weight) {
    $view['#weight'] = $weight;
    return $view;
}
Responses