You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Drupal核心功能覆写、视图优化及无头CMS选型咨询

针对Drupal POC问题的解决方案

1. 控制器层面去除文章内容的多余HTML标签

可以通过自定义控制器直接处理节点内容,绕过默认模板的嵌套HTML结构。核心思路是加载节点后,对字段内容进行HTML清理,再返回纯文本或精简后的HTML。

示例代码(自定义控制器)

假设你创建了一个名为custom_content的模块,在src/Controller/CleanContentController.php中编写:

<?php

namespace Drupal\custom_content\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\node\Entity\Node;

/**
 * 清理文章内容HTML标签的控制器.
 */
class CleanContentController extends ControllerBase {

  /**
   * 获取清理后的文章内容.
   *
   * @param int $nid
   *   节点ID.
   *
   * @return array
   *   渲染数组.
   */
  public function getCleanContent($nid) {
    // 加载节点
    $node = Node::load($nid);
    if (!$node) {
      return ['#markup' => $this->t('文章不存在')];
    }

    // 获取body字段原始内容并清理标签
    $body_value = $node->get('body')->value;
    // 保留必要标签,比如<p><h2>,其余全部去除
    $cleaned_content = strip_tags($body_value, '<p><h2><h3>');

    return [
      '#markup' => $cleaned_content,
    ];
  }

}

然后在custom_content.routing.yml中配置路由:

custom_content.clean_content:
  path: '/clean-content/{nid}'
  defaults:
    _controller: '\Drupal\custom_content\Controller\CleanContentController::getCleanContent'
    _title: '清理后的文章内容'
  requirements:
    _permission: 'access content'
    nid: \d+

访问/clean-content/[节点ID]即可看到清理后的内容。如果要替换默认文章页面,可修改节点的视图模式,将其指向这个控制器的输出。

2. 为区块配置独立控制器获取数据

Drupal中可以通过自定义区块插件实现独立数据逻辑,直接在区块的build()方法中编写数据库查询或调用业务逻辑。以下是自定义区块的示例:

示例代码(自定义区块)

在src/Plugin/Block/RecentArticlesBlock.php中编写:

<?php

namespace Drupal\custom_content\Plugin\Block;

use Drupal\Core\Block\BlockBase;
use Drupal\Core\Database\Connection;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * 显示最新文章的自定义区块.
 *
 * @Block(
 *   id = "recent_articles_block",
 *   admin_label = @Translation("最新文章区块"),
 *   category = @Translation("自定义区块")
 * )
 */
class RecentArticlesBlock extends BlockBase {

  /**
   * 数据库连接服务.
   *
   * @var \Drupal\Core\Database\Connection
   */
  protected $database;

  /**
   * 构造函数.
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, Connection $database) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this->database = $database;
  }

  /**
   * 依赖注入.
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('database')
    );
  }

  /**
   * 构建区块内容.
   */
  public function build() {
    // 从数据库查询最新5篇已发布文章
    $query = $this->database->select('node_field_data', 'n')
      ->fields('n', ['nid', 'title'])
      ->condition('type', 'article')
      ->condition('status', 1)
      ->orderBy('created', 'DESC')
      ->range(0, 5);
    $articles = $query->execute()->fetchAll();

    // 构建渲染数组
    $items = [];
    foreach ($articles as $article) {
      $items[] = [
        '#type' => 'link',
        '#title' => $article->title,
        '#url' => \Drupal\Core\Url::fromRoute('entity.node.canonical', ['node' => $article->nid]),
      ];
    }

    return [
      '#theme' => 'item_list',
      '#items' => $items,
      '#title' => $this->t('最新文章'),
    ];
  }

}

启用模块后,在后台「结构」→「区块」中找到「最新文章区块」,将其放置到指定区域即可。这个区块的数据源完全由自定义逻辑控制,无需依赖视图或默认内容展示。

3. 无头Drupal vs Strapi/Ghost的选择建议

选无头Drupal的场景

  • POC后续需要扩展复杂内容模型、多角色权限控制、工作流管理(比如审核流程),或者需要整合Drupal成熟的生态模块(电商、会员系统等)。
  • 团队已有PHP/Drupal开发经验,能驾驭Drupal的学习曲线。
  • 需要与现有Drupal站点共享内容或数据。

选Strapi的场景

  • 追求快速搭建、轻量灵活,内容模型相对简单,团队熟悉Node.js技术栈。
  • 需要快速生成REST/GraphQL API,且对自定义字段、权限的需求不复杂。

选Ghost的场景

  • 核心需求是博客内容发布,需要开箱即用的博客功能(订阅、标签、内容排版等),无需复杂自定义。

总结

如果POC仅验证基础内容展示逻辑,Strapi/Ghost上手更快;如果后续有复杂业务需求,无头Drupal的扩展性更强,适合长期迭代。

内容的提问来源于stack exchange,提问作者Immanuel Thomas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 14:42:28