Làm cách nào để thay đổi tiêu đề của liên kết menu?


8

Trong trang web của tôi, người dùng có thể thu thập một số 'điểm' theo thời gian. Tôi có một menu trên cùng với một số liên kết (ví dụ: "nhà", "hồ sơ", "đăng xuất"). Tôi muốn thay đổi "hồ sơ" mục menu và thêm số điểm thuộc sở hữu của người dùng được kết nối hiện tại.

Tôi đã thử một vài cái móc, và tôi gần như đã thành công trong việc đạt được thứ mình muốn hook_link_alter().

function mycustommodule_link_alter(&$variables) {
  if ($variables['text'] == "profile") {
    // Do some work.
    $variables['text'] = $variables['text'] . " (you have $nb_points points)";
  }
}

Tôi đã xóa bộ đệm (với drush cr) và mục menu hiển thị giá trị tôi muốn. Nhưng, nếu giá trị thay đổi vì một số lý do, nó hiển thị giá trị cũ. Tôi phải xóa bộ nhớ cache mọi lúc để cập nhật giá trị của nó.

Làm cách nào tôi có thể tránh làm sạch bộ đệm để cập nhật tiêu đề menu tất cả các lần điểm đạt được từ người dùng thay đổi?


Có vẻ như bạn cần plugin tùy chỉnh cho việc này. Câu hỏi thú vị. Nói chung, bạn nên tránh thực hiện bất kỳ móc trường học cũ trong D8. Câu hỏi là làm thế nào để thay đổi tiêu đề menu thông qua plugin tùy chỉnh.
Codium

Là thực đơn của bạn trong một khối? Nếu đó là trường hợp có thể cố gắng đặt bộ đệm thành 0 cho khối đó
pbonnefoi

nó là một khối được tạo từ giao diện quản trị. Tôi không truy cập vào cấu hình bộ đệm :)
matthieu lopez

Tôi khuyên bạn nên bắt đầu với drupal.org/docs/8/api/menu-api , '#cache' => ['max-age' => 0], không phải là một giải pháp. bạn cần tạo một liên kết menu động.
Arnold PÉTER

"Mục menu hiển thị giá trị tôi muốn" Bạn đã kiểm tra menu bằng tài khoản người dùng khác chưa? Tôi nghi ngờ nó đang hiển thị cùng một số điểm cho tất cả người dùng.
ya.teck

Câu trả lời:


7

Tôi đề nghị thực hiện một plugin liên kết menu tùy chỉnh. Mã dưới đây giả sử tên mô-đun của bạn là ví dụ .

<?php

namespace Drupal\example\Plugin\Menu;

use Drupal\Core\Database\Connection;
use Drupal\Core\Menu\MenuLinkDefault;
use Drupal\Core\Menu\StaticMenuLinkOverridesInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * A menu link that displays number of points.
 */
class ExampleMenuLink extends MenuLinkDefault {

  /**
   * The database connection.
   *
   * @var \Drupal\Core\Database\Connection
   */
  protected $dbConnection;

  /**
   * Constructs a new points menu link.
   *
   * @param array $configuration
   *   A configuration array containing information about the plugin instance.
   * @param string $plugin_id
   *   The plugin_id for the plugin instance.
   * @param mixed $plugin_definition
   *   The plugin implementation definition.
   * @param \Drupal\Core\Menu\StaticMenuLinkOverridesInterface $static_override
   *   The static override storage.
   * @param \Drupal\Core\Database\Connection $db_connection
   *   The database connection.
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, StaticMenuLinkOverridesInterface $static_override, Connection $db_connection) {
    parent::__construct($configuration, $plugin_id, $plugin_definition, $static_override);
    $this->dbConnection = $db_connection;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('menu_link.static.overrides'),
      $container->get('database')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function getTitle() {
    $count = $this->dbConnection->query('SELECT COUNT(*) FROM {example_points}')->fetchField();
    return $this->t('You have (@count) points', ['@count' => $count]);
  }

  /**
   * {@inheritdoc}
   */
  public function getCacheTags() {
    // Invalidate these tags when number of points is changed.
    return ['example.points_count'];
  }

}

Nếu bạn không muốn tiêm dịch vụ cơ sở dữ liệu, lớp sẽ trở nên đơn giản hơn nhiều.

<?php

namespace Drupal\example\Plugin\Menu;

use Drupal\Core\Menu\MenuLinkDefault;
use Drupal\Core\Menu\StaticMenuLinkOverridesInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * A menu link that displays number of points.
 */
class ExampleMenuLink extends MenuLinkDefault {

  /**
   * {@inheritdoc}
   */
  public function getTitle() {
    $count = \Drupal::database()->query('SELECT COUNT(*) FROM {example_points}')->fetchField();
    return $this->t('You have (@count) points', ['@count' => $count]);
  }

  /**
   * {@inheritdoc}
   */
  public function getCacheTags() {
    // Invalidate these tags when number of points is changed.
    return ['example.points_count'];
  }

}

Tiếp theo, bạn cần đặt định nghĩa liên kết vào tệp example.links.menu.yml .

example.user_points:
  route_name: <front>
  menu_name: main
  class: Drupal\example\Plugin\Menu\ExampleMenuLink
  weight: 30

Vấn đề bộ nhớ đệm

Bất cứ khi nào số lượng điểm được thay đổi, bộ đệm liên kết menu sẽ bị vô hiệu hóa như sau.

 \Drupal::service('cache_tags.invalidator')->invalidateTags(['example.points_count']);

Bạn cần tìm ra đúng nơi cho việc này. Nếu các điểm được quản lý bởi mô-đun đóng góp, hãy kiểm tra API mô-đun và chọn một hook thích hợp ( hook_point_insert () , hook_point_delete () , v.v.).

Vì số điểm được tính cho từng tài khoản người dùng, bạn có thể cân nhắc sử dụng mỗi thẻ bộ nhớ cache của tài khoản (đại loại như ['example.points_count.' . $uid]). Do đó, bộ đệm sẽ được bảo tồn cho người dùng có điểm không thay đổi.


Để tạo mã cho plugin liên kết Menu, tôi đã sử dụng Trình tạo mã Drupal .


Câu trả lời này được đặt ra (và hữu ích hơn tài liệu chính thức hiện tại . Tuy nhiên, tệp yaml nên được đặt tên example.links.menu.yml, không example.menu-links.yml . Sau đó, xóa bộ nhớ cache và mục menu của bạn sẽ xuất hiện.
Sut3kh

Điều này có thể ghi đè lên phương thức getRouteParameter () không? Nếu không, làm thế nào người ta có thể thay đổi route_parameter thành động? Trong trường hợp của tôi, tôi có {user} trong liên kết định tuyến và menu sẽ cung cấp ID người dùng một cách linh hoạt như ID người dùng của người dùng hiện tại.
Igal

@Igal nghĩ là có thể.
ya.teck

2

Tôi phải đối mặt với cùng một vấn đề. Các mục menu được lưu trong bộ nhớ cache, vì vậy nó luôn hiển thị giá trị cũ cho đến khi bạn xóa bộ đệm. Cách khác là sử dụng hook_page_attachments(), đính kèm các điểm vào drupalSinstall.YOUR_MODULE_OR_THEME.YOUR_VARIABLE và truy cập chúng bằng JavaScript và hiển thị trong trình duyệt.

Cách thông thường là vô hiệu hóa bộ đệm cho các trang bất cứ khi nào menu "hồ sơ" hiển thị ở hiệu suất trang.


0

Vô hiệu hóa bộ đệm cho menu đó hook_preprocess_menu()bằng cách đặt $variables['#cache']['max-age']thành 0.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.