如何设置页面标题?


29

我知道我可以使用来更改页面标题drupal_set_title(t('Amy page title')),但是当我在Drupal 8中尝试使用它时,我得到了,没有这样的功能错误。

如何在Drupal 8中更改页面标题?

Answers:


30

正如你可以看到这里该函数在Drupal 8已经过时了。

现在,可以根据您的用例以各种方式设置路线上的标题。以前只是drupal_set_title()在任何地方被称为。存在以下用例:

静态标题

对于静态标题,请在路由定义中设置“ _title”:

block.admin_add:
  path: '/admin/structure/block/add/{plugin_id}/{theme}'
  defaults:
    _controller: '\Drupal\block\Controller\BlockAddController::blockAddConfigureForm'
    _title: 'Configure block'
  requirements:
    _permission: 'administer blocks'

动态标题

如果编写控制器并且需要动态标题(例如,取决于站点配置),请在默认路由中使用_title_callback。

mymodule.test:
  path: '/mymodule/test'
  defaults:
    _controller: '\Drupal\mymodule\Controller\Test::getContent'
    _title_callback: '\Drupal\mymodule\Controller\Test::getTitle'

<?php
class Test {

  /**
   * Returns a page title.
   */
  public function getTitle() {
    return  'Foo: ' . \Drupal::config()->get('system.site')->get('name');
  }

  /**
   * Returns a page render array.
   */
  public function getContent() {
    $build = array();
    $build['#markup'] = 'Hello Drupal';
    return $build;
  }
}
?>

最终标题覆盖

如果编写控制器,并且需要覆盖路径中的标题,则可以在渲染数组中返回#title。通常应避免这种情况,因为完全渲染后的页面标题可能与其他上下文(例如面包屑)中的标题不同。

<?php
class Test {

  /**
   * Renders a page with a title.
   *
   * @return array
   *   A render array as expected by drupal_render()
   */
  public function getContentWithTitle() {
    $build = array();
    $build['#markup'] = 'Hello Drupal';
    $build['#title'] = 'Foo: ' . Drupal::config()->get('system.site')->get('name');

    return $build;
  }

}
?>

的输出标志 drupal_set_title()

Drupal 8中的输出验证与Drupal 7相反。我们必须明确指定PASS_THROUGH,并且在Drupal 7中默认情况下CHECK_PLAIN是默认的,而在Drupal 8中情况则有所不同。除非标记为安全,否则输出将自动转义。双方t()new FormattableMarkup返回的对象不会是自动逃脱。

$form['#title'] = $this->t('Add new shortcut');
$form['#title'] = $this->t("'%name' block", array('%name' => $info[$block->delta]['info']));

Drupal 8.5+

$request = \Drupal::request();
if ($route = $request->attributes->get(\Symfony\Cmf\Component\Routing\RouteObjectInterface::ROUTE_OBJECT)) {
  $route->setDefault('_title', 'New Title');
}

而且您也可以使用hook_preprocess_HOOK()它来覆盖它

/**
 * Implements hook_preprocess_HOOK().
 */
function MYMODULE_preprocess_page_title(&$variables) {
   // WRITE YOUR LOGIC HERE, 
  if ($YOUR_LOGICS === TRUE) {

    $variables['title'] = 'New Title';
  }
}

为什么必须附加system.site-> name?如果您提供的标题字符串不包含在HTML标题中,则将其附加到html标题中。
anoopjohn

5

更改您的HTML文档的标题中的标题标签。

function mymodule_preprocess_html(&$variables) {

  $variables['head_title']['title'] = $something;
}

更改页面内容中显示的标题。

function mymodule_preprocess_block(&$variables) {

  if ('page_title_block' == $variables['plugin_id']) {
    $variables['content']['#title'] = $something;
  }
}

4

Drupal 8中的drupal_set_title()

$request = \Drupal::request();
if ($route = $request->attributes->get(\Symfony\Cmf\Component\Routing\RouteObjectInterface::ROUTE_OBJECT)) {
  $route->setDefault('_title', 'New Title');
}

Drupal 8中的drupal_get_title()

$request = \Drupal::request();
if ($route = $request->attributes->get(\Symfony\Cmf\Component\Routing\RouteObjectInterface::ROUTE_OBJECT)) {
  $title = \Drupal::service('title_resolver')->getTitle($request, $route);
}

