Advanced Layout Templates In WordPress’ Content Editor
As a Web designer, I often find myself building WordPress-based websites that will ultimately be updated and maintained by clients who have little to no experience working with HTML. While the TinyMCE rich-text editor is great for giving Web content managers of any skill level the tools they need to easily style and publish their posts to a degree, creating anything beyond a single column of text with a few floated images generally requires at least a basic understanding of HTML.

This article shows you an easy-to-implement trick that enables even the least tech-savvy of clients to manage multi-column content layouts within the comfort of the WYSIWIG editor. And for you advanced users, it’s still a great way to standardize and streamline your content entry.
Creating A Custom Layout
All we’re really going to do here is inject a few HTML elements into the editing window and style them. WordPress’ default_content filter allows us to insert set content into any post as soon as it’s created so that our clients don’t have to. This filter is also great for adding boilerplate text to posts.
The Back End
By adding the following to functions.php, each new post we create will come pre-stocked with two divs, classed content-col-main and content-col-side, respectively. I should note now that this code has been tested only in WordPress version 3.0 and up:
<?php
add_filter( 'default_content', 'custom_editor_content' );
function custom_editor_content( $content ) {
$content = '
<div class="content-col-main">
This is your main page content
</div>
<div class="content-col-side">
This is your sidebar content
</div>
';
return $content;
}
?>
A couple of things to note:
- The
default_contentfilter is fired only when a new post is created; any posts or pages that existed before you added this code will not receive this content. - The line spacing and additional
are not essential, but I’ve found them to be useful for preventing a few of TinyMCE’s little quirks.
Now we just need to give it some style. Add the following to functions.php:
<?php
add_editor_style( 'editor-style.css' );
?>
The add_editor_style() function looks for the specified style sheet and applies any CSS it contains to the content in our TinyMCE editing window. If you don’t specify the name of a style sheet, it will look for editor-style.css by default, but for the purpose of this article, I’ve written it out. Create a style sheet named editor-style.css, and place it in the theme folder, with the following styles:
body {
background: #f5f5f5;
}
.content-col-main {
float:left;
width:66%;
padding:1%;
border: 1px dotted #ccc;
background: #fff;
}
.content-col-side {
float:right;
width:29%;
padding:1%;
border: 1px dotted #ccc;
background: #fff;
}
img { /* Makes sure your images stay within their columns */
max-width: 100%;
width: auto;
height: auto;
}
Now, when you create a new post, you will see two columns that you can type or paste your content into:

This basic multi-column template will now appear any time you create a new page or post.
And there you have it: a simple multi-column template in your content editor. You can go back and edit the default_content and editor-styles.css to adapt the content layout to your needs:

Use this technique to create your own layout templates, customized to your content.
The Front End
When your post is displayed on the front end of the website, the content will still appear in a single column, as before. The styles you wrote out in editor-style.css do not get passed to the front end of the website. However, by viewing the page source, you’ll see that the divs we created with our custom_editor_content() function have been passed through and are wrapping the different sections of the content. Simply open style.css (or whatever style sheet you’re using for your theme) and style to your heart’s desire.

This technique applies not only to the visual layout of content. Use JavaScript to target specific containers to make on-the-fly slideshows and other dynamic effects.
Get More From Your Templates
Beyond just opening up new styling possibilities, this technique can also be used to create objects to target later with JavaScript.

