WordPress
Article

Creating Custom “Snow Fall” Designs in WordPress

By James Steinbach

In December 2012, the New York Times broke out of their standard online post layout and wowed us with John Branch’s beautiful “Snow Fall” article. Instead of simply containing headings, text, and the occasional inline photo, this article made liberal use of full screen images, videos, custom text layouts, and animations to draw readers in and captivate them with a well-designed and well-told story.

NYT Snow Fall Article

It wasn’t long before other publishing sites followed suit and began departing from their “normal” design for occasional art-directed articles, like The Chicago Tribune’s “His Saving Grace” and The Verge’s “longform” articles.

His Saving Grace


Example of The Verge's Longform Article

Normally, articles on news sites follow a pretty standard pattern: featured image, headline, content (text, headings, and inline images), with a menu above, a sidebar next-door, and comments and a footer below. The large majority of WordPress sites follow that pattern as well. But with a little help from a couple helpful plugins and a custom template page, you can easily build attention-grabbing art-directed articles in WordPress.

For the sake of this tutorial, let’s pick several unique design elements we’d like to add to our “Snow Fall” layout. We’ll want (1) normal WYSIWYG editor areas, (2) hero images with optional text overlay, and (3) pull-quotes. We’ll also want to use as many of each kind of content as we want, in whatever order we want. Let’s go!

Advanced Custom Fields & Flexible Content Fields

To create customizable layouts, we’ll start with the Advanced Custom Fields plugin (WP Plugin Repo). ACF is free, but we’ll also need one of its paid add-ons: Flexible Content Fields. This add-on is less than $25 (USD) and is well worth it!

Once you’ve installed those plugins, click the Custom Fields icon in Dashboard, then click “Add New” to create a new field group. Let’s call it “Snow Fall Template Fields.” Click ”Add Field“ to add a new field to this group. Name it ”Content Block“ and set its Field Type to ”Flexible Content."

Add Flexible Content Field

This will open a new row labelled “Layout.” Here we’ll add our first content block option: a WYSIWYG editor. For its Label, use “Standard Text,” then click the “+ Add Sub Field” button. Label the new sub-field “WYSIWYG” and choose “WYSIWYG Editor” for its Field Type.

Add a WYSIWYG Block

Now we’ll add the other blocks we need. Hover on the Layout title cell (to the right of the sub-field we just added) and click “Add New.” Name this row “Hero Image” add an image field and a text field. Add a row named “Pull-Quote” with a quote text area field and an author text field. Click the “Publish” button. We’ll edit a few more things once we’ve set up the the page template.

All Flexible Content Layouts

Custom Template Page

Now we’ll need a custom template page in the theme for this content. The basics of WordPress Page Templates are in the Codex. Create a template file (snowfall.php, for example) in your theme.

<?php

/*
Template Name: Snow Fall Template
*/

get_header();
//template stuff
get_footer();

?>

Once this file is ready, go back to the Snow Fall Template Fields page. In the Location box, select “Page Template” is equal to “Snow Fall Template.” In the Options box, hide all the sections you don’t need (in this case, the Editor). Click “Update” to save your changes. Create a new Page and choose the Snow Fall Template: you’ll see the old Editor replaced by a new “Add Content Block” box where you can now add as many of those blocks as you like, in whatever order you like.

Now for the PHP template to build our custom page. The fields we’ve built are available through some custom functions (here’s all the ACF documentation for Flexible Content Fields).

We can loop through each content block with a syntax very similar to the one in WP Core’s WP_Query():

if ( have_rows('content_block') ) {
  while ( have_rows('content_block') ) : the_row();
  // All your subfields code for this goes here.
}

Once you’re inside that loop, you’ll need to get the data for each block properly. Let’s use a switch to test which kind of content block we have and then only ask for the necessary fields.

switch (get_row_layout()) {
  case 'standard_text' :
    // get wysiwyg sub-field
    break;
  case 'hero_image' :
    // get hero image sub-field(s)
    break;
  case 'pull_quote' :
    // get pull quote sub-field(s)
    break;
}

The following code will check to make sure there’s a WYSIWYG field and then print its contents to the page. Note: ordinarily in ACF, you’d use get_field(), but because this is nested in a Flexible Content Field, use get_sub_field().

