คุณจะใช้เกล็ดขนมปังได้อย่างไร?


18

ฉันพยายามกำหนด breadcrumb override ใหม่ แต่ฉันยังคงได้รับค่าเริ่มต้นของไซต์

ฉันได้สร้างโมดูลที่กำหนดเองแล้ว 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 breadcrumbsแต่ดูเหมือนว่ามันจะใช้เวอร์ชั่นเก่ากว่าของการโหลดอัตโนมัติ PSR-4 ที่ไม่มีอยู่อีกต่อไป (สำหรับเร็กคอร์ดที่ฉันใช้ 8.0.0 -dev-beta3) ดังนั้นฉันไปตามที่โมดูลอื่น ๆ ทั้งหมดทำงานใน codebase

ตอนนี้ฉันค่อนข้างแน่ใจว่าถูกต้องเพื่อให้โมดูลโหลด; แต่ฉันไม่แน่ใจว่า

class BreadcrumbBuild extends BreadcrumbBuilderBase

ถูกต้อง. ปัญหาคือว่าการกวดวิชาเก่าที่ฉันเชื่อมโยงกับการกล่าวถึงขยายBreadcrumbBuilderBaseแต่เอกสารเพิ่มเติมปัจจุบันดูเหมือนจะไม่พูดถึงและฉันสงสัยว่ามันล้าสมัย - และฉันควรทำอย่างไร

ในทำนองเดียวกันฉันไม่เข้าใจจริงๆว่าservices.ymlไฟล์ทำอะไรในเรื่องนี้ไม่มีเอกสารสำหรับเรื่องนี้

คำตอบ:


8

ใช่ breadcrumb เปลี่ยนไปและเอกสารจะต้องอัปเดต

ในทำนองเดียวกันฉันไม่เข้าใจจริงๆว่าไฟล์ services.yml กำลังทำอะไรในเรื่องนี้ไม่มีเอกสารใด ๆ สำหรับเรื่องนี้

สำหรับDrupal 8: The Crash Course | DrupalCon Amsterdam 2014การนำเสนอที่ยอดเยี่ยมประมาณ 47:02:

Drupal 8 ใน 2 ขั้นตอน:

  1. สร้างเครื่องมือ
  2. สายมันขึ้นมา

การเดินสายอาจแตกต่างกันวิธีการเดียวกัน

วิธีที่เรา "วางสาย" เกล็ดขนมปัง:

สำหรับhttp://www.palantir.net/blog/d8ftw-breadcrumbs-work :

ตอนนี้เราต้องบอกระบบเกี่ยวกับชั้นเรียนของเรา ในการทำเช่นนั้นเราได้กำหนดบริการใหม่ (จำเหล่านั้นหรือไม่) อ้างอิงชั้นเรียนใหม่ของเรา เราจะทำเช่นนั้นในไฟล์ * .services.yml ซึ่งมีอยู่เพื่อวัตถุประสงค์นี้

คล้ายกับ "เบ็ดข้อมูล" ใน Drupal รุ่นก่อนหน้าเรากำลังกำหนดบริการชื่อ mymodule.breadcrumb มันจะเป็นตัวอย่างของคลาส breadcrumb ของเรา หากจำเป็นเราสามารถส่งข้อโต้แย้งไปยังผู้สร้างคลาสของเราได้เช่นกัน อย่างไรก็ตามที่สำคัญเรายังติดแท็กบริการ บริการที่ติดแท็กเป็นคุณลักษณะหนึ่งขององค์ประกอบ Symfony DependencyInjection โดยเฉพาะและบอกให้ระบบเชื่อมต่อเครื่องสร้างของเรากับผู้จัดการเกล็ดขนมปังโดยอัตโนมัติ ลำดับความสำคัญระบุในลำดับใดที่ผู้สร้างต่างๆควรเรียกว่าอันดับสูงสุดก่อน ในกรณีที่สองใช้ () วิธีการอาจทั้งสองคืนจริงผู้สร้างใดก็ตามที่มีความสำคัญสูงกว่าจะใช้และอื่น ๆ ละเว้น

คุณสามารถใช้รหัสนี้เพื่อจุดประสงค์:

โครงสร้าง (ไม่สำคัญมาก):

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

จำไว้ว่าให้ล้างแคชในตอนท้าย


