Wie lege ich den Seitentitel fest?

29

Ich weiß, dass ich den Seitentitel mit ändern könnte drupal_set_title(t('Amy page title')), aber wenn ich es in Drupal 8 versuche, erhalte ich den Hinweis, dass es keinen solchen Funktionsfehler gibt .

Wie kann ich den Seitentitel in Drupal 8 ändern?

Jeff Madison
quelle

Antworten:

30

Wie Sie hier sehen können , ist diese Funktion in Drupal 8 veraltet.

Titel auf Routen können jetzt je nach Anwendungsfall auf verschiedene Arten festgelegt werden. Bisher wurde gerade drupal_set_title()an welcher Stelle auch immer angerufen. Es gibt folgende Anwendungsfälle:

Statischer Titel

Für statische Titel legen Sie in der Routing-Definition einen '_title' fest:

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'

Dynamischer Titel

Wenn Sie einen Controller schreiben und einen dynamischen Titel benötigen, z. B. abhängig von der Site-Konfiguration, verwenden Sie _title_callback in den Routenstandards.

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

Final Title Override

Wenn Sie einen Controller schreiben und den Titel von der Route überschreiben müssen, können Sie #title im Render-Array zurückgeben. Dies sollte generell vermieden werden, da der Titel der Seite im vollständig gerenderten Zustand von dem Titel in anderen Kontexten (wie im Breadcrumb) abweichen kann.

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

}
?>

Ausgabeflag von drupal_set_title()

Die Ausgabeüberprüfung in Drupal 8 ist im Gegensatz zu Drupal 7. Wir müssen PASS_THROUGH explizit angeben und CHECK_PLAIN ist standardmäßig in Drupal 7, wohingegen in Drupal 8 die Situation anders ist. Die Ausgabe wird automatisch maskiert, sofern sie nicht als sicher markiert ist. Beide t()und new FormattableMarkupgeben Objekte zurück, die nicht automatisch maskiert werden.

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

und Sie können es auch verwenden hook_preprocess_HOOK(), um es zu überschreiben

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

    $variables['title'] = 'New Title';
  }
}
Yusef
quelle
Warum muss der system.site-> name angehängt werden? Dies wird als Teil des Titels angehängt, der in den HTML-Kopf eingefügt wird, wenn Sie eine Titelzeichenfolge ohne diese angeben.
Anoopjohn
5

Ändern Sie das Titel-Tag im Kopf Ihres HTML-Dokuments.

function mymodule_preprocess_html(&$variables) {

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

Ändern Sie den Titel, der im Seiteninhalt angezeigt wird.

function mymodule_preprocess_block(&$variables) {

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

drupal_set_title () in 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 () in 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
quelle
GET-Titel funktioniert vielleicht überall. Ich frage mich, wo der Titel gesetzt werden soll, da er auf der Vorverarbeitungsseite nicht zu funktionieren scheint.
Leymannx
3

Diese Funktion wurde aus Drupal 8 entfernt.
Änderungssatz: drupal_set_title () und drupal_get_title () wurden entfernt .

Sie können jetzt den Titel festlegen, wenn Sie die Routen in definieren modulename.routing.yml. Ein Beispiel dafür, wie es gemacht werden könnte, ist der Link zum Änderungsdatensatz oben.

Ajits
quelle
3

Ich habe in D8 festgestellt, dass Sie hook_ENTITY_TYPE_view_alter () verwenden können, wenn Sie den Titel für eine Entitätsansicht ändern möchten. So können Sie beispielsweise die Ansicht einer Benutzerentität mit einem Feld im Benutzer "field_display_name" anstelle der Benutzer-ID als Titel ändern:

/**
* 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
quelle
Guter und sauberer Ansatz. Funktioniert gut in D8 /
Vishal Kumar Sahu
2

Ich habe einen anderen Weg gefunden, der möglicherweise einfacher ist, wenn Sie keinen Controller haben und den Titel auf Ihrer Website ändern möchten. Sie können ihn verwenden, um den Titel basierend auf dem aktuellen Knoten zu ändern.

Entfernen Sie zuerst das Tag in Ihrer html.html.twig. Haken Sie dann hook_page_attachments_alter ein

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

Den aktuellen Taxonomieknoten erhalten Sie mit

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

Schauen Sie sich Automatic Entity Label an , ein sehr gut zusammengestelltes Modul zum Festlegen von Knotentiteln und Ähnlichem.

(Beachten Sie, dass "Seitentitel" eine umgangssprachlichere Bezeichnung für "Entitätsbezeichnung" ist, wobei "Seite" eine Inhaltsentität ist und "Bezeichnung" den Titel und das Äquivalent für andere Entitäten umfasst, z. B. Kommentarthemen, Taxonomiebegriffsnamen.)

Während op anscheinend um Anleitung zum Schreiben von benutzerdefiniertem Code bittet, ist aus den verfügbaren Details nicht ersichtlich, dass benutzerdefinierter Code die beste Empfehlung ist. Für Leser ohne einen ganz bestimmten Grund für das Duplizieren einer Funktion, die aus beigesteuertem Code verfügbar ist, empfiehlt die Drupal-Community nachdrücklich, ein vorhandenes Modul zu übernehmen (und Websitebesitzer davon zu profitieren).

Kay V
quelle
2

drupal_set_title()und drupal_get_title()beide sind aus Drupal 8 entfernt, aber das Beste daran ist, dass es einen separaten Block für gibt page_title. Der Benutzer kann diesen Block auf jeder Seite / Region verbergen oder hinzufügen.

Hierfür gibt es 2 Lösungen.

  1. Deaktivieren Sie diese Option title_blockauf einer bestimmten Seite und fügen Sie einen neuen benutzerdefinierten Block mit einem gewissen Markup für den Titel hinzu. Platzieren Sie diesen Block jetzt direkt nach dem title_blockBlockabschnitt in Drupal.
  2. Mit der hook_preprocess_block()Funktion in Ihrer custom_theme.themeDatei.
    Hier ist das Codebeispiel:

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

    In meinem Fall habe ich die oben genannte 2. Methode verwendet, die nur für Benutzerprofilseiten funktioniert.

Manav
quelle
1

Ich kämpfte damit und versuchte alle oben genannten Lösungen. Die Lösung, die schließlich funktionierte, war:

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

aber erst nachdem ich mein benutzerdefiniertes Modulgewicht aktualisiert habe:

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

Das Abrufen des Seitentitels funktioniert einwandfrei, wie in der Antwort von @ rpayanm beschrieben. Aber es stellte sich als ziemlich kompliziert heraus. Schließlich stellte sich heraus, dass hook_preprocess_HOOK()sich der Seitentitel ganz einfach vorverarbeiten lässt.

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

  if ($MYLOGIC === TRUE) {

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

Und wie bereits in anderen Antworten erwähnt, können Sie zusätzlich hook_preprocess_html()das HTML-Head-Title-Tag entsprechend einstellen.

leymannx
quelle
0

Ich habe den Block "page_title" für "user / uid" in einen anderen benutzerdefinierten Feldnamen geändert:

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
quelle