web-dev-qa-db-ja.com

ブレッドクラムをどのように実装しますか?

新しいパンくずリストのオーバーライドを定義しようとしましたが、まだサイトのデフォルトを取得しています。

カスタムモジュールfoo_breadcrumbを作成しました。

   - modules/custom/foo_breadcrumb
     - foo_breadcrumb.info.yml
     - foo_breadcrumb.services.yml
     - src/
         - BreadcrumbBuild.php

foo_breadcrumb.services.yml

services:
    foo_breadcrumb.breadcrumb:
        class: Drupal\foo_breadcrumb\BreadcrumbBuild
        tags:
            - { name: breadcrumb_builder, priority: 100 }

内部src/BreadcrumbBuild.php、 私が持っています:

<?php

namespace Drupal\foo_breadcrumb;

use Drupal\Core\Breadcrumb\BreadcrumbBuilderBase;

class BreadcrumbBuild implements BreadcrumbManager {
    /**
     * {@inheritdoc}
     */
    public function applies(array $attributes) {
        return true;
    }

    /**
     * {@inheritdoc}
     */
    public function build(array $attributes) {
        $breadcrumb[] = $this->l($this->t('Test'), NULL);
        $breadcrumb[] = $this->l($this->t('Test2'), 'test');
        return $breadcrumb;
    }
}
?>

私は Drupal 8ブレッドクラム で見つけることができる書き込みのみ)から作業を開始しましたが、問題はそれが古いバージョンのPSR-4オートローディングを使用しているようです(記録のために、私は8.0.0-dev-beta3を使用しています)がもう設置されていないため、他のすべてのモジュールがコードベースでどのように機能するかを確認しました。

これで、モジュールをロードするためにこれが正しいと確信しています。しかし、私はわからない

class BreadcrumbBuild extends BreadcrumbBuilderBase

正しい。問題は、私がBreadcrumbBuilderBaseからの言及にリンクしている古いチュートリアルですが、最新のドキュメントには言及されていないようで、古くなっているのではないか、そしてどうすればよいでしょうか。

同様に、私はservices.ymlファイルはこの点で実行されています。これに関するドキュメントはどこにもありません。

18
njp

うんパンくずを変更し、ドキュメントを更新する必要があります。

同様に、services.ymlファイルがこれに関して何をしているのか本当に理解していません。これについてのドキュメントはどこにもありません。

Drupal 8:クラッシュコース| DrupalConアムステルダム2014 、素晴らしいプレゼンテーション、約47:02:

2ステップのDrupal 8:

  1. ツールを構築する
  2. 配線する

配線は異なる場合があり、アプローチは同じです。

パンくずリストを「配線する」方法:

http://www.palantir.net/blog/d8ftw-breadcrumbs-work の場合:

次に、クラスについてシステムに通知する必要があります。そのために、新しいクラスを参照する新しいサービスを定義します(覚えていますか?)。これは、まさにこの目的のために存在する* .services.ymlファイルで行います。

以前のDrupal=バージョンの「情報フック」と同様に、mymodule.breadcrumbという名前のサービスを定義しています。これはブレッドクラムクラスのインスタンスになります。必要に応じて、クラスのコンストラクターも重要です。ただし、サービスにもタグを付けます。タグ付きサービスはSymfony DependencyInjectionコンポーネントの機能であり、ビルダーにブレッドクラムマネージャーに自動的に接続するようにシステムに指示します。優先度は、さまざまなビルダーがどの順序で2つのapply()メソッドが両方ともtrueを返す場合、どちらのビルダーがより高い優先度を持つかが使用され、もう一方は無視されます。

あなたはあなたが目指すためにこのコードを使うことができます:

構造(あまり問題ではない):

- modules/custom/foo_breadcrumb
  - foo_breadcrumb.info.yml
  - foo_breadcrumb.services.yml
  - src/
    - Breadcrumb/
      - BlogBreadcrumbBuilder.php

foo_breadcrumb.services.yml:

services:
  foo_breadcrumb.breadcrumb_blog:
    class: Drupal\foo_breadcrumb\Breadcrumb\BlogBreadcrumbBuilder
    tags:
      - { name: breadcrumb_builder, priority: 100 }

BlogBreadcrumbBuilder.php:

class BlogBreadcrumbBuilder implements BreadcrumbBuilderInterface {
  use StringTranslationTrait;
  use LinkGeneratorTrait;

