In this tutorial we’re going to create our theme’s custom homepage, it’s going to have a slider and some more content below that. To pull it off we’re going to learn some new functions, get our heads around featured images, and write a few loops.
Recommended Reading
If you’re not familiar with Loops, conditional tags, and WP_Query
, you may wish to consider reading the following, if not, most things are explained along the way.
WordPress and Non-blog Homepages
Each of the more recent WordPress releases have come bundled with a theme, with the current theme Twenty Twelve being the first to include a custom homepage option, rather than the standard list of blog posts that has been the norm over the years. If you’re not familiar with it, here’s how it looks:
Creating a Custom Homepage
When it comes to making your own, there’s a number of approaches you can take, but the most basic method is using WordPress’ Reading Settings in the Dashboard. In here you can set an existing page to take the role of the homepage.
You could even create a custom page template for it, which is certainly a good idea in the case that you want something functional, and this is a great way to do it all things being equal.
However, if you want a more involved, purpose built homepage, it’s best to roll a fresh template for it using a new file, in this case home.php
. As per the template hierarchy, WordPress will preferentially load home.php
as the homepage before index.php
.
What We’re Making
We’re going to take the hard way out and build our own homepage, but we’ll be making it slightly less hard by using the Bootstrap/Flatstrap Carousel layout for our homepage which looks like so:
Note: You can find this file as carousel.html
in the examples directory where you first downloaded and extracted Flatstrap, otherwise you can find it on GitHub.
Creating the Homepage Header
I think it’s best to take it from the top, so to get started we need to create a new header, header-home.php
. In here we need to place the contents of <head>
from carousel.html
, with three important steps we must then take:
- Delete the CSS that’s in the header, and the linked CSS files, instead putting
wp_head
in it’s place - Replace static content with Template Tags so that the correct content is generated in the right places by WordPress.
- Change the hrefs of the favicons and icons from absolute, to generated by using
get_template_directory
Here’s the final code for header-home.php
, it should make sense to you by this stage, but if you’re having a hard time following just speak up in the comments!
<!DOCTYPE html> <html <?php language_attributes(); ?>> <head> <meta charset="<?php bloginfo( 'charset' ); ?>" /> <title><?php bloginfo( 'name' ); ?><?php wp_title(); ?></title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="description" content=""> <meta name="author" content=""> <!-- Le styles --> <?php wp_head(); ?> <!-- HTML5 shim, for IE6-8 support of HTML5 elements --> <!--[if lt IE 9]> <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> <!-- Fav and touch icons --> <link rel="shortcut icon" href="<?php echo get_template_directory_uri(); ?>/assets/ico/favicon.ico"> <link rel="apple-touch-icon-precomposed" sizes="144x144" href="<?php echo get_template_directory_uri(); ?>/assets/ico/apple-touch-icon-144-precomposed.png"> <link rel="apple-touch-icon-precomposed" sizes="114x114" href="<?php echo get_template_directory_uri(); ?>/assets/ico/apple-touch-icon-114-precomposed.png"> <link rel="apple-touch-icon-precomposed" sizes="72x72" href="<?php echo get_template_directory_uri(); ?>/assets/ico/apple-touch-icon-72-precomposed.png"> <link rel="apple-touch-icon-precomposed" href="<?php echo get_template_directory_uri(); ?>/assets/ico/apple-touch-icon-57-precomposed.png"> </head>
Creating home.php
Now create home.php
in the theme directory. To get it up and running faster, simply open carousel.html
and cut from the opening <body>
to the end of the columns below the slider. Save and and continue/
We need to use the template tags get_header
and get_footer
to bring the header and footer in to create the page, but this time with a slight twist. When you use get_header
, do it like this:
<?php get_header('home'); ?>
WordPress will then know that you want it to load header-home.php
rather than the default header.php
.
One last touch is to add the body_class
function to the body tag as we need it later.
<body <?php body_class(); ?>>
Save your homepage and open it up in your browser, it’ll look something like this.
There’s two reasons for it look poor, firstly because we deleted the styles from the document head just before, and because the images aren’t referenced in an acceptable format for WordPress, though that excludes the placeholder images as they’re from the internet instead of the theme directory.
Homepage CSS
It’s time to create another file, this time it’s home.css
, and please make sure you create this in the /assets/css
directory. We need to put the previously deleted CSS in this file, which you can find here.
To load the CSS we’ll use the same techniques as before where we queue and register the style in functions.php
.
Once again the code should be straight forward to you by this stage, and if not it’s very easy to figure it out, otherwise here’s the code below, with the new additions highlighted.
//first we register the styles wp_register_style( 'bootstrap', get_stylesheet_directory_uri().'/assets/css/bootstrap.css'); wp_register_style( 'bootstrap-responsive', get_stylesheet_directory_uri().'/assets/css/bootstrap-responsive.css'); wp_register_style( 'docs', get_stylesheet_directory_uri().'/assets/css/docs.css'); wp_register_style( 'prettify', get_stylesheet_directory_uri().'/assets/js/google-code-prettify/prettify.css'); wp_register_style( 'our-css', get_stylesheet_directory_uri().'/assets/css/style.css'); wp_register_style( 'home', get_stylesheet_directory_uri().'/assets/css/home.css'); //now we enqueue them wp_enqueue_style( 'bootstrap' ); wp_enqueue_style( 'bootstrap-responsive' ); wp_enqueue_style( 'docs' ); wp_enqueue_style( 'prettify' ); wp_enqueue_style( 'our-css' ); if (is_home()){ wp_enqueue_style( 'home' ); }
Note the use of is_home
, it checks if the page you’re loading is the homepage, and if so executes what’s within it. By doing this we avoid CSS overlaps and loading more than we need to.
If you save these changes the homepage will have some structure to it now, but there’s some padding up the top we need to be rid of, so lets open up our styles, which are in assets/css/style.css
, and add the following:
/*Custom Homepage CSS*/ body.home { padding-top: 0; }
Note: This will strictly target the homepage body tag which is what we want, but if you should choose to take a different path for the homepage down the track please be mindful that this may effect the layout.
As mentioned before, WordPress is trying to load images out of the wrong directory, so to easily bring these back, replace the two full stops in the six img
tags with <?php echo get_template_directory_uri(); ?>
.
With that saved, order should now be relatively restored to the home page.
Replacing the Navigation Menu
Currently the navigation menu is hard coded as HTML. To bring back our menu, all we need to do is delete the unordered list that currently forms the static menu and replace it with the nav menu code from header.php
<div class="container navbar-wrapper"> <div class="navbar navbar-inverse"> <div class="navbar-inner"> <!-- Responsive Navbar Part 1: Button for triggering responsive navbar (not covered in tutorial). Include responsive CSS to utilize. --> <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse"> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </a> <a class="brand" href="<?php bloginfo( 'wpurl' ); ?>"><?php bloginfo( 'name' ); ?></a> <!-- Responsive Navbar Part 2: Place all navbar contents you want collapsed withing .navbar-collapse.collapse. --> <div class="nav-collapse collapse"> <?php wp_nav_menu( array( 'container' => 'false', 'menu_class' => 'nav', ) )?> </div><!--/.nav-collapse --> </div><!-- /.navbar-inner --> </div><!-- /.navbar --> </div><!-- /.container -->
That’s really all there is to it.
Restoring Slider Functionality
At the moment, the slider doesn’t slide, entirely defeating its purpose. The reason is that we haven’t included certain JavaScript dependencies, particularly the bootstrap.min.js
file, or told it to start. Of course, this means we now must register and queue it, here’s the updated code for functions.php
with the new lines highlighted.
//First we register the scripts wp_register_script( 'jquery-flatstrap', get_stylesheet_directory_uri().'/assets/js/jquery.js', '', '1.8.1', true ); //true is to place it in the footer wp_register_script( 'collapse', get_stylesheet_directory_uri().'/assets/js/bootstrap-collapse.js', array( 'jquery-flatstrap' ), '2.3.1', true); wp_register_script( 'bootstrap', get_stylesheet_directory_uri().'/assets/js/bootstrap.min.js','2.3.1','', true ); //Now we enqueue them wp_enqueue_script('jquery-flatstrap'); wp_enqueue_script( 'collapse'); wp_enqueue_script( 'bootstrap' ); }
With the scripts good to go, it’s time to write a little jQuery. Open up footer.php
and write this before the closing body tag.
<?php if (is_home()){ ?> <script type="text/javascript"> jQuery(document).ready(function($) { $('#myCarousel').carousel({ interval: 5000 }) }); </script> <?php } ?>
If you’re new to JavaScript and or jQuery, this might look a little intimidating, but it’s fairly straight forward. Simply, it tells the browser that once the page has loaded the carousel should start, specifically target an element with an id of myCarousel
, and change slides every five seconds.
We’ve also used is_home
again so that it only loads on the homepage.
Dynamically Generating Slider Content
We’ve already got a fair bit under the belt, having created our new homepage, header for the homepage, registered and queued various scripts and stylesheets, and written some jQuery. Now it’s time to use WordPress’ functionality to customize the slider, though there are a few questions we need to first answer.
Most importantly, what do we want to go in the slider? The answer to this question will most likely vary depending on the contents of your site, but in a general sense, it’s likely that it’ll will be for something you want to feature.
The second question is how many items do we want in the slider?
That means there needs to be a way to dictate what is featured, and fortunately there are a few ways to do this, such as the use of a tag, category, or even the sticky posts feature. Whatever you choose, the solution will be the same, to use WP_Query
. It allows us to run a query in whatever tag/category we feel like, sort posts by many methods, and define how many results we want it to return.
For the purpose of this exercise I’ll be using a tag, featured, and requesting five posts of it. For this tutorial I have gone into the Dashboard and added this tag to five posts.
We also need to consider what to display, as we have a headline, text (which could be easily filled as the excerpt), and read more button. Further, there’s also the background image to consider, which we can get there by using a featured image, which we’ll cover shortly. For the moment it’ll be easiest to use what’s already in place, these images are slide-01, slide-02, and slide-03, and can be found in /assets/img/examples
in the theme directory.
Creating a Query for the Slider
It’s time to get cosy with WP_Query
, and we get to write two queries straight up! If you’re yet to use it, you should check out our fantastic primer on WP_Query.
It’s pretty easy to use and you’ll recognize tags we’ve touched on previously, here’s the first query, I’ll explain it below.
<?php $featured_query = new WP_Query(array( 'tag' => 'featured', 'posts_per_page' => 1 )); while ($featured_query->have_posts() ) : $featured_query->the_post(); ?> <div class="item active"> <img src="<?php echo get_template_directory_uri(); ?>/assets/img/examples/slide-03.jpg" alt=""> <div class="container"> <div class="carousel-caption"> <h1><?php the_title(); ?></h1> <p class="lead"><?php the_excerpt();?></p> <a class="btn btn-large btn-primary" href="<?php the_permalink(); ?>">Continue Reading</a> </div> </div> </div><!-- item active --> <?php endwhile; wp_reset_postdata(); ?>
We’re storing our WP_Query
in $featured_query
, and are simply specifying that it’s to run in the featured tag, and retrieve only one post. Thereafter it runs a loop as regular as any loop before it.
What’s most important to note is that we’re running this one post loop within <div class="item active">
– the active class is what the slider displays on load, jQuery takes care of it from there. Finally we end the while loop and reset it with wp_reset_postdata
, bringing us to our second loop.
<?php $featured_query = new WP_Query(array( 'tag' => 'featured', 'posts_per_page' => 4, 'offset' => 1 )); while ( $featured_query->have_posts() ) : $featured_query->the_post(); ?> <div class="item"> <img src="<?php echo get_template_directory_uri(); ?> /assets/img/examples/slide-03.jpg" alt=""> <div class="container"> <div class="carousel-caption"> <h1> <?php the_title(); ?></h1> <p class="lead"> <?php the_excerpt();?></p> <a class="btn btn-large btn-primary" href="<?php the_permalink(); ?>">Continue Reading</a> </div> </div> </div> <?php endwhile; wp_reset_postdata(); ?>
The key difference here is we’re requesting four posts from WP_Query
but specifying an offset
of 1, this ensures we get our five posts but we don’t get the first one twice. And once again, we make sure to use wp_reset_postdata
to wrap it up.
Save the changes and open up your site and you’ll see this.
It’s alright, but it’s not what we’re after. Check the HTML that it’s generating and you’ll see what’s going on.
It’s ignoring that we want the excerpt within <p class="lead">
and placing it in its own, and even putting superfluous paragraph tags after it, too. To fix this is very easy using a remove_filter
in functions.php
, put it essentially anywhere, but down the bottom is a good place.
//remove the automatic paragraph tags in the excerpt on the home page if (!is_page_template( 'home.php' )){ remove_filter( 'the_excerpt', 'wpautop' ); }
Critically, we are using the function is_page_template
to make sure this only runs on the homepage, as you wouldn’t typically run this on the whole site. Compared to times previous where we’ve used add_filter
, such as to change the logo url on the login page, this time, we use remove_filter
to take the automatic excerpt away with wpautop
.
Save it and refresh to see the updated results.
Setting up the Featurettes
With the slider and navigation menu working, it’s time to move down and tackle the three featurettes.
The two most obvious possibilities are to use either widgets or posts, we’re going to roll with posts here, but you could very easily implement a widget area, just as we have before.
As above, the easiest way to pull this off is with WP_Query
, just like so:
<!-- Three columns of text below the carousel --> <div class="row"> <?php $featurettes = new WP_Query(array('posts_per_page' => 3)); while ($featurettes->have_posts() ) : $featurettes->the_post(); ?> <div class="span4"> <img class="img-circle" src="http://placehold.it/140x140"> <h2><?php the_title(); ?></h2> <p><?php the_excerpt(); ?></p> <p><a class="btn" href="<?php the_permalink();?>">View details »</a></p> </div><!-- /.span4 --> <?php endwhile; wp_reset_postdata(); ?> </div><!-- /.row -->
This loop will still return posts tagged with featured. If you wanted to exclude those you can use the tag__not_in
parameter in the query.
Otherwise it’s simple, all we’re dictating is three items. If you want to use more than three just change the value, but as per the way Bootstrap is built, it’s best to use multiples of three, in the end I went with six.
Featured Images
With all of the page content generating correctly it’s time to tackle featured images.
The first step is to enable theme support, which can be done in functions.php
, so crack it open and add the following line.
add_theme_support( 'post-thumbnails' );
Save that, and go to add a new post, you should now see the “Featured Image” widget on the right hand side like so:
Adding Featured Image Sizes
By default, WordPress has three preset thumbnail sizes, they are:
- Thumbnail: 150 x 150px
- Medium: 300 x 300px
- Large: 640 x 640px
- Full: Original dimensions
Which means that each time you upload an image, it’ll resize it into these dimensions as well as keep the original. For our purposes, that’s not terribly useful.
We need two images sizes, 1500 x 550px for the slider, and 140 x 140px for the featurettes below, fortunately it’s very easy to add images sizes using the function add_image_size
. So once again open up functions.php
and add this code beneath add_theme_support
.
add_image_size('featured', 1550, 500); //images for the homepage add_image_size('featurette', 140, 140); //images for items below slider
There’s another option you can use at your will, and that’s what crop mode you want. There’s two choices, hard and soft. Hard will force resize the image, and will probably distort images, soft will scale the image proportionally. It’s soft by default, but if you want to turn it on add true
to it like so: add_image_size('featurette', 140, 140, true); //images for items below slider
Note: When working with images as large as 1550 x 500px, it’s definitely wise to be very intentional in choosing images that you’re going to use, so as to not give too much concern to scaling.
Implementing Featured Images
Now for the easy part, remove the img
tags in both slider loops, replacing it with the following:
<?php if ( has_post_thumbnail() ) { the_post_thumbnail( 'featured' ); } ?>
And the same for the featurette loop, being mindful to specify the other thumbnail name:
<?php if ( has_post_thumbnail() ) { the_post_thumbnail( 'featurette' ); } ?>
If you save and refresh, you’ll find that the slider probably doesn’t have any featured images, but will find that some of the features do. To test it all works I’m using this photo of stars courtesy of davedehetre on flickr that I’ve scaled down a little. I’ve set it as a featured image on the post “Hello World” and here’s what I get.
If you’re also looking at this, it’s a good result. The slider works, it’s pulling in a featured image, and we can see that at least one featurette below has a featured image too.
Winding Up
That’s our custom homepage out of the way, as you’ve experienced there’s been a lot we’ve had to take care of including:
- Creating the homepage itself, home.php
- Creating a custom header for the homepage
- Using conditional statements to load what we need, when we need
- Enqueued new styles and scripts
- Written three loops with WP_Query
- Touch on a little jQuery
- Used our first remove_filter
- Learnt about featured images
The post Part 2: Creating a Responsive Custom Homepage with a Carousel Slider appeared first on YinPress.