Jak ustawić tytuł strony?

29

Wiem, że mógłbym zmienić tytuł strony drupal_set_title(t('Amy page title')), ale kiedy próbuję go w Drupal 8, pojawia się komunikat Nie ma takiego błędu funkcji .

Jak mogę zmienić tytuł strony w Drupal 8?

Jeff Madison
źródło

Odpowiedzi:

30

Jak widać tutaj, ta funkcja jest przestarzała w Drupal 8.

Tytuły na trasach można teraz ustawić na różne sposoby, w zależności od przypadku użycia. Wcześniej drupal_set_title()był nazywany w dowolnym miejscu. Istnieją następujące przypadki użycia:

Tytuł statyczny

W przypadku tytułów statycznych ustawiono „_title” w definicji routingu:

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'

Dynamiczny tytuł

Jeśli piszesz kontroler i potrzebujesz dynamicznego tytułu, na przykład w zależności od konfiguracji witryny, użyj _title_callback w ustawieniach domyślnych trasy.

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;
  }
}
?>

Ostateczne zastąpienie tytułu

Jeśli napiszesz kontroler i musisz przesłonić tytuł z trasy, możesz zwrócić #title w tablicy renderowania. Zasadniczo należy tego unikać, ponieważ tytuł strony po pełnym renderowaniu może różnić się od tytułu w innych kontekstach (np. W bułce tartej).

<?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;
  }

}
?>

Flaga wyjściowa z drupal_set_title()

Sprawdzanie poprawności danych wyjściowych w Drupal 8 jest odwrotne do Drupala 7. Musimy wyraźnie określić PASS_THROUGH, a CHECK_PLAIN jest domyślnie w Drupal 7, podczas gdy w Drupal 8 sytuacja jest inna. Wyjście jest automatycznie wybierane, chyba że jest oznaczone jako bezpieczne. Zarówno t()i new FormattableMarkupobiekty powrotne, że nie będzie auto uciekł.

$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');
}

a także możesz użyć, hook_preprocess_HOOK()aby go zastąpić

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

    $variables['title'] = 'New Title';
  }
}
Yusef
źródło
Dlaczego musisz dołączyć nazwę system.site->? Jest to dołączane jako część tytułu, który trafia do nagłówka HTML, jeśli podasz ciąg tytułu bez tego.
anoopjohn
5

Zmień tag tytułowy w nagłówku dokumentu HTML.

function mymodule_preprocess_html(&$variables) {

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

Zmień tytuł pojawiający się w treści strony.

function mymodule_preprocess_block(&$variables) {

  if ('page_title_block' == $variables['plugin_id']) {
    $variables['content']['#title'] = $something;
  }
}
arnoldbird
źródło
4

drupal_set_title () w 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 () w 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
źródło
GET tytuł działa dobrze, może wszędzie. Zastanawiam się, gdzie ustawić tytuł, ponieważ na stronie procesu wstępnego wydaje się, że nie działa.
leymannx
3

Ta funkcja została usunięta z Drupal 8.
Zmień zapis: drupal_set_title () i drupal_get_title () zostały usunięte .

Możesz teraz ustawić tytuł podczas definiowania tras w modulename.routing.yml. Przykład tego, jak można to zrobić, pokazano powyżej link do rekordu zmian.

AjitS
źródło
3

W D8 znalazłem, że jeśli chcesz zmienić tytuł widoku encji, możesz użyć hook_ENTITY_TYPE_view_alter (). Na przykład oto sposób, w jaki można zmienić widok encji użytkownika za pomocą pola użytkownika „nazwa_wyświetlania pola” zamiast identyfikatora użytkownika jako tytułu:

/**
* 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();
}
Tyler Fahey
źródło
Dobre i czyste podejście. Działa dobrze w D8 /
Vishal Kumar Sahu
2

Znalazłem inny sposób, który może być prostszy, jeśli nie masz kontrolera i chcesz zmodyfikować tytuł w swojej witrynie. Możesz go użyć do zmodyfikowania tytułu na podstawie bieżącego węzła.

Najpierw usuń znacznik z pliku html.html.twig Następnie zaczep hak_page_attachments_alter

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

Możesz pobrać bieżący węzeł terminu taksonomii za pomocą

$node = \Drupal::routeMatch()->getParameter('node');
$term = \Drupal::routeMatch()->getParameter('taxonomy_term')
Kodiak
źródło
2

Spójrz na Automatic Entity Label , bardzo dobrze spreparowany moduł do ustawiania tytułów węzłów i tym podobne.

(Należy zauważyć, że „tytuł strony” to bardziej potoczny sposób na określenie „etykiety jednostki”, gdzie „strona” jest jednostką treści, a „etykieta” obejmuje tytuł i odpowiednik dla innych jednostek, np. Tematów komentarzy, nazw terminów taksonomicznych.)

Chociaż op wydaje się prosić o wskazówki dotyczące pisania niestandardowego kodu, z dostępnych szczegółów nie wynika, że ​​kod niestandardowy jest najlepszą rekomendacją. Dla czytelników bez konkretnego powodu do powielania funkcji dostępnej z kodu, społeczność Drupal zdecydowanie zaleca (i właściciele witryn bardzo korzystają) przyjęcie istniejącego modułu.

Kay V.
źródło
2

drupal_set_title()i drupal_get_title()oba zostały usunięte z drupala 8, ale najlepsze jest to, że jest tam osobny blok dla page_title. Użytkownik może ukryć lub dodać ten blok na dowolnej stronie / regionie.

Istnieją na to 2 rozwiązania.

  1. Wyłącz title_blockna określonej stronie i dodaj nowy blok niestandardowy z pewnymi znacznikami dla tytułu. Teraz umieść ten blok tuż za title_blocksekcją bloku drupala.
  2. Korzystając z hook_preprocess_block()funkcji w custom_theme.themepliku.
    Oto przykład kodu:

    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';
        }
      }
    }
    

    W moim przypadku użyłem powyżej 2. metody, która będzie działać tylko dla strony profilu użytkownika.

Manav
źródło
1

Walczyłem z tym i wypróbowałem wszystkie powyższe rozwiązania. Ostatecznie działającym rozwiązaniem było:

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

ale dopiero po zaktualizowaniu wagi niestandardowego modułu:

drush php:eval "module_set_weight('mymodule', 10);"
Piotr
źródło
1

Uzyskiwanie tytułu strony działa dobrze, jak napisano w odpowiedzi @ rpayanm. Ale ustawienie go okazało się dość skomplikowane. W końcu odkryłem, że hook_preprocess_HOOK()można go po prostu dość łatwo wstępnie przetworzyć tytuł strony.

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

  if ($MYLOGIC === TRUE) {

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

I jak już wspomniano w innych odpowiedziach tutaj, możesz dodatkowo użyć, hook_preprocess_html()aby odpowiednio ustawić znacznik tytułu nagłówka HTML.

leymannx
źródło
0

zmieniłem blok page_title dla user / uid na inną nazwę pola niestandardowego konta, taką jak:

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
źródło