  /**
   * @inheritdoc
   */
  public function applies(RouteMatchInterface $route_match) {
    // This breadcrumb apply only for all articles
    $parameters = $route_match->getParameters()->all();
    if (isset($parameters['node'])) {
      return $parameters['node']->getType() == 'article';
    }
  }

  /**
   * @inheritdoc
   */
  public function build(RouteMatchInterface $route_match) {
    $breadcrumb = [Link::createFromRoute($this->t('Home'), '<front>')];
    $breadcrumb[] = Link::createFromRoute($this->t('Blog'), '<<<your route for blog>>>');
    return $breadcrumb;
  }
}

覚えて、最後にキャッシュをクリアしてください。

8
rpayanm

ああ、またか。これらの答えはほとんど正しいです。忘れてはならないことの1つは、「キャッシュタグ」と「キャッシュコンテキスト」です。

ノードに分類基準をパンくずリストとして設定していました。

私はこの投稿からのアドバイスでそれを機能させましたが、私は周りをクリックしてすべてのページに同じパンくずリストに気づきました。

要するに、いくつかのキャッシュコンテキストとタグを設定してください。

ここに要点の私のサービスがあります: https://Gist.github.com/jonpugh/ccaeb01e173abbc6c88f7a332d271e4a

これが私のbuild()メソッドです:

/**
 * {@inheritdoc}
 */
public function build(RouteMatchInterface $route_match) {
  $node = $route_match->getParameter('node');
  $breadcrumb = new Breadcrumb();

  // By setting a "cache context" to the "url", each requested URL gets it's own cache.
  // This way a single breadcrumb isn't cached for all pages on the site.
  $breadcrumb->addCacheContexts(["url"]);

  // By adding "cache tags" for this specific node, the cache is invalidated when the node is edited.
  $breadcrumb->addCacheTags(["node:{$node->nid->value}"]);

  // Add "Home" breadcrumb link.
  $breadcrumb->addLink(Link::createFromRoute($this->t('Home'), '<front>'));

  // Given we have a taxonomy term reference field named "field_section", and that field has data,
  // Add that term as a breadcrumb link.
  if (!empty($node->field_section->entity)) {
    $breadcrumb->addLink($node->field_section->entity->toLink());
  }
  return $breadcrumb;
}
10
Jon Pugh

2016年更新Drupal 8

ドキュメントには、パンくずクラスのインスタンスを返す必要があると記載されています。うまく動作しない場合。ここに私のために働いた解決策があります。

<?php

//modules/MY_MODULE/src/MyBreadcrumbBuilder.php

namespace Drupal\registration;

use Drupal\Core\Breadcrumb\BreadcrumbBuilderInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Breadcrumb\Breadcrumb;
use Drupal\Core\Link;

class MyBreadcrumbBuilder implements BreadcrumbBuilderInterface {

    /**
     * @inheritdoc
     */
    public function applies(RouteMatchInterface $route_match) {
        /* Allways use this. Change this is another module needs to use a new custom breadcrumb */
        return true;
        /* This code allows for only the registration page to get used by this breadcrumb
         * $parameters = explode('.', $route_match->getRouteName());
         * if ($parameters[0] === 'registration') {
         *     return true;
         * } else {
         *     return false;
         * }
         */
    }

    /**
     * @inheritdoc
     */
    public function build(RouteMatchInterface $route_match) {
        $parameters = explode('.', $route_match->getRouteName());
        $b = new Breadcrumb();
        if ($parameters[0] === 'registration') {
            /* If registration page use these links */
            $b->setLinks($this->buildRegistration($parameters[1]));
        }
        return $b;
    }

    /**
     * Creates all the links for the registration breadcrumb
     * @param type $page
     * @return type
     */
    private function buildRegistration($page) {
        return [
            Link::createFromRoute(t('Step One'), 'registration.one'),
            Link::createFromRoute(t('Step Two'), 'registration.two'),
            Link::createFromRoute(t('Step Three'), 'registration.three'),
            Link::createFromRoute(t('Step Four'), 'registration.four'),
            Link::createFromRoute(t('Step Five'), 'registration.five'),
            Link::createFromRoute(t('Step Six'), 'registration.six'),
            Link::createFromRoute(t('Step Seven'), 'registration.seven')
        ];
    }

}

