2020-06-28 / 1552阅 / 悠然
在古腾堡编辑器中注册自定义块类型。
块是古腾堡(Gutenberg)编辑器的基本元素。WordPress提供了许多默认的块类型,例如段落,标题和图像。所述acf_register_block_type()函数可用于通过PHP添加新的块类型。
一旦注册,您的块将在编辑字段组时显示在“块”位置规则中。这使您可以将字段映射到块并定义内容。
要渲染该块,请创建一个PHP模板(或回调函数)以使用PHP函数(如get_field()和the_field())输出该块HTML 。
注意:块类型注册应在acf / init操作中完成。这不是必需的,但是是确保ACF完全初始化的安全方法。
块类型可以支持任意数量的内置核心功能,例如名称,图标,描述,类别等。有关支持的功能的完整列表,请参见$ settings参数。
acf_register_block_type( $settings );
(数组) (必需)用于注册块类型的参数数组。也可以使用JavaScript registerBlockType()函数中的任何参数。
'name' => 'testimonial',
'title' => __('Testimonial'),
'description' => __('My testimonial block.'),
'category' => 'embed',
// Specifying a dashicon for the block'icon' => 'book-alt',// Specifying a custom HTML svg for the block'icon' => '<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path fill="none" d="M0 0h24v24H0V0z" /><path d="M19 13H5v-2h14v2z" /></svg>',// Specifying colors'icon' => array( // Specifying a background color to appear with the icon e.g.: in the inserter. 'background' => '#7e70af', // Specifying a color for the icon (optional: if not set, a readable color will be automatically defined) 'foreground' => '#fff', // Specifying a dashicon for the block 'src' => 'book-alt',),
'keywords' => array('quote', 'mention', 'cite'),
'post_types' => array('post', 'page'),
'mode' => 'auto',
'align' => 'full',
// Specifying a relative path within the active theme'render_template' => 'template-parts/blocks/testimonial/testimonial.php',// Specifying an absolute path'render_template' => plugin_dir_path( __FILE__ ) . 'template-parts/blocks/testimonial/testimonial.php',
// Specifying a function'render_callback' => 'my_acf_block_render_callback',// Specifying a class method'render_callback' => array($this, 'block_render_callback'),
'enqueue_style' => get_template_directory_uri() . '/template-parts/blocks/testimonial/testimonial.css',
'enqueue_script' => get_template_directory_uri() . '/template-parts/blocks/testimonial/testimonial.js',
// Specifying a function name'enqueue_assets' => 'my_acf_block_enqueue_assets',// Specifying a class method'enqueue_assets' => array($this, 'block_enqueue_assets'),// Specifying an anonymouse function'enqueue_assets' => function(){ wp_enqueue_style( 'block-testimonial', get_template_directory_uri() . '/template-parts/blocks/testimonial/testimonial.css' ); wp_enqueue_script( 'block-testimonial', get_template_directory_uri() . '/template-parts/blocks/testimonial/testimonial.js', array('jquery'), '', true );},
'supports' => array( /* ... */ ),
true
。设置为false
隐藏对齐工具栏。设置为特定对齐名称的数组以自定义工具栏。// disable alignment toolbar'align' => false,// customize alignment toolbar'align' => array( 'left', 'right', 'full' ),
true
。// disable preview/edit toggle'mode' => false,
true
。'multiple' => false,
$block['data']
或在块渲染模板/回调中可用 get_field()
。'example' => array( 'attributes' => array( 'mode' => 'preview', 'data' => array( 'testimonial' => "Your testimonial text here", 'author' => "John Smith" ) ))
(数组)已验证和已注册的块设置。
本示例说明如何使用render_template设置注册块。
add_action('acf/init', 'my_acf_blocks_init');
function my_acf_blocks_init() {
// Check function exists.
if( function_exists('acf_register_block_type') ) {
// Register a testimonial block.
acf_register_block_type(array(
'name' => 'testimonial',
'title' => __('Testimonial'),
'description' => __('A custom testimonial block.'),
'render_template' => 'template-parts/blocks/testimonial/testimonial.php',
'category' => 'formatting',
));
}
}
<?php
/**
* Testimonial Block Template.
*
* @param array $block The block settings and attributes.
* @param string $content The block inner HTML (empty).
* @param bool $is_preview True during AJAX preview.
* @param (int|string) $post_id The post ID this block is saved to.
*/
// Create id attribute allowing for custom "anchor" value.
$id = 'testimonial-' . $block['id'];
if( !empty($block['anchor']) ) {
$id = $block['anchor'];
}
// Create class attribute allowing for custom "className" and "align" values.
$className = 'testimonial';
if( !empty($block['className']) ) {
$className .= ' ' . $block['className'];
}
if( !empty($block['align']) ) {
$className .= ' align' . $block['align'];
}
// Load values and assing defaults.
$text = get_field('testimonial') ?: 'Your testimonial here...';
$author = get_field('author') ?: 'Author name';
$role = get_field('role') ?: 'Author role';
$image = get_field('image') ?: 295;
$background_color = get_field('background_color');
$text_color = get_field('text_color');
?>
<div id="<?php echo esc_attr($id); ?>" class="<?php echo esc_attr($className); ?>">
<blockquote class="testimonial-blockquote">
<span class="testimonial-text"><?php echo $text; ?></span>
<span class="testimonial-author"><?php echo $author; ?></span>
<span class="testimonial-role"><?php echo $role; ?></span>
</blockquote>
<div class="testimonial-image">
<?php echo wp_get_attachment_image( $image, 'full' ); ?>
</div>
<style type="text/css">
#<?php echo $id; ?> {
background: <?php echo $background_color; ?>;
color: <?php echo $text_color; ?>;
}
</style>
</div>
本示例说明如何使用render_callback设置注册块。
<?php
add_action('acf/init', 'my_register_blocks');
function my_register_blocks() {
// check function exists.
if( function_exists('acf_register_block_type') ) {
// register a testimonial block.
acf_register_block_type(array(
'name' => 'testimonial',
'title' => __('Testimonial'),
'description' => __('A custom testimonial block.'),
'render_callback' => 'my_acf_block_render_callback',
'category' => 'formatting',
));
}
}
/**
* Testimonial Block Callback Function.
*
* @param array $block The block settings and attributes.
* @param string $content The block inner HTML (empty).
* @param bool $is_preview True during AJAX preview.
* @param (int|string) $post_id The post ID this block is saved to.
*/
function my_acf_block_render_callback( $block, $content = '', $is_preview = false, $post_id = 0 ) {
// Create id attribute allowing for custom "anchor" value.
$id = 'testimonial-' . $block['id'];
if( !empty($block['anchor']) ) {
$id = $block['anchor'];
}
// Create class attribute allowing for custom "className" and "align" values.
$className = 'testimonial';
if( !empty($block['className']) ) {
$className .= ' ' . $block['className'];
}
if( !empty($block['align']) ) {
$className .= ' align' . $block['align'];
}
// Load values and assing defaults.
$text = get_field('testimonial') ?: 'Your testimonial here...';
$author = get_field('author') ?: 'Author name';
$role = get_field('role') ?: 'Author role';
$image = get_field('image') ?: 295;
$background_color = get_field('background_color');
$text_color = get_field('text_color');
?>
<div id="<?php echo esc_attr($id); ?>" class="<?php echo esc_attr($className); ?>">
<blockquote class="testimonial-blockquote">
<span class="testimonial-text"><?php echo $text; ?></span>
<span class="testimonial-author"><?php echo $author; ?></span>
<span class="testimonial-role"><?php echo $role; ?></span>
</blockquote>
<div class="testimonial-image">
<?php echo wp_get_attachment_image( $image, 'full' ); ?>
</div>
<style type="text/css">
#<?php echo $id; ?> {
background: <?php echo $background_color; ?>;
color: <?php echo $text_color; ?>;
}
</style>
</div>
<?php
}
为了确保在编辑器和前端中都正确设置了样式,我们建议使用enqueue_style或enqueue_assets设置,如下所示:
acf_register_block_type(array(
'name' => 'testimonial',
'title' => __('Testimonial'),
'description' => __('A custom testimonial block.'),
'render_template' => get_template_directory() . '/template-parts/blocks/testimonial/testimonial.php',
'enqueue_style' => get_template_directory_uri() . '/template-parts/blocks/testimonial/testimonial.css',
));
<blockquote class="testimonial">
...
</blockquote>
.testimonial {
background: #00e4ba;
color: #fff;
}
注意:如果创建个人样式表不是您的最佳选择,请查看WordPress提供的enqueue_block_assets和enqueue_block_editor_assets操作,以使您的样式入队。
与样式类似,我们建议使用enqueue_script或enqueue_assets设置为您的块正确地加入JavaScript。
为了使JavaScript在编辑器和前端都能按预期运行,在编辑帖子时了解块的生命周期非常重要。
根据是否显示块预览以及是否进行了更改,您的块在单个页面加载期间可能会多次渲染。在这种情况下,术语“渲染”表示已通过对您的PHP模板或回调函数的AJAX调用来更新/替换了该块的HTML。
每次渲染块时,都会丢弃先前的HTML,并显示新的HTML。结果,对先前DOM元素的任何JavaScript修改也将丢失。
要解决此问题,只需挂接到我们的JS操作“ render_block_preview / type = {$ type}”,然后应用您的JavaScript功能,就像重新绘制了该块一样。
此示例演示了如何使脚本入队,同时提供与块的前端和后端状态的兼容性。
acf_register_block_type(array(
'name' => 'testimonial',
'title' => __('Testimonial'),
'description' => __('A custom testimonial block.'),
'render_template' => get_template_directory() . '/template-parts/blocks/testimonial/testimonial.php',
'enqueue_script' => get_template_directory_uri() . '/template-parts/blocks/testimonial/testimonial.js',
));
<blockquote class="testimonial">
<img src="..." />
...
</blockquote>
(function($){
/**
* initializeBlock
*
* Adds custom JavaScript to the block HTML.
*
* @date 15/4/19
* @since 1.0.0
*
* @param object $block The block jQuery element.
* @param object attributes The block attributes (only available when editing).
* @return void
*/
var initializeBlock = function( $block ) {
$block.find('img').doSomething();
}
// Initialize each block on page load (front end).
$(document).ready(function(){
$('.testimonial').each(function(){
initializeBlock( $(this) );
});
});
// Initialize dynamic block preview (editor).
if( window.acf ) {
window.acf.addAction( 'render_block_preview/type=testimonial', initializeBlock );
}
})(jQuery);
块预览提供了一种优雅的解决方案,用于识别和区分插入器面板中显示的各种块类型。
要增加对块预览的支持,请使用“ example”设置来定义WordPress用于构建预览的属性数组,如以下示例所示。
acf_register_block_type(array(
'name' => 'testimonial',
'title' => __('Testimonial'),
'description' => __('A custom testimonial block.'),
'example' => array(
'attributes' => array(
'mode' => 'preview',
'data' => array(
'testimonial' => "Blocks are...",
'author' => "Jane Smith",
'role' => "Person",
'is_preview' => true
)
)
)
));
在“数据”属性数组中定义的所有值将通过$block['data']
或在块渲染模板/回调中可用get_field()
。
在上面的示例中,定义了三个与三个现有自定义字段(“个人鉴定”,“作者”和“角色”)名称匹配的值。定义了一个附加的非自定义字段值('is_preview'),该值可在渲染器中用于显示替代标记。
?由于预览旨在传达视觉设计,我们建议您使用“预览” 模式,但是,也可以将其设置为“编辑”,这将显示连接到该块的自定义字段。
术语“内部块”是指启用嵌套内容(块内的块)的功能。这个简短的视频演示了如何使用内部块仅使用基本PHP来创建日期限制的块。
要增加对内部块的支持,请<InnerBlocks />
在渲染模板/回调中使用Component定义可编辑区域。编辑内容时,此特殊元素将显示为本机“块插入区域”,查看内容时,将显示为已保存的“内部块内容”。请注意,<InnerBlocks />
每个块只能使用一个组件。
为了使<innerBlocks />
Component在基于React的块编辑器中运行,必须首先将块HTML解析为JSX。通过添加对该__experimental_jsx
属性的支持,可以轻松完成此操作。
下面的示例演示如何创建前面提到的“受限制的”内容块。
add_action('acf/init', 'my_acf_init_blocks');
function my_acf_init_blocks() {
// Check function exists.
if( function_exists('acf_register_block_type') ) {
// Register a restricted block.
acf_register_block_type(array(
'name' => 'restricted',
'title' => 'Restricted',
'description' => 'A restricted content block.',
'category' => 'formatting',
'mode' => 'preview',
'supports' => array(
'align' => true,
'mode' => false,
'__experimental_jsx' => true
),
'render_template' => 'template-parts/blocks/restricted/restricted.php',
));
}
}
<?php
/**
* Restricted Block Template.
*
* @param array $block The block settings and attributes.
* @param string $content The block inner HTML (empty).
* @param bool $is_preview True during AJAX preview.
* @param (int|string) $post_id The post ID this block is saved to.
*/
// Create class attribute allowing for custom "className" and "align" values.
$classes = '';
if( !empty($block['className']) ) {
$classes .= sprintf( ' %s', $block['className'] );
}
if( !empty($block['align']) ) {
$classes .= sprintf( ' align%s', $block['align'] );
}
// Load custom field values.
$start_date = get_field('start_date');
$end_date = get_field('end_date');
// Restrict block output (front-end only).
if( !$is_preview ) {
$now = time();
if( $start_date && strtotime($start_date) > $now ) {
echo sprintf( '<p>Content restricted until %s. Please check back later.</p>', $start_date );
return;
}
if( $end_date && strtotime($end_date) < $now ) {
echo sprintf( '<p>Content expired on %s.</p>', $end_date );
return;
}
}
// Define notification message shown when editing.
if( $start_date && $end_date ) {
$notification = sprintf( 'Content visible from %s until %s.', $start_date, $end_date );
} elseif( $start_date ) {
$notification = sprintf( 'Content visible from %s.', $start_date );
} elseif( $end_date ) {
$notification = sprintf( 'Content visible until %s.', $end_date );
} else {
$notification = 'Content unrestricted.';
}
?>
<div class="restricted-block <?php echo esc_attr($classes); ?>">
<span class="restricted-block-notification"><?php echo esc_html( $notification ); ?></span>
<InnerBlocks />
</div>
该<InnerBlocks />
组件还可以与作为记录中的以下属性定制InnerBlocks部件指南。
$allowed_blocks = array( 'core/image', 'core/paragraph' );echo '<innerBlocks allowedBlocks="' . esc_attr( wp_json_encode( $allowed_blocks ) ) . '" />';
$template = array( array( 'core/paragraph', array( 'placeholder' => 'Add a root-level paragraph', ) ), array( 'core/columns', array(), array( array( 'core/column', array(), array( array( 'core/image', array() ), ) ), array( 'core/column', array(), array( array( 'core/paragraph', array( 'placeholder' => 'Add a inner paragraph' ) ), ) ), ) ));echo '<innerBlocks template="' . esc_attr( wp_json_encode( $template ) ) . '" templateLock="all" />';