In the example above, we were able to turn a series of content areas into more easily digestible tabbed sections for the user, while still allowing the administrator to update all of the information on one page. These are just a few of the many ways you can take your WordPress templates further.
Templates For Templates
The code above will simply apply the same layout and styling to all of your posts, pages, custom posts… anywhere the TinyMCE editor appears. This is probably not ideal. By adding conditional statements to the custom_editor_content() function above, you can serve a different default layout template to each of your post types:
<?php
add_filter( 'default_content', 'custom_editor_content' );
function custom_editor_content( $content ) {
global $current_screen;
if ( $current_screen->post_type == 'page') {
$content = '
// TEMPLATE FOR YOUR PAGES
';
}
elseif ( $current_screen->post_type == 'POSTTYPE') {
$content = '
// TEMPLATE FOR YOUR CUSTOM POST TYPE
';
}
else {
$content = '
// TEMPLATE FOR EVERYTHING ELSE
';
}
return $content;
}
?>
You can style all of your default content elements in the editor-style.css file, but if you’d like to use a different style sheet entirely for each post type, you can do so with this snippet from WPStorm:
<?php
function custom_editor_style() {
global $current_screen;
switch ($current_screen->post_type) {
case 'post':
add_editor_style('editor-style-post.css');
break;
case 'page':
add_editor_style('editor-style-page.css');
break;
case '[POSTTYPE]':
add_editor_style('editor-style-[POSTTYPE].css');
break;
}
}
add_action( 'admin_head', 'custom_editor_style' );
?>
Add the above to your functions.php file, and then create the editor-style-[POSTTYPE].css files to use different style sheets for the corresponding post types. Just replace [POSTTYPE] with the name of your custom post type. Extend the code above by adding new cases for each additional post type.
Alternatively, you could use the following code to automatically look for a style sheet named editor-style- followed by the name of the post type that you’re currently editing. Again, just make sure that the suffix of the new style sheet you create matches exactly the name of the post type.
<?php
function custom_editor_style() {
global $current_screen;
add_editor_style(
array(
'editor-style.css',
'editor-style-'.$current_screen->post_type.'.css'
)
);
}
add_action( 'admin_head', 'custom_editor_style' );
?>
(In this snippet, editor-style.css will also be included on all post-editing pages, in addition to the style sheet that is specific to that post type, which will be named editor-style-[POSTTYPE].css.)
Conclusion
While this method does have its drawbacks — it assumes you already know the layout that your client wants to give their content, and the layout structures cannot be easily edited by the client themselves — it does enable you to create more interesting sandboxes for your client to play in, while encouraging a standardized format for the content.
If the client decides they don’t want to use a pre-defined container for a particular post, they can simply click inside the container and hit Backspace until all the content is gone, and then hit Backspace once more, and TinyMCE will delete the div wrapper, leaving a clean slate for them to work with.
I hope you’ve found this little technique useful. I’m excited to see all of the ways you guys will customize and improve it for more dynamic layouts.
Additional Resources
- “Editor Styles for Custom Post Types in WordPress 3.0,” WPStorm
- “Killer Hacks to Enhance WordPress Editor” Jean-Baptiste Jung
- “Custom Post Types in WordPress,” Justin Tadlock
- “New WordPress Power Tips for Template Developers and Consultants,” Jacob Goldman
(al)





