WordPress

edytor bloków — Przekazywanie kontekstu do rdzenia/linku nawigacyjnego

  • 20 marca, 2024
  • 3 min read
edytor bloków — Przekazywanie kontekstu do rdzenia/linku nawigacyjnego


Rozszerzam domyślną nawigację o style motywów, muszę mieć możliwość modyfikowania danych wyjściowych w oparciu o kontekst, w którym używana jest nawigacja.

Próbowałem postępować zgodnie z przewodnikiem dotyczącym kontekstu, ale wydaje się, że nie działa to w moim przypadku, jeśli zastosuje się je za pomocą filtrów do rdzenia/nawigacji i rdzenia/linku do nawigacji.

Obecnie działa w edytorze tylko podczas edycji części szablonu, widzę to w obiekcie ustawień w JavaScript.

Ale z jakiegoś powodu zostaje utracony podczas edycji samej nawigacji i podczas renderowania interfejsu użytkownika. Musiałem użyć atrybutów do przechowywania kontekstu, ale wiąże się to z ograniczeniami, więc jednej nawigacji można używać tylko w jednym kontekście.

Mój kod:

blok nadrzędny blok.json

    "providesContext": {
        "mytheme/menuStyles": "menuStyles"
    }

na hooks.js z linkiem nawigacyjnym

import { useEffect } from '@wordpress/element';
import { createHigherOrderComponent } from '@wordpress/compose';

const blockControls = createHigherOrderComponent( ( BlockEdit ) => {
    return ( props ) => {
        const { name, context, attributes, setAttributes } = props;

        if ( name !== 'core/navigation-link' ) {
            return <BlockEdit { ...props } />;
        }

        useEffect( () => {
            if ( 'mytheme/menuStyles' in context && context[ 'mytheme/menuStyles' ] !== attributes.menuStyles ) {
                setAttributes( {
                    menuStyles: context[ 'mytheme/menuStyles' ],
                } );
            }
        }, [ context, setAttributes, attributes.menuStyles ] );

        return (
            <BlockEdit { ...props } />
        );
    };
}, 'blockControls' );

const blockSettings = function ( settings, name ) {
    if ( name !== 'core/navigation-link' ) {
        return settings;
    }

    const { usesContext } = settings;
    if ( ! ( 'mytheme/menuStyles' in usesContext ) ) {
        settings.usesContext = Object.assign( [ ...usesContext, 'mytheme/menuStyles' ] );
    }

    const { ...otherAttrributes } = settings.attributes;
    settings.attributes = Object.assign( otherAttrributes, {
        menuStyles: {
            type: 'string',
            default: 'header',
        },
    } );

    return settings;
};

wp.hooks.addFilter(
    'blocks.registerBlockType',
    'mytheme/navigation-link',
    blockSettings
);

wp.hooks.addFilter( 'editor.BlockEdit', 'mytheme/navigation-link', blockControls );

i filtr.php

add_filter(
    'render_block_core/navigation-link',
    function ( $attributes, $block_content, $block ) {
        if (empty($block->attributes)) return '';
        $menu_styles = array_key_exists('menuStyles', $block->attributes) ? $block->attributes['menuStyles'] : 'header';
        $label       = array_key_exists('label', $block->attributes) ? $block->attributes['label'] : '';
        $url         = array_key_exists('url', $block->attributes) ? $block->attributes['url'] : '#';

        ob_start();
        switch ($menu_styles) {
            case 'footer':
                ?>
        <div class="footer_item">
            <a class="footer_link" href="<?php echo esc_url($url); ?>">
            <?php echo esc_html($label); ?>
            </a>
        </div>
            <?php
                break;

            case 'header':
            default:
                ?>
                <div class="header_item">
                    <a class="header_link" href="<?php echo esc_url($url); ?>">
            <?php echo esc_html($label); ?>
                    </a>
                </div>
            <?php
                break;
        }
        
        $ob_content = ob_get_contents();
        ob_end_clean();

        return $ob_content;
    },
    10,
    3
);


Źródło

Warto przeczytać!  Jak dodać rolę edytora SEO w WordPress