Okruszki — [okruszki]

Skrót z wtyczki 4Hand, nie moduł Divi.
Kod siedzi we wtyczce 4hand-realizacje-powiazane (wersja 2.6.1), wygląd w globalnym Niestandardowym CSS.
Wstawiasz modułem Tekst, wpisując w nim [okruszki].

Skąd biorą się nazwy ogniw

To jest sedno tego modułu i jedyne miejsce, które potrafi zaskoczyć. Nazwa ogniwa szukana jest w trzech miejscach, po kolei:

  1. Atrybut skrótu — jeśli podasz [okruszki tu="Okna"], użyta zostanie ta nazwa.
  2. Etykieta z menu — jeśli strona stoi w którymkolwiek menu, brana jest jej nazwa z menu.
  3. Tytuł strony — dopiero gdy strony nie ma w żadnym menu.

Dlaczego nie od razu tytuł strony? Bo tytuły podstron są pisane pod wyszukiwarki. Strona /okna/ ma tytuł „Okna PVC, drewniane i aluminiowe – producent 4Hand | Warszawa, Milanówek” i taki napis wjeżdżał do okruszków, łamiąc się na dwie linijki. W menu stoi krótkie „Okna” — i to jest właściwa nazwa do ścieżki. Zmiana nazwy w menu przenosi się na okruszki sama.

Jak budowana jest ścieżka

  • Podstrony — z hierarchii stron. /drzwi/drzwi-kompozytowe/ da 4HAND / Drzwi / Drzwi kompozytowe, bo strona ma rodzica.
  • Realizacje — ogniwem nadrzędnym jest zwykła strona /realizacje/. Trzeba było to obsłużyć osobno, bo archiwum tego typu wpisów wyłączyliśmy we wtyczce 2.3.
  • Strona główna — skrót nie wypisuje niczego.

Dane strukturalne

Obok widocznej ścieżki skrót wypisuje BreadcrumbList w formacie JSON-LD. Dzięki temu Google może pokazać ścieżkę pod tytułem w wynikach wyszukiwania zamiast samego adresu. Nie trzeba nic ustawiać — dzieje się to samo.

Żywy podgląd

Ta strona nie stoi w menu, więc pierwszy przykład pokazuje odwrót do tytułu strony. Drugi ma nazwę podaną ręcznie.

[okruszki]

[okruszki tu="Okruszki"]

Ustawienia skrótu

  • [okruszki] — zwykłe użycie, pierwsze ogniwo to 4HAND
  • [okruszki dom="Strona główna"] — inna nazwa pierwszego ogniwa
  • [okruszki link="https://4hand.uuru.pl/"] — inny adres pierwszego ogniwa
  • [okruszki tu="Okna"] — ręczne nadpisanie nazwy bieżącej strony, gdy nie ma jej w menu

Ustawienia wyglądu

Zmienne na .okruszki, na górze arkusza:

  • --ok-kolor — kolor ogniw klikalnych
  • --ok-kolor-tu — kolor bieżącej strony
  • --ok-separator — kolor ukośnika
  • --ok-odstep — przerwa wokół ukośnika

Separator rysuje arkusz przez .okruszki-link + *::before, nie wtyczka. Zamiana ukośnika na strzałkę to podmiana jednego znaku w CSS, bez wgrywania wtyczki od nowa. Jest też gotowa klasa okruszki-jasne na ciemne tło.

Co gdzie wgrać

  1. Wtyczka — Wtyczki → Dodaj nową wtyczkę → Wyślij wtyczkę na serwer → Zastąp obecną wersję. Kod skrótu siedzi w niej, więc bez tego [okruszki] wypisze się na stronie jako zwykły tekst.
  2. CSS — Divi → Opcje szablonów graficznych → Niestandardowy CSS.
  3. Skrót — moduł Tekst nad nagłówkiem podstrony.

