4

我创建了一批自定义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;

?>

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


?>

我的文件夹结构如下:

theme
  inc
    acf-blocks
      blocks.php
      functions.php
  src
    components
      hero
        hero.js
        hero.scss
        hero.png

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

编辑:

我已经添加了该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');
}

?>

编辑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.';
}


?>

甚至尝试过:

<?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;
}


?>

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

在此处输入图像描述

4

4 回答 4

10

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

它说“没有可用的预览”,因为它确实如此,而且您定义的不是 ACF 甚至 WordPress 支持的东西,即imagearg ( 'image' => $img_root . '/hero/hero.png') 不会开箱即用。

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

不,那不是图像

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

而那个(核心)段落块,它实际上定义了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,
} );

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

示例块预览

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

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

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

示例
(数组)(可选)用于构建块插入器中显示的预览的结构化数据数组。输入到“数据”属性数组中的所有值都将通过$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',
        ),
    ),
);

基本上,无论渲染回调/模板输出如何,您在通过块插入器 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.';
}

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

/* 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.';
}

实际上,您可以通过这些显示实际图像if

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

然后为您提供如下预览:

示例块预览 2

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

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

于 2021-02-01T10:15:53.507 回答
6

在互联网上阅读了无数关于如何在自定义 ACF 块中添加图像作为预览的帖子后,我发现自己无处可去:

  1. 您需要在注册 ACF 块时添加“示例”,将“模式”属性添加为“预览”以及您想要传递的任何特定数据。
acf_register_block_type(
        array(
            'name' => 'name-of-block',
            'title' => __('Your Title'),
            'description' => __('Your description'),
            'post_types' => array('page'),
            'category' => 'common',
            'render_template' => '../your/path/block_template.php', // your template
            'icon' => '', // svg code for icon
            'keywords' => array('Keyword', 'another'),
            'example'  => array(
                'attributes' => array(
                    'mode' => 'preview',
                    'data' => array(
                        'preview_image_help' => '../your/dir/block-image-preview.jpg',
                    )
                )
            )
        )
    );

警告:“preview_image_help”字段必须是唯一名称,并且不能在块字段中存在。

块将在 2 个位置以预览模式呈现,编辑器和块插入器预览(当您将鼠标悬停在块的名称上时)。在编辑器中呈现时,它将具有您在块中定义的所有字段。当在插入器预览中呈现时,将只有“preview_image_help”字段。

  1. 现在渲染部分(在您的模板中),检查唯一字段,您将知道渲染发生的位置:
<?       
        if( isset( $block['data']['preview_image_help'] )  ) :    /* rendering in inserter preview  */

            echo '<img src="'. $block['data']['preview_image_help'] .'" style="width:100%; height:auto;">';
    
        
        else : /* rendering in editor body */
            
            $text   = get_field('text');
            $author = get_field('author');
            $title  = get_field('title');
            ?>
            <div class="my-class">
                <span class="class-title"><?=$title?></span>
                <span class="class-text"><?=$text?></span>
                <span class="class-author"><?=$author?></span>
            </div>
            <?
            
        endif;
于 2021-06-05T04:04:12.283 回答
2

acf_register_block_type()我在文档(https://www.advancedcustomfields.com/resources/acf_register_block_type/ )的函数中没有找到任何关于“图像”的信息。

如果您使用此功能并设置modepreview,则在块编辑器中将鼠标悬停在块上时,您将获得渲染模板的预览。

函数.php

acf_register_block_type(array(
    'name' => 'name-of-block',
    'title' => __('Your Title'),
    'description' => __('Your description'),
    'post_types' => array('page'),
    'category' => 'common',
    'render_template' => '../your/path/block_template.php', // your template file
    'enqueue_style' => get_template_directory_uri() . '/style.css', // path to css file
    'icon' => '', // svg code for icon
    'keywords' => array('Keyword', 'another'),
    'example'  => array(
        'attributes' => array(
            'mode' => 'preview' // this needs to be set to preview (!)
        )
    ),
));

如果您为块使用自定义字段,则需要确保在您的古腾堡块模板文件的预览中显示一个值。

block_template.php

$myfield = get_field( 'my_field' );

<p><?php if ($myfield) { echo $myfield; } else { echo "my fallback paragraph"; } ?></p>

这样,预览将成为您渲染的块模板。它不是您想要的图像,但它显示了您的块的外观。这就是预览的本意。

于 2021-01-30T20:13:43.013 回答
0
  1. 添加回调函数

    'render_callback' => 'block_render',
  2. 添加示例和图像

     'example' => array(
     'attributes' => array(
         'mode' => 'preview', // Important!
         'data' => array(
             'image' => '<img src="' . get_template_directory_uri() . '/gutenberg-preview/cta.png' . '" style="display: block; margin: 0 auto;">'
         ),
     ),
    

    ),

  3. 制作回调函数

     /**
      * Callback block render,
      * return preview image
      */
     function block_render( $block, $content = '', $is_preview = false ) {
         /**
          * Back-end preview
          */
          if ( $is_preview && ! empty( $block['data'] ) ) {
               echo $block['data']['image'];
               return;
          } else {
               if ( $block ) :
                    $template = $block['render_template'];
                    $template = str_replace( '.php', '', $template );
                    get_template_part( '/' . $template );
               endif;
          }
     }
    

来源https://www.grbav.com/acf-custom-block-shows-preview-image-in-gutenberg/

于 2021-11-01T13:12:30.783 回答