Ali Jafarian

This tutorial provides an elegant way to display previous and next posts using Advanced Custom Fields and it’s Relationship/Post Object fields.


I use Advanced Custom Fields in most of my WordPress projects, and I often get tasked with creating custom courses. So here’s an example of where I’d like to show the previous and next posts for a specific course on every post, much like the standard prev/next links in WordPress. However, in this case I’m using the Advanced Custom Fields Relationship and Post Object fields, so I don’t have access to the normal WP the_post_navigation() function. So we’ll have to create our own!

Note – this is a more advanced tutorial. If you’re unfamiliar with code and WordPress or Advanced Custom Fields you will have a tough time understanding this, so please don’t come here expecting to copy/paste a solution! I also like to call my course posts modules in this example, but you can substitute modules for whatever you prefer or use.

The Code

<?php $parent_course = get_field('parent_course'); ?>

<?php if ( $parent_course ) : ?>
	<div class="post-nav nav-modules">
		<?php
			// get modules for parent course
			$modules = get_field( 'course_modules', $parent_course->ID );

			// create empty array for module ids
			$module_ids = array();

			// loop through modules and add them to array
			foreach( $modules as $module ) :
				$module_ids[] = $module->ID;
			endforeach;

			// get the current index
			$current_index = array_search( $current_post_id, $module_ids );

			// find the prev/next items
			$prev_module = $current_index - 1;
			$next_module = $current_index + 1;

			// find first and last modules
			$first_module = $module_ids[0];
			$last_module = end($module_ids);
		?>
		<div class="nav-links">
			<div class="nav-previous">
				<?php if ( $module_ids[$prev_module] ) : ?>
					<a href="<?php echo get_permalink( $module_ids[$prev_module] ); ?>">
						<span class="link-title"><?php echo get_the_title( $module_ids[$prev_module] ); ?></span>
					</a>
				<?php else : ?>
					<span class="no-link">This is the first module.</span>	
				<?php endif; ?>
			</div>
			<!--/.nav-previous-->
			<div class="nav-next">
				<?php if ( $module_ids[$next_module] ) : ?>
					<a href="<?php echo get_permalink( $module_ids[$next_module] ); ?>">
						<span class="link-title"><?php echo get_the_title( $module_ids[$next_module] ); ?></span>
					</a>
				<?php else : ?>
					<span class="no-link">This is the last module.</span>	
				<?php endif; ?>
			</div>
			<!--/.nav-next-->
		</div>
		<!--/.nav-links-->
	</div> 
	<!--/.post-nav-->
<?php endif; ?>
Now let’s break this down –

For starters, this post (module) has a custom field for a Parent Course, which is a Post Object type in ACF. I grab that and store it in a variable using the code below:

$parent_course = get_field('parent_course');

Next, we have to get our list of modules for the parent course. This just returns a list of post objects via the ACF Relationship field.

$modules = get_field( 'course_modules', $parent_course->ID );

Then we will create an empty array to store the module list in, and loop through them to order them properly. We’ll call this new array $module_ids.

// create empty array for module ids
$module_ids = array();

// loop through modules and add them to array
foreach( $modules as $module ) :
	$module_ids[] = $module->ID;
endforeach;

Finally, we’ll create some variables to extract where we are in the array of modules. These will be useful when we’re trying to display things in the UI.

// get the current index
$current_index = array_search( $current_post_id, $module_ids );

// find the prev/next items
$prev_module = $current_index - 1;
$next_module = $current_index + 1;

// find first and last modules
$first_module = $module_ids[0];
$last_module = end($module_ids);

Now we have everything we need to create an intuitive post navigation for our course modules. I also provide some logic to show a message if it’s the first or last module in the course, instead of leaving it blank.

<div class="nav-links">
	<div class="nav-previous">
		<?php if ( $module_ids[$prev_module] ) : ?>
			<a href="<?php echo get_permalink( $module_ids[$prev_module] ); ?>">
				<span class="link-title"><?php echo get_the_title( $module_ids[$prev_module] ); ?></span>
			</a>
		<?php else : ?>
			<span class="no-link">This is the first module.</span>	
		<?php endif; ?>
	</div>
	<!--/.nav-previous-->
	<div class="nav-next">
		<?php if ( $module_ids[$next_module] ) : ?>
			<a href="<?php echo get_permalink( $module_ids[$next_module] ); ?>">
				<span class="link-title"><?php echo get_the_title( $module_ids[$next_module] ); ?></span>
			</a>
		<?php else : ?>
			<span class="no-link">This is the last module.</span>	
		<?php endif; ?>
	</div>
	<!--/.nav-next-->
</div>
<!--/.nav-links-->

And that’s all there is to it. A nice and logical way to create previous/next posts (modules) with Advanced Custom Fields.

I hope this is helpful in your projects!

Discussion

2 thoughts on “How To Create Previous and Next Posts with Advanced Custom Fields”
  1. Thank you for posting this! Really helped me out.

    To anybody else seeing “Undefined offset” warnings (because WP debug is turned on) you can keep them hidden by changing to (and do the same thing with $next_module)

Leave a Comment

Your email address will not be published. Required fields are marked *