GET标题可能在任何地方都可以正常工作。我想知道在哪里设置标题,因为在预处理页面中它似乎不起作用。
leymannx


3

我在D8中发现,如果要更改实体视图的标题,则可以使用hook_ENTITY_TYPE_view_alter()。例如,以下是通过用户“ field_display_name”上的字段而不是用户ID作为标题来更改用户实体的视图的方法:

/**
* Implements hook_ENTITY_TYPE_view_alter().
*/
function mymodule_user_view_alter(array &$build, Drupal\Core\Entity\EntityInterface $entity, \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display) {
  $build['#title'] = $entity->get('field_display_name')->getString();
}

好的和干净的方法。在D8 /
Vishal Kumar Sahu

2

我发现了另一种方法,如果您没有控制器并且想在整个网站上修改标题,则可能更简单。您可以使用它来基于当前节点修改标题。

首先,删除html.html.twig中的标签,然后,钩上hook_page_attachments_alter

function mytemplate_page_attachments_alter(array &$page) {
    $page['#attached']['html_head'][] = [
        [
          '#tag' => 'title',
          '#value' => "My title"
        ],
        'title'
    ];
}

您可以使用以下命令获取分类术语的当前节点

$node = \Drupal::routeMatch()->getParameter('node');
$term = \Drupal::routeMatch()->getParameter('taxonomy_term')

2

看一下“ 自动实体标签”,这是一个精心制作的,用于设置节点标题等的贡献模块。

(请注意,“页面标题”是通俗地说“实体标签”的一种方式,其中“页面”是内容实体,“标签”包含标题和其他实体的对等物,例如评论主题,分类法术语名称。)

尽管op似乎正在寻求有关编写自定义代码的指导,但根据可用细节尚不清楚,自定义代码是最佳建议。对于没有非常特定的理由要复制贡献代码中可用功能的读者,Drupal社区强烈建议(并且网站所有者可以从中受益)采用现有模块。


2

drupal_set_title()并且drupal_get_title()都从drupal 8中删除,但是最好的部分是这有一个单独的块page_title。用户可以在任何页面/区域上隐藏或添加此块。

有两种解决方案。

  1. title_block在特定页面上禁用,并添加带有标题标记的新自定义块。现在,将此块放置title_block在drupal块部分之后。
  2. 通过hook_preprocess_block()custom_theme.theme文件中使用功能。
    这是代码示例:

    function custom_themename_preprocess_block(&$variables) {
      if ('page_title_block' == $variables['plugin_id']) {
        $request = \Drupal::request();
        $path = $request->getRequestUri(); // get current path
        if(strpos($path, 'user')) { //check current path is user profile page
          $variables['content']['#title'] = 'My Profile';
        }
      }
    }

    就我而言,我使用了上述第二种方法,该方法仅适用于用户个人资料页面。


1

我为此苦苦挣扎,并尝试了上述所有解决方案。最终有效的解决方案是:

function mymodule_preprocess_html(&$variables) {
  $variables['head_title']['title'] = $something;
}

但只有在更新自定义模块权重之后:

drush php:eval "module_set_weight('mymodule', 10);"

1

获取页面标题的工作原理与@rpayanm的答案中所写的一样。但是设置它却非常复杂。最终发现,它hook_preprocess_HOOK()可以很容易地用于预处理页面标题。

/**
 * Implements hook_preprocess_HOOK().
 */
function MYMODULE_preprocess_page_title(&$variables) {

  if ($MYLOGIC === TRUE) {

    $variables['title'] = 'New Title';
  }
}

就像在其他答案中已经提到的那样,您可能还需要另外使用hook_preprocess_html()HTML标题标题标签。


0

我已经将user / uid的page_title块更改为另一个自定义帐户字段名称,如下所示:

function hook_preprocess_block(&$variables) {  
  $path = \Drupal::request()->getpathInfo();
  $arg = explode('/', $path);
  if (isset($arg[2]) && $arg[2] == 'user' && isset($arg[3])) {
    if (isset($variables['elements']['content']['#type']) && $variables['elements']['content']['#type'] == 'page_title') {
      $account = \Drupal\user\Entity\User::load($arg[3]);
      if(isset($account) && isset($account->field_mycustomfield->value)){
        $variables['content']['#title']['#markup']=$account->field_mycustomfield->value;
      }
    }
  }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.