web-dev-qa-db-fra.com

Comment implémentez-vous un fil d'Ariane?

J'ai essayé de définir un nouveau remplacement de fil d'Ariane, mais j'obtiens toujours le site par défaut.

J'ai créé un module personnalisé, foo_breadcrumb:

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

Voici le foo_breadcrumb.services.yml:

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

À l'intérieur src/BreadcrumbBuild.php, J'ai:

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

J'ai commencé à travailler sur le seul document que j'ai pu trouver sur Drupal 8 chapelure , mais le fait est qu'il semble utiliser une ancienne version du chargement automatique du PSR-4 qui n'est plus en place (pour mémoire, je suis sur 8.0.0-dev-beta3), et donc je suis allé voir comment tous les autres modules fonctionnent dans la base de code.

Maintenant, je suis assez certain que cela est correct pour charger le module; mais je ne sais pas si

class BreadcrumbBuild extends BreadcrumbBuilderBase

est correct. Le problème est que l'ancien tutoriel que j'ai lié aux mentions s'étendant de BreadcrumbBuilderBase, mais les documents les plus récents ne semblent pas le mentionner et je me demande s'il est obsolète - et comment je dois le faire.

De même, je ne comprends pas vraiment ce que le services.yml le fichier fait à cet égard, il n'y a aucune documentation pour cela.

18
njp

Ouais le fil d'Ariane a changé et la documentation doit être mise à jour.

De même, je ne comprends pas vraiment ce que fait le fichier services.yml à cet égard, il n'y a aucune documentation pour cela.

Pour Drupal 8: The Crash Course | DrupalCon Amsterdam 2014 , présentation impressionnante, environ 47:02:

Drupal 8 en 2 étapes:

  1. Construire un outil
  2. Câbler

Le câblage peut varier, l'approche est la même.

Comment nous "câblons" le fil d'Ariane:

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

Maintenant, nous devons parler au système de notre classe. Pour ce faire, nous définissons un nouveau service (vous vous en souvenez?) Référençant notre nouvelle classe. Nous le ferons dans notre fichier * .services.yml, qui existe exactement à cet effet

Semblable à un "info hook" dans les versions précédentes Drupal, nous définissons un service nommé mymodule.breadcrumb. Ce sera une instance de notre classe de fil d'Ariane. Si nécessaire, nous pourrions passer des arguments à notre Le constructeur de notre classe également. Il est important de noter, cependant, que nous marquons également le service. Les services balisés sont une caractéristique du composant Symfony DependencyInjection spécifiquement et indiquent au système de connecter automatiquement notre générateur au gestionnaire de fil d'Ariane. La priorité spécifie dans quel ordre les différents constructeurs doivent être appelé, le plus haut en premier. Dans le cas où deux méthodes apply () pourraient toutes deux renvoyer true, le constructeur ayant la priorité la plus élevée sera utilisé et l'autre ignoré.

Vous pouvez utiliser ce code pour votre objectif:

Structure (peu importe):

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

N'oubliez pas, vider le cache à la fin.

8
rpayanm

On y va encore une fois. Ces réponses sont généralement correctes. Une chose que vous ne pouvez pas oublier est les "balises de cache" et les "contextes de cache".

Je mettais en place un terme de taxonomie sur un nœud comme fil d'Ariane.

Je l'ai fait fonctionner avec les conseils de ce post, mais j'ai cliqué et j'ai remarqué les mêmes chapelures sur chaque page.

Pour faire court, assurez-vous de définir certains contextes et balises de cache.

Voici mon service dans un Gist: https://Gist.github.com/jonpugh/ccaeb01e173abbc6c88f7a332d271e4a

Voici ma méthode 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

Mise à jour 2016 Drupal 8

La documentation indique que vous devez renvoyer une instance de la classe de fil d'Ariane. Si vous avez du mal à le faire fonctionner. voici la solution qui a fonctionné pour moi.

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

}

Ensuite, le fichier yml

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

PS: si vous utilisez bootstrap allez dans votre /admin/appearance/settings page des paramètres et regardez les paramètres du fil d'Ariane. Show 'Home' breadcrumb link doit être coché. Et Show current page title at end doit être coché.

Après tout cela, videz votre cache. Chaque fois que vous modifiez un fichier YML, même en mode débogage, vous devez vider votre cache. tu peux aller à /core/rebuild.php si vous êtes bloqué et ne pouvez pas reconstruire.

8
Neoaptt

N'oubliez pas la mise en cache

Le cache de rendu a été modifié assez tard dans le cycle de développement D8, et il n'est donc pas mentionné dans la série d8ftw, ni dans les autres réponses à cette question.

Documentation de l'API Cache se réfère spécifiquement aux tableaux de rendu, mais toutes ces instructions s'appliquent également à Breadcrumbs. Les miettes de pain ont une méthode toRenderable() , Drupal va essayer de les mettre en cache dans le cache de rendu, et cela signifie que vous doit spécifier suffisamment d'informations pour permettre à Drupal de le faire correctement).

Les détails sont dans la documentation, mais la version courte est que Breadcrumb implémente RefinableCachableDependencyInterface . Dans votre classe de générateur, vous voudrez appeler addCachableDependency() avec toutes les entités ou objets de configuration utilisés pour créer le fil d'Ariane. La documentation de 'CacheableDependencyInterface & friends' explique plus en détail comment et pourquoi.

S'il existe d'autres contextes où le fil d'Ariane peut changer, vous devrez également utiliser manuellement addCacheContexts() pour vous assurer que le bloc varie, addCacheTags() pour vous assurer que l'entrée du cache peut être correctement invalidée, et mergeCacheMaxAge() si le cache est sensible au temps et doit expirer.

Si cela n'est pas fait correctement, l'un de vos services de création de fil d'Ariane personnalisé "gagnera", et le fil d'Ariane pour cette page spécifique sera servi sur chaque page, à tous les visiteurs, pour toujours.

7
Sean C.

Il existe un autre moyen d'y parvenir.

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

Et puis créez un autre fichier dans le dossier de modèle de votre thème nommé "breadcrumb.html.twig" et mettez le code ci-dessous dans ce fichier:

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

C'est ça. Maintenant, videz le cache et vous obtiendrez le fil d'Ariane avec le titre de la page actuelle comme Accueil/Titre de la page actuelle. Vous pouvez changer le séparateur en remplaçant "/" par celui souhaité.

4
Sachin

Vous devez utiliser un module contrib pour ajouter le titre de la page actuelle au fil d'Ariane tel que Current Page Crumb: https://www.drupal.org/project/current_page_crumb

Si vous souhaitez le coder manuellement, vous pouvez extraire le code du dossier src de ce module. Vous pouvez trouver plus de détails sur Drupal 8 chapelure ici: http://www.gregboggs.com/drupal8-breadcrumbs/

2
Greg Boggs

J'avais utilisé un fil d'Ariane personnalisé en utilisant un jeton dans Drupal 7 et lorsque ce module n'était pas disponible pour Drupal 8 j'ai fini par créer des vues pour mes types de contenu individuels en utilisant le champs qui étaient à l'origine des champs de jeton. L'utiliser comme un bloc et désactiver le fil d'Ariane normal. C'était un peu plus de travail que le fil d'Ariane personnalisé, mais cela fonctionne.

0
weben