if( get_sub_field('wysiwyg') ) {
  print get_sub_field('wysiwyg');
}

Put all that together and you get this:

<?php

/*
Template Name: Snow Fall Template
*/

get_header();
if ( have_rows('content_block') ) { //1
  while ( have_rows('content_block') ) : the_row();
    printf('<div class="%s">', get_row_layout());
      switch (get_row_layout()) {
        case 'standard_text' :
          if( get_sub_field('wysiwyg') ) {
            print get_sub_field('wysiwyg');
          }
          break;
        case 'hero_image' :
          if( get_sub_field('image') ) {
	$image_array = get_sub_field('image');
            printf('<img src="%s">', $image_arrayhttps%3A%2F%2Fwww.sitepoint.com);
						
          }
          if( get_sub_field('text_overlay') ) {
            printf('<h3>%s</h3>', get_sub_field('text_overlay'));
          }
          break;
        case 'pull_quote' :
          if( get_sub_field('quote') ) {
            printf('<p>%s</p>', get_sub_field('quote'));
          }
          if( get_sub_field('author') ) {
            printf('<p>%s</p>', get_sub_field('author'));
          }
          break;
      print '</div>';
    }
	endwhile;
}
get_footer();

?>

Of course, styling all that output is entirely up to your imagination! There is a lot you can do with ACF flexible content fields, have fun and share in the comments any amazing pages you build with this technique!

Free Guide:

7 Habits of Successful CTOs

"What makes a great CTO?" Engineering skills? Business savvy? An innate tendency to channel a mythical creature (ahem, unicorn)? All of the above? Discover the top traits of the most successful CTOs in this free guide.

  • Todd Zmijewski

    or… you could use Drupal 7+ which has a fully integrated solution for adding fields to content. Added bonus is it isn’t all stored in a gigantic serialized array either. Just saying…

    • Pete

      And what if Drupal isn’t an option? What if you’re already using WordPress or the client has specifically requested it? Seriously, comments like these are never helpful.

      Thanks for the article, James. Very informative!

    • Rahe

      ACF does not store it in a gigantic serialized object. Just saying…

  • http://www.blue-dreamer.co.uk/ Rob (bluedreamer)

    Or use something like ExpressionEnine which has always had custom field functionality baked into the core, so need need for 3rd party addons :)

  • http://nickhaskins.com/ Nick Haskins

    Or you could opt for Aesop Story Engine, which this was built for. ;
    )http://wordpress.org/plugins/aesop-story-engine/

  • http://ChiefAlchemist.com/ Mark Simchock

    How about the WP plugin + theme architecture Aesop Story Engine?

    http://aesopstoryengine.com/

    https://www.facebook.com/aesopinteractive

    Moi? That’s probably were I would start and then fork from there :)

  • Scott

    I do this a lot with custom templates I work on. Found this code below to be a little cleaner in place of your switch/case, which breaks each module out into a file named after itself:

    if( get_field(‘modules’) ):

    while ( has_sub_field(‘modules’) ) :

    $rowName = get_row_layout();

    include(locate_template(‘modules/’.$rowName.’.php’));

    endwhile;

    endif;

  • http://themes.fastlinemedia.com/ Justin Busa

    Or the FastLine Page Builder, which allows you to build pages like this visually on the front-end :) http://themes.fastlinemedia.com/

  • http://jamessteinbach.com/ James Steinbach

    Great point! For a large scale project, that’s exactly what I do: call smaller partials for individual content blocks. I’d use WP’s get_template_part() function instead of include(locate_template())) though.

  • http://jamessteinbach.com/ James Steinbach

    That looks like a really useful plugin – thanks for sharing it!

  • M S

    I really hate when first im forced to scroll and scroll even when the content could have fit perfectly on my screen.
    And THEN, when I try to do that scrolling, instead of the page scrolling, weird shit happens.

    Its like a big “fuck you!” addressed personally to the usability designer in me.

Recommended
Sponsors
Because We Like You
Free Ebooks!

Grab SitePoint's top 10 web dev and design ebooks, completely free!

Get the latest in WordPress, once a week, for free.