One-Page Theme | Part One

How to create a one-page theme for WordPress


Update: I have recently changed the WP_Query function featured in this posting. The original function would query pages by specific names, i.e “Masthead” or “Start”. This proved to be inflexible, and in practice provided a poor user experience. For instance, if a user wanted to label their pages more semantically, they couldn’t. This was because any page that did not use one of the correct content-page endings, such as “Masthead” or “Start”, would not be styled correctly. The answer was to change these required names into categories and then query the pages by category, this way the user can name the page anything they like as long as they select the correct category for the page. See below for an indepth look.


One-page themes are very popular. Whether they employ exciting animations or parallax scrolling, they are a unique way to present information on the web. A one-page theme is fairly simple in theory, it is an HTML file with multiple sections. Usually, a one-page theme employs a navigation bar that jumps the user further along down the page using anchor links.

But as simple as this process seems it begins to get a bit more complicated when we wish to hand over control of the content to an end-user. The beauty of WordPress is the ability to give novice end-users control over a dynamic website. Our aim for this project is to avoid hardcoding functionality as much as possible so an end-user can maintain the content, design, and functionality as they desire.

How does a one-page theme work in WordPress?

WordPress is a great CMS because it allows for people with very little coding experience to maintain and run a website. It does this by using a text editor, widgets, featured images, galleries, custom post types, and a variety of other tools. Our goal with this theme build is to utilize these tools to assist our end user when they use our theme.

Planning a theme

Before we go further!


Run over to BlazRobar.com and download a copy of his free PSD “Take”, we will base our build off of this design. Click here!

If you can visualize it, you can build it.

First, we need to visualize what our average user will want to do with the theme. They will probably want to:

  • Edit each section’s content
  • Edit the ‘hero’ images
  • Add and edit widgets
  • Customize background images, colors and fonts

In order to achieve these objectives, we will need to create a page that has multiple editors, along with multiple featured images, and areas for widgets. In WordPress, a page can only have one section of content that is created by the editor. In a standard page we would usually output this information with:

<?php the_content(); ?>

This function outputs the content of the current page in the Loop. Because we want multiple sections, each with its own unique content section, we will have to combine multiple pages together into one long page. Each page will serve as its own section and provide its own editor and be output by our function the_content().

One-page-site.php and The Loop

First, we will build a template called one-page-site.php. This page will serve as the ‘base’ page for our one-page scroller. Every other page we create will be pulled onto one-page-site.php via a custom query in The Loop.

WordPress uses a piece of code called the Loop. It’s responsible for querying your posts and pulling them onto a page based on specified criteria.

In our site, the Loop will ask if we have posts, then, while we have posts the Loop will post the_post.

<?php while(have_posts() ) : the_post(); ?>

What the Loop asks for is called a query, and we can query many different things by using the WP_Query() function.

WP_Query is a WordPress function that allows us to specify certain arguments for the Loop. By default, the Loop will loop in any posts. In our case, we would like to loop in specific pages (pages are confusingly considered a post-type but let’s put that aside for now). Using WP_Query we can create an array of arguments that will instruct the loop to select all pages with specific categories, list them in a specific order and to make sure that order starts from lowest to highest, i.e. ascending order.

Take a look at the code:

<?php $args = array( 'post_type' => 'page',
	'order' => 'ASC',
        'orderby' => 'menu_order',
	'category_name' => 'masthead, start, full-image, three-col-grid, subscribe options, contact'
	);
$the_query = new WP_Query($args);

?>

<?php while($the_query->have_posts() ) : $the_query->the_post(); ?>

<?php endwhile; ?>

Now that we have a loop that will pull in our pages we can create our template. This project utilizes Underscores, a WordPress starter theme. This theme provides a couple different template files that work right out of the box. We will bring up the page.php file and delete the content between the main tags. Here, we will nest our code inside of a bootstrap container-fluid tag. Take a look:

<?php /** * Template Name: One Page Site */ get_header(); ?>


<div id="primary" class="content-area container-fluid">
	<main id="main" class="site-main" role="main">

<div class="row">		

<div class="col-sm-12">
				<?php $args = array( 'post_type' => 'page',
					'order' => 'ASC',
					'orderby' => 'menu_order',
	                                'category_name' => 'masthead, start, full-image, three-col-grid, subscribe options, contact'
					);
				$the_query = new WP_Query($args);

				?>

				<?php while($the_query->have_posts() ) : $the_query->the_post(); ?>

			<?php endwhile; ?>

		</div>

