Building Smarter WordPress Themes: Making Layout Decisions, Not Options

In the convoluted world of WordPress themes that are built to stretch to infinity, and offer “all the options you’ll ever need”, its become easy to forget what delivering focused solutions to a client or customer’s problem entails.

Problem solving: it’s the reason we build. It’s the reason we scratch our heads and yell obscenities when we can’t get our precious code to work. The urge to solve problems is ultimately what drives us as creators to keep on creating.

Me? I like to design. I like solving people’s design problems and I try to create solutions that not only make web content look beautiful, but are also easy to interact with.

You’ve probably heard that spiel before, because it sounds like something a WordPress theme designer would say. That’s how I mainly deliver my solutions to people—through themes.

From my years of experience of building focused themes for clients, releasing premium skins for a popular theme framework (and now my own standalone theme), and running multiple sites of my own, I’ve learned a lot about what people want when building a site with WordPress.

But most importantly, I’ve learned what people don’t want. That’s why I’m creating the SmartWP series here on Kolakube. I want to share my ideas and methods of creating solutions that work for the user, instead of making the user work.

And I’m starting with something I’ve been dying to talk about in themes: layout options.

The Typical Layout Options Panel

A feature built into a lot of themes is some kind of layout chooser. It gives the user the ability to pick a one, two, three, or however many columns they want their layout to support. Some even offer sorting options (content on left, sidebar on right, or: content on the right, two sidebars on the left etc.).

Here’s one I built into a theme I never released. It pretty much sums up what the industry standard says these things should look like:

WordPress Layout Options

The idea is simple: choose from different graphical representations of what your site layout could look like, save your selection, and your entire site layout will change.

For themes that act as site builders (namely, frameworks), this is a great way to deliver simple, powerful customization options to the user. It requires little work, and is fairly easy to understand.

But for simpler themes that want to offer layout customization at a more basic level, I’d argue that options like these can be a huge overkill.

For example, while I was building Chronicl, I wanted to add some flexibility when it came to adding/removing sidebars. I didn’t want to offer every layout combination under the sun, I just wanted a theme that could support upto two additional sidebars to the right of the content box.

Since I couldn’t justify creating a new options panel for a layout with those basic requirements, I needed to explore other methods. Having sidebars in Chronicl are optional, so any solution I came up with had to be based around those moving parts.

The Anatomy of a WordPress Sidebar

WordPress WidgetsLet’s talk about another industry standard: widgetized sidebars. Any premium theme worth its money will have this most basic of all features built into it.

The Widgets interface is best used for sidebars, as the hierarchy in both the backend and frontend are the same.

Dragging Widgets into a Widget area will create a descending hierarchy. Structurally, a Widget area in the backend perfectly mirrors what it will output on the frontend.

So when a Widget area is empty, how should that reflect on the frontend?

Most developers write code to detect when a Widget area is empty, and output a message telling user’s to go fill in the blank space by adding Widgets to the backend.

This is great, because it tells the user what to do next with that predefined space.

Even though the Widget area is empty, it still outputs something on the site, thus breaking that “mirror image” between the frontend and backend.

While adding an instructional message has its benefits, it can also be an unwanted replacement.

What if, when a Widget area is devoid of content, the entire section gets removed from the website? What if an entire site’s layout could readjust itself based on the user’s decisions to add (or remove) content from these sidebar areas?

Eliminate choices, and make decisions. Don’t make the user think about their layout, just give them places to put their content, and lead the way from there.

With these questions and thoughts running through my mind, I had my direction.

How to Build A Layout That Builds Itself

Diving into the WordPress Codex, I found the nifty is_active_sidebar() conditional.

As the Codex describes it:

This Conditional Tag checks if a given sidebar is active (in use). This is a boolean function, meaning it returns either TRUE or FALSE. Any sidebar that contains widgets will return TRUE, whereas any sidebar that does not contain any widgets will return FALSE.

