如何为Drupal 9的所有4xx、5xx错误状态自定义错误页面?
在Drupal 9中自定义所有4xx/5xx错误页面的解决方案
一、修复error_page模块的配置问题
如果你已经安装了error_page模块但未生效,按以下步骤排查调整:
- 确认模块已启用:通过后台“扩展”页面或执行
drush en error_page -y确保模块处于启用状态 - 调整settings.php代码位置:把你添加的代码移到
settings.php文件的最末尾,避免被后续配置覆盖 - 验证模板目录与文件:
- 确保
$settings['error_page']['template_dir']指向的目录真实存在,比如DRUPAL_ROOT . '/../templates/errors' - 在该目录下创建对应状态码的Twig模板,命名格式为
[status_code].html.twig(如500.html.twig、503.html.twig),模板需包含完整HTML结构(错误页面不会加载主题资源)
- 确保
- 检查文件权限:给模板目录和文件设置web服务器用户可读权限(如
chmod -R 644 /path/to/templates、chown -R www-data:www-data /path/to/templates) - 正确测试错误页面:不要直接访问模板文件,需触发对应错误(比如手动在代码中抛出
new \Symfony\Component\HttpKernel\Exception\HttpException(500),或启用维护模式测试503)
二、无需模块的自定义实现方法
如果不想依赖第三方模块,可通过以下两种方式实现:
方法1:自定义事件订阅器(Drupal标准方式,推荐)
创建一个自定义模块(如custom_error_pages),通过事件订阅器拦截错误响应并替换为自定义模板:
- 创建模块结构:
custom_error_pages/ ├── custom_error_pages.info.yml ├── custom_error_pages.services.yml └── src/ └── EventSubscriber/ └── CustomErrorPageSubscriber.php └── templates/ ├── 404.html.twig ├── 500.html.twig ├── 503.html.twig └── error.html.twig # 通用 fallback 模板
- 编写模块信息文件(custom_error_pages.info.yml):
name: Custom Error Pages type: module description: 'Customizes all 4xx/5xx error pages' core_version_requirement: ^9 || ^10 package: Custom
- 注册事件订阅器(custom_error_pages.services.yml):
services: custom_error_pages.subscriber: class: Drupal\custom_error_pages\EventSubscriber\CustomErrorPageSubscriber arguments: ['@twig'] tags: - { name: event_subscriber }
- 编写订阅器代码(CustomErrorPageSubscriber.php):
<?php namespace Drupal\custom_error_pages\EventSubscriber; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpKernel\Event\ExceptionEvent; use Symfony\Component\HttpKernel\Event\ResponseEvent; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\HttpFoundation\Response; use Twig\Environment; class CustomErrorPageSubscriber implements EventSubscriberInterface { protected $twig; public function __construct(Environment $twig) { $this->twig = $twig; } public static function getSubscribedEvents() { $events[KernelEvents::EXCEPTION] = ['onException', 0]; $events[KernelEvents::RESPONSE] = ['onResponse', 0]; return $events; } public function onException(ExceptionEvent $event) { $exception = $event->getThrowable(); $statusCode = method_exists($exception, 'getStatusCode') ? $exception->getStatusCode() : 500; if ($statusCode >= 400 && $statusCode < 600) { $template = $this->getErrorTemplate($statusCode); if ($template) { $content = $this->twig->render($template, ['status_code' => $statusCode]); $response = new Response($content, $statusCode); $event->setResponse($response); } } } public function onResponse(ResponseEvent $event) { if (!$event->isMainRequest()) { return; } $response = $event->getResponse(); $statusCode = $response->getStatusCode(); if ($statusCode >= 400 && $statusCode < 600) { $template = $this->getErrorTemplate($statusCode); if ($template) { $content = $this->twig->render($template, ['status_code' => $statusCode]); $response->setContent($content); } } } protected function getErrorTemplate($statusCode) { $modulePath = drupal_get_path('module', 'custom_error_pages'); $templateFile = $modulePath . '/templates/' . $statusCode . '.html.twig'; if (file_exists($templateFile)) { return '@custom_error_pages/' . $statusCode . '.html.twig'; } // 通用 fallback 模板 $fallbackFile = $modulePath . '/templates/error.html.twig'; if (file_exists($fallbackFile)) { return '@custom_error_pages/error.html.twig'; } return NULL; } }
- 创建Twig模板:
比如500.html.twig:
<!DOCTYPE html> <html> <head> <title>服务器错误</title> <style> body { text-align: center; padding: 50px; font-family: Arial, sans-serif; } h1 { font-size: 50px; } p { font-size: 20px; } </style> </head> <body> <h1>500 - 服务器内部错误</h1> <p>我们正在处理这个问题,请稍后再试。</p> </body> </html>
- 启用模块:执行
drush en custom_error_pages -y或后台启用模块,测试对应错误即可。
方法2:通过.htaccess配置(仅适用于Apache服务器)
如果你的站点使用Apache,可直接修改webroot下的.htaccess文件,添加ErrorDocument指令:
# 自定义错误页面 ErrorDocument 404 /custom-404.html ErrorDocument 403 /custom-403.html ErrorDocument 500 /custom-500.html ErrorDocument 503 /custom-503.html
注意:将custom-xxx.html替换为你实际创建的静态HTML文件路径,文件需放在webroot目录下。
内容的提问来源于stack exchange,提问作者Sops
相关产品推荐
相关产品推荐

