WordPress开发笔记

WordPress块主题自定义导航的方法

在讲述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 );

深度样式定制