You may have heard of or used this conditional before. Here’s an example of how I used it for the Chronicl sidebars (take note of this structure, we’ll be using it as reference for later):

<?php if ( is_active_sidebar( 'sidebar-1' ) || is_active_sidebar( 'sidebar-2' ) ) : ?>
	<div class="sidebars">
		<?php if ( is_active_sidebar( 'sidebar-1' ) ) : ?>
			<div class="sidebar sidebar-1">
				<?php dynamic_sidebar( 'sidebar-1' ); ?>
			</div>
		<?php endif; ?>
		<?php if ( is_active_sidebar( 'sidebar-2' ) ) : ?>
			<div class="sidebar sidebar-1">
				<?php dynamic_sidebar( 'sidebar-2' ); ?>
			</div>
		<?php endif; ?>
	</div>
<?php endif; ?>

That says:

First, check to see if EITHER sidebar one or two are active. If either of them are, load the sidebars HTML. Then, run individual checks on sidebar one and two, and output its contents. If there are no widgets, don’t load that particular sidebar.

While this functionality is a step in the right direction, it’s not yet bulletproof. Say we remove all Widgets from sidebar two. Since it’s now empty, it won’t load. That leaves us with an empty gap, as we can see in this GIF:

Chronicl Layout

Problem: A visual of the code above, the entire HTML of the sidebar will disappear when the Widget area is empty, leaving an empty gap in the layout.

Obviously, this looks terrible. We need a fix, otherwise this whole idea is useless.

So far we’ve been able to figure out how to make our sidebars disappear when a Widget area is empty in the backend. But now we need to figure out how to make our layout change too.

Thinking Modularly

The main structural elements of the site were set up like so in my stylesheet:

.container { width: 1175px; /* 1075px is the actual width. I added an extra 100px to account for padding inside the container */ }

.content { width: 600px; }

.sidebars { width: 475px; }

.sidebar-1 { width: 300px; }

.sidebar-2 { width: 150px; }

Now that I understand exactly how my layout is going to change, I need to be able to change the widths of these sections as the layout changes.

Custom Body Classes

I decided that I’d break down these widths into body classes, so I could write specific CSS for specific layout combinations.

Luckily, there’s the handy body_class() filter I could use to add these classes to my body tag dynamically. Nice.

Using the is_active_sidebar() conditional, I could detect when to add/remove classes based on the state of a sidebar Widget area.

Here’s a basic version of the code I ended up with:

function kol_body_class( $classes ) {
	if ( is_active_sidebar( 'sidebar-1' ) && is_active_sidebar( 'sidebar-2' ) )
		$classes[] = 'container-wide'; // for three column layout
	elseif ( is_active_sidebar( 'sidebar-1' ) || is_active_sidebar( 'sidebar-2' ) )
		$classes[] = 'container-slim'; // for two column layout
	else
		$classes[] = 'container-small'; // for one column layout

	return $classes;
}
add_filter( 'body_class', 'kol_body_class' );

This conditional is very basic. It says:

If BOTH sidebar one AND two are active, change the body class to container-wide. If not, go check to see if EITHER sidebar one OR sidebar two is active, and apply container-slim to the body class if true. If neither of those conditions are true (i.e., both are empty), then apply container-small.

With a system in place that can detect changes to Widget areas, I can now alter my CSS to specifically target different layout combinations:

/* the width of my content never changes, so this class can remain generic */

.content { width: 600px; }

/* 3 column layout */

.container-wide .container { width: 1175px; }

.container-wide .sidebars { width: 475px; }

.container-wide .sidebar-1 { width: 300px; }

.container-wide .sidebar-2 { width: 150px; }


/* 2 column layout */

.container-slim .container { width: 1050px; }

.container-slim .sidebars { width: 350px; }

/* I don't need to overwrite single sidebar widths, since they were only applied to the three column layout above */


/* 1 column layout */

