Ekmek kırıntısını nasıl uygularsınız?


18

Yeni bir kırıntı geçersiz kılma tanımlamaya çalıştım, ancak yine de site varsayılanını alıyorum.

Foo_breadcrumb özel bir modül oluşturdum:

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

İşte foo_breadcrumb.services.yml:

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

İçimde 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 ekmek kırıntılarında bulabileceğim tek yazı üzerinde çalışmaya başladım , ancak mesele artık PSR-4 otomatik yüklemesinin artık yerinde olmayan eski bir sürümünü kullanıyor gibi görünüyor (kayıt için 8.0.0'dayım -dev-beta3) ve diğer tüm modüllerin kod tabanında nasıl çalıştığını anladım.

Şimdi modülün yüklenmesini sağlamak için bunun doğru olduğundan eminim; ancak emin değilim

class BreadcrumbBuild extends BreadcrumbBuilderBase

doğru. Sorun şu ki, bahsettiğim eski öğretici, genişleyen sözler BreadcrumbBuilderBase, ancak daha güncel dokümanlar bundan bahsetmiyor gibi görünüyor ve güncel olup olmadığını merak ediyorum - ve bunu nasıl yapmalıyım.

Aynı şekilde, services.ymldosyanın bu konuda ne yaptığını gerçekten anlamıyorum , bunun için hiçbir yerde belge yok.

Yanıtlar:


8

Evet, kırıntı değişti ve belgelerin güncellenmesi gerekiyor.

Aynı şekilde, services.yml dosyasının bu konuda ne yaptığını gerçekten anlamıyorum, bunun için hiçbir yerde belge yok.

İçin | Crash Course: Drupal 8 DrupalCon Amsterdam 2014 , harika sunum, yaklaşık 47:02:

2 adımda Drupal 8:

  1. Bir araç oluşturun
  2. Bağlayın

Kablolama değişebilir, yaklaşım aynıdır.

Ekmek kırıntısını nasıl "bağlarız":

İçin http://www.palantir.net/blog/d8ftw-breadcrumbs-work :

Şimdi sisteme sınıfımızdan bahsetmeliyiz. Bunu yapmak için yeni sınıfımızı referans alan yeni bir hizmet (bunları hatırlıyor musunuz?) Tanımlarız. Bunu tam olarak bu amaç için var olan * .services.yml dosyamızda yapacağız

Önceki Drupal sürümlerindeki bir "bilgi kancası" na benzer şekilde, mymodule.breadcrumb adlı bir hizmet tanımlıyoruz. Bu, kırıntı sınıfımızın bir örneği olacak. Gerekirse sınıfımızın yapıcısına da argümanlar aktarabiliriz. Yine de, hizmeti de etiketliyoruz. Etiketli hizmetler Symfony DependencyInjection bileşeninin bir özelliğidir ve sisteme, üreticimizi otomatik olarak kırıntı yöneticisine bağlamasını bildirir. Öncelik, çeşitli inşaatçıların hangi sırayla çağrılması gerektiğini en yüksekte belirtir. İki Apply () yönteminin her ikisi de true değerini döndürebiliyorsa, hangisinin daha yüksek önceliğe sahip olduğu kullanılır ve diğeri yok sayılır.

Bu kodu amaçlamak için kullanabilirsiniz:

Yapı (çok önemli değil):

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

Unutmayın, sonunda önbelleği temizleyin.


Şimdiye kadar sevinç yok. Aslında taksonomiyi çekirdeğimi olabildiğince kopyaladım (bu, uygulama () yönteminden dpm ('Test') diyebilirim ve çıktı alır. Ama kodumda öyle değil; kasıtlı sözdizimi hataları bile değil) görünür - bu da hizmet yönlendirmesinin doğru olmadığından şüphelenmemi sağlıyor.Ancak
yaml'im

1
@njp size Breadcrumb sınıfının yolunu gözden geçiririm (Breadcrumb klasörünü eklerim) ve servis dosyasındaki "class" parametresiyle eşleşmelidir. Sınıfın tüm adlarını çok fazla kontrol edin, bazen bazı dosya veya parametrelerde eşleşmiyor.
rpayanm

1
Tebrik! Bir soru: değişikliklerden sonra "önbelleği temizlediniz mi?" Belki de bu olabilir.
rpayanm

1
Evet, hizmetleri güncellemek için yeterli olan önbelleği temizlemeniz gerekir. Ayrıca, bahsetmeye değer bir şey önceliktir. True () değerini TRUE döndüren ilk oluşturucu kazanacaktır, bu nedenle bu etiketle (kolay bir metin aramasıdır) diğer hizmetleri aramanız ve ağırlıklarını kontrol etmeniz ve uygulamaları uygulamanız gerekebilir.
Berdir

1
@njp, öncelikli olarak, çeşitli inşaatçıların hangi sırayla çağırılması gerektiğini en yüksekte belirtir. İki Apply () yönteminin her ikisi de true değerini döndürebiliyorsa, hangisinin daha yüksek önceliğe sahip olduğu kullanılır ve diğeri yok sayılır.
rpayanm

10

İşte yine gidiyoruz. Bu cevaplar çoğunlukla doğrudur. Unutamayacağınız bir şey "önbellek etiketleri" ve "önbellek bağlamları" dır.

Bir düğüm üzerinde bir kırıntı olarak bir sınıflandırma terimi ayarlıyordum.

Bu yazıdan tavsiye ile çalıştım, ama sonra tıkladım ve her sayfada aynı ekmek kırıntılarını fark ettim.

Uzun lafın kısası, bazı önbellek bağlamları ve etiketleri ayarladığınızdan emin olun.

İşte bir özette hizmetim: https://gist.github.com/jonpugh/ccaeb01e173abbc6c88f7a332d271e4a

İşte benim build () yöntemi:

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

Bu önbellek sorunu beni deli ediyordu ve bloglar vb çevrimiçi birçok bilgi bu noktayı kaçırmak gibi görünüyor - teşekkür ederim!
kbrinner

8

Güncelleme 2016 Drupal 8

Belgeler, kırıntı sınıfının bir örneğini döndürmeniz gerektiğini belirtir. Eğer işe almakta sorun yaşıyorsanız. işte benim için işe yarayan çözüm.

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

}

