Bagaimana Anda menerapkan remah roti?


18

Saya sudah mencoba mendefinisikan override breadcrumb baru, tetapi saya masih mendapatkan situs default.

Saya telah membuat modul khusus, foo_breadcrumb:

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

Inilah foo_breadcrumb.services.yml:

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

Di dalam src/BreadcrumbBuild.php, saya punya:

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

Saya mulai mengerjakan satu - satunya writeup yang dapat saya temukan di remah roti Drupal 8 , tetapi masalahnya tampaknya menggunakan versi lama dari autoloading PSR-4 yang tidak lagi terpasang (sebagai catatan saya menggunakan 8.0.0 -dev-beta3), jadi saya membahas bagaimana semua modul lainnya bekerja di basis kode.

Sekarang saya cukup yakin ini benar untuk mendapatkan modul memuat; namun saya tidak yakin apakah

class BreadcrumbBuild extends BreadcrumbBuilderBase

benar. Masalahnya adalah bahwa tutorial lama yang saya tautkan dengan menyebutkan berasal dari BreadcrumbBuilderBase, tetapi semakin banyak dokumen saat ini tampaknya tidak menyebutkannya dan saya bertanya-tanya apakah itu sudah ketinggalan zaman - dan bagaimana saya harus melakukan ini.

Demikian juga, saya tidak begitu mengerti apa yang dilakukan services.ymlfile dalam hal ini, tidak ada dokumentasi di mana pun untuk ini.

Jawaban:


8

Ya remah roti berubah dan dokumentasi harus diperbarui.

Demikian juga, saya tidak begitu mengerti apa yang dilakukan oleh file services.yml dalam hal ini, tidak ada dokumentasi di mana pun untuk ini.

Untuk Drupal 8: Kursus Kecelakaan | DrupalCon Amsterdam 2014 , presentasi yang luar biasa, sekitar 47:02:

Drupal 8 dalam 2 langkah:

  1. Bangun alat
  2. Sambungkan

Kabel dapat bervariasi, pendekatannya sama.

Bagaimana kami "Memasangnya" pada remah roti:

Untuk http://www.palantir.net/blog/d8ftw-breadcrumbs-work :

Sekarang kita perlu memberi tahu sistem tentang kelas kita. Untuk melakukan itu, kami mendefinisikan layanan baru (ingat?) Yang merujuk pada kelas baru kami. Kami akan melakukannya di file * .services.yml kami, yang ada persis untuk tujuan ini

Mirip dengan "info hook" di versi Drupal sebelumnya, kami mendefinisikan layanan bernama mymodule.breadcrumb. Ini akan menjadi instance dari kelas remah roti kami. Jika perlu kita bisa meneruskan argumen ke konstruktor kelas kita juga. Yang penting, kami juga menandai layanan ini. Layanan yang ditandai adalah fitur komponen Symfony DependencyInjection secara khusus dan memberi tahu sistem untuk secara otomatis menghubungkan pembuat kami ke pengelola breadcrumb. Prioritas menentukan dalam urutan apa berbagai pembangun harus dipanggil, tertinggi terlebih dahulu. Dalam kasus dua berlaku () metode dapat kembali benar, pembangun mana pun yang memiliki prioritas lebih tinggi akan digunakan dan yang lainnya diabaikan.

Anda dapat menggunakan kode ini untuk tujuan Anda:

Struktur (tidak terlalu penting):

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

Ingat, kosongkan cache di akhir.


