ACF Blocks背景图无法获取:如何将块样式移至<head>?
解决ACF Block背景图字段返回NULL的问题
你的问题出在字段的存储位置和获取上下文不匹配,我来给你拆解原因和解决方案:
为什么$background_image总是返回NULL?
你当前用get_field('background_image', get_the_ID())是在尝试从**当前文章的自定义字段(post_meta)**里读取值,但你的background_image是ACF Block本身的字段——ACF Block的字段并不是存在文章的post_meta中,而是序列化后存在文章的post_content里,属于每个块实例自己的上下文。所以不管你用get_the_ID()还是get_queried_object_id(),都拿不到块里的字段值。
最简单的解决方案:在Block模板里直接生成样式
既然Block模板本身就在当前块的渲染上下文里,直接在模板里读取字段并输出样式就好,还能避免多个块样式冲突,步骤如下:
1. 修改page-intro.php模板文件
<?php /** * Page Intro 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. */ // 直接读取当前块的background_image字段 $background_image = get_field('background_image'); $bg_url = ''; $bg_url_2x = ''; if ($background_image) { // 获取不同分辨率的图片URL $bg_url = wp_get_attachment_image_src($background_image, 'hero')[0]; $bg_url_2x = wp_get_attachment_image_src($background_image, 'hero-2x')[0]; } ?> <?php if ($bg_url) : ?> <style> /* 给每个块加唯一ID类,避免多块样式冲突 */ .page-intro-wrapper-<?php echo esc_attr($block['id']); ?> { background: url(<?php echo esc_url($bg_url); ?>); /* 可以补充背景图的显示属性,比如background-size: cover; background-position: center; */ } @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { .page-intro-wrapper-<?php echo esc_attr($block['id']); ?> { background: url(<?php echo esc_url($bg_url_2x); ?>); } } </style> <?php endif; ?> <!-- 给容器添加唯一ID类 --> <div class="page-intro-wrapper page-intro-wrapper-<?php echo esc_attr($block['id']); ?>"> <div class="page-intro"> <?php $title = esc_html( get_field('title') ); if( get_field('include_intro_text') == 'yes' ) { echo '<h2>'.$title.'</h2>'; echo get_field('text'); } else { echo '<h2 class="no-intro-text">'.$title.'</h2>'; } ?> </div> </div>
2. 移除原来的page_intro_styles函数
因为现在样式已经直接在Block模板里生成了,不需要再通过wp_head钩子注入。
备选方案:通过解析文章内容获取块字段(适合必须用wp_head的场景)
如果你一定要在wp_head里生成样式,可以解析文章内容里的所有块,提取目标块的字段:
function page_intro_styles() { // 只在单页面/文章页面执行 if (!is_singular()) return; $current_post = get_post(); if (!$current_post) return; // 解析文章内容里的所有块 $blocks = parse_blocks($current_post->post_content); foreach ($blocks as $block) { // 过滤出我们注册的intro-intro块 if ($block['blockName'] !== 'acf/intro-intro') continue; // ACF块的字段存储在attrs->data里 $block_fields = $block['attrs']['data'] ?? []; $background_image = $block_fields['background_image'] ?? null; if (!$background_image) continue; $bg_url = wp_get_attachment_image_src($background_image, 'hero')[0]; $bg_url_2x = wp_get_attachment_image_src($background_image, 'hero-2x')[0]; // 用块的唯一ID作为样式前缀 $block_unique_id = $block['attrs']['id'] ?? uniqid('page-intro-'); ?> <style> .page-intro-wrapper-<?php echo esc_attr($block_unique_id); ?> { background: url(<?php echo esc_url($bg_url); ?>); } @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { .page-intro-wrapper-<?php echo esc_attr($block_unique_id); ?> { background: url(<?php echo esc_url($bg_url_2x); ?>); } } </style> <?php } } add_action('wp_head', 'page_intro_styles');
同时要确保Block模板里的容器加上对应的唯一ID类(和第一个方案里的模板修改一致)。
额外检查项
最后再确认两个细节:
- 你在ACF后台确实给
intro-intro块添加了名为background_image的字段,字段名称没有拼写错误; - 你上传的背景图已经正确保存,在Block编辑界面能正常预览到图片。
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

