Two or three column section


A while back I wrote a quick and dirty tutorial on how to display more than one page. This can be done in a number of different ways. You can read about them in other tutorials and guides because this time I’ll go over another method using the WP_Query method. The codex page some really great ways and examples of using it to your advantage, I highly recommend you give it a skim and return to this.

So, on to the code!

What I’ll be using is a switch statement, an active callback, and of course the customizer API.

First we will create the settings and controls:

$wp_customize->add_section( 'demo-front-sections',
				 array(
					 'title' => __( 'Front page sections', 'text-domain' ),
					 'description' => __( 'Choose what pages to show on the front page panels', 'text-domain' ),
					 'priority' => 1,
					 'active_callback' => 'is_front_page'
				 ) );
$wp_customize->add_setting( 'col-count',
				 array(
					'default' => 2,
					'sanitize_callback' => 'absint'
				 ) );
$wp_customize->add_control( 'panel-count',
				 array(
					'settings' => 'col-count',
					'label' => __( 'How many panels on this section', 'text-domain' ),
					'type' => 'radio',
					'choices' => array( '2' => 2, '3' => 3 ),
					'section' => 'demo-front-sections',

				 ) );

// Register the page settings to get the IDs
$wp_customize->add_setting( 'page-1',
				 array(
					'default' => 0,
					'sanitize_callback' => 'absint'
				 ) );
$wp_customize->add_setting( 'page-2',
				 array(
					'default' => 0,
					'sanitize_callback' => 'absint'
				 ) );
$wp_customize->add_setting( 'page-3',
				 array(
					'default' => 0,
					'sanitize_callback' => 'absint'
				 ) );

// Set the controls
$wp_customize->add_control( 'panel-1',
				 array(
					 'settings' => 'page-1',
					 'label' => __( 'Pick what page you would like to showcase', 'text-domain' ),
					 'type' => 'dropdown-pages',
					 'section' => 'demo-front-sections'
				 ) );
$wp_customize->add_control( 'panel-2',
				 array(
					 'settings' => 'page-2',
					 'label' => __( 'Pick what page you would like to showcase', 'text-domain' ),
					 'type' => 'dropdown-pages',
					 'section' => 'demo-front-sections'
				 ) );
$wp_customize->add_control( 'panel-3',
				 array(
					 'settings' => 'page-3',
					 'label' => __( 'Pick what page you would like to showcase', 'text-domain' ),
					 'type' => 'dropdown-pages',
					 'section' => 'demo-front-sections',
					 'active_callback' => 'panel_countcheck'
				 ) );

You’ll notice I used a basic active callback for the section so that the section will only show up on the front page. You may also notice that I’ve added a callback to the third control. We haven’t created that callback so let’s do it:

function panel_countcheck( $value ){
	if ( get_theme_mod( 'col-count' ) > 2 ){
		return true;
	}
	return false;
}

Great! Now what does it do? Let’s break it down a little. So, if the first value ( col-count ) is greater than 2, then let’s show this control, otherwise we won’t. Pretty self-explanatory, right?

Great now we just need to display this on a page template, or the front page ( in our case ). We use get_theme_mod to get the values and the code will look a little like:

// get setting for how many
$count = intval( get_theme_mod( 'col-count', 2 ) );
// create an array for the new query
$ids= array();
// get the pages
$ids[] = intval( get_theme_mod( 'page-1', 0 ) );
$ids[] = intval( get_theme_mod( 'page-2', 0 ) );
if ( $count > 2 ){
	$ids[] = intval( get_theme_mod( 'page-3', 0 ) );
}

$query = new WP_Query( array( 'post_type' => 'page', 'post__in' => $ids, 'orderby' => 'post__in' ) );

switch( $count ){
	case 2:
		while( $query->have_posts() ): $query->the_post();
			echo '<div class="col-2">';
				the_title( '<h2>', '</h2>'); the_content();
			echo '</div>';
		endwhile;
	wp_reset_postdata();
	break;
	case 3:
		while( $query->have_posts() ): $query->the_post();
			echo '<div class="col-3">';
				the_title( '<h2>', '</h2>'); the_content();
			echo '</div>';
		endwhile;
	wp_reset_postdata();
	break;
}

Yeah, it is a little messy but we will break it down and explain what does what.

The first setting we get is the column count. You’ll see that I am using intval because we want to make sure that we are setting an integer. The value being passed from the customizer setting is an ID number that corresponds to a page ID, so we make sure that it really is an integer.

$count = intval( get_theme_mod( 'col-count', 2 ) );

Next up, we get our pages and build up the array that we will pass our new WP_Query. As you can see, we first get the first two pages and conditionally add the third if the $count is greater than 2. Remember this is the setting that the user picks.

$ids[] = intval( get_theme_mod( 'page-1', 0 ) );
$ids[] = intval( get_theme_mod( 'page-2', 0 ) );
if ( $count > 2 ){
	$ids[] = intval( get_theme_mod( 'page-3', 0 ) );
}

From there, we build up the new query. Pretty simple. We make sure that the post type is a page, and the order is maintained by what we pass it.

$query = new WP_Query( array( 'post_type' => 'page', 'post__in' => $ids, 'orderby' => 'post__in' ) );

Now we get to the switch statement! This is where the fun sort of begins.

switch( $count ){
	case 2:
		while( $query->have_posts() ): $query->the_post();
			echo '<div class="col-2">';
				the_title( '<h2>', '</h2>'); the_content();
			echo '</div>';
		endwhile;
	wp_reset_postdata();
	break;
	case 3:
		while( $query->have_posts() ): $query->the_post();
			echo '<div class="col-3">';
				the_title( '<h2>', '</h2>'); the_content();
			echo '</div>';
		endwhile;
	wp_reset_postdata();
	break;
}

Okay. Let’s look over the lines a bit. As you can see we pass it the $count variable we first created, which houses the option of whether to show 2 pages or 3. We create a case for each one and as you can see the only real difference here is the class. For showing two pages it is 2-col and for the 3 it is 3-col. You can create a quick wrapper for that if you want so it can be extended by a child theme like:

function jc_classes(){
	$classes = array();
	$classes[] = 'span';
	$cols = get_theme_mod( 'col-count', 2 );
	switch( $cols ){
		case 2:
		$classes[] = 'col-2';
		break;
		case 3:
		$classes[] = 'col-2';
		break;
	}
	
	return 'class="' . esc_attr( implode( ' ', apply_filters( 'jc_custom_classes', $classes ) ) ) . '"';
}

From there we can lose the switch statement and use:

$query = new WP_Query( array( 'post_type' => 'page', 'post__in' => $ids, 'orderby' => 'post__in' ) );
while( $query->have_posts() ): $query->the_post();
	echo '<div ' . jc_classes() .'>';
		the_title( '<h2>', '</h2>'); the_content();
	echo '</div>';
endwhile;
wp_reset_postdata();

What’s really nice is you can use basic CSS to style it. A quick snippet:

.col-2 {
	float: left;
	width: 50%;
}

.col-3 {
	float: left;
	width: 33%;
}

So, go on, experiment, and fiddle around with the code a bit. Do remember I used basic things, so be sure to add the proper settings, text, and values for your needs.