Как установить заголовок страницы?

29

Я знаю, что могу изменить заголовок страницы drupal_set_title(t('Amy page title')), но когда я пытаюсь сделать это в Drupal 8, я получаю сообщение « Нет такой ошибки».

Как я могу изменить заголовок страницы в Drupal 8?

Джефф Мэдисон
источник

Ответы:

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, а CHECK_PLAIN по умолчанию в Drupal 7, тогда как в 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, если вы предоставите строку заголовка без этого.
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;
  }
}
arnoldbird
источник
4

drupal_set_title () в Drupal 8

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

drupal_get_title () в Drupal 8

$request = \Drupal::request();
if ($route = $request->attributes->get(\Symfony\Cmf\Component\Routing\RouteObjectInterface::ROUTE_OBJECT)) {
  $title = \Drupal::service('title_resolver')->getTitle($request, $route);
}
rpayanm
источник
GET title отлично работает, может быть, везде. Интересно, где установить заголовок, потому что на странице предварительной обработки он не работает.
Leymannx
3

Эта функция была удалена из Drupal 8.
Запись об изменении: drupal_set_title () и drupal_get_title () были удалены .

Теперь вы можете установить заголовок при определении маршрутов в modulename.routing.yml. Пример того, как это можно сделать, показан выше по ссылке об изменении записи.

AjitS
источник
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 /
Вишал Кумар Саху
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')
Kodiak
источник
2

Взгляните на Automatic Entity Label , очень хорошо разработанный модуль для настройки заголовков узлов и тому подобное.

(Обратите внимание, что «заголовок страницы» является более разговорным способом сказать «метка сущности», где «страница» является сущностью контента, а «метка» включает в себя заголовок и эквивалент для других сущностей, например, тем комментариев, названий терминов таксономии.)

Несмотря на то, что op запрашивает руководство по написанию пользовательского кода, из доступных деталей не ясно, что пользовательский код - лучшая рекомендация. Для читателей, у которых нет особой причины для дублирования функций, доступных в добавленном коде, сообщество Drupal настоятельно рекомендует (и владельцы сайтов получают большую выгоду) принять существующий модуль.

Кей V
источник
2

drupal_set_title()и drupal_get_title()оба удалены из drupal 8, но лучшая часть - это отдельный блок для page_title. Пользователь может скрыть или добавить этот блок на любую страницу / регион.

Есть 2 решения для этого.

  1. Отключить title_blockна определенной странице и добавить новый пользовательский блок с некоторой разметкой для заголовка. Теперь разместите этот блок сразу после title_blockсекции блоков в друпале.
  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';
        }
      }
    }

    В моем случае я использовал выше 2-й метод, который будет работать только для страницы профиля пользователя.

Manav
источник
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-заголовка.

leymannx
источник
0

я изменил блок page_title для user / uid на другое имя настраиваемого поля учетной записи, например:

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;
      }
    }
  }
}
Matoeil
источник