Over the last couple days I’ve had the dilemma of trying to figure out how to word-wrap WordPress post content into two columns. Here is an example of what I needed to produce.
As you can tell it shouldn’t be too difficult, but there’s a crux that I’ll bring up after the first solution.
The first solution that will use CSS3 column-count; and some js for that browser we all hate ( IE if you couldn’t tell ).
For Firefox and Webkit browsers ( chrome and safari ) it’s as easy as this:
#container {
text-align: justify;
width: 885px;
margin: 10px auto;
padding: 10px;
}
.columns {
-moz-column-count: 2;
-moz-column-gap: 1.5em;
-moz-column-rule: none;
-webkit-column-count: 2;
-webkit-column-gap: 1.5em;
-webkit-column-rule: none;
/* future proof */
column-count: 2;
column-gap: 1.5em;
column-rule: none;
}
Then for IE there’s a great script that will parse through your CSS and force IE to split the content up into two columns. Here’s a demo of the script in action. You should be able to figure out how to implement it from there, it’s pretty easy.
[note: just make sure that you don't have your style sheets on a different domain, otherwise the script will not be able to parse it. I ran into this because of how I have my local wp dev setup]
Now this solution will solve just about 99% of anyones needs. However, if you wanted to print that same page you’re at a lose, the columns will break down.
Here comes my second solution, the one that I’m using on the current project.
The below function will essentially figure out where the middle of the content is, then insert your separation code in-between.
function content_split($text, $separator = '<hr/>', $start = false ) {
if ( $start === false) {
$start = strlen($text) / 2;
}
$lastSpace = false;
$split = substr($text, 0, $start - 1);
// if the text is split at a good breaking point already.
if (in_array(substr($text, $start - 1, 1), array(' ', '.', '!', '?'))) {
$split .= substr($text, $start, 1);
// Calculate when we should start the split
$trueStart = strlen($split);
// find a good point to break the text.
} else {
$split = substr($split, 0, $start - strlen($separator));
$lastSpace = strrpos($split, ' ');
if ($lastSpace !== false) {
$split = substr($split, 0, $lastSpace);
}
if (in_array(substr($split, -1, 1), array(','))) {
$split = substr($split, 0, -1);
}
// Calculate when we should start the split
$trueStart = strlen($split);
}
//now we know when to split the text
return substr_replace($text, $separator, $trueStart, 0);
}
[props to this function which helped me through]
And to implement it into WordPress just place the above function in your functions.php file, then just use the function anywhere you’d like and pass the appropriate vars:
<div class="first-column column"> <?php $text = get_the_content(); $separator = '</div><div class="second-column column">'; echo content_split($text,$separator); ?> </div>
My CSS is basic after that:
.column {
float: left;
width: 430px;
clear: right;
}
.first-column {
margin-right: 20px;
}
Now I can print the page exactly how it looks on the web ( maybe with a little print.css love ).

Why aren't you just hooking into the_content rather than doing manipulation in the template file?
add_filter( 'the_content', 'split_content_into_two_columns');
function split_content_into_two_columns($content) {
// Check content for length or something
$separator = '</div><div class=”second-column column”>';
$content = content_split($content,$separator);
return $content;
}
Also, you've got some typos in that first CSS sample. You double specify a -moz property, I believe.
Otherwise, looking good. PS, I might steal this for my book
Also, forgot to mention this in my first comment, but what about splitting around HTML tags?
$content = '<div>
This is my first sentence. This is my second sentence.
</div>';
$content = content_split($content,'</div><div>');
Wouldn't this be bad?
You're right this would invalidate the markup for p tags but there's no way around it; since I can't wait until the next closing p tag to start the split, although possible.
As far as any other markup, like an img tag, this script would totally screw it up. Since an img tag for example has a very high potential getting slit with it having a lot of spaces; anchors are another concern.
I'll need to think about it a little more.
So, I'm not hooking into the_content because this wont be used throughout the theme, only with certain posts under a certain condition ( modal box ).
Gotcha, cool beans.
This is cool stuff, although you know I don't like the javascript-only thing, even just for IE. I wasn't aware of that particular CSS 3 attribute, though, so that's cool. For the non-IE browsers, do you know what versions the proprietary substitutes (the -moz and -webkit versions) were introduced in?
Anyway, for the PHP side, it would be great if you could keep the HTML valid, since it could end up throwing off other stuff in your page if the break is bad enough.
Maybe you could try loading the content as XML and manipulating it with the PHP DOM libraries? You could walk through the nodes until you find the one the split should be in, and then handle that particular node by replacing it with two nodes that have the content split out, and then do the split out from there, closing any open parent nodes and starting corresponding new ones in the next column. It isn't easy, but that's my first thought on how to tackle it and still end up with valid HTML at the end.
Or just say no to the client asking for this…
Browser support: http://tinyurl.com/ygphca7
http://www.quirksmode.org/css/multicolumn.html
Supported by Firefox 1.5+ and Safari 3. So a while ago.
XML and PHP: Yeah right, I'm shying away from any php+xml for a long while, the last time I tried it was a mess.
I think I'll just search over X amount of characters (like 20) before the $start for a “<” tag, then just move the $split there.
Hi,
i have an issue with modyfing the content in the functions.php. I wanted to input a gallery into the content so i downloaded several galleries (nextgen for example). now for using a gallery into the content we have to type in in the post [gallery = x] and the gallery is displayed on the page.
But because i am modifying the content in my functions.php the shortcode is echoed and not inteprated. so i dont see the gallery, but i see the shortcode [gallery = x]. I dont know how to solve this issue, that i do modify the content (because of splitting into two columns) and that the gallery is shown.
Thanks for your help in advance. I cant find a solution on this.
add_filter( 'the_content', 'add_gallery_shortcode_and_interpret' );
function add_gallery_shortcode_and_interpret($content) {
$content .= do_shortcode('[gallery id=xxx]');
return $content;
}
Hi Nick,
The thing is in this way i am not flexible anymore, because i want to paste the gallery by the user in his post… and if he posted a gallery then i want to put this gallery on the right side… so do i have to parse the $content in my function and as soon as a shortcode comes i can add it by calling the function do_shortcode?
Otherwise i will always add the gallery on the end of my post and i have to give the id of the galleriy in my function :-S
If you're only trying to get the shortcode interpreted, just call do_shortcode on the entirety of your content after you're finished doing whatever it is you want with it.
Hi Dan,
Thanks for sharing this.
Unfortunately, you made a false assumption at one point. Basically you're saying: “if it's not IE, it supports CSS3 column-count”. That is not true; for instance Opera does not support column-count, yet you don't allow Opera to fall back on the js solution.
Instead of browser-sniffing, I think you'd better check if the browser actually supports column-count. A script like modernizr (http://www.modernizr.com/) does that. When you detect features instead of browsers, you automatically support every js-enabled browser and you won't have to update your code every time a browser implements a new feature.
Thanks very much!!!
This was EXACTLY what I was looking for and with a few tweaks to the CSS it worked perfectly on my site.
Any chance you feel like elaborating on your reply to Jared:
“I think I'll just search over X amount of characters (like 20) before the $start for a “<” tag, then just move the $split there.”
An example of this would be fantastic.
Thanks,
Carlo
Hiya —
I'm trying to split my WP archives into two columns. I have the function setup. However, I'm ending up with this:
<div class=”first-column column”>
<li>February 2010</li>
<li>February 2007</li>
</div><div class=”second-column column”>
</div>
This is my code:
<div class=”first-column column”>
<? php
$text = wp_get_archives('type=daily');
$separator = '</div><div class=”second-column column”>';
echo content_split($text,$separator);
? >
</div>
In your case, since it's not so dynamic, I'd just create do have
two wp_get_archives. One with something like “before 2005″ and the other
“after 2004″
Hiya — thanks, but the problem is that I'm creating a custom template for a client who hasn't even launched the site yet…
I would just do a custom query against how many unique days your client has content for, then split the days in half and query against each separately for your archives, just like Dan suggested. That way you won't ever have to update your template.
just write some code to search backward to the previous p tag, if it comes before the end of the last div then put the tag in before the </div> tag. As for writing the code – someone else may be able to help im no expert with PHP. You could do the same for any html tag such as or </li></ul>. Would basically just be a case of switching using a arrays or summit.
That won't really work, since a post could have 7 paragraphs not just
2. Also, the last paragraph could be of a different length from the
first.
–
Dan Cameron
Solution Engineer
Very informative and we might could use a plugin as well for WordPress soon for a client.
~Clint
@cazoomi
But when i use the “get_the_content();” strips all the content. You dont get the P’s used in wordpress.
How can i fix this?
Dan, I’ve been googling around for a code snippet or script that can help me create automatically detect the width and either create 2 or 3 columns, for easier reading and better usage of screen real estate. I’m not really very technical, so just wondering… Is it possible? Is it easy enough to code?
Buy Louis Vuitton is one of the most counterfeited brands in the fashion world due to its image as a status symbol.Now we have great discount for our
Louis Vuitton Sale.
Louis Vuitton Handbags is one of the world’s leading international fashion houses.
Louis Vuitton Bags sells its products through standalone boutiques.Louis Vuitton Outlet is one of the World’s most recognized brands. Louis Vuitton Online A long time symbol of prestige and wealth,The Louis Vuitton Purses Brand and the famous Louis Vuitton Outlet Store monogram are among the world’s most valuable brands. A genuine Louis Vuitton purse.
Now there are many Coach Outlet which provide cheaper price for the consumer. Coach outlet Store .Now Coach are available in our Coach factory outlet ,come here to choose your favorite coach handbags and Coach bags from Coach Outlet Online coupon .We hope you have a happy shopping in our Coach Factory Outlet store! The Coach Factory Outlets,are more than 100 kinds of products.
Thanks Mate..
Dude, you saved the day.
Thanks!