CSS można też trzymać w style.css motywu potomnego, ale wbudowany w WordPressa edytor plików sprawdza składnię przestarzałym narzędziem, które nie zna zmiennych CSS i zgłasza siedem nieistniejących błędów. Pole w Divi nie ma takiego sprawdzania.

CSS do skopiowania

/* =====================================================
   OKRUSZKI (breadcrumbs) - skrot [okruszki] z wtyczki 4Hand
   Do dopisania w motywie potomnym: Wyglad -> Edytor plikow
   motywu -> divi-4hand-child -> style.css

   Cala warstwa wygladu siedzi tutaj. Wtyczka wypisuje sam HTML:
     nav.okruszki > a.okruszki-link ... span.okruszki-tu
   ===================================================== */

.okruszki{
  --ok-kolor: #323232;        /* ogniwa klikalne */
  --ok-kolor-tu: #F0C609;     /* biezaca strona */
  --ok-separator: #c9c4bb;    /* ukosnik */
  --ok-odstep: 10px;          /* przerwa wokol separatora */

  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0;
  margin: 0 0 10px;
  font-family: "Source Sans Pro", system-ui, Arial, sans-serif;
  font-size: 14px;
  line-height: 1.5;
}

.okruszki-link{
  color: var(--ok-kolor);
  text-decoration: none;
  transition: color .25s ease;
}
.okruszki-link:hover{ color: var(--ok-kolor-tu); }

.okruszki-tu{
  color: var(--ok-kolor-tu);
}

/* Separator rysuje arkusz, nie wtyczka - dzieki temu zmiana ukosnika
   na strzalke czy kropke to jedna linijka, bez ruszania kodu PHP.
   Regula dotyczy kazdego elementu, przed ktorym stoi odnosnik. */
.okruszki-link + *::before{
  content: "/";
  margin: 0 var(--ok-odstep);
  color: var(--ok-separator);
}

/* wariant na ciemnym tle - klasa na module Tekst obok [okruszki] */
.okruszki-jasne{
  --ok-kolor: #ffffff;
  --ok-separator: rgba(255,255,255,.45);
}

@media (max-width: 590px){
  .okruszki{ font-size: 13px; --ok-odstep: 7px; }
}

Kod skrótu (jest już we wtyczce)

Tego nie trzeba nigdzie wklejać – siedzi we wtyczce. Wersja poglądowa, żeby dało się prześledzić, skąd biorą się nazwy ogniw.

/* =====================================================
   OKRUSZKI (breadcrumbs) — [okruszki]                (v2.6.1)
   -----------------------------------------------------
   Ścieżkę buduje z hierarchii stron. Dla wpisów CPT „realizacje"
   ogniwem nadrzędnym jest zwykła strona /realizacje/.

   ETYKIETY: najpierw z MENU, dopiero potem z tytułu strony.
   Tytuły podstron bywają długie i pisane pod wyszukiwarki
   („Okna PVC, drewniane i aluminiowe – producent 4Hand…"),
   a w menu stoi krótkie „Okna" — i to jest właściwa nazwa
   do okruszków. Kolejność: atrybut skrótu → etykieta z menu →
   tytuł strony.

   Wygląd w całości po stronie CSS — separator rysuje arkusz
   (`.okruszki-link + *::before`), więc zmiana ukośnika na strzałkę
   nie wymaga ruszania wtyczki.

   Wypisuje też dane strukturalne BreadcrumbList.

   Użycie:  [okruszki]
            [okruszki dom="Strona główna"]
            [okruszki tu="Okna"]                 — nadpisuje ostatnie ogniwo
            [okruszki dom="4HAND" link="https://4hand.uuru.pl/"]
   ===================================================== */

/* Mapa: identyfikator strony → etykieta z menu.
   Budowana raz na żądanie, ze wszystkich zarejestrowanych menu. */