Sonra yml dosyası

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

Not: Bootstrap kullanıyorsanız /admin/appearance/settingsayarlar sayfanıza gidin ve ekmek kırıntıları ayarlarına bakın. Show 'Home' breadcrumb linkkontrol edilmelidir. Ve Show current page title at endkontrol edilmelidir.

Tüm bunlar yapıldıktan sonra önbelleğinizi temizleyin. Bir YML dosyasını her değiştirdiğinizde, hata ayıklama modunda bile önbelleğinizi temizlemeniz gerekir. Eğer gidebilirsiniz /core/rebuild.phpeğer takılıyorum ve yeniden olamaz.


7

Önbelleğe almayı unutma

Oluşturma önbelleği D8 geliştirme döngüsünde oldukça geç değiştirildi ve bu nedenle d8ftw serisinde veya bu sorunun diğer cevaplarında belirtilmedi.

Önbellek API belgeleri diziler işlemek için özel olarak ifade eder; ancak bu talimatların tümünü kırıntıları aynı şekilde uygulanır. Ekmek kırıntılarının bir toRenderable()yöntemi vardır, Drupal bunları oluşturma önbelleğinde önbelleğe almaya çalışır ve bu, Drupal'ın düzgün bir şekilde yapmasına izin vermek için yeterli bilgi belirtmeniz gerektiği anlamına gelir .

Ayrıntıları dokümanlarında, ama kısa versiyon olmasıdır Breadcrumbuygular RefinableCachableDependencyInterface. Oluşturucu sınıfınızda, addCachableDependency()kırıntı oluşturmak için kullanılan tüm varlıklarla veya yapılandırma nesneleriyle çağrı yapmak istersiniz . 'CacheableDependencyInterface & friends' belgeleri nasıl ve niçin daha ayrıntılı.

Ekmek kırıntısının değişebileceği başka bağlamlar varsa addCacheContexts(), bloğun değiştiğinden addCacheTags()emin olmak için, önbellek girişinin doğru bir şekilde geçersiz kılınabildiğinden emin olmak için manuel olarak da kullanmanız vemergeCacheMaxAge() önbelleğin zamana duyarlı ve süresinin dolması .

Bu doğru şekilde yapılmazsa, özel Breadcrumb oluşturucu hizmetlerinizden biri 'kazanır' ve belirli bir sayfanın ekmek kırıntıları her sayfada, tüm ziyaretçilere sonsuza kadar sunulur.


4

Bunu başarmanın başka bir yolu var.

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

Ardından temanızın şablon klasöründe "breadcrumb.html.twig" adlı başka bir dosya oluşturun ve bu dosyaya aşağıdaki kodu yazın:

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

Bu kadar. Şimdi önbelleği temizleyin ve Ana Sayfa / Geçerli Sayfa Başlığı gibi geçerli sayfa başlığına sahip kırıntı elde edersiniz. Ayırıcıyı "/" yerine istediğiniz bir tane koyarak değiştirebilirsiniz.


2

Geçerli sayfa başlığını Geçerli Sayfa Kırıntısı gibi ekmek kırıntısına eklemek için katkıda bulunan bir modül kullanmalısınız: https://www.drupal.org/project/current_page_crumb

El kodlaması yapmak isterseniz, kodu bu modülün src klasöründen alabilirsiniz. Drupal 8 ekmek kırıntıları hakkında daha fazla bilgiyi burada bulabilirsiniz: http://www.gregboggs.com/drupal8-breadcrumbs/


Bu kadar basit bir şeyin onu eklemek için katkıda bulunan modüller gerektirmesi kadar sinir bozucu.
Kevin

Drupal yolu böyle. Her ne kadar Drupal 8 şimdi Drupal 7'nin hiç yapmadığı bir TON yapıyor. Çekebilseydim çekirdek Drupal 8 kırıntılarını düzeltebilirdim. Ama drush en current_page_crumbo kadar da kötü değil.
Greg Boggs

0

Drupal 7'de token kullanarak Özel Breadcrumbs kullanmıştım ve bu modül Drupal 8 için mevcut olmadığında, orijinal olarak token alanları olan alanları kullanarak bireysel içerik türlerim için görünümler oluşturdum. Bir blok olarak kullanmak ve normal kırıntıyı devre dışı bırakmak. Custom Breadcrumbs'dan biraz daha fazla işti ama işe yarıyor.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.