显示自定义古腾堡块的预览图像

Fre*_*ddy 4 php wordpress wordpress-gutenberg acf-gutenberg

我创建了一批自定义ACF gutenberg块,现在尝试分配预览图像。

问题:让预览图像显示

下图显示了一个paragraph组件,它是一个默认块。

在此处输入图片说明

您可以在右侧看到,段落块旁边有一个图像和描述。以下是我的组件当前的显示方式(完整代码将在末尾提供)

在此处输入图片说明

正如您所看到的,它说“没有可用的预览”并且没有添加任何描述,即使我已经在代码中定义了两者。

方法:

acf-blocks/blocks.php

<?php
$img_root = "../../src/components";

$hero = array(
    'name' => 'hero',
    'title' => __('Hero') ,
    'description' => __('Hero section') ,
    'render_callback' => 'block_render',
    'category' => 'formatting',
    'icon' => 'admin-comments',
    'image' => $img_root . '/hero/hero.png',
    'mode' => 'edit',
    'keywords' => array(
        'hero'
    ) ,
);

$blocks = [$hero];

return $blocks;

?>
Run Code Online (Sandbox Code Playgroud)

acf-blocks/functions.php

<?php

function block_acf_init(){
  $path = get_template_directory().'/inc/acf-blocks/blocks.php';
  $blocks = require($path);
  foreach($blocks as $block) {
    acf_register_block_type($block);
  }
}

if( function_exists('acf_register_block_type') ) {
  add_action('acf/init', 'block_acf_init');
}


?>
Run Code Online (Sandbox Code Playgroud)

我的文件夹结构如下:

theme
  inc
    acf-blocks
      blocks.php
      functions.php
  src
    components
      hero
        hero.js
        hero.scss
        hero.png
Run Code Online (Sandbox Code Playgroud)

不确定为什么我的预览图像不显示?

编辑:

我已经添加了该block_render功能,但仍然没有成功。这是我当前的functions.php文件:

<?php

$component_path = "../../src/components" . strtolower($block['title']) . strtolower($block['title']).".js";

function block_render( $block, $content = '', $is_preview = false ) {
  $context = get_context();
    $context['block'] = $block; // store block values
    $context['fields'] = get_fields(); // store field values
    $context['is_preview'] = $is_preview;
    render($component_path, $context ); // render the block
}

function block_acf_init(){
  $path = get_template_directory().'/inc/acf-blocks/blocks.php';
  $blocks = require($path);
  foreach($blocks as $block) {
    acf_register_block_type($block);
  }
}

if( function_exists('acf_register_block_type') ) {
  add_action('acf/init', 'block_acf_init');
}

?>
Run Code Online (Sandbox Code Playgroud)

编辑2:

<?php

$hero = array(
    'name' => 'hero',
    'title' => __('Hero'),
    'description' => __('Add hero section'),
    'render_callback' => 'block_render',
    'category' => 'formatting',
    'icon' => 'admin-comments',
    'mode' => 'edit',
    'category' => 'custom',
    'post_types' => array(
        'page'
    ),
    'keywords' => array(
        'hero'
    ),
    'example' => array(
        'mode' => 'preview',
        'data' => array(
            'field' => 'value' // sample data
        )
    )
);


function block_render($block, $content = '', $is_preview = false)
{
    if ($is_preview && !empty($block['data'])) {
        echo '<img src="https://i.picsum.photos/id/1021/536/354.jpg?hmac=XeUbyCXoxX2IrSELemo2mRl4zVXzhjFyxtj3GTVZ8xo">';
        return;
    } elseif ($is_preview) {
        echo 'A Hero block using ACF';
        return;
    }
    
    echo 'A Hero block using ACF.';
}


?>
Run Code Online (Sandbox Code Playgroud)

甚至尝试过:

<?php

function block_render( $block, $content = '', $is_preview = false ) {
  if($is_preview):
    echo '<img src="https://i.picsum.photos/id/1021/536/354.jpg?hmac=XeUbyCXoxX2IrSELemo2mRl4zVXzhjFyxtj3GTVZ8xo">';
  else:
    echo '<img src="https://i.picsum.photos/id/1021/536/354.jpg?hmac=XeUbyCXoxX2IrSELemo2mRl4zVXzhjFyxtj3GTVZ8xo">';
  endif;
}


?>
Run Code Online (Sandbox Code Playgroud)

在这两种情况下,当尝试显示图像(不是块预览)时,我看到的是块的 ACF 字段,而不是定义的虚拟图像:

在此处输入图片说明

pau*_*agu 10

在阅读了互联网上无数关于如何在自定义 ACF 块中添加图像作为预览的帖子后,我找到了一个解决方案:

\n
    \n
  1. 注册ACF块时需要添加\xe2\x80\x98example\xe2\x80\x99,添加\xe2\x80\x9cmode\xe2\x80\x9d属性为\xe2\x80\x9cpreview\xe2\x80\x9d以及您想要传递的任何特定数据。
  2. \n