.container-small .container { width: 1000px; }

Of course, you’ll need to modify other properties like floats and spacing. But for the sake of simplicity here, I only showed you how widths change.

With these checks in place, let’s see what happens now when I remove all Widgets from sidebar two:

Chronicl Layout

Solution: Perfect! The layout can now change its width based on active Widget areas.

The more layouts you decide to support, the more complex your conditional logic can get. Chronicl also supports a one column layout, and will slim all the way down if both widget areas are empty.

When a one column layout is active, I also decided to center the content box and the header. This was another layout decision I made for the user, and it was all done with basic CSS and a few if/else statements:

Chronicl Layout

Unlimited customization: Since we’re adding classes to the body, we can target any element. I decided to center the content and menu links.

No Options, No Problem

Empty Widgets

I think it’s amazing that an entire layout of a website can adjust to a simple change in Widget content.

Instead of creating a new interface for our layout options, we were able to build on top of an existing, already familiar interface in WordPress.

And the code to do it isn’t even anything special—it’s just a few native WordPress functions mixed with some modular CSS.

As theme developers, it’s so easy to want to reinvent the wheel. Sometimes, we just have to look around and find ways to utilize the tools we already have before going out and getting new ones.

Could a method like this have its drawbacks and limitations? No doubt. But, I think if we strive to create more focused themes—themes that serve a specific, defined purpose—methods like this will always have a place in the forefront of any theme developer’s toolbox.

You’ve Got To Make The Decisions

It’s easy to feel self conscious about your theme when you compare it to others. You may not support “unlimited” layouts, have design options, or other “coveted features” that most super-themes these days do.

But you know what? That’s fine. I’m a believer that the best options are the ones user’s never notice, because everything should “just work”.

If you spend more time focusing on the intricate and smaller details of your themes, the quality of your work will only go up.

While you won’t make a living marketing these kinds of things (a lesson I learned the hard way with Chronicl), or even getting much appreciation for them—you’ll have created a product that is so much easier for your customer’s to love.

