ฉันรู้ว่าฉันสามารถเปลี่ยนชื่อหน้าด้วยdrupal_set_title(t('Amy page title'))
แต่เมื่อฉันลองใน Drupal 8 ฉันได้รับไม่มีข้อผิดพลาดของฟังก์ชั่นดังกล่าว
ฉันจะเปลี่ยนชื่อหน้าใน Drupal 8 ได้อย่างไร
ฉันรู้ว่าฉันสามารถเปลี่ยนชื่อหน้าด้วยdrupal_set_title(t('Amy page title'))
แต่เมื่อฉันลองใน Drupal 8 ฉันได้รับไม่มีข้อผิดพลาดของฟังก์ชั่นดังกล่าว
ฉันจะเปลี่ยนชื่อหน้าใน Drupal 8 ได้อย่างไร
คำตอบ:
อย่างที่คุณเห็นตรงนี้ฟังก์ชั่นนั้นเลิกใช้แล้วใน 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 ของคุณ
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;
}
}
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);
}
ฟังก์ชั่นนั้นถูกลบออกจาก Drupal 8
เปลี่ยนบันทึก:
drupal_set_title () และ drupal_get_title () ถูกลบออกถูกถอดออก
modulename.routing.yml
ตอนนี้คุณสามารถตั้งชื่อเมื่อกำหนดเส้นทางใน ตัวอย่างของวิธีการที่สามารถทำได้แสดงลิงค์บันทึกการเปลี่ยนแปลงข้างต้น
ฉันพบใน 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();
}
ฉันพบวิธีอื่นซึ่งอาจจะง่ายกว่านี้ถ้าคุณไม่มีตัวควบคุมและต้องการแก้ไขชื่อในเว็บไซต์ของคุณ คุณสามารถใช้เพื่อแก้ไขหัวเรื่องตามโหนดปัจจุบัน
ก่อนอื่นให้ลบแท็กใน 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')
ลองดูที่Automatic Entity Labelซึ่งเป็นโมดูลที่สร้างขึ้นมาอย่างดีสำหรับการตั้งค่าชื่อโหนดและสิ่งที่คล้ายกัน
(โปรดทราบว่า 'ชื่อหน้า' เป็นวิธีพูดมากกว่าที่จะพูดถึง 'ป้ายชื่อเอนทิตี' โดยที่ 'หน้า' เป็นเอนทิตีเนื้อหาและ 'ป้ายกำกับ' ครอบคลุมชื่อเรื่องและสิ่งที่เทียบเท่ากับเอนทิตีอื่น ๆ เช่นหัวเรื่องความคิดเห็นชื่อเทอม taxonomy)
ในขณะที่ op ดูเหมือนจะขอคำแนะนำในการเขียนรหัสที่กำหนดเอง แต่ก็ไม่ชัดเจนจากรายละเอียดที่มีอยู่ว่ารหัสที่กำหนดเองเป็นคำแนะนำที่ดีที่สุด สำหรับผู้อ่านที่ไม่มีเหตุผลเฉพาะเจาะจงสำหรับการทำซ้ำคุณลักษณะที่มีให้จากรหัสที่สนับสนุนชุมชน Drupal ขอแนะนำอย่างยิ่ง (และเจ้าของเว็บไซต์ได้รับประโยชน์อย่างมากจากการใช้โมดูลที่มีอยู่แล้ว)
drupal_set_title()
และdrupal_get_title()
ทั้งสองจะถูกลบออกจาก drupal 8 แต่ส่วนที่ดีที่สุดคือมีบล็อกแยกต่างหากสำหรับpage_title
แต่ส่วนที่ดีที่สุดคือการนี้จะมีบล็อกที่แยกต่างหากสำหรับ ผู้ใช้สามารถซ่อนหรือเพิ่มบล็อกนี้ในหน้า / ภูมิภาคใดก็ได้
มี 2 วิธีแก้ปัญหานี้
title_block
ในบางหน้าและเพิ่มบล็อกที่กำหนดเองใหม่ที่มีมาร์กอัปสำหรับชื่อ ตอนนี้วางบล็อกนี้หลังจากtitle_block
ในบล็อก drupalโดยใช้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 ข้างต้นซึ่งจะใช้ได้เฉพาะกับหน้าโปรไฟล์ผู้ใช้
ฉันต่อสู้กับสิ่งนี้และลองวิธีแก้ปัญหาทั้งหมดข้างต้น วิธีแก้ปัญหาที่ใช้งานได้ในที่สุดคือ:
function mymodule_preprocess_html(&$variables) {
$variables['head_title']['title'] = $something;
}
แต่หลังจากที่ฉันอัปเดตน้ำหนักโมดูลที่กำหนดเองแล้ว:
drush php:eval "module_set_weight('mymodule', 10);"
การทำให้ชื่อหน้าทำงานได้ดีตามที่เขียนไว้ในคำตอบของ @ 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 ตาม
ฉันได้เปลี่ยน 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;
}
}
}
}