function fourhand_okruszki_etykieta( $id ) {

    static $mapa = null;

    if ( null === $mapa ) {
        $mapa = array();
        foreach ( get_nav_menu_locations() as $id_menu ) {
            if ( ! $id_menu ) {
                continue;
            }
            $pozycje = wp_get_nav_menu_items( $id_menu );
            if ( ! $pozycje ) {
                continue;
            }
            foreach ( $pozycje as $p ) {
                $obiekt = (int) $p->object_id;
                if ( 'post_type' === $p->type && $obiekt && ! isset( $mapa[ $obiekt ] ) ) {
                    $mapa[ $obiekt ] = $p->title;
                }
            }
        }
    }

    $id = (int) $id;
    return isset( $mapa[ $id ] ) && '' !== trim( $mapa[ $id ] )
        ? $mapa[ $id ]
        : get_the_title( $id );
}

add_shortcode( 'okruszki', function ( $atts ) {

    if ( is_front_page() ) {
        return '';
    }

    $a = shortcode_atts( array(
        'dom'  => '4HAND',   // etykieta pierwszego ogniwa
        'link' => '',        // własny adres pierwszego ogniwa
        'tu'   => '',        // własna nazwa bieżącej strony
    ), $atts, 'okruszki' );

    $ogniwa = array( array(
        'nazwa' => $a['dom'],
        'url'   => $a['link'] ? $a['link'] : home_url( '/' ),
    ) );

    if ( is_singular() ) {

        $id  = get_queried_object_id();
        $typ = get_post_type( $id );

        if ( 'realizacje' === $typ ) {
            /* archiwum CPT jest wyłączone (v2.3), więc ogniwem nadrzędnym
               jest zwykła strona o adresie /realizacje/ */
            $rodzic = get_page_by_path( 'realizacje' );
            if ( $rodzic ) {
                $ogniwa[] = array(
                    'nazwa' => fourhand_okruszki_etykieta( $rodzic->ID ),
                    'url'   => get_permalink( $rodzic ),
                );
            }
        } else {
            /* zwykłe podstrony — pełen łańcuch rodziców, od najstarszego */
            foreach ( array_reverse( get_post_ancestors( $id ) ) as $przodek ) {
                $ogniwa[] = array(
                    'nazwa' => fourhand_okruszki_etykieta( $przodek ),
                    'url'   => get_permalink( $przodek ),
                );
            }
        }

        $ogniwa[] = array(
            'nazwa' => $a['tu'] ? $a['tu'] : fourhand_okruszki_etykieta( $id ),
            'url'   => '',
        );

    } elseif ( is_archive() ) {
        $ogniwa[] = array( 'nazwa' => wp_strip_all_tags( get_the_archive_title() ), 'url' => '' );
    } elseif ( is_search() ) {
        $ogniwa[] = array( 'nazwa' => 'Wyniki wyszukiwania', 'url' => '' );
    } elseif ( is_404() ) {
        $ogniwa[] = array( 'nazwa' => 'Nie znaleziono strony', 'url' => '' );
    }

    $html  = '<nav class="okruszki" aria-label="Ścieżka nawigacji">';
    $lista = array();
    $poz   = 1;

    foreach ( $ogniwa as $o ) {
        if ( $o['url'] ) {
            $html .= '<a class="okruszki-link" href="' . esc_url( $o['url'] ) . '">'
                   . esc_html( $o['nazwa'] ) . '</a>';
        } else {
            $html .= '<span class="okruszki-tu" aria-current="page">'
                   . esc_html( $o['nazwa'] ) . '</span>';
        }

        $element = array(
            '@type'    => 'ListItem',
            'position' => $poz,
            'name'     => $o['nazwa'],
        );
        if ( $o['url'] ) {
            $element['item'] = $o['url'];
        }
        $lista[] = $element;
        $poz++;
    }

    $html .= '</nav>';

    $dane = array(
        '@context'        => 'https://schema.org',
        '@type'           => 'BreadcrumbList',
        'itemListElement' => $lista,
    );
    $html .= '<script type="application/ld+json">'
           . wp_json_encode( $dane, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES )
           . '</script>';

    return $html;
} );