Posted 02.20.2015
A Modular Approach to WordPress Theming, Using Flexible Content
I do a lot of WordPress Development. I wouldn’t necessarily consider myself a WordPress developer, I have experience on other platforms, but I use whatever tool will meet the client’s needs best. Recently, that means WordPress.
One of the things I’ve started doing is coding custom themes so they’re modular. What does this mean?I just launched billseaver.com. On the home page, each “stripe” is considered a module. This gives Bill the freedom to rearrange the elements on the home page on the fly. If he has a podcast release that day, he can move the podcast stripe to the top, increasing its visibility.
As a designer, I don’t feel like the design of the site is being compromised because I’ve designed how each section should look. It’s just providing more flexibility and more value to my customers accommodating their digital strategy.
So, how did I pull this off?
The trick is the Advanced Custom Fields (ACF) plugin. — It’s one of those WordPress Plug Ins I could not live without.
Let’s walk through the setup.
Within WordPress
I have the ACF Pro Plugin installed. Once it’s activated, it gives you a Custom Fields nav item in the left sidebar. Click on that and then the Add a New Field button.
Let’s call this field group “Home Page” but you can really call it anything you like. This label is will be displayed on the “Edit Home Page” above our form fields.


Before we start adding fields, let’s adjust our Location rules. I want this field group to display on the home page only. Meaning, Bill will have to click on Pages and then find the Home page to edit. There are several ways I could set the rules.
I could say if the Page is equal to Home.

or I could say if the Page Template is equal to Home.

Personally, I prefer the second option since the template itself is really dependent on these fields.
Then, in the Options box, below that, we can control the display and the other elements on the page. I try and hide all the elements I don’t need to minimize confusion:
- Content Editor (all content is within the stripes, no need for body copy which all means, no need for an Excerpt)
- Excerpt
- Comments
- Author (don’t need to set an author for the home page)
- Featured Image
- Send Trackbacks
- Custom Fields (this refers to the WordPress built in Custom Fields, not the Advanced Custom Fields we’re creating)
- Format
- Categories
- Discussion
- Tags
Now for the fun part, the actual fields. Click the Add Field button. I’m going to name this “Home Page Content”, but call it whatever you like.


NOTE
If you’re looking at my screenshots, I have a few other fields on the home page (background, subheading, and tertiary heading), in addition to the flexible content fields we’re creating. I don’t go into details about those fields, here, since our focus is on the flexible content.
You can see that the Field Name gets filled in automatically based on how you name the label field. I usually keep the default name unless it adds in dashes (“Home – Page” becomes home_-_page).
Select Flexible Content from the Field Type dropdown menu.
You can add instructions if you’d like. I usually leave this blank unless it’s a link (I’ll remind people to include the http://) or an image (I’ll include the image dimensions).
Within the Layout Row let’s start naming our stripes. We have 5.
Let’s name the first one “Receive Email Updates.” We don’t need any additional fields here since it’s simply a MailChimp Signup Form.
Click on the Add New link under Layout to add another row.
Name this one “New Podcast”. It will automatically pull in the most recent podcast. The only additional fields we might need is a background image. Click on the Add Field button. Name it (Podcast Background Image) and select Image from the Field Type dropdown menu. In this particular case, I’m going to select the Image URL radio button, but the Image Array option is useful when you want to grab a particular size and include the alt text.
Click on the Add New link under Layout to add another row. You get the idea. I went through the same process for the “Testimonials” (no input fields), “From the Blog” (no input fields), and the “Services” stripe with the following input fields:
- Column 1 Heading
- Column 1 Content
- Column 2 Heading
- Column 2 Content
- Column 3 Heading
- Column 3 Content
Within the Code
Within my WordPress theme folder, I have a subfolder called partials. This includes smaller elements that I can reuse in other places on the site. In the case of Bill’s site, that folder contains a file for every stripe:
- stripe-email.php
- stripe-podcast.php
- stripe-services.php
- stripe-testimonial.php
- blog-excerpt.php

You’ll see the folder structure in the left pane and the code for the services stripe on the right.
NOTE
You’ll notice the “From the Blog” stripe is not prepended with “stripe”, that’s because that element is not only used on the home page, it’s also used to display a blog excerpt on the archives, categories, and tags pages.
My page-home.php template has this code. I tried to include comments, explaining what each section does:
<main class="main" role="main">
<?php // open the WordPress loop
if (have_posts()) : while (have_posts()) : the_post();
// are there any rows within within our flexible content?
if( have_rows('home_page_content') ):
// loop through all the rows of flexible content
while ( have_rows('home_page_content') ) : the_row();
// EMAIL UPDATES
if( get_row_layout() == 'receive_email_updates' )
get_template_part('partials/stripe', 'email');
// NEW PODCAST
if( get_row_layout() == 'new_podcast' )
get_template_part('partials/stripe', 'podcast');
// SERVICES STRIPE
if( get_row_layout() == 'services' )
get_template_part('partials/stripe', 'services');
// TESTIMONIAL
if( get_row_layout() == 'testimonials' )
get_template_part('partials/stripe', 'testimonial');
// FROM THE BLOG
if( get_row_layout() == 'from_the_blog' )
get_template_part('partials/blog', 'excerpt');
endwhile; // close the loop of flexible content
endif; // close flexible content conditional
endwhile; endif; // close the WordPress loop ?>
</main>
NOTE
You’ll notice that my if
statements do not have brackets ({
and }
). They’re not needed since there’s only one line of code after the condition. However, if you need to add additional lines within the statement, be sure to insert those brackets!
If you see the have_rows()
and get_row_layout()
functions, that’s all ACF. You can get additional documentation for the Flexible Content fields on ACF’s site.
The get_template_part()
function is built into WordPress (more information within the WordPress Codex). The first parameter of the function is the folder name (partials) and the first part of the file name before the dash (remember I named my files stripe-email.php?). The second parameter is the fiel name after the dash (email).
The get_template_part()
function is great for other places in your WordPress themes, not just within Flexible Content. I mentioned the blog-excerpt.php snippet is also used within the archive.php template:
<?php if (have_posts()): while (have_posts()) : the_post(); ?>
<!-- article -->
<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
<?php get_template_part('partials/blog', 'post'); ?>
</article>
<!-- /article -->
<?php endwhile; ?>
The beauty in this method is if I need to change the way the blog excerpt is being displayed, I only have to change one file! I don’t have to remember every place that a blog excerpt is being implemented.
Other implementations
This modular method is also useful for formatting content. I used it on the portfolio section of my site.
I knew each page would need a different format depending on whether it was a website or a print project and what assets I have for each.