ACF字段与短代码结构异常:a标签嵌套导致重复链接问题
问题排查与修复:WordPress Parrainage短代码嵌套链接错误
核心错误原因
你的代码存在HTML嵌套违规问题:HTML规范明确禁止<a>标签嵌套其他<a>标签。当lien_parrainage字段有值时,你会用外层<a>包裹整个卡片内容,而卡片内部又会输出lien_avis对应的<a>标签,浏览器为了修复无效结构,会自动拆分标签,最终导致生成重复的lien_avis链接。
修复方案
调整链接结构,避免<a>标签嵌套:将外层lien_parrainage的链接仅应用于需要跳转的元素(比如“Découvrir l'offre”按钮),而非整个卡片。如果标题也需要跳转,可以单独给标题添加链接,而非包裹整个卡片。
修复后的完整代码
function parrainage_shortcode($atts) { $atts = shortcode_atts(array( 'id' => '', ), $atts, 'parrainage'); $post_id = $atts['id']; $output = ''; if (empty($post_id)) return $output; $post = get_post($post_id); if (!$post) return $output; // 获取字段值 $image = get_the_post_thumbnail($post_id, array(80, 80)); $title = get_the_title($post_id); $description = apply_filters('the_content', $post->post_content); $lien_parrainage = get_field('lien_parrainage', $post_id); $lien_avis = get_field('lien_avis', $post_id); $offre_prefixe = get_field('offre_prefixe', $post_id); $offre = get_field('offre', $post_id); $offre_suffixe = get_field('offre_suffixe', $post_id); $note = get_field('note', $post_id); $mettre_en_avant_value = get_field('mettre_en_avant', $post_id); // 开始输出内容(使用输出缓冲简化字符串拼接) ob_start(); ?> <div class="parrainage_1 <?php echo esc_attr($mettre_en_avant_value); ?>"> <div class="parrainage-image-title-note"> <div class="parrainage-image"><?php echo $image; ?></div> <div class="parrainage-title"> <?php if (!empty($lien_parrainage)) : ?> <a href="<?php echo esc_url($lien_parrainage); ?>" class="parrainage-title-link"><?php echo esc_html($title); ?></a> <?php else : ?> <span class="parrainage-title-link"><?php echo esc_html($title); ?></span> <?php endif; ?> <?php if (!empty($note)) : ?> <span class="parrainage-note"> <span class="parrainage-note-value"><?php echo esc_html($note); ?></span> </span> <?php endif; ?> <?php if (get_post_type($post_id) !== 'avis' && !empty($lien_avis)) : ?> <a class="parrainage-lien-avis" href="<?php echo esc_url($lien_avis); ?>">Notre avis</a> <?php endif; ?> </div> </div> <?php if (!empty($description)) : ?> <div class="parrainage-description"><?php echo wp_kses_post($description); ?></div> <?php endif; ?> <div class="parrainage-offres"> <div class="parrainage-offre-labels"> <?php if (!empty($offre_prefixe)) : ?> <p class="parrainage-offre-prefixe"><?php echo esc_html($offre_prefixe); ?></p> <?php endif; ?> <?php if (!empty($offre)) : ?> <span class="parrainage-offre-offre"><?php echo esc_html($offre); ?></span> <?php endif; ?> <?php if (!empty($offre_suffixe)) : ?> <p class="parrainage-offre-suffixe"><?php echo esc_html($offre_suffixe); ?></p> <?php endif; ?> </div> <?php if (!empty($lien_parrainage)) : ?> <a href="<?php echo esc_url($lien_parrainage); ?>" class="parrainage-lien-parrainage button">Découvrir l'offre</a> <?php endif; ?> </div> </div> <?php $output = ob_get_clean(); return $output; } add_shortcode('parrainage', 'parrainage_shortcode');
代码简化与优化建议
- 使用输出缓冲:用
ob_start()/ob_get_clean()替代字符串拼接,让HTML结构更直观,减少语法错误。 - 添加安全过滤:用
esc_url()处理链接、esc_html()处理文本、wp_kses_post()处理富文本内容,避免XSS漏洞。 - 提前终止执行:在
post_id为空或get_post失败时直接返回空,减少嵌套层级。 - 优化条件判断:将
get_post_type()改为传入$post_id,确保获取目标文章的类型,而非当前上下文的类型。 - 拆分链接逻辑:避免用单个链接包裹整个卡片,针对需要跳转的元素单独添加链接,符合HTML规范。
内容的提问来源于stack exchange,提问作者Loris GFT
相关产品推荐
相关产品推荐