ไม่มีความสุขจนถึงขณะนี้ ฉันคัดลอก taxonomy ใน core ที่ใกล้เคียงที่สุดเท่าที่จะเป็นไปได้เนื่องจากมีการใช้งาน (ฉันสามารถเรียก dpm ('Test') จากวิธีใช้ () และมันจะแสดงผล แต่ไม่ใช่ในรหัสของฉันไม่ใช่ข้อผิดพลาดทางไวยากรณ์โดยเจตนา ปรากฏขึ้น - ซึ่งทำให้ฉันสงสัยว่าการกำหนดเส้นทางบริการไม่ถูกต้อง แต่ yaml ของฉันถูกต้อง ... ถอนหายใจ :(
njp

1
@njp ตรวจสอบเส้นทางของคลาส Breadcrumb ของคุณ (ฉันเพิ่มโฟลเดอร์ Breadcrumb) และจะต้องตรงกับพารามิเตอร์ "class" ในไฟล์บริการของคุณ ตรวจสอบชื่อทั้งหมดของคลาสด้วยบางครั้งไม่ตรงกับไฟล์หรือพารามิเตอร์บางตัว
rpayanm

1
ขอแสดงความยินดี! คำถามหนึ่งข้อ: คุณ "ล้างแคช" หลังจากการแก้ไขหรือไม่ อาจเป็นได้
rpayanm

1
ใช่คุณต้องล้างแคชที่ควรจะเพียงพอที่จะอัปเดตบริการ อีกอย่างหนึ่งที่อาจพูดถึงก็คุ้มค่า ผู้สร้างรายแรกที่ส่งกลับค่า TRUE จาก Apply () กำลังจะชนะดังนั้นคุณอาจต้องค้นหาบริการอื่น ๆ ด้วยแท็กนั้น (ซึ่งเป็นการค้นหาข้อความแบบง่าย) และตรวจสอบน้ำหนักและการนำไปใช้ ()
Berdir

1
@njp ในทางตรงกันข้ามลำดับความสำคัญที่ระบุในสิ่งที่ผู้สร้างต่างๆควรจะเรียกว่าลำดับสูงสุดก่อน ในกรณีที่สองใช้ () วิธีการอาจทั้งสองคืนจริงผู้สร้างใดก็ตามที่มีความสำคัญสูงกว่าจะใช้และอื่น ๆ ละเว้น
rpayanm

10

ที่นี่เราไปอีกครั้ง คำตอบเหล่านี้ส่วนใหญ่ถูกต้อง สิ่งหนึ่งที่คุณลืมไม่ได้คือ "แท็กแคช" และ "บริบทของแคช"

ฉันกำลังตั้งค่าคำศัพท์อนุกรมวิธานบนโหนดเป็นเกล็ดขนมปัง

ฉันได้มันทำงานด้วยคำแนะนำจากโพสต์นี้ แต่จากนั้นฉันคลิกไปรอบ ๆ และสังเกตเห็น breadcrumbs เดียวกันในทุกหน้า

เรื่องสั้นสั้น ๆ อย่าลืมตั้งค่าบริบทและแท็กของแคช

นี่คือบริการของฉันในส่วนสำคัญ: https://gist.github.com/jonpugh/ccaeb01e173abbc6c88f7a332d271e4a

นี่คือวิธีการสร้างของฉัน ():

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

ปัญหาการแคชนี้ทำให้ฉันสับสนและมีข้อมูลออนไลน์จำนวนมากในบล็อกและอื่น ๆ ที่ดูเหมือนจะพลาดจุดนี้ - ขอบคุณ!
kbrinner

8

อัพเดท 2016 Drupal 8

เอกสารระบุว่าคุณต้องส่งคืนอินสแตนซ์ของคลาส breadcrumb หากคุณมีปัญหาในการทำให้มันใช้งานได้ นี่คือทางออกที่ได้ผลสำหรับฉัน

<?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หน้าการตั้งค่าของคุณและดูการตั้งค่า breadcrumbs Show 'Home' breadcrumb linkควรตรวจสอบใน และShow current page title at endควรจะตรวจสอบออก

หลังจากเสร็จสิ้นการล้างแคชของคุณ ทุกครั้งที่คุณเปลี่ยนไฟล์ YML แม้ในโหมดแก้ไขข้อบกพร่องคุณต้องล้างแคชของคุณ คุณสามารถไปที่/core/rebuild.phpหากคุณติดขัดและไม่สามารถสร้างใหม่ได้


7

อย่าลืมแคช

แคชเรนเดอร์ถูกเปลี่ยนค่อนข้างช้าในรอบการพัฒนา D8 และดังนั้นจึงไม่ได้กล่าวถึงในซีรีย์ d8ftw หรือคำตอบอื่น ๆ สำหรับคำถามนี้

เอกสารแคช APIหมายถึงเฉพาะที่จะทำให้อาร์เรย์ แต่ทุกคำแนะนำเหล่านั้นใช้กับ Breadcrumbs Breadcrumbs มีtoRenderable()เมธอด Drupal จะพยายามแคชในเรนเดอร์แคชและนั่นหมายความว่าคุณต้องระบุข้อมูลให้เพียงพอเพื่อให้ Drupal สามารถทำได้อย่างถูกต้อง

โดยมีรายละเอียดในเอกสาร แต่รุ่นสั้น ๆ ว่าการดำเนินการBreadcrumb RefinableCachableDependencyInterfaceในคลาสผู้สร้างของคุณคุณจะต้องโทรหาaddCachableDependency()เอนทิตีหรือวัตถุการกำหนดค่าใด ๆ และทั้งหมดที่ใช้ในการสร้างเกล็ดขนมปัง เอกสารสำหรับ 'CacheableDependencyInterface & Friends'มีรายละเอียดเพิ่มเติมเกี่ยวกับวิธีการและเหตุผล

หากมีบริบทอื่น ๆ ที่ breadcrumb อาจเปลี่ยนแปลงคุณจะต้องใช้ด้วยตนเองaddCacheContexts()เพื่อให้แน่ใจว่าบล็อกแตกต่างกันไปaddCacheTags()เพื่อให้แน่ใจว่ารายการแคชสามารถทำให้ใช้งานไม่ได้อย่างถูกต้องและmergeCacheMaxAge()หากแคชนั้นไวต่อเวลาและต้องหมดอายุ

หากการดำเนินการนี้ไม่ถูกต้องบริการสร้างตัวสร้าง Breadcrumb แบบกำหนดเองของคุณจะ 'ชนะ' และเส้นทางสำหรับแต่ละหน้านั้นจะแสดงบนทุกหน้าทุกผู้เข้าชมตลอดไป


4

มีวิธีอื่นเพื่อให้บรรลุนี้

/**
 * 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 %}

แค่นั้นแหละ. ตอนนี้ล้างแคชและคุณจะได้รับ breadcrumb ด้วยชื่อหน้าปัจจุบันเช่นหน้าแรก / ชื่อหน้าปัจจุบัน คุณสามารถเปลี่ยนตัวคั่นได้โดยแทนที่ "/" ด้วยตัวที่ต้องการ


2

คุณควรใช้โมดูล contrib เพื่อเพิ่มชื่อหน้าปัจจุบันลงใน breadcrumb เช่น Crumb หน้าปัจจุบัน: https://www.drupal.org/project/current_page_crumb

หากต้องการโค้ดด้วยตนเองคุณสามารถดึงรหัสจากโฟลเดอร์ src ของโมดูลนั้น คุณสามารถหารายละเอียดเพิ่มเติมเกี่ยวกับ Drupal 8 breadcrumbs ได้ที่นี่: http://www.gregboggs.com/drupal8-breadcrumbs/


มันน่าผิดหวังมากที่บางสิ่งที่ง่ายอย่างนี้ต้องมีโมดูล contrib โลภเพื่อเพิ่มเข้า
Kevin

นั่นคือวิธี Drupal แม้ว่า Drupal 8 จะใช้ TON เป็นแกนกลางซึ่ง Drupal 7 ไม่เคยทำได้ ฉันจะแก้ไขแกนกลางของ Drupal 8 ในแกนกลางถ้าทำได้ แต่drush en current_page_crumbก็ไม่ได้เลวร้ายอะไร
Greg Boggs

0

ฉันใช้ Custom Breadcrumbs โดยใช้โทเค็นใน Drupal 7 และเมื่อโมดูลนั้นไม่พร้อมใช้งานสำหรับ Drupal 8 ฉันสิ้นสุดการสร้างมุมมองสำหรับประเภทเนื้อหาส่วนบุคคลของฉันโดยใช้ฟิลด์ที่เดิมเป็นเขตโทเค็น ใช้เป็นบล็อกและปิดการใช้งาน breadcrumb ปกติ มันเป็นงานมากกว่า Custom Breadcrumbs แต่ใช้งานได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.