在讲述WordPress块主题自定义导航的方法之前,需明确一要点:
块主题中的导航块的结构(“外观”->“编辑”->“导航”)与经典主题中(“外观”->“菜单”)导航结构不仅写法不同,其核心实现也不同。所以直接将经典的实现方式用于导航块方向、方法、思路是不正确的或者说是不推荐的,为了结构清晰、未来兼容,建议经典主题使用传统方式解决,块主题使用块的方式来解决。
class Walker_Nav_Menu 对块主题无效
尽管我们可以想办法使得wp_nav_menu()函数使用自定义worker类来实现导航块的展示为我们的自定义结构样式,如上所述,这并不推荐,因为这极有可能为未来的维护、管理带来麻烦。
具体的原因可以查看wp-includesblocksnavigation.php中的代码。
使用wp_nav_menu()函数自定义导航结构,则需自定义class Walker_Nav_Menu该worker类;
如果我们使用类似的方法对块主题的导航块进行自定义,则需自定义wp-includesblocksnavigation.php中的class WP_Navigation_Block_Renderer;但是我们不推荐这么做,因为这样做不仅复杂、难度大、易出错,而且代码量太大。
为块主题自定义导航块的推荐做法
结合以上所述,依据现有的情况来看,我们依然有多重方法来实现。
方法1、创建新区块
如果对你来说创建新区块没有难度,那么这可能是一个最佳选择。但是创建新区块对于大多数用户来说,难度并不小,因为这不仅需要精通多种语言,而且对能力高度要求较高。
方法2、直接使用系统默认导航区块【推荐】
直接使用系统默认导航区块,并直接从自定义css的方式覆盖系统样式。这个方法相对来说比下方方法4简单一些。
方法3、使用经典+区块的混合主题的方式【推荐】
可以以经典主题为主,加入区块的方法(本质是经典主题);也可以以块主题为主,加入经典主题的开发方式(本质是块主题);无论是使用哪一种方式都是可行。
推荐以块主题为主进行开发主题,这样的主题,我们可以以经典主题开发自定义导航的方式,将导航封装在一个php文件并放入“patterns”文件夹,并通过在“parts”中创建一个调取该php文件的html文件。注意:文件内部结构遵循块主题开发规则。其他方面的配置不再赘述,遵循块主题开发规则进行即可。
php文件:内部区块封装推荐使用“自定义HTML”
关于 patterns 的.php文件、parts 中的.html文件,以及修改theme.json与其他关联的部分…这些是创作WordPress块主题的知识,如果有疑问,你应该查阅WordPress块主题开发文档。
按照以上示例,最后还大量CSS样式来实现整体的布局。
我们不仅可以将这些样式写入zzw_block_styles函数中,也可以将这些放入我们的自定义样式表中。
使用如下代码的方式,将自定义样式表加载到块编辑器:
if ( ! function_exists( 'zzw_theme_setup' ) ) {
function zzw_theme_setup(){
//在块编辑器中加载自定义的CSS样式表
// add_editor_style( 'assets/css/editor-style.css' );
// add_editor_style( 'style.css' );
//或者:
add_editor_style( get_parent_theme_file_uri( 'style.css' ) );
}
}
add_action('after_setup_theme','zzw_theme_setup');使用如下代码的方式,将自定义样式表加载到网站前台中:
if ( ! function_exists( 'zzw_just_cssjs' ) ) :
function zzw_just_cssjs() {
// wp_register_style( 'bootstrap-min', get_template_directory_uri() . '/css/bootstrap.min.css', array(), null);
// wp_register_style( 'swiper-bundle-min', get_template_directory_uri() . '/css/swiper-bundle.min.css', array(), null);
wp_register_style( 'style', get_template_directory_uri() . '/css/style.css', array(),null);
// wp_register_script('jquery-min', get_template_directory_uri() . '/js/jquery.min.js', array(), null, true);
// wp_register_script('swiper-bundle-min', get_template_directory_uri() . '/js/swiper-bundle.min.js', array(), null, true);
// wp_enqueue_style('bootstrap-min');
// wp_enqueue_style('swiper-bundle-min');
wp_enqueue_style('style');
// wp_enqueue_script('jquery-min');
// wp_enqueue_script('swiper-bundle-min');
}
endif;
add_action( 'wp_enqueue_scripts', 'zzw_just_cssjs' );方法4、使用“变体+多种区块”的方式【不推荐】
不推荐理由:
使用这种方式,不仅增加工作量(因为系统默认样式和后台样式的问题,做起来不会那么简洁),而且在不创建自定义区块的前提下同样实现不了前后台一致(比如js效果在后台无效)。
在我查找该思路的解决方案的时候,始终绕不开创建区块问题,如果你有更好的方式或看法,可以在评论区留下您的见解。
使用现有的区块,再加上一些区块变体,我们依然能够创造出自定义区块导航。
区块变体
推荐参看函数 register_block_style()
示例代码:
(为列表块增加变体:勾号列表)
if ( ! function_exists( 'zzw_block_styles' ) ) :
function zzw_block_styles() {
//列表-自定义块样式
register_block_style(
'core/list',
array(
'name' => 'list-gou',
'label' => __( '勾号列表', 'yixiuk2' ),
'inline_style' => '
ul.is-style-list-gou {
list-style-type: "2713";
}
ul.is-style-list-gou li {
padding-inline-start: 1ch;
}',
)
);
}
endif;
add_action( 'init', 'zzw_block_styles' );为区块变体赋能
推荐参看钩子 render_block
示例代码:
(为列表块的变体“勾号列表”呈现代码的外围添加一个nav标签)
if ( ! function_exists( 'zzw_block_wrapper' ) ) :
function zzw_block_wrapper( $block_content, $block ) {
if ( $block['blockName'] === 'core/list' ) {
if ( isset($block['attrs']['className']) && $block['attrs']['className'] === 'is-style-list-gou' ) {
$content = '<nav class="zzw-nav">';
$content .= $block_content;
$content .= '</nav>';
return $content;
}
}
return $block_content;
}
endif;
add_filter( 'render_block', 'zzw_block_wrapper', 10, 2 );深度样式定制

