I have a simple columns shortcode. (How) can this be adjusted to output a containing div around multiple columns?

Really don't want to nest shortcodes in the frontend. Perhaps some kind of filter?

My functions.php looks like this:

// Columns shortcode 
function abc_custom_column( $atts, $content = null ) {

   return '<div class="column">' . do_shortcode( $content ) . '</div>';

add_shortcode('col', 'abc_custom_column');

Hoping for something like:

if ( 'col' === >2 ) {

   return '<div class="multi_columns">' . do_shortcode( $content ) . '</div>';

} else { 

    return '<div class="column">' . do_shortcode( $content ) . '</div>';


*** I know that clearly won't work / isn't valid code.


If all you want to do is count how many times the shortcode exists in the content then you can use substr_count on the original content before it's parsed to output shortcodes like this:

$count = substr_count( get_the_content(), '[col]' );

But nesting shortcodes is most likely the best solution unless you know exactly the type of content being added to the post/page.

So your full code would look like this:

// Get the content
$content = get_the_content();

// Get number of col shortcodes added to the content
$count = substr_count( $content, '[col]' );

// Output content
if ( $count > 1 ) {

   return '<div class="multi_columns">' . do_shortcode( $content ) . '</div>';

} else { 

    return '<div class="column">' . do_shortcode( $content ) . '</div>';


But I see no reason to avoid using nested columns. Especially if this is for a client site or an item for reproduction if someday they want to change the way the site works it could potentially issues - it seems the way you want things to work expects only columns to be added to the post content (but maybe that's what you want?). In which case you may be better off not using column shortcodes and instead using a repeatable meta field such as this - https://www.advancedcustomfields.com/add-ons/repeater-field/

  • Thanks WPExplorer. To clarify, where would I add / how would I use this code? It will be on pages I am directly editing, so i know there will be 2, or 3 columns max. – the-first-man Jul 24 '17 at 22:01
  • @the-first-man I edited my response ;) – WPExplorer Jul 24 '17 at 22:06
  • I'll give your suggestion a whirl! It's just for my own site. I wanted a simple way to introduce the occasional two-col layout within page or post content. I actually have CMB2 running instead of ACF (content still shows if the plugin is disabled/removed!), but the idea of adding repeating content areas to each page seemed overkill and more restrictive. Given that a page/post layout would be predetermined. – the-first-man Jul 24 '17 at 22:13
  • Yes if the page/post layout is predetermined then I see no issue in doing things like this ;) Let me know if it doesn't work out. There are other methods (using preg_match ) but I believe substr_count is the quickest and most efficient. – WPExplorer Jul 24 '17 at 22:19
  • Strange. Pasting your code directly into my (blank) function produced a white screen… Thinking about it, is this the most efficient code to wrap any '[cols]' found in the content? after all, i'd never have just one. – the-first-man Jul 24 '17 at 22:23

Every time you feel like you need a shortcode to insert an HTML tag, you should ask yourself, what is it you are doing wrong. In this case, you can easily go into the "text" tab and add the div.

The general problem you are facing is that html and the editor support mainly an top to bottom flow. It is hard to make the editor to support any other flow without reaching a state equivalent to having a page builder of sorts, something that no human should be forced to use ;)

The key to a solution is to handle each content area as a different content. Think for example about how widgets work - their content is displayed on the page, but it is not edited with the editor.

So the problem can be reduced to how to edit several content areas in one edit screen and how to "arrange" it in the main post. You can obviously just have a different post which contain that content, or you can add a meta with an editor (call wp_editor), and assign each content fragment some identifying name. Now all that is left is to have a "multicolounm" short code, give it the identifiers of the content fragments as attributes, and create whatever complex HTML you need.

The drawback for this approach are obvious as it result in a less of a WYSIWYG editing experience (although if wordpress had any front end editing framework it would have easily mitigated that problem), the advantage is that many times this kind of columns are semantically isolated, and this kind of editing structure helps to enforce it.

Hmmmmm, you say your columns are not semantically isolated? maybe (and I say it very quietly) what you need is to just use a table?

  • Appreciate your very considered answer… "what is it you are doing wrong. In this case you can easily go into the text tab and add the div" - On the contrary. I disagree. Shortcodes exist for this very purpose, do they not, to make it easier. It would not be convenient or, most importantly, quick to type out <div id="unique" class"column"> ….. content … </div> <div id="unique2" class="column"> … content… You get the picture. – the-first-man Jul 25 '17 at 12:47
  • Agreed… Separating content areas would usually be an acceptable way to go. However, there should be no need to split it up into separate widgets, whose content would vanish if I remove the theme. That is to say, I don't want each of my pages to follow the: 'Page content, then Columns below, format. I am simply trying to reach a solution where I can include two/three columns on two/three pages. – the-first-man Jul 25 '17 at 12:51
  • @the-first-man, how is it different than implementing a short code? if you do not want the content to "vanish" the proper way is to just inset the tags in the HTML view. And to get unrelated things here, the ability to assemble various contents in one "view" (on a post page or archieve) is one of the great things that are missing from wordpress now (gutenberg is in some way heading that direction, but with the totally wrong philosophy IMHO) – Mark Kaplun Jul 25 '17 at 13:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.