Drupal 8中自定义404模板文件

12
如何在Drupal 8中创建自定义404页面?
我已在后台创建了一个名为“404”的新页面(内容)(节点编号100)。我已将其设置为404默认页面,方法是在“配置”>“基本网站”设置中进行。

Settings

它能够与我在后台设置的内容一起工作。

但现在我想让它可通过编程进行编辑,但我不知道如何创建覆盖文件。

我尝试创建mytheme/templates/html--node--100.html.twig,并且仅当请求直接为该URL(node/100)时才有效,但是当您在URL上尝试随机的slug并且drupal必须解析它时,它就无法工作。 当这种情况发生时,drupal会向我提供后台中404页面的内容,而不是我刚刚创建的文件中的内容。

我尝试了几个文件,例如page--404-html.twightml--node--404.html.twightml--page--404.html.twig,但都没有效果。

有人能帮我吗?

4个回答

13

在Drupal 8.3中,与其他4xx状态相对应的page--system--404.html.twig(或等效文件)不再起作用,因为4xx响应处理已更改。现在,您需要从https://www.drupal.org/node/2363987获取核心补丁,或使用类似的自定义模块钩子为这些页面添加模板建议。

/**
 * Implements hook_theme_suggestions_page() to set 40x template suggestions
 */
function MYMODULE_theme_suggestions_page(array $variables) {
  $path_args = explode('/', trim(\Drupal::service('path.current')->getPath(), '/'));
  $suggestions = theme_get_suggestions($path_args, 'page');
  $http_error_suggestions = [
    'system.401' => 'page__401',
    'system.403' => 'page__403',
    'system.404' => 'page__404',
  ];
  $route_name = \Drupal::routeMatch()->getRouteName();
  if (isset($http_error_suggestions[$route_name])) {
    $suggestions[] = $http_error_suggestions[$route_name];
  }

  return $suggestions;
}
编辑:使用hook_theme_suggestions_page_alter更好地修改建议数组。请在https://www.drupal.org/project/fourxx_templates(或https://github.com/ahebrank/fourxx_templates/blob/8.x-1.x/fourxx_templates.module)中查看此代码的更新版本。

只有在配置中没有设置自定义404页面时,此方法才有效。至少在我的情况下(Drupal 8.4.4),\Drupal::routeMatch()->getRouteName()返回 "entity.node.canonical"。在这种情况下如何识别和更改404页面?请提供任何指针。 - fritzmg
在这种情况下,似乎您需要执行以下操作:https://drupal.stackexchange.com/a/231652/80492 - fritzmg
我认为你应该优先使用HOOK_theme_suggestions_page_alter(array &$suggestions, array $variables),否则会覆盖$suggestions数组。这可能是你不想要的,例如使用Context模块提供页面模板时。 - Raphael Larrinaga
@RaphaelLarrinaga,你可能是对的。我已经更新了https://www.drupal.org/project/fourxx_templates以考虑这一点。 - ahebrank

12
以下实现向页面添加了一个模板建议,如果您在主题中创建一个page--404.html.twig文件,您将能够自定义该页面并与Drupal 8.5.1一起使用。
MYTHEME.theme
/**
 * Implements hook_theme_suggestions_HOOK_alter().
 */
function MYTHEME_theme_suggestions_page_alter(&$suggestions, $variables, $hook) {
  /**
   * 404 template suggestion.
   */
  if (!is_null(Drupal::requestStack()->getCurrentRequest()->attributes->get('exception'))) {
    $status_code = Drupal::requestStack()->getCurrentRequest()->attributes->get('exception')->getStatusCode();
    switch ($status_code) {
      case 404: {
        $suggestions[] = 'page__' . (string) $status_code;
        break;
      }
      default:
        break;
    }
  }
}

创建一个名为 page--404.html.twig 的模板并覆盖其中的内容。

或者,如果你想为所有的错误页面添加建议,只需去掉 switch 语句。

/**
 * Implements hook_theme_suggestions_HOOK_alter().
 */
function MYTHEME_theme_suggestions_page_alter(&$suggestions, $variables) {
  /**
   * error page template suggestions.
   */
  if (!is_null(Drupal::requestStack()->getCurrentRequest()->attributes->get('exception'))) {
    $status_code = Drupal::requestStack()->getCurrentRequest()->attributes->get('exception')->getStatusCode();
    $suggestions[] = 'page__' . (string) $status_code;
  }
}

2

你还可以为每个错误代码使用特定的预处理函数,例如: function TEMPLATE_preprocess_page__4xx(&$vars) { } - Interdruper

0
尝试页面--system--404.html.twig

7
尝试在你的回答中获得更多细节。一句话通常就足够了。 - Matthew Fisher

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接