\n
acf_register_block_type(\n        array(\n            \'name\' => \'name-of-block\',\n            \'title\' => __(\'Your Title\'),\n            \'description\' => __(\'Your description\'),\n            \'post_types\' => array(\'page\'),\n            \'category\' => \'common\',\n            \'render_template\' => \'../your/path/block_template.php\', // your template\n            \'icon\' => \'\', // svg code for icon\n            \'keywords\' => array(\'Keyword\', \'another\'),\n            \'example\'  => array(\n                \'attributes\' => array(\n                    \'mode\' => \'preview\',\n                    \'data\' => array(\n                        \'preview_image_help\' => \'../your/dir/block-image-preview.jpg\',\n                    )\n                )\n            )\n        )\n    );\n
Run Code Online (Sandbox Code Playgroud)\n

警告:\n字段 \xe2\x80\x9cpreview_image_help\xe2\x80\x9d 需要是唯一的名称,并且不能存在于块字段中。

\n

该块将在两个位置以预览模式渲染:编辑器和块插入器预览(当您将鼠标悬停在块的名称上时)。\n在编辑器中渲染时,它将包含您在块中定义的所有字段。 \n在插入器预览中渲染时,只有字段 \xe2\x80\x9cpreview_image_help\xe2\x80\x9d。

\n
    \n
  1. 现在是渲染部分(在您的模板中),检查唯一字段,您将知道渲染发生在哪里:
  2. \n
\n
<?       \n        if( isset( $block[\'data\'][\'preview_image_help\'] )  ) :    /* rendering in inserter preview  */\n\n            echo \'<img src="\'. $block[\'data\'][\'preview_image_help\'] .\'" style="width:100%; height:auto;">\';\n    \n        \n        else : /* rendering in editor body */\n            \n            $text   = get_field(\'text\');\n            $author = get_field(\'author\');\n            $title  = get_field(\'title\');\n            ?>\n            <div class="my-class">\n                <span class="class-title"><?=$title?></span>\n                <span class="class-text"><?=$text?></span>\n                <span class="class-author"><?=$author?></span>\n            </div>\n            <?\n            \n        endif;\n
Run Code Online (Sandbox Code Playgroud)\n


Sal*_* CJ 7

它说“没有可用的预览”并且没有添加描述,即使我已经在代码中定义了

它说“没有可用的预览”,因为确实如此,并且您定义的内容不是 ACF 甚至 WordPress 支持的内容,即imagearg ( 'image' => $img_root . '/hero/hero.png') 不会立即执行任何操作。

您可以在右侧看到,段落块旁边有一个图像和描述。

不,那不是图像

相反,它是块的渲染回调(在您的情况下是函数)或在 ACF 块类型的情况下的模板返回的块输出的预览block_render()

而那个(核心)Paragraph 块,它实际上定义了一个example属性即使该属性为空(即未定义属性),该属性也可以启用块预览。工作示例使用registerBlockType()

registerBlockType( 'my-blocks/foo-bar', {
    title: 'My Foo Bar block',
    category: 'formatting',
    description: 'Sample description.',

    // Just define this property and there'll be a preview.
    example: {},

    // And the preview is the one coming from this callback.
    edit: () => <p>just testing the block previews :)</p>,

    save: () => null,
} );
Run Code Online (Sandbox Code Playgroud)

有了这个,你会得到这个预览:

示例块预览

但我提供该示例只是为了让您知道如何向非动态块添加预览。

那么如何通过ACF添加区块预览

简单,如其他答案以及acf_register_block_type() 文档中所示,使用examplearg:

示例
(数组)(可选)用于构建块插入器中显示的预览的结构化数据数组。输入到 'data' 属性数组中的所有值都将通过$block['data']或 在块渲染模板/回调中可用get_field()

因此,在您的情况下,您可以将该 arg 添加到您的$hero数组中:

$hero = array(
    'name'            => 'hero',
    'title'           => __( 'Hero' ),
    'description'     => __( 'Hero section' ),
    'render_callback' => 'block_render',
    'category'        => 'formatting',
    'icon'            => 'admin-comments',
    'keywords'        => array( 'hero' ),
    // Just add this and you'll get the block preview:
    'example'         => array(
        'attributes' => array(
            'mode' => 'preview',
        ),
    ),
);
Run Code Online (Sandbox Code Playgroud)

基本上,无论渲染回调/模板输出如何,当您通过块插入器 UI 添加块时,您在预览中会看到什么。

但是,如果您在预览模式下想要不同的输出——无论是在通过 UI 插入块时还是在将块添加到编辑器后,您都可以使用$is_preview传递给渲染回调的参数:

function block_render( $block, $content = '', $is_preview = false ) {
    // back-end preview
    if ( $is_preview ) {
        echo 'A Hero block using ACF — In preview mode.';
        return;
    }

    // front-end output
    echo 'A Hero block using ACF.';
}
Run Code Online (Sandbox Code Playgroud)

如果您想在插入器 UI 和编辑器中进行不同的预览,请在dataarg 中设置examplearg,并在渲染回调中检查 argdata是否不为空:

/* In $hero, add example.attributes.data:
$hero = array(
    'name'            => 'hero',
    ...
    'example'         => array(
        'attributes' => array(
            'mode' => 'preview',
            'data' => array(
                'my_field' => 'Sample value',
            ),
        ),
    ),
);
 */

function block_render( $block, $content = '', $is_preview = false ) {
    // back-end previews
    if ( $is_preview && ! empty( $block['data'] ) ) {
        echo 'A Hero block using ACF — In preview mode — In the block inserter UI.';
        return;
    } elseif ( $is_preview ) {
        echo 'A Hero block using ACF — In preview mode — In the editor.';
        return;
    }

    // front-end output
    echo 'A Hero block using ACF.';
}
Run Code Online (Sandbox Code Playgroud)

实际上,您可以通过以下方式显示实际图像if

if ( $is_preview && ! empty( $block['data'] ) ) {
    echo '<img src="https://example.com/path/to/image-file-name.png">';
    return;
}
Run Code Online (Sandbox Code Playgroud)

然后为您提供如下所示的预览:

示例块预览 2

所以我希望这有帮助?:)

请注意,这些示例已经在 ACF Pro 5.9.4 和 WordPress 5.6 上进行了尝试和测试,这两个版本都是撰写本文时的最新版本。

  • 你太棒了,我现在已经成功了。非常感谢您的深入回答,非常感谢:) (2认同)