admin管理员组

文章数量:1126069

I am extending default navigation with theme styles, i need to be able to modify output based on context, where navigation is used.

I tried following the guide about context, but it seems to be not working for me, if applied via filters to core/navigation and core/navigation-link.

Currently it is working in editor only when editing template-part, i can see it in settings object in javascript.

But it is lost when editing navigation itself and during frontend rendering for some reason. I had to use attributes to store context, but it implies limitations, so that one navigation can only be used in one context.

My code:

parent block block.json

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

on navigation-link hooks.js

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

and filter.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
);

本文标签: block editorPassing context to corenavigationlink