如何在WordPress自定义主题中实现指定区块的动态化配置?
WordPress自定义主题可绑定文章动态区块实现方案
1. 实现逻辑说明
该方案可同时满足两种内容调用需求:
- 绑定已发布的博客文章,数据调用逻辑与普通文章查询完全一致
- 未绑定文章时支持直接在区块配置项中填写自定义内容,也可对接自定义字段工具扩展配置项
- 支持在区块编辑器中手动下拉选择要绑定的目标文章
2. 服务端注册代码(添加到主题functions.php文件中)
add_action('init', function() { register_block_type('custom/post-bind-block', [ 'attributes' => [ 'bindPostId' => [ 'type' => 'number', 'default' => 0 ], 'customTitle' => [ 'type' => 'string', 'default' => '' ], 'customContent' => [ 'type' => 'string', 'default' => '' ] ], 'render_callback' => function($attributes) { $postId = $attributes['bindPostId'] ?? 0; ob_start(); if ($postId && get_post_status($postId) === 'publish') { // 绑定已有文章的场景,复用原生文章查询逻辑 $query = new WP_Query(['p' => $postId, 'post_type' => 'post']); if ($query->have_posts()) { while ($query->have_posts()) { $query->the_post(); ?> <div class="custom-bound-post"> <h3><?php the_title() ?></h3> <?php if (has_post_thumbnail()) : ?> <?php the_post_thumbnail('medium') ?> <?php endif; ?> <div class="post-excerpt"><?php the_excerpt() ?></div> <!-- 需调用自定义字段可直接使用 get_post_meta(get_the_ID(), '字段名', true) --> </div> <?php } wp_reset_postdata(); } } else { // 未绑定文章的场景,输出自定义内容 $customTitle = $attributes['customTitle'] ?? ''; $customContent = $attributes['customContent'] ?? ''; if ($customTitle || $customContent) { ?> <div class="custom-bound-post"> <?php if ($customTitle) : ?> <h3><?php echo esc_html($customTitle) ?></h3> <?php endif; ?> <div class="post-excerpt"><?php echo esc_html($customContent) ?></div> </div> <?php } } return ob_get_clean(); } ]); });
3. 区块编辑器端注册代码
import { registerBlockType } from '@wordpress/blocks'; import { useSelect } from '@wordpress/data'; import { ComboboxControl, TextControl, TextareaControl } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; registerBlockType('custom/post-bind-block', { title: __('文章绑定动态区块', 'text-domain'), icon: 'admin-post', category: 'common', attributes: { bindPostId: { type: 'number', default: 0 }, customTitle: { type: 'string', default: '' }, customContent: { type: 'string', default: '' } }, edit: ({ attributes, setAttributes }) => { // 拉取所有已发布文章生成下拉选项 const allPosts = useSelect(select => { return select('core').getEntityRecords('postType', 'post', { status: 'publish', per_page: -1 }); }, []); const postOptions = allPosts ? allPosts.map(post => ({ label: post.title.rendered, value: post.id })) : []; return ( <div className="custom-block-editor"> <ComboboxControl label={__('选择要绑定的文章', 'text-domain')} value={attributes.bindPostId} options={postOptions} onChange={(val) => setAttributes({ bindPostId: val ? Number(val) : 0 })} /> {/* 未选择绑定文章时展示自定义内容填写控件 */} {!attributes.bindPostId && ( <> <TextControl label={__('自定义标题', 'text-domain')} value={attributes.customTitle} onChange={(val) => setAttributes({ customTitle: val })} /> <TextareaControl label={__('自定义内容', 'text-domain')} value={attributes.customContent} onChange={(val) => setAttributes({ customContent: val })} /> </> )} </div> ); }, // 动态区块走服务端渲染,save方法直接返回null即可 save: () => null });
内容的提问来源于stack exchange,提问作者Aniruddha Mandal
相关产品推荐
相关产品推荐

