Wordpress Gutenberg 自定义列块

Posted

技术标签:

【中文标题】Wordpress Gutenberg 自定义列块【英文标题】:Wordpress Gutenberg custom columns block 【发布时间】:2021-06-19 14:42:25 【问题描述】:

我正在尝试使用 ACF 和 Wordpress 为 Gutenberg 创建一个自定义“列”块,所以我想要一个易于管理的列块,用户可以在其中输入一些代表所需列数量的数字(例如, 5) 和 for 将创建这些列。

一切正常,因为我尝试创建多个内部块...我的代码是这样开始的:

acf_register_block_type([
    'name' => "theme-columns",
    'title' => __("Columns", "mytheme"),
    'description' => __("Columns", "mytheme"),
    'category' => "theme-blocks",
    'icon' => "grid-view",
    'render_callback' => [$this->renderers, "columns_renderer"],
    'mode' => "preview",
    'supports' => [
        'align' => true,
        'mode' => false,
        'jsx' => true
    ],
    'enqueue_assets' => function()
        wp_enqueue_style("bootstrap");
    
]);

还有columns_renderer 函数:

public function columns_renderer()

    $count = get_field("columns-count");
    ?>
    <div class="row row-cols-1 row-cols-md-3 row-cols-xl-5 justify-content-center">
        <?php for($i = 0; $i < $count; $i++): ?>
        <div class="col">
            <InnerBlocks />
        </div>
        <?php endfor; ?>
    </div>
    <?php

因此,正如(不是)预期的那样,它不起作用,因为 Gutenberg 不支持每个块多个 &lt;InnerBlocks /&gt;... 在网络上搜索,我发现有些人在谈论这样做就像 core/column 块一样,使用一些“黑客”......但我无法理解该怎么做......

有人可以帮助我并给我一些方法来达到我的需要吗?

谢谢!

-- 更新--

尝试创建“列”块并将“列”设置为仅接受新创建的“列”块,但仍然无法正常工作...

public function column()

    $this->register_block([
        'name' => "theme-column",
        'title' => __("Column", "mytheme"),
        'description' => __("Column", "mytheme"),
        'category' => "theme-blocks",
        'icon' => "columns",
        'render_callback' => [$this->renderers, "column_renderer"],
        'mode' => "preview",
        'supports' => [
            'align' => true,
            'mode' => false,
            'jsx' => true
        ],
        'enqueue_assets' => function()
            wp_enqueue_style("theme-main");
        
    ]);

public function column_renderer()

    ?>
    <InnerBlocks />
    <?php

public function columns()

    $this->register_block([
        'name' => "theme-columns",
        'title' => __("Columns", "mytheme"),
        'description' => __("Columns", "mytheme"),
        'category' => "theme-blocks",
        'icon' => "columns",
        'render_callback' => [$this->renderers, "columns_renderer"],
        'mode' => "preview",
        'supports' => [
            'align' => true,
            'mode' => false,
            'jsx' => true
        ],
        'enqueue_assets' => function()
            wp_enqueue_style("theme-main");
        
    ]);

public function columns_renderer()

    $allowedBlocks = ["acf/theme-column"];
    $template = array(
        array('acf/biore-column', []),
    );
    $column_count = get_field("columns-count");
    ?>
    <div class="row py-4">
        <?php for($i = 0; $i < $column_count; $i++): ?>
        <div class="col">
            <InnerBlocks allowedBlocks="<?= esc_attr(wp_json_encode($allowedBlocks)); ?>" template="<?= esc_attr(wp_json_encode($template)); ?>" />
        </div>
        <?php endfor; ?>
    </div>
    <?php

【问题讨论】:

【参考方案1】:

我实际上一直在做一些非常相似的事情,尽管我现在被困在一个不同的问题上。

您似乎仍在尝试在您的 columns_renderer 函数中创建多个 InnerBlocks。相反,我要做的是创建一个 InnerBlocks 并用由多个 Column 块组成的 $template 填充它。

我在Row InnerBlocks 上使用templateLock="all" 来阻止在那里添加任何新块,也可以通过使用allowedBlocks 来实现类似的效果,具体取决于您是否希望能够添加更多Columns是否来自可视化编辑器。我将 templateLock="false" 添加到 Columns InnerBlocks 以覆盖父 (Row) 值并允许将内容添加到其中。

我使用acfRow 块创建一个带有数字范围滑块的cols 字段,默认值为1 以创建1 列。当您移动滑块时,将添加更多Columns

设置块:

acf_register_block_type(array(
  'name'                => 'row',
  'title'               => 'Row',
  'description'         => 'A row content block.',
  'category'            => 'formatting',
  'mode'                => 'preview',
  'supports'            => array(
    'align'             => true,
    'anchor'            => true,
    'customClassName'   => true,
    'mode'              => false,
    'jsx'               => true
  ),
  'render_callback' => 'block_row',
));

acf_register_block_type(array(
  'name'                => 'column',
  'title'               => 'Column',
  'description'         => 'A column content block.',
  'category'            => 'formatting',
  'mode'                => 'preview',
  'supports'            => array(
    'align'             => true,
    'anchor'            => true,
    'customClassName'   => true,
    'mode'              => false,
    'jsx'               => true,
  ),
  'render_callback' => 'block_col',
));

输出Row 内容:

function block_row( $block )
    $classes = '';
    if( !empty( $block['className'] ) ) 
        $classes .= sprintf( ' %s', $block['className'] );
    
    if( !empty( $block['align'] ) ) 
        $classes .= sprintf( ' align%s', $block['align'] );
    

    $cols = get_field('cols');
    if( empty( $cols ) ) 
        $cols = 1;
    

    for( $x = 0; $x < $cols; $x++ ) 
        $template[] = array( 'acf/column' );
    
?>
<div class="row-block row <?php echo esc_attr($classes); ?>">
    <h1>Row</h1>
    <?php 
    echo '<InnerBlocks template="' . esc_attr( wp_json_encode( $template ) ) . '" templateLock="all"/>';
    ?>
</div>
<?php

输出Column 块:

function block_col( $block )
    $classes = '';
    if( !empty( $block['className'] ) ) 
        $classes .= sprintf( ' %s', $block['className'] );
    
    if( !empty( $block['align'] ) ) 
        $classes .= sprintf( ' align%s', $block['align'] );
    

    $template = array( array( 'core/paragraph', array(
            'content' => 'Enter content here',
        ) ) );
?>
<div class="col-block <?php echo esc_attr($classes); ?>">
    <h1>Col</h1>
    <?php 
    echo '<InnerBlocks template="' . esc_attr( wp_json_encode( $template ) ) . '" templateLock="false"/>';
    ?>
</div>
<?php

【讨论】:

以上是关于Wordpress Gutenberg 自定义列块的主要内容,如果未能解决你的问题,请参考以下文章

WordPress Gutenberg,以编程方式更新帖子内容

Post Gutenberg 编辑器中未显示自定义分类法

在 WordPress Gutenberg Block 插件中包含图像资产

是否可以在 Wordpress Gutenberg Editor 中使用可拖动项目?

如何从 Wordpress 上 Gutenberg 的 YouTube 视频嵌入中删除 HTML 包装器

WordPress REST API 不适用于自定义 wordpress 路径