Jak wdrożyć bułkę tartą?

18

Próbowałem zdefiniować nowy sposób zastępowania okruszków, ale nadal dostaję domyślną stronę.

Utworzyłem niestandardowy moduł, foo_breadcrumb:

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

Oto foo_breadcrumb.services.yml:

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

W środku src/BreadcrumbBuild.phpmam:

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

Zacząłem pracować nad jedynym opisem, jaki mogłem znaleźć na bułce tartej Drupal 8 , ale wydaje się, że używa starszej wersji automatycznego ładowania PSR-4, która nie jest już na miejscu (dla rekordu jestem w wersji 8.0.0 -dev-beta3), więc sprawdziłem, jak działają wszystkie pozostałe moduły w bazie kodu.

Teraz jestem całkiem pewien, że to poprawne, aby moduł się załadował; jednak nie jestem pewien, czy

class BreadcrumbBuild extends BreadcrumbBuilderBase

jest poprawne. Problem polega na tym, że stary samouczek, do którego nawiązałem, wzmiankuje BreadcrumbBuilderBase, ale bardziej aktualne dokumenty nie wydają się o nim wspominać i zastanawiam się, czy jest nieaktualny - i jak powinienem to zrobić.

Podobnie, tak naprawdę nie rozumiem, co services.ymlrobi plik w tym zakresie, nigdzie nie ma na to dokumentacji.

njp
źródło

Odpowiedzi:

8

Tak, bułka tarta zmieniona i dokumentacja musi zostać zaktualizowana.

Podobnie, tak naprawdę nie rozumiem, co robi plik services.yml w tym zakresie, nigdzie nie ma na to dokumentacji.

Dla Drupal 8: The Crash Course | DrupalCon Amsterdam 2014 , świetna prezentacja, około 47:02:

Drupal 8 w 2 krokach:

  1. Zbuduj narzędzie
  2. Połącz to

Okablowanie może się różnić, podejście jest takie samo.

Jak „łączymy” bułkę tartą:

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

Teraz musimy powiedzieć systemowi o naszej klasie. W tym celu definiujemy nową usługę (pamiętasz te?) Odnoszącą się do naszej nowej klasy. Zrobimy to w naszym pliku * .services.yml, który istnieje właśnie w tym celu

Podobnie do „haka informacyjnego” w poprzednich wersjach Drupala, definiujemy usługę o nazwie mymodule.breadcrumb. Będzie to przykład naszej klasy bułki tartej. W razie potrzeby możemy przekazać argumenty również konstruktorowi naszej klasy. Co ważne, oznaczamy również usługę. Tagowane usługi są specyficzną cechą komponentu Symfony DependencyInjection i informują system, aby automatycznie łączył naszego konstruktora z menedżerem breadcrumb. Priorytet określa, w jakiej kolejności należy wywoływać różnych konstruktorów, najpierw najwyższy. W przypadku, gdy dwie metody apply () mogą zwrócić wartość true, zostanie użyty ten, który ma wyższy priorytet, a drugi zostanie zignorowany.

Możesz użyć tego kodu w celu:

Struktura (nie ma większego znaczenia):

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

Pamiętaj, wyczyść pamięć podręczną na końcu.

rpayanm
źródło
Jak dotąd bez radości. Faktycznie skopiowałem taksonomię w rdzeniu tak dokładnie, jak to możliwe, ponieważ miała działającą implementację (mogę wywołać dpm ('Test') z metody apply () i wyświetli się. Ale nie w moim kodzie; nawet umyślne błędy składniowe pojawia się - co sprawia, że ​​podejrzewam, że routing usługi jest nieprawidłowy. Ale mój yaml jest prawidłowy ... westchnienie :(
njp
1
@njp przejrzyj ścieżkę Twojej klasy Breadcrumb (dodaję folder Breadcrumb) i musi on pasować do parametru „class” w pliku usługi. Zbyt sprawdzane są wszystkie nazwy klas, czasami nie pasują do niektórych plików lub parametrów.
rpayanm,
1
Gratulacje! Jedno pytanie: czy „wyczyściłeś pamięć podręczną” po wprowadzeniu modyfikacji? Być może tak może być.
rpayanm,
1
Tak, musisz wyczyścić pamięć podręczną, co powinno wystarczyć do zaktualizowania usług. Warto również wspomnieć o priorytecie. Pierwszy konstruktor, który zwraca PRAWDA z apply (), wygra, więc może być konieczne wyszukiwanie innych usług za pomocą tego tagu (co jest łatwym wyszukiwaniem tekstu) i sprawdzenie ich wagi oraz implementacji apply ().
Berdir
1
@ njp wręcz przeciwnie, priorytet określa, w jakiej kolejności należy wywoływać różnych konstruktorów, najpierw najwyższy. W przypadku, gdy dwie metody apply () mogą zwrócić wartość true, zostanie użyty ten, który ma wyższy priorytet, a drugi zostanie zignorowany.
rpayanm
10

Znowu zaczynamy. Te odpowiedzi są w większości prawidłowe. Jedną z rzeczy, o których nie można zapomnieć, są „tagi pamięci podręcznej” i „konteksty pamięci podręcznej”.

Ustawiałem termin taksonomii na węźle jako bułkę tartą.

Pracowałem z radami tego postu, ale potem kliknąłem i zauważyłem te same bułki tarte na każdej stronie.

Krótko mówiąc, pamiętaj o ustawieniu kontekstów i tagów pamięci podręcznej.

Oto moja usługa w skrócie: https://gist.github.com/jonpugh/ccaeb01e173abbc6c88f7a332d271e4a

Oto moja metoda 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;
}
Jon Pugh
źródło
Ten problem z pamięcią podręczną doprowadzał mnie do szału i wiele informacji w blogach itp. Wydaje się pomijać ten punkt - dziękuję!
kbrinner
8

Aktualizacja 2016 Drupal 8

Dokumentacja stanowi, że musisz zwrócić instancję klasy breadcrumb. Jeśli masz problemy z uruchomieniem go. oto rozwiązanie, które zadziałało dla mnie.

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

}

