ฉันจะตั้งชื่อหน้าได้อย่างไร


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 ในเรนเดอร์อาร์เรย์ได้ โดยทั่วไปควรหลีกเลี่ยงเนื่องจากชื่อเรื่องของหน้าเมื่อการแสดงผลอย่างสมบูรณ์อาจแตกต่างจากชื่อในบริบทอื่น ๆ (เช่นใน breadcrumb)

<?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 ในขณะที่สถานการณ์ 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';
  }
}

ทำไมคุณต้องผนวกระบบชื่อไซต์ -> ที่ถูกผนวกเข้าเป็นส่วนหนึ่งของชื่อเรื่องที่จะเข้าสู่ส่วนหัวของ 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_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);
}

GET ชื่อใช้งานได้ดีทุกที่ ฉันสงสัยว่าจะตั้งชื่อเรื่องไว้ที่ใดทำให้หน้าประมวลผลไม่ปรากฏขึ้น
leymannx

3

ฟังก์ชั่นนั้นถูกลบออกจาก Drupal 8
เปลี่ยนบันทึก: drupal_set_title () และ drupal_get_title () ถูกลบออกถูกถอดออก

modulename.routing.ymlตอนนี้คุณสามารถตั้งชื่อเมื่อกำหนดเส้นทางใน ตัวอย่างของวิธีการที่สามารถทำได้แสดงลิงค์บันทึกการเปลี่ยนแปลงข้างต้น


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 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

ลองดูที่Automatic Entity Labelซึ่งเป็นโมดูลที่สร้างขึ้นมาอย่างดีสำหรับการตั้งค่าชื่อโหนดและสิ่งที่คล้ายกัน

(โปรดทราบว่า 'ชื่อหน้า' เป็นวิธีพูดมากกว่าที่จะพูดถึง 'ป้ายชื่อเอนทิตี' โดยที่ 'หน้า' เป็นเอนทิตีเนื้อหาและ 'ป้ายกำกับ' ครอบคลุมชื่อเรื่องและสิ่งที่เทียบเท่ากับเอนทิตีอื่น ๆ เช่นหัวเรื่องความคิดเห็นชื่อเทอม taxonomy)

ในขณะที่ op ดูเหมือนจะขอคำแนะนำในการเขียนรหัสที่กำหนดเอง แต่ก็ไม่ชัดเจนจากรายละเอียดที่มีอยู่ว่ารหัสที่กำหนดเองเป็นคำแนะนำที่ดีที่สุด สำหรับผู้อ่านที่ไม่มีเหตุผลเฉพาะเจาะจงสำหรับการทำซ้ำคุณลักษณะที่มีให้จากรหัสที่สนับสนุนชุมชน Drupal ขอแนะนำอย่างยิ่ง (และเจ้าของเว็บไซต์ได้รับประโยชน์อย่างมากจากการใช้โมดูลที่มีอยู่แล้ว)


2

drupal_set_title()และdrupal_get_title()ทั้งสองจะถูกลบออกจาก drupal 8 แต่ส่วนที่ดีที่สุดคือมีบล็อกแยกต่างหากสำหรับpage_titleแต่ส่วนที่ดีที่สุดคือการนี้จะมีบล็อกที่แยกต่างหากสำหรับ ผู้ใช้สามารถซ่อนหรือเพิ่มบล็อกนี้ในหน้า / ภูมิภาคใดก็ได้

มี 2 ​​วิธีแก้ปัญหานี้

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

    ในกรณีของฉันฉันได้ใช้วิธีที่ 2 ข้างต้นซึ่งจะใช้ได้เฉพาะกับหน้าโปรไฟล์ผู้ใช้


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

ฉันได้เปลี่ยน page_title block สำหรับ 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;
      }
    }
  }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.