Zachary Schuessler
October 14th, 2011 7:41 amGreat post David!
I had a layout that required a nested div on one of the columns, and it seems TinyMCE was trying to be too helpful and ran into problems. So my solution was to get the contents of each column (I have three) and then display them on the page/post as I needed, so I may apply markup.
My solution requires PHP DOMDocument, which requires PHP 5. Note, you can also do this with any DOM parser:
http://pastebin.com/5Xn17yKT
Would be nice to make a plugin so you can use each column similar to the_content(). I may work on this if others have interest in it?
Cheers.
Steve Taylor
October 14th, 2011 10:28 amAn interesting technique, but definitely one to file under “Use if nothing else works” rather than to be seen as another good trick for developing a theme. I think most situations where this might be used would be better served using additional custom meta boxes with mulitple TinyMCE fields (both techniques are pretty straight-forward these days, given either one of many plugins or a quick Google). Putting presentational markup into the post content obviously mixes up, er… presentation and content! We all end up mixing these a bit, but I think the above technique goes too far, especially given there’s other options for tackling the same issue in a more flexible and future-proof way.
David Hansen
October 14th, 2011 8:42 pmThanks Steve,
On an ideological level, I agree with both what you’ve said, and the separation between presentation and content concept as a whole. Personally, I also prefer entering more complex content like this in custom fields.
However, in practice, I’ve often run into clients who are easily overwhelmed by rows of custom fields and multiple editor windows that correlate to different columns, and they could care less about my arguments for “a better web”. They just want a truer “What-You-See-Is-What-You-Get” experience, similar to what you’d find in programs like DreamWeaver. And while I’m also well aware of the messiness those programs have cause over the years, I’ve developed this technique in the hopes to find a balance between the two.
moabi
October 15th, 2011 3:20 amIt’s definitely a “way to go” for clients…Custom Meta boxes are really tricky for them,
Nice article,
Thx
Brian Kuyath
October 16th, 2011 8:15 amDavid, I have to agree with you. Ideally, clients would easily understand that entering content into the custom meta data boxes will fill out their pages, but in my experience that’s not the case. Your approach provides non-technical people with a visual guide through the build out of a given page. It creates a more approachable and easy-to-understand interface that will encourage users to come back and create new content. As developers providing our clients with the ability to manage their own content, we need to make that process as simplified as possible.
Deryck Oñate
October 17th, 2011 11:55 amYou’re so rigth David. There is always more than one way to solve needs but the most “client level” should be the first avoiding precisely that the post sale support become a pain in the ass. I personally found this a really good solution and still semantic and standards complaining if the client does not mess the code later.
Thanks a lot for your post.
Sam
October 14th, 2011 4:20 pmActually i think this is extremely handy…Thanks for showing this, guys!
Its simple for the client to ‘get’, easily made awesome by some simple jquery, DOES NOT use any plug-ins which is great, leverages the default hooks of WP, can be bundled with a themes functions.php, is undo-able by a simple backspace, and by being able to target post-types, is very useful for some clients.
It makes the clients life easier, and the coders too. Whats not to LOVE!?
One question…Is there any way to target custom page templates’ default content? That way regular pages are left alone, and multiple layouts are possible, for pages at least?
David Hansen
October 14th, 2011 8:24 pmThanks for your response Sam — glad you find it useful :)
As is, you would not able to target the default content to a specific Page Template using the methods I described above. The problem is that the default_content filter we’re using is only fired when a page or post is first created, and at that time, the page will have no template associated with it to look for.
In order for these custom layouts to be targeted to Page Templates, you’d have to wait until you select a page template and save the post before firing our function, or possibly grab that selection event with some AJAX (making sure in both cases to only insert the default content if the editor window is empty, or risk deleting good content).
Pancho
December 7th, 2011 5:11 amHi David,
Thanx for the post and all the cool code, but have you get a solution to use a different ‘custom_editor_content’ depending of the Page Template that the page select. No matter if have to be after or before save de page. Because I can´t find a way to specify in the code the Page Template name.
John
February 22nd, 2013 11:07 amA plugin like TinyMCE Templates when combined with some good use of editor-styles.css can be very useful, and has the added advantage of being repeatable, or even of being able to add multiple template in different combinations. The ‘quirks of TinyMCE’ will always persist though.
Kevin Doherty
October 14th, 2011 4:55 pmwow , i had no idea this was possible. I typically try to layout my pages in a more strict fashion with meta fields and calling them in my template pages. However, this could be super useful in lots of situations, especially when tabular data needs to be displayed.
gonna give it a try for sure.
Iwani Khalid
October 15th, 2011 1:47 amCool tips, I’m going to be needing this very soon. Before, I used [shortcode] which may not be the easiest method for clients to adapt to. Multiple write panels are better but they make the edit page looks congested
Deryck Oñate
October 17th, 2011 11:59 amHi Iwani. Any idea of can I create TinyMCE toolbar buttons that generate shortcodes and if possible even with parameters?
Thanks in advance.
Ryan
October 21st, 2011 4:53 amHere you can see how I add custom buttons for custom shortcodes in TinyMCE. I have given one shortcode example for a “Tabs” tabbed box and then the functions for adding all the custom buttons used (Soundcloud, YouTube, Vimeo, Tabs).
You would have one shortcode function for each button, but since I added the buttons in an array you can see how to add multiple buttons in the example. Then just make a function for each button to specify how it’s shortcode works.
http://snipt.org/xolx
Hope this helps you. I have used this in WordPress 3+
Rob Fenech
October 15th, 2011 2:19 amVery very cool – this is a bit of a gamechanger for wordpress in my opinion – being able to manipulate the content editor like that is fantastic for clients!!
Great post – I rarely reply unless something really wows me, and this was is – fantastic!!
Thank you :)
David Hansen
October 15th, 2011 5:03 amThanks Rob! Glad I could provide something useful to the community :)
Gregor
October 15th, 2011 3:17 amCan’t agree more to what Rob Fenech said. This is very helpfull for clients that always have problems -and fear- working with WP (any) administration. Thanks for sharing!
Josh
October 15th, 2011 4:40 amI’ve been using shortcodes to define areas like content and sidebar but the formatting in the editor can get ugly.
This awesome article has brought some much needed light on the subject. Thank you!
Florescu Adrian
October 15th, 2011 5:11 amIf I knew this technique I would save a lot of time for many projects of mine!
I think we can find a solution for the custom wysiwyg editor to be shown only a specific custom page template. Can we?
Emile Jobity
October 15th, 2011 5:38 amI didnt know this feature existed but its preety cool. I like it. Using this with the power of custom meta boxes makes wordpress even more flexible.
Paul
October 15th, 2011 7:21 amHi David
Seem like a good solution, but I hope you wouldn’t mind if I ask.
Is there any caveat ?
David Hansen
October 15th, 2011 8:18 amHi Paul,
Besides the limitations I listed in my conclusion, my main caution would be not to try to get too fancy with it. While I’ve found it useful to allow clients to easily manage simple 2- or 3-column layouts, or creating sections for tabbed or carousel content, anything beyond that may get messy. Remember, hand-crafted code will always be cleaner than anything produced through a WYSIWYG editor.
Also, before going this route, always ask yourself whether the content may be better suited for a custom field / custom metabox solution. If you want to separate your content for more functional purposes, like sorting and filtering, custom fields are the way to go. If you are separating your content for purely presentational purposes, this method may be a better alternative.
Hope this is helpful :)
Charles Harris
October 15th, 2011 7:22 amVery nice, found this handy.
Michael
October 15th, 2011 9:43 amThanks for this article David, which came serendipitously for me, and from comments above, quite as an epiphany for others.
I confess to setting up several client sites base on woothemess “canvas” theme/framework. And although it ships with some sweet shortcodes for creating columns in a post, for some of my clients and apparently others, even that simple invocation from the tinyMCE fields presents a bit of a mental block.
This by default, seems like an excellent workaround for client sites who’s posts would require plug and play styling afforded by your technique.
So again, thanks!
Michael
Nick
October 15th, 2011 11:26 amThis was absolutely fantastic. I’ve been looking for an article like this for quite some time.. thanks so much!
Paul
October 15th, 2011 11:43 amI’ve been dabbling with some elements that this articles deals with but I had no idea all this could be achieved………. Can’t wait to put it into action…….
Thanks for such a great post!
:-p
Mark Simchock
October 15th, 2011 2:36 pmGreat tip, thanks a lot David. Who knew? :)
I have a question…is there way to make this work with post format on the Admin side? That is, pick a post format and get the WYSIWYG to present the appropriate default_content “layout”?
I would think there’s a way to get javascript to pick up the format select and then populate the WYSIWYG content area with the appropriate “layout” framework. Mind you, I’m no JS genius, but something like that would be pretty powerful, yes?
David Hansen
October 15th, 2011 3:16 pmHi Mark,
In concept, this shouldn’t be too difficult, though we we’d still have the same issues I described in my reply to Sam above about loading a specific template when you select a different Page Template. Rather than using WordPress’ “default_content”, which is only run when a post is first created (before you’d ever get a chance to assign a post format to it), you would use Javascript as you described to detect that selection event and insert your html accordingly — making sure not to overwrite any content already in the editor window. I’m not sure if there are any existing hooks we could use for this, or if it’d have to be completely custom, but this is something I may look into for future projects.
Thanks for reading!
Josh
October 15th, 2011 6:08 pmCouldn’t a button be used in the editor that would load what’s needed? Like buttons for one, two, three column layouts similar to shrtcodes but using the editor styling?
Tieson Wooten
October 15th, 2011 4:42 pmThanks for this post! I love the idea of different layouts for each template. I am going to start hammering through this little beauty right now!
sanjay
October 15th, 2011 8:23 pmNice, I didn’t know this was possible. Before shortcode was the way to go, but this opens a new door of opportunity. Thanks for sharing!
Andrew
October 16th, 2011 7:23 amThis is a great post! I will certainly use this from now on. One note though, the default wordpress editor renders html/css horribly, I would recommend using CK Editor for wordpress. My clients love it!
Sami Keijonen
October 16th, 2011 11:07 amI’m definitely gonna try this. It looks something I could use. Thanks for sharing.
@Andrew – I forget CK editor, thanks for reminder.
Scarlet
October 16th, 2011 3:07 pmLove it~ open my eyes, will definitely to use in the next project, thanks! You are awesome!
Web Design Automaton
October 16th, 2011 8:17 pmI always do this for least tech savvy of my clients, when you can only describe how to work a wysiwyg so many times this becomes almost second nature to implement on projects.
alectro
October 16th, 2011 8:49 pmHey, great article! Thanks for sharing it.
Anyone found solution to apply editor style per page template?
Ash
October 17th, 2011 1:47 amThis is great, but I wonder if you could get it to load this custom editor layout, based on the page template they select. For example if they select the 3 column template, it would change the editor to reflect that?
This would allow you to keep it working within pages & posts (if needed), without having to separate it out as a custom post type.
Jonathan de Jong
October 17th, 2011 3:11 amThis was some seriously great stuff :) I’m always concerned with how the client will interact with the backend and this way it would be so clear I could cry
Mika Andrianarijaona
October 17th, 2011 4:18 amThank you very much, that’s really interesting and helpful!!
Adam
October 17th, 2011 7:12 amGood for a developer, bad for a client. With my experience, a client, unfortunately, will probably wind up deleting a “div” or all the “div’s” when editing content, and become really frustrated. Using Advanced Custom Fields plugin is the safest and best option when setting up a page with multiple columns. That’s my 2 cents. :)
adam
October 17th, 2011 8:48 amThis is really cool thanks David, will def come in handy for many of our less techy clients & save some backup buddy time for us….now to find some of this ‘tactical bacon’: )
Anthony
October 17th, 2011 9:15 pmVery interesting, I can see this technique in my next project to empower the client further. Thanks.
Dwaynne
October 17th, 2011 11:21 pmFantastic post…very ‘real-world’! Quick one, though: how would you implement this for a specific post template or custom post type? So for example I might have a product post type, a blog post type and a news post type. What is the syntax to implement three different custom templates on the backend via functions.php?
Creamotion
October 18th, 2011 4:19 amRealy realy REALY amazing !
Thanks for that tutorial ;)
Creamotion
Jeremy Tarpley
October 18th, 2011 6:59 amDavid – this is first rate, definitely plan to use. Thanks!
edgarr
October 18th, 2011 7:57 amthanks David, very helpful!… This fixes a lot of issues from the root, instead of trying complicated solutions…..
Olivia
December 24th, 2011 1:28 pmA simple and ineltlgient point, well made. Thanks!
Kęstas
October 18th, 2011 8:27 pmThis is very helpful. And just in time as I needed this solution. I’ve used another meta box with editor for similar purposes, but this is simpler and yes, more client-friendly. Lots of thanks.
Holly Knott
October 19th, 2011 3:19 pmGreat post! This has been such a limitation in my mind on being able to format pages the way my customers would like them to be formatted. FYI, the TinyMCE Advanced version allows you to insert tables (and edit them) in the WYSIWYG editor. http://wordpress.org/extend/plugins/tinymce-advanced/ Just wanted to mention this in case you didn’t know about it. Now I’m curious which might be better to implement for my customers – that, or your CSS method! (My customers mostly being folks who could never grasp HTML, nor do they want to)
Tom
October 20th, 2011 8:54 amVery usefull, thanks!!!
Anthony Hortin
October 20th, 2011 3:07 pmAs a lot of other have said, some clients aren’t all the comfortable dealing with multiple meta boxes so this provides another solution to handle those trickier layout problems. Great Post David. Thanks :-)
Javier Villanueva
October 29th, 2011 1:06 pmNice tip, is there a way to load the styles depending on the page template instead of doing it on every page?
Niall O'Brien
November 2nd, 2011 1:33 pmThis is a horrible solution in my opinion. Custom meta boxes yield far more predictable results.
Michael Carter
November 7th, 2011 11:47 amHello David –
Neat idea. But need a tweak related to default content.
I’ve been searching for couple days for an answer to this and hope you can help. First, the above code works without a hitch. My question: How can I apply this to only ONE type of whatever?
Specifically, I have a custom post type, Recipes, which is the only place I want default text. I’ve tried what little I know, like putting a conditional
if(is_singular(‘Recipes’)) {
around the function. No go. Is there a way to do this?
Thanks, Mike
Jimmy Quintos
November 15th, 2011 12:33 pmAwesome tutorial, David!
In which license your tutorial released?
May I use for my projects? And still with your name in the credit for this part.
David Hansen
April 21st, 2013 6:52 amHi Jimmy,
This tutorial follows only the license and terms-of-use guidelines imposed by the Smashing Magazine site. You are free to use for your client projects and are not required to credit me. Thanks!
Jonas
November 16th, 2011 2:25 amThis is quite an eye-opener, although I fear that clients removing elements by accident would be a very common problem. Would it be possible to make certain elements “indestructible”? Or only removable when you’re in HTML mode.
Julien
November 22nd, 2011 7:34 amThis is so useful! indeed Jonas I wonder too how to prevent the div in the editor to be deleted??? anybody has some suggestions?
Rick
December 9th, 2011 3:19 amIt seems really interesting (havn’t tried it out yet).. but im curious, what if i want more templates for postype = page. Lets say i want the “end-user” to have 3 different types of content to add.
A 3 column structure, a 2 column structure, a tabbed (javascript) structure.
As far as I have seen, this code means for “all pages” and all “posts” or am i incorrect? Ifso, how can the end user select the template he wants?
nomadone
December 21st, 2011 5:24 amVery cool technique, though definitely not extremely practical for the vast majority of sites out there which would need some flexibility in post layouts.
It would be great to have a range of content layouts, and then using a custom wp editor button populate the editor with a layout for product, custom blog post, etc any type of layout based on the site’s needs.
Once of the problems I find with using custom field data for custom post structures is that when the site is repurposed, the theme changed, or fed to RSS, mobile theme etc custom fields don’t get sent along with the_content.
I’ve found a few plugins which help adding custom field data via shortcodes, but these also, require manually adding those shortcodes in each time.
Still looking for the ideal post layout, custom fields data combination solution which still allows opting out for general posts without special layout and custom fields.
Donal
December 28th, 2011 8:32 amHi, I tried the code in the functions.php file and it is not working for me. After I put the code in and go to the site, the site is off line.
Does this code work on wp 3.3 and if it does, I must be putting the code on the wrong line, could you please tell me what line I should start the code on.
Thanks a million, love you site, has being very helpful to me.
Gioska
February 6th, 2012 7:40 pmAmazing…but how i can apply to a single page or post?
Pablo
November 16th, 2012 5:59 amTrue. I would like to know how do it in single page.
David Hansen
April 21st, 2013 6:49 amHi Gioska,
To add a custom template to a single post or page, simply follow the steps to create and import the editor_style.css; then, instead of inserting the markup to all posts via the “default_content” filter, just place your template markup directly into that post via the “HTML” tab in the editor.
Caps
February 26th, 2012 1:57 pmA true multi-column environment would allow text to flow from one column to the next depending on: browser window size, client’s browser font settings and padding. It looks as though in this article all have agreed that column endings are hard coded using the /div tag. To me, this is not in character with modern day web page presentation.
WordPress needs to step up to the next generation of text editors and integrate Edit-in-Preview-Mode, real time editing. The author can select while in preview mode, predefined page layouts, text color, image positioning, text and image padding. Columns are elastic or snap to grid, columns may be even, or unbalanced, text flows from one column to the next on-the-fly.
So while the solution stated in this article is grand, the solution is a band aide for WordPress lack of implementing new technologies that are available. WordPress needs to step up to the next generation of content management systems. Currently the implementation of Drag-In-Drop on a live page among other things (like taxonomy) is sorely lacking.
Him
May 2nd, 2012 4:38 amIts just wonderful stuff. I tried it both with a custom content type, and without it for ‘post’ type.
My problem is that I want to use custom content editor layouts for different categories. And all wordpress gives us are the 5 standard post types or the option of custom post types. Right now, all new posts show the same layout. It would be fantastic if I could somehow load seperate content layouts (and text) for categories.
Fabio Bianchi
May 15th, 2012 12:47 pmJust what I am looking for!
Simple and no plugins needed.
But can you tell me how to display a certain Custom Field inside a and how to control its appereance with CSS?
Thanks!
Michael
December 18th, 2012 2:34 pmHello Dave,
What if I only want 1 page to have this layout? How can I do ? I have added this page filter ‘if ( $current_screen->post_type == ‘page’)’ and I have 2 custom pages default page and 2 column page. I want only to affect 2 custom page
Thanks a lot!
Mike