WordPress: Display Content in multiple Columns

Recently I had to create a website which displays the content in 2 columns.

While CSS 3 is capable of doing this on its own with the new Grid Position Module, a lot of browsers do not support this functions yet, so I needed to add a little extra markup to the output which is generated via the_content() to get the following result:


To get this result we need to filter the_content() before output with a custom function and add 2 divs to the output, which we style with CSS later on. So Ladys and Gentleman please open the functions.php file of your current WordPress Theme.

What functions.php does is let you create functions you can reuse in your theme. It works similar to a plugin file, being loaded when the theme is first loaded.

First of all: here you can see the whole code we need to filter our content, step by step description follows:

function my_multi_col($content){
$columns = explode('<h2>', $content);

$i = 0;

	foreach ($columns as $column){
	if (($i % 2) == 0){
		$return .= '<div class="content_left">' . "\n";
		if ($i > 1){
		$return .= "<h2>";
	} else{
		$return .= '<div class="content_right">' . "\n <h2>";
	}
		$return .= $column;
		$return .= '</p></div>';
		$i++;
	}

	if(isset($columns[1])){
	    $content = wpautop($return);
	}else{
	    $content = wpautop($content);
	}
	echo $content;
}
add_filter('the_content', 'my_multi_col');

What we do first is define a delimiter and split the whole content at specific points. I wanted to create a new column whenever a h2 tag was found.

$columns = explode('<h2>', $content);

The result is stored in an array which we will use to create a new $content string. To access each array item we will use a foreach loop:

        $i = 0;

	foreach ($columns as $column){
        $i++;
	}

You should have noticed the variable $i by now, we will use it to check if the current content part should be stored in a left column or right column div. To accomplish this we simply use the modulo operation ( $i % 2).

The modulo operator divides the first integer by the second and returns the remainder. Since we divide by 2 there are only 2 possible values to return: 0 and 1. If zero is returned we need a left content div, if 1 is returned a right content div:

        $i = 0;
	foreach ($columns as $column){
            if (($i % 2) == 0){
                $return .= '<div class="content_left">' . "\n";
            }else{
                $return .= '<div class="content_right">' . "\n";
            }
        $i++;
	}

Since the explode function we used earlier strips away our <h2> opening tags we need to add them to the code again, but we must be careful were to add them: We always need an opening tag in the right column and always need an opening tag in the left column except for the first time!

$i = 0;

	foreach ($columns as $column){
	if (($i % 2) == 0){
		$return .= '<div class="content_left">' . "\n";
		if ($i > 1){
		$return .= "<h2>";
	} else{
		$return .= '<div class="content_right">' . "\n <h2>";
	}

	}

After adding the opening tags we simply put in the exploded $content parts and close the current <p> (automatically generated by WordPress) and <div> tag. After creating our new content string which is currently stored as a whole in $return we pass it to the wpautop which automatically adds formating to the string, store it in $content and then output it with echo, but ONLY if there was an h2 tag found. Otherwise we don’t need a second column and display the_content() without modifications.

$i = 0;

	foreach ($columns as $column){
	if (($i % 2) == 0){
		$return .= '<div class="content_left">' . "\n";
		if ($i > 1){
		$return .= "<h2>";
	} else{
		$return .= '<div class="content_right">' . "\n <h2>";
	}
		$return .= $column;
		$return .= '</p></div>';
		$i++;
	}

        if(isset($columns[1])){
	    $content = wpautop($return);
	}else{
	    $content = wpautop($content);
	}	echo $content;
}

Last but not least we have to tell WordPress when to activate our function. This is simply done with “add_filter”

add_filter('the_content', 'my_multi_col');

Now whenever $content contains any h2 items they will be put in different divs . Just add some basic CSS and you are done:

.content_right, .content_left{
float:left;
width:45%;
}

.content_left{
padding-right:5%;
}

The function we created is far from perfect, but the main goal of this tutorial is to show you how you can modify the output of the WordPress generated content in an easy way. Have fun doing so ;)

Tags: ,
73 replies
Newer Comments »
  1. quanta
    quanta says:

    Good stuff, but there appears to be a missing end bracket in the code. I believe it should be on Line 10. It also seems to behave strangely if you have more than one H2 tag in the content. A H2 tag at the very beginning of the content as well as in the middle of the content would cause 3 columns to be created, with the first one having no content whatsoever and the content beginning on Column #2 instead.

    I further tweaked the code and changed the delimiter to “[!–break–]” (replace brackets to pointy brackets) as it was style-neutral. This simplifies the code a bit.

  2. Alejandro Urrutia Daglio
    Alejandro Urrutia Daglio says:

    Hi Kriesi, nice tutorials you got here.

    I must say that I try to implement this one in a test wordpress installation I got and the result is:
    Parse error: syntax error, unexpected $end in W:\xampp\htdocs\wordpress\wp-content\themes\default\functions.php on line 34

    This is the code I use:

    <?php
    /**
    * @package WordPress
    * @subpackage Default_Theme
    */

    function my_multi_col($content){
    $columns = explode(”, $content);

    $i = 0;

    foreach ($columns as $column){
    if (($i % 2) == 0){
    $return .= ” . “\n”;
    if ($i > 1){
    $return .= “”;
    } else{
    $return .= ” . “\n “;
    }
    $return .= $column;
    $return .= ”;
    $i++;
    }

    if(isset($columns[1])){
    $content = wpautop($return);
    }else{
    $content = wpautop($content);
    }
    echo $content;
    }
    add_filter(‘the_content’, ‘my_multi_col’);

    ?>

    Any Idea why is it working bad?

  3. Covi
    Covi says:

    content_left and content_right???
    What if you want to put temporaly content_left in the right side?? …or serve your document as xml ^^!

    A small but basic suggestion:
    What about primary|secondary|…_content…?

    ^^!

  4. Arturex
    Arturex says:

    Excelent tutorial I was looking for this just the way its explained in here Thanks very Much Kriesi

    Hola Alejandro Urrutia Daglio
    the problem you have i had it, all you need to do is close with a }after de “add filter” like this:

    add_filter(’the_content’, ‘my_multi_col’);
    }
    ?>

  5. floris
    floris says:

    i get an unexpected $end on line 213 as soon as i try to update functions.php. then: if i try to access my site i get same error, try to acces wp admin, same error.

    only when i re-upload functions.php im not getting the error anymore. w
    can someone tell me how to edit functions.php correctly.

    please mail floris_lant@hotmail.com

  6. San Diego Website Design
    San Diego Website Design says:

    Is there a plugin of somesort made for this function? It would be easier than having to create some custom php code if you want to change the layout of the content.

    It seems that things like this would be more difficult to implement in WP, and we’ll have to resort to expression engine instead (which isn’t a bad thing)

  7. gina michel
    gina michel says:

    i read every single of your post sometimes i read it over and over again ..you really inspired many people here..wish you a good luck in everything you do..

  8. Monika
    Monika says:

    These function doesn’t work, maybe it outputs the divs but there is no content between them and the html looks very creative ;)

  9. daft01
    daft01 says:

    if you want 2 columns pages, 3 columns pages etc…
    you just need to float the default .post class.

  10. Jasper
    Jasper says:

    Great function. Just what I was looking for! One question though. If I would like to do make this function work on a particular page only? How would you make this function work for a particular WordPress page or some WordPress pages only?

Trackbacks & Pingbacks

  1. […] page. All three blocks of content are unique to that page. This solution was heavily inspired by a post at kriesi.at, but I’ve modified it with the help of Chris Bratlien to make as many content areas as you […]

  2. […] We had a look around and we found a potential solution on this blog post. […]

  3. […] en una o dos columnas y quieres cambiarlo a más pero que sea usable, te invito a que revises este tutorial que explica cómo trabajar el código haciendo uso de CSS3 y respetando los estándares de la […]

  4. […] questo post viene spiegato come spezzare e visualizzare il testo di un articolo su due […]

  5. […] Using excerpts in templates Cool plugins, including disabling formatting, twitter, article list Removing <p> tags 1 Removing <p> tags 2 Multiple columns in posts […]

  6. […] en una o dos columnas y quieres cambiarlo a más pero que sea usable, te invito a que revises este tutorial que explica cómo trabajar el código haciendo uso de CSS3 y respetando los estándares de la […]

Newer Comments »

Comments are closed.