12 comments add yours

  1. #brilliant! (I use hashtags wherever I want… like a boss)

    Focused theme building, I’ve found, makes a lot more sense than… well… everything. It took building my own WP framework to realize that it was nothing more than a code library packed with a bunch of “what ifs” with no clear direction.

    Can frameworks and option-packed themes benefit a certain group of developers/designers? Sure. But the idea that they should be the first choice is terribly misguided, in my opinion. It’s about time the WordPress community understood that the WordPress Codex and PHP is all the code library you need to create a theme that does exactly what it’s supposed to do.

    The way you set Chronicl up is wonderful. You’re totally right about the back-end mirroring the front-end. If there’s no widget being used in the back-end, does there really need to be a widgetized area on the front-end?

    The only reason we accept that kind of behavior is because frameworks dominate water cooler conversations these days. Themes have certainly gone overboard for the average user. Frameworks and themes with a ton of options need to be put back in the hands of developers/designers who really need their added benefits. And for regular users…

    …this. This is what they need. Well done.

    • Preeeach it man!

      Everything comes down to time these days. One of the biggest arguments for frameworks out there is that they save time. They save time upfront by giving you a full site structure, and they save time down the road by offering shortcut tools.

      The more and more I used frameworks, though, the more I became frustrated with all the things they weren’t doing for me. The worst part about any tool is facing the things they can’t do. Since I was renting my tools out instead of using my own—I kept running into limitations, and philosophical differences in how I want to use them.

      After a certain point, it just gets tiring to deal with. Yeah, I loved that I already had a full site structure to work with when I installed a framework. But I didn’t like going in and changing predefined HTML structures. I’d rather just write raw code and edit template files, not work through a proxy of actions and filters.

      I feel like it’d be a worthwhile investment for developers to try and create their own standalone theme. Hell, even just create a starter theme and use that as your own “framework”. Your tools, your code, your system.

      I never took much time to look at the world outside of frameworks once I got into Thesis, because I got so comfortable with taking shortcuts.

      Now that I know tools like the Codex and _s exist, I’m discovering a whole new world of possibilities out there for my work. It’s exciting being able to do your own thing, free of anybody else’s rules.

  2. I don’t need to tell you how incredibly forward-thinking Chronicl is (though if you didn’t already know my opinion on it there you go 😉 )..

    But you also hit the nail on the head regarding focused solutions. How often do people jump in not really knowing what it is they need, let alone want, and I think it’s there that they fall into thinking a theme with every option under the sun is their solution.

    My dad used to always say to us kids, “If you don’t know what you want to eat you must not be very hungry.” I think about this a lot when situations come up where clients don’t know what it is they want – they must not be very hungry/serious/dedicated/inspired/etc.

    And themes vs. frameworks – I think they all have their place, but to assume any are the end-all solution for every site is rather narrow thinking. Lovely to see you spreading your skills in several directions! 🙂

    • Why thank you Erica. 😀

      It’s easy to get caught up in the marketing behind themes like that. Some people buy the tools that can help them build what they want, when what they really want is something that’s already built for them.

      I like how you applied your dad’s saying to clients, I think it’s perfect! We want the dessert—the sweet stuff that’ll only spoil our appetite—rather than the meat and potatoes; a ready-to-go solution.

      Frameworks absolutely have their place in the world, they’re excellent tools. They’re just not for everybody, and people need to be okay with that idea.

  3. As a user I found what you did in Chronicl absolutely brilliant, so simple as to be completely transparent, the way good design should be.

    I’m looking forward to how you continue with this way of working. Honestly it’s the way I always thought it should be.

    Nice job Alex!

    • Brady, I’m SO happy to hear that! I’m glad it’s something you can appreciate, because it’s one of those things that once you experience, you wonder why you ever had to play with layout options before.

      I’m excited to keep releasing and writing about this stuff. It’s too easy to just go with the flow, and follow the “industry standards” about everything. Let’s shake the game up a little!

  4. In design, i always follow Steve Job Quote

    “It’s not just what it looks like and feels like. Design is how it works.” – Steve Jobs

    So when design my layout, i always think to make high conversions and sales 😀

  5. It seems like a lot of front-end devs and designer/developers building themes & frameworks could seriously benefit from these kinds of education bombs. Love how you used GIFs to show before/after snapshots to demonstrate the problem, solution, and fix!

  6. This is truly a great tutorial.

    One question: With the conditional that sets the body_class();
    How would you set that condition to target a specific page template?

    I have a file called front-page.php and Im trying to only set this function/condition to only run on that page only.

    I tried this but with no luck:

    function cc_body_class( $classes ) {

    if ( is_page_template( ‘front-page.php’) ) {

    if ( is_active_sidebar( ‘sidebar-1’ ) && is_active_sidebar( ‘sidebar-2’ ) && is_active_sidebar( ‘sidebar-3’ ) )
    $classes[] = ‘col-sm-4’; // for three column layout
    elseif ( is_active_sidebar( ‘sidebar-1’ ) || is_active_sidebar( ‘sidebar-2’ ) )
    $classes[] = ‘col-sm-6’; // for two column layout
    else
    $classes[] = ‘col-md-2’; // for one column layout

    return $classes;
    }
    }
    add_filter( ‘body_class’, ‘cc_body_class’ );

    I keep getting a syntax error when I try to move the code around. I am using Bootstrap 3 and know that the condition for the body class does work properly but just can’t figure out how to set it to my front-page.php

    Any advice on this would be great.

  7. Where does this conditional go? Function.php or right above the actual conditionals to add the sidebar?

    Or…..

    Are you just replacing the first conditional with the function for the body class?

    Also was wondering if I want to place this code in the middle of front-page.php where do I place it?

Leave a Comment