Następnie plik yml

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

PS: jeśli używasz bootstrap, przejdź do /admin/appearance/settingsstrony ustawień i sprawdź ustawienia bułki tartej. Show 'Home' breadcrumb linknależy sprawdzić. I Show current page title at endnależy to sprawdzić.

Po tym wszystkim wyczyść pamięć podręczną. Za każdym razem, gdy zmieniasz plik YML, nawet w trybie debugowania, musisz wyczyścić pamięć podręczną. możesz przejść, /core/rebuild.phpjeśli utkniesz i nie możesz odbudować.

Neoaptt
źródło
7

Nie zapomnij o buforowaniu

Pamięć podręczna renderowania została zmieniona dość późno w cyklu rozwoju D8, dlatego nie jest wspomniana w serii d8ftw ani w innych odpowiedziach na to pytanie.

Dokumentacja API pamięci podręcznej odnosi się konkretnie do renderowania tablic, ale wszystkie te instrukcje dotyczą jednakowo bułki tartej. Bułka tarta ma toRenderable()metodę, Drupal będzie próbował buforować je w pamięci podręcznej renderowania, a to oznacza, że musisz podać wystarczającą ilość informacji, aby Drupal mógł to zrobić poprawnie.

Szczegóły znajdują się w dokumentacji, ale krótka wersja Breadcrumbimplementuje RefinableCachableDependencyInterface. W swojej klasie konstruktora będziesz chciał wywoływać addCachableDependency()dowolne jednostki lub obiekty konfiguracyjne, które są używane do budowania bułki tartej. Dokumentacja „CacheableDependencyInterface & friends” zawiera bardziej szczegółowe informacje na temat tego, jak i dlaczego.

Jeśli istnieją inne konteksty, w których bułka tarta może ulec zmianie, musisz również ręcznie użyć, addCacheContexts()aby upewnić się, że blok się zmienia, addCacheTags()aby upewnić się, że wpis w pamięci podręcznej może zostać poprawnie unieważniony, a mergeCacheMaxAge()jeśli pamięć podręczna jest wrażliwa na czas i musi wygasnąć.

Jeśli nie zostanie to wykonane poprawnie, jedna z niestandardowych usług konstruktora Breadcrumb „wygra”, a bułka tarta dla tej konkretnej strony będzie wyświetlana na każdej stronie wszystkim użytkownikom na zawsze.

Sean C.
źródło
4

Jest inny sposób na osiągnięcie tego.

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

A następnie utwórz inny plik w folderze szablonów kompozycji o nazwie „breadcrumb.html.twig” i umieść poniższy kod w tym pliku:

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

Otóż ​​to. Teraz opróżnij pamięć podręczną, a pojawi się menu nawigacyjne z bieżącym tytułem strony, takim jak Strona główna / Bieżący tytuł strony. Możesz zmienić separator, zastępując „/” żądanym.

Sachin
źródło
2

Powinieneś użyć modułu contrib, aby dodać bieżący tytuł strony do breadcrumb, takiego jak Current Page Crumb: https://www.drupal.org/project/current_page_crumb

Jeśli chcesz go ręcznie kodować, możesz pobrać kod z folderu src tego modułu. Więcej informacji o bułce tartej Drupal 8 można znaleźć tutaj: http://www.gregboggs.com/drupal8-breadcrumbs/

Greg Boggs
źródło
To jest tak frustrujące, że coś tak prostego musi wymagać pobrania modułów contrib, aby go dodać.
Kevin
Taki jest sposób Drupala. Chociaż Drupal 8 ma teraz rdzeń TON, którego Drupal 7 nigdy nie zrobił. Naprawiłbym rdzeń bułki tartej Drupal 8 w rdzeniu, gdybym mógł. Ale drush en current_page_crumbnie jest tak źle.
Greg Boggs,
0

Użyłem niestandardowych bułek tartych przy użyciu tokena w Drupal 7, a kiedy ten moduł nie był dostępny w Drupal 8, ostatecznie stworzyłem widoki dla moich indywidualnych typów treści, używając pól, które pierwotnie były polami tokenów. Używanie go jako bloku i wyłączanie normalnej bułki tartej. To było trochę więcej pracy niż Custom Breadcrumbs, ale działa.

weben
źródło