Tidak ada sukacita sejauh ini. Saya benar-benar menyalin taksonomi dalam inti sedekat mungkin karena ini memiliki implementasi yang berfungsi (saya dapat memanggil dpm ('Test') dari metode apply () dan itu akan keluar. Tetapi tidak demikian dalam kode saya, bahkan tidak ada kesalahan sintaksis yang disengaja muncul - yang membuat saya curiga perutean layanan tidak benar. Tapi yaml saya valid ... sigh :(
njp

1
@ njp meninjau jalur Anda kelas Breadcrumb (saya menambahkan folder Breadcrumb) dan harus sesuai dengan parameter "class" pada file layanan Anda. Periksa juga semua nama kelas, terkadang tidak cocok dengan beberapa file atau parameter.
rpayanm

1
Selamat! Satu pertanyaan: apakah Anda "membersihkan cache" setelah modifikasi? Mungkin itu bisa saja.
rpayanm

1
Ya, Anda perlu menghapus cache, yang seharusnya cukup untuk memperbarui layanan. Juga, satu yang mungkin layak disebutkan adalah prioritas. Pembangun pertama yang mengembalikan TRUE dari apply () akan menang, jadi Anda mungkin perlu mencari layanan lain dengan tag itu (yang merupakan pencarian teks mudah) dan memeriksa bobotnya dan menerapkan () implementasi.
Berdir

1
@ njp sebaliknya, prioritas menentukan dalam urutan apa berbagai pembangun harus dipanggil, tertinggi terlebih dahulu. Dalam kasus dua berlaku () metode dapat kembali benar, pembangun mana pun yang memiliki prioritas lebih tinggi akan digunakan dan yang lainnya diabaikan.
rpayanm

10

Baiklah, kita lanjut lagi. Jawaban-jawaban ini sebagian besar benar. Satu hal yang tidak dapat Anda lupakan adalah "tag cache" dan "konteks cache".

Saya menyiapkan istilah taksonomi pada simpul sebagai remah roti.

Saya mendapatkannya bekerja dengan saran dari posting ini, tetapi kemudian saya mengklik dan melihat remah roti yang sama pada setiap halaman.

Singkat cerita, pastikan untuk mengatur beberapa konteks dan tag cache.

Inilah layanan saya di intisari: https://gist.github.com/jonpugh/ccaeb01e173abbc6c88f7a332d271e4a

Inilah metode build () saya:

/**
 * {@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;
}

Masalah caching ini membuat saya gila dan banyak informasi daring di blog dll. Sepertinya melewatkan hal ini - terima kasih!
kbrinner

8

Perbarui 2016 Drupal 8

Dokumentasi menyatakan bahwa Anda harus mengembalikan turunan dari kelas breadcrumb. Jika Anda kesulitan membuatnya bekerja. di sini adalah solusi yang bekerja untuk saya.

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

}

Lalu file yml

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

PS: jika Anda menggunakan bootstrap pergi ke /admin/appearance/settingshalaman pengaturan Anda dan lihat pengaturan remah roti. Show 'Home' breadcrumb linkharus diperiksa. Dan Show current page title at endharus diperiksa.

Setelah semua ini dilakukan, bersihkan cache Anda. Setiap kali Anda mengubah file YML, bahkan dalam mode debug, Anda perlu menghapus cache Anda. Anda dapat pergi ke /core/rebuild.phpjika Anda macet dan tidak dapat membangun kembali.


7

Jangan lupa caching

Cache render diubah cukup terlambat dalam siklus pengembangan D8, dan karena itu tidak disebutkan dalam seri d8ftw, atau jawaban lain untuk pertanyaan ini.

The Cache dokumentasi API merujuk secara khusus untuk membuat array, tetapi semua instruksi yang berlaku untuk Breadcrumbs. Breadcrumbs memiliki toRenderable()metode, Drupal akan mencoba untuk me-cache mereka di cache render, dan itu berarti Anda harus menentukan informasi yang cukup untuk memungkinkan Drupal melakukannya dengan benar.

Detailnya ada di dokumen, tetapi versi singkatnya adalah yang Breadcrumbmengimplementasikan RefinableCachableDependencyInterface. Di kelas pembangun Anda, Anda akan ingin memanggil addCachableDependency()dengan semua dan semua entitas atau objek konfigurasi yang digunakan untuk membangun remah roti. Dokumentasi untuk 'CacheableDependencyInterface & friends' menjelaskan lebih detail tentang bagaimana dan mengapa.

Jika ada konteks lain di mana remah roti mungkin berubah, Anda juga harus menggunakan secara manual addCacheContexts()untuk memastikan blok bervariasi, addCacheTags()untuk memastikan entri cache dapat dibatalkan dengan benar, dan mergeCacheMaxAge()jika cache sensitif terhadap waktu dan perlu kedaluwarsa.

Jika ini tidak dilakukan dengan benar, salah satu layanan pembuat Breadcrumb kustom Anda akan 'menang', dan remah roti untuk satu halaman tertentu akan disajikan di setiap halaman, untuk semua pengunjung, selamanya.


4

Ada cara lain untuk mencapai ini.

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

Dan kemudian buat file lain di folder templat tema Anda yang dinamai "breadcrumb.html.twig" dan tuliskan kode di bawah ini dalam file ini:

{% 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 %}

Itu dia. Sekarang siram cache dan Anda akan mendapatkan remah roti dengan judul halaman saat ini seperti Home / Current Page Title. Anda dapat mengubah pemisah dengan mengganti "/" dengan yang diinginkan.


2

Anda harus menggunakan modul contrib untuk menambahkan judul halaman saat ini ke breadcrumb seperti Crumb Halaman Saat Ini: https://www.drupal.org/project/current_page_crumb

Jika ingin memberikan kode tangan, Anda dapat menarik kode dari folder src pada modul itu. Anda dapat menemukan rincian lebih lanjut tentang Drupal 8 breadcrumbs di sini: http://www.gregboggs.com/drupal8-breadcrumbs/


Sangat menyebalkan bahwa sesuatu yang sederhana seperti ini harus memerlukan modul contrib untuk menambahkannya.
Kevin

Begitulah cara Drupal. Meskipun Drupal 8 sekarang melakukan TON di inti yang Drupal 7 tidak pernah lakukan. Saya akan memperbaiki inti Drupal 8 remah roti di inti jika saya bisa. Tapi, drush en current_page_crumbtidak terlalu buruk.
Greg Boggs

0

Saya telah menggunakan Custom Breadcrumbs menggunakan token di Drupal 7 dan ketika modul itu tidak tersedia untuk Drupal 8, saya akhirnya membuat tampilan untuk masing-masing tipe konten saya menggunakan bidang yang awalnya merupakan bidang token. Menggunakannya sebagai blok dan menonaktifkan remah roti normal. Itu sedikit lebih banyak bekerja daripada Custom Breadcrumbs tetapi berhasil.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.