<!--end post column-->
	</div>

</main><!-- #main -->
</div>

<!-- #primary -->

<?php get_footer(); ?>

The commented section at the top /*** Template Name: One Page Site*/ is how we declare to WordPress that this page is a template file.

Save this file to the root directory of your theme and call it one-page-theme.php. Now, we will go into our WordPress dashboard and create a page called home. This page will not have any content, you can also go ahead and set the template to One Page Site. Publish this page and then click on Settings > Reading in the left hand column of your dashboard. Here, set the Front page displays to a static page and set the ‘front page’ option to the page we just created titled ‘home’. You can ignore the posts page dropdown. Click save.

Content & Categories

At this point, we have a page template called one-page-site.php. This template runs a loop that utilizes the WP_Query() function in order to query pages that are a part of the categories: masthead, start, full-image, three-col-grid, subscribe-options, and contact (we will create these categories further down the page).

Let’s create our pages. Based on our PSD file we will have six sections. In our theme each section is technically its own page. Go ahead and create these pages in the WordPress dashboard. The pages can be called:

  • Masthead
  • Start
  • Full Image
  • Three Col Grid
  • Subscribe Options
  • Contact

But any name will do, just be sure that they properly describe the section.

Create them and give them some filler text, you can use this basic lorem text:
Lorem ipsum dolor sit amet, falli instructior te sit, no sit fastidii fabellas urbanitas. Eum et veri conclusionemque, duo an unum feugiat legimus. Ea virtute indoctum iracundia eum, mea denique epicurei cu. Mei harum delenit petentium et, verear placerat scribentur mel at. Sit in legere antiopam, nec utamur theophrastus an. Qui an dolor vocent option, consul graece impetus has an.

Make sure to publish each page.

Now we need to assign each page to a specific category. By default, pages cannot use categories or tags. But by editing our functions.php file we can create this functionality.

Go ahead and open your functions.php file and add the following code to the bottom before the closing ?> tag:

/**
*Add categories and tags to pages
*/
function add_taxonomies_to_pages() {
 register_taxonomy_for_object_type( 'post_tag', 'page' );
 register_taxonomy_for_object_type( 'category', 'page' );
 }
add_action( 'init', 'add_taxonomies_to_pages' );
 if ( ! is_admin() ) {
 add_action( 'pre_get_posts', 'category_and_tag_archives' );
 
 }
function category_and_tag_archives( $wp_query ) {
$my_post_array = array('post','page');
 
 if ( $wp_query->get( 'category_name' ) || $wp_query->get( 'cat' ) )
 $wp_query->set( 'post_type', $my_post_array );
 
 if ( $wp_query->get( 'tag' ) )
 $wp_query->set( 'post_type', $my_post_array );
}

This code registers categories and tags for pages. Then it modifies our WP_Query so when Wp_Query asks for a category it retrieves the page category.

Save this file and hover over the Page section in your dashboard. In the slide-out menu click on Categories. Here you will enter in the categories: masthead, start, full-image, three-col-grid, subscribe-options, and contact.

Click save.

Now, go to your Pages section of the dashboard and click each page and assign each with a different category. Also, apply the follow orders to each page: masthead[1], start[2], full-image[3], three-col-grid[4], subscribe-options[5], and contact[6].

one-page1

As you can see, the name of the page can be anything you like but the category needs to match the intended section. This example page is intended to be the ‘Masthead’ at the top of the page. We can name it anything we like, but by setting the category to ‘Masthead’ it will use the content-masthead.php template which we will discuss in the next post.

Also, note that the Order box is set to ‘1′. This ensures that the Masthead section is the first section to be looped onto the page and will be displayed at the top, this is where order => 'ASC' comes into play.

If you return to your page preview you should see that only the pages in our defined categories should be displaying in the correct order.

Wrap Up

That is all for part one. We have learned how to create a page template and then use the WordPress Loop to query specific parameters with the function WP_Query. We have also set up our functions file so that we can create categories and tags for the pages post type. Using these categories we now can control what pages are outputted to the front page and subsequently are included in our one-page theme.

Coming up, we will discuss how to modify the HTML structure of each individual section using content-parts. Here is the code, try to figure out how we would implement this into our files:

<?php global $post; $slug=$post->post_name;
   get_template_part('content', $slug);
   //	var_dump($slug);
?>