如何让WordPress中ACF灵活内容字段按后台排序而非PHP文件顺序显示?
问题原因与解决方案
核心问题
你当前的代码逻辑是对project_sections重复进行多次循环,每次循环只筛选一种布局类型(比如先循环所有single_wide,再循环所有two_column_wide),这就导致所有同类型区块被集中展示,完全无视了后台设置的区块顺序。
修复方法
只需要对project_sections做一次循环,在循环内部根据当前行的布局类型,输出对应的HTML结构,这样就能严格遵循后台添加区块的顺序。修改后的代码如下:
<div id="main"> <section> <?php if ( have_posts() ) : ?> <?php while ( have_posts() ) : the_post(); ?> <div id="project"> <?php $backgroundImg = wp_get_attachment_image_src( get_post_thumbnail_id($post->ID), 'full' ); ?> <div id="feature_image" style="background: url('<?php echo $backgroundImg[0]; ?>') no-repeat; background-size: cover; background-position: center; background-repeat: no-repeat;"></div> <div class="project_body"> <div class="project_hero_text"> <ul> <li> <h1><?php the_title(); ?></h1> <div class="services"> <h3><?php $terms = get_the_terms( $post->ID, 'service' ); if($terms != null) { end($terms); $endKey = key($terms); foreach($terms as $key => $term) { echo $key != $endKey? $term->name.", " : $term->name; unset($term); } }?> </h3> </div> </li> <li> <p><?php the_content(); ?></p> </li> </ul> </div> <!-- 只循环一次project_sections,按后台顺序输出 --> <?php if( have_rows('project_sections') ): ?> <?php while( have_rows('project_sections') ): the_row(); ?> <?php if( get_row_layout() == 'single_wide' ): $image = get_sub_field('image'); ?> <div class="single_wide"> <img src="<?php echo $image['url']; ?>" alt="<?php echo $image['alt']; ?>"> </div> <?php endif; ?> <?php if( get_row_layout() == 'two_column_wide' ): $left = get_sub_field('left'); $right = get_sub_field('right'); ?> <div class="two_column_wide"> <ul> <li> <img src="<?php echo $left['url']; ?>" alt="<?php echo $left['alt']; ?>"> </li> <li> <img src="<?php echo $right['url']; ?>" alt="<?php echo $right['alt']; ?>"> </li> </ul> </div> <?php endif; ?> <?php if( get_row_layout() == 'single_small' ): $image = get_sub_field('image'); ?> <div class="single_small"> <img src="<?php echo $image['url']; ?>" alt="<?php echo $image['alt']; ?>"> </div> <?php endif; ?> <?php if( get_row_layout() == 'two_column_small' ): $left = get_sub_field('left'); $right = get_sub_field('right'); ?> <div class="two_column_small"> <ul> <li> <img src="<?php echo $left['url']; ?>" alt="<?php echo $left['alt']; ?>"> </li> <li> <img src="<?php echo $right['url']; ?>" alt="<?php echo $right['alt']; ?>"> </li> </ul> </div> <?php endif; ?> <?php if( get_row_layout() == 'project_text' ): ?> <div class="project_text"> <p> <span class="annotation"> <?php echo str_replace('<br>', '\n', get_sub_field( 'annotation' )); ?> </span> <?php echo str_replace('<br>', '\n', get_sub_field( 'text' )); ?> </p> </div> <?php endif; ?> <?php endwhile; ?> <?php endif; ?> <div class="project_credits"> <?php if( have_rows('credits') ): ?> <ul> <?php while( have_rows('credits') ) : the_row(); // Get parent value. $parent_title = get_sub_field('credit'); // Loop over sub repeater rows. if( have_rows('credit') ): while( have_rows('credit') ) : the_row(); // Get sub value. $child_title = get_sub_field('name'); ?> <li> <p> <span class="annotation"> <?php echo str_replace('<br>', '\n', get_sub_field( 'discipline' )); ?> </span> <a href="<?php echo str_replace('<br>', '\n', get_sub_field( 'link' )); ?>"> <?php echo str_replace('<br>', '\n', get_sub_field( 'name' )); ?> </a> </p> </li> <?php endwhile; ?> <?php endif; ?> <?php endwhile; ?> </ul> <?php endif; ?> </div> <?php wp_link_pages(); ?> </div> </div> <?php endwhile; ?> <?php else : ?> <?php endif; ?> </section> </div>
关于单独文件引入的问题
不需要把自定义字段放到单独PHP文件再引入,不过如果后期代码量增大,为了提升可维护性,可以把project_sections的渲染逻辑封装成独立模板文件(比如template-parts/project-sections.php),然后在single.php中用get_template_part('template-parts/project-sections')引入,但这和区块顺序问题无关。
内容的提问来源于stack exchange,提问作者Dominic Hands
相关产品推荐
相关产品推荐