次に、ymlファイル

# modules/MY_MODULE/registration/MY_MODULE.services.yml
services:
  registration.breadcrumb:
    class: Drupal\registration\MyBreadcrumbBuilder
    tags:
      - { name: breadcrumb_builder, priority: 100 }

PS:bootstrapを使用している場合は、/admin/appearance/settings設定ページに移動してブレッドクラム設定を確認してください。 Show 'Home' breadcrumb linkをオンにする必要があります。そしてShow current page title at endをオフにする必要があります。

やっとこれが終わったらキャッシュをクリアします。 YMLファイルを変更するたびに、デバッグモードでも、キャッシュをクリアする必要があります。行き詰まって再構築できない場合は、/core/rebuild.phpにアクセスできます。

8
Neoaptt

キャッシングを忘れないでください

レンダーキャッシュはD8開発サイクルのかなり後の方で変更されたため、d8ftwシリーズやこの質問に対する他の回答では言及されていません。

キャッシュAPIドキュメント は、特に配列のレンダリングを指しますが、これらの手順はすべて、パンくずリストにも同様に適用されます。ブレッドクラムには toRenderable() メソッドがあり、Drupalはレンダーキャッシュにそれらをキャッシュしようとします。つまり、must十分な情報を指定して、Drupalが適切に実行できるようにします。

詳細はドキュメントにありますが、短いバージョンでは BreadcrumbRefinableCachableDependencyInterface を実装しています。ビルダークラスでは、ブレッドクラムの構築に使用されるすべてのエンティティまたは構成オブジェクトを指定して addCachableDependency() を呼び出す必要があります。 「CacheableDependencyInterface&フレンズ」のドキュメント は、その方法と理由を詳しく説明しています。

ブレッドクラムが変更される可能性がある他のコンテキストがある場合は、ブロックを確実に変更するために、手動で addCacheContexts() を使用する必要もあります addCacheTags() キャッシュエントリを正しく無効にできることを確認します。 mergeCacheMaxAge() キャッシュが時間に敏感で、期限切れにする必要がある場合。

これが適切に行われない場合、カスタムBreadcrumbビルダーサービスの1つが「勝ち」、その1つの特定のページのブレッドクラムがすべての訪問者にすべてのページで永久に提供されます。

7
Sean C.

これを達成する別の方法があります。

/**
 * Implements hook_preprocess_breadcrumb().
 */
 function theme_name_preprocess_breadcrumb(&$variables){
  if(($node = \Drupal::routeMatch()->getParameter('node')) && $variables['breadcrumb']){
    $variables['breadcrumb'][] = array(
     'text' => $node->getTitle() 
   );
  }
}

次に、テーマのテンプレートフォルダーに「breadcrumb.html.twig」という名前の別のファイルを作成し、このファイルのコードの下に配置します。

{% if breadcrumb %}
  <nav class="breadcrumb" role="navigation" aria-labelledby="system-breadcrumb">
    <h2 id="system-breadcrumb" class="visually-hidden">{{ 'Breadcrumb'|t }}</h2>
    <ul>
    {% for item in breadcrumb %}
      <li>
        {% if item.url %}
          <a href="{{ item.url }}">{{ item.text }}</a>
        {% else %}
          {{ item.text }}
        {% endif %}
      </li> /
    {% endfor %}
    </ul>
  </nav>
{% endif %}

それでおしまい。キャッシュをフラッシュすると、Home/Current Page Titleのような現在のページタイトルが付いたブレッドクラムが表示されます。 「/」を目的のセパレーターに置き換えることで、セパレーターを変更できます。

4
Sachin

現在のページのクラムなどの現在のページタイトルをブレッドクラムに追加するには、contribモジュールを使用する必要があります。 https://www.drupal.org/project/current_page_crumb

手動でコーディングしたい場合は、そのモジュールのsrcフォルダーからコードをプルできます。 Drupal 8つのパンくずリストについて詳しくはこちらをご覧ください: http://www.gregboggs.com/drupal8-breadcrumbs/

2
Greg Boggs

Drupal 7でトークンを使用してカスタムブレッドクラムを使用しており、そのモジュールがDrupal 8で使用できない場合、元はトークンフィールドであったフィールドです。これをブロックとして使用し、通常のブレッドクラムを無効にします。カスタムブレッドクラムより少し手間がかかりましたが、機能します。

0
weben