Advertisement

Build a Basic Newspaper style layout with Wordpress and jQuery

by
Student iconAre you a student? Get a yearly Tuts+ subscription for $45 →

Grid/Newspaper/Magazine templates are becoming more and more predominant in the wordpress skin and theme community. They look classy, but it can be daunting knowing where to start. In this tutorial we use the power of jQuery to create a grid layout with size-degrading headers!

Preface

This tutorial assumes that you have a wordpress engine running on a server that you have access to upload files, download files and browse to. If you want to run a local server on your computer with a wordpress installation, there is a tutorial on that here for Windows, and here for OS X.

Step 1 - Let's start with the necessities...

Create a new folder in your 'wp-content/themes/' folder, and name it whatever you want to name the skin we're about to make. Make 2 new files in this new folder, one called 'index.php' and the other 'style.css'. We are going to start off with some basic wordpress code. This 'base code' is what I start off with every time I create a full wordpress skin, because it includes most of the necessary information. I've kept it in here because you might want to develop this into a full skin. I also use a default stylesheet for my themes, so copy this code snippet into your 'style.css', and edit the content respectively. The stylesheet is reled in with the line:

<link rel="stylesheet" href="<?php bloginfo('stylesheet_url'); ?>" type="text/css" media="screen" />

You'll also need 2 JavaScript files, one being a copy of jQuery and an empty .js file called myTheme.js. Don't forget to rel these in with this in your head element:

<script type="text/javascript" src="<?php bloginfo('template_directory'); ?>/jquery-1.2.6.min.js"></script>
<script type="text/javascript" src="<?php bloginfo('template_directory'); ?>/myTheme.js"></script>

Don't forget to change the name of the jQuery rel if you're using a different package to me, which you most likely are. 'myTheme.js' must come under the jQuery link, not above.

Note: jQuery 1.2.6 is also packaged with Wordpress 2.2 and above, so if you don't want to download it, you can find it in wp-includes/js/jquery/jquery.js. To include THIS jQuery document, use this instead of the jQuery rel above. You'll still need myTheme.js though!

<script type="text/javascript" src="<?php bloginfo('url'); ?>/wp-includes/js/jquery.js"></script>

Step 2 - The PHP/Wordpress/XHTML code.

Once you've selected and activated your new theme, open 'index.php' with your favourite editor, and let's get coding!

Here is all the XHTML/PHP/Wordpress code we need to set out the content and the metadata for each post. Paste or type it inbetween the html open and close tags. I will explain it bit by bit below!

<div id="wrapper">
	<?php if(have_posts()) : ?><?php while(have_posts()) : the_post(); ?>

		<div class="post">

			<div class="left">
				<p class="postmetadata">
					<strong>Post Details</strong><br />
					Posted: <em><?php the_time('l, jS F, Y'); ?></em>
					at <em><?php the_time('g:i a'); ?></em>.<br />
					Written by: <em><?php the_author(); ?>.</em><br />
					Number of comments: <em><?php the_comments_number('none', '1', '%'); ?></em>.<br />
					Posted in: <em><?php the_category(', '); ?></em>.
				</p>
			</div><!-- end div.left -->

			<div class="right">
				<h2><?php the_title(); ?></h2>
				<div class="entry">
					<?php the_content('more...'); ?>
				</div><<!-- end div.entry -->
			</div><!-- end div.right -->

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

	<?php endwhile; ?>
	<?php endif; ?>
</div><!-- end div#wrapper -->

Divs

<div id="wrapper">

The wrapper div basically wraps the whole thing so we can lay it out nicely later on. All divs are pretty self explanitory, and I have also commented in the ends of the divs, so I'll skip them while explaining. In short, I've wrapped everything accordingly so it's easy to style. the .left div is the left column, the .right div is the right column, the .entry div is the post entry, so on and so forth. I've used classes within the loop, as if there are more than one posts, the id's would back up and create a validation error.

The famous Wordpress Loop.

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

If you don't get what this is, go back to wordpress school. It basically loops through the database's information in respect to the calls made within the loop. If you ask for the title, the loop will look into the database for the title for you.

The Post's MetaData.

<p class="postmetadata">
	<strong>Post Details</strong><br />
	Posted: <em><?php the_time('l, jS F, Y'); ?></em> at <em><?php the_time('g:i a'); ?></em>.<br />
	Written by: <em><?php the_author(); ?>.</em><br />
	Number of comments: <em><?php comments_number('none', '1', '%'); ?></em>.<br />
	Posted in: <em><?php the_category(', '); ?></em>.
</p>

Now for the nitty gritty stuff. Everything above contains the information that we want to display about the post. In respective order, we ask for;

  • Date and Time - We ask for the date in the format of l, jS F, Y (e.g. Sunday, 8th June, 2008), and the time in the format of g:i a (e.g. 4:45 pm). I've used the_time(); twice, because if we use the_date(); to ask for the date, it will only show it once per day. If you posted numerous posts on the same day, the date wouldn't show once per post, but once on the first post of the day.
  • Author - This is self explanitory, we are simply asking for the author of the post.
  • Comments Number - This calls for the number of comments on a post. If the post has no comments, it will return the value 'none'. If it has one, it will return the value '1', and, yep you guessed it! If it has more than one, it will return a value like '21' or '6', all depending on how many comments the post has.
  • Category - the_category(); asks the database for the categories that a post have been assigned to. Thanks to wordpress, we don't have to worry about using an extensive and raw php foreach loop, as the (', '); seperates the categories with a comma for us. Thanks Wordpress!

The Content.

<h2><?php the_title(); ?></h2>
<div class="entry">
	<?php the_content('more...'); ?>
</div><<!-- end div.entry -->

Does it get more self explanitory than that? We ask for the title (wrapped in a h2 element so we can style it accordingly), and the content (wrapped in a .entry div so that all content is nested in it's own div for easy styling and access too.). 'more...' in brackets are for when you use the <!-- more --> tag in the wordpress post editor.

Come on... The loop end!

<?php endwhile; ?>
<?php endif; ?>

You code bunnies should get this... It's the basic loop again! It closes off the loop so that only the contained 'functions' within the loop are executed over and over.

Step 3 - The CSS: Layout.

Phew! You've braved all the wordpress code we need for this tutorial! Well done! It should look something ugly like this:

Note: I have used content from my own local server (which happens to be from my own blog) as filler content, so your content wont reflect mine.

Now that we've got all the xhtml and php functions out of the way, we can move onto making it look pretty with css! Joy!

Open up 'style.css' once again with your favourite editor, and if you haven't already, paste this code into it. But you should have done that anyway, because otherwise you wouldn't have been able to activate the theme!

In this tutorial, I utilise the beauty of css's 'float' and 'clear' to float the post details (or metadata, whatever you want to call it), and the content side by side, and one post after the other. Here is the basic layout code: (NOTE: This will NOT make your page pretty JUST yet.)

/*-----LAYOUT-----*/
#wrapper{
	width: 600px;
	margin: 0 auto;
}

.post{
	clear: both;
	width: 600px;
}

.post .left{
	width: 180px;
	float: left;
	padding-right: 20px;
}

.post .right{
	width: 400px;
	float: right;
	padding: 0 25px 20px;
}

Simple:

  • #wrapper - These attributes place everything we have in the middle our page, and at 600px wide.
  • #post - the posts may accidentally ride up next to a poorly floated previous post, or one that doesn't have enough content because we're using floats. The 'clear' attribute makes sure that it's pushed all the way to the bottom of the previous element, no matter what.
  • .left and .right divs - These are floated left and right respectively, because this is what makes them go side by side! If we didn't set the widths of the divs though, this technique wouldn't work. I've made the post details column slightly slimmer than the content column, because we want more attention and more space for the content (considering there is less content in the 'post details' column).
    I've done my math, and made sure that the total width adds up to 600 so both columns fit nicely into the parent '.post' div:180px+20px(padding, so we have some spacing)+400px=600px

Yay! Now, lets make it pretty looking!

Step 4 - The CSS: Styling.

So we've got the skeleton layout down pat, but it still looks kinda ugly:

This is when we use the true power of our cascading stylesheets. Copy or type the following into your style.css underneath the previous 'Layout' code:

/*-----STYLES-----*/

body{
	font: 75%/18px Georgia, "Times New Roman", Times, serif;
	background-color: #e4e4e4;
}

a{
	color: #006082;
	text-decoration: none;
}

.post .left{
	text-align: right;
	color: #898989;
}

.post .left p.postmetadata strong{
	display: block;
	text-transform: uppercase;
}

.right{
	background-color: #fff;
	min-height: 150px;
}

.entry{
	color: #3c3c3c;
}

.entry p img{
	padding: 0 10px 7px 0;
	float: left;
}

a.more-link{
	display: block;
	padding-top: 10px;
	text-transform: uppercase;
}

The Breakdown.

This is a handful of code to process, and it might all look daunting, but it's actually really simple! Because majority of you are probably adequate at CSS, I'll be quick and snappy through this part.

  • body - Here it is that we set the standard text/font size, and the background colour
  • a - Makes all links look pretty.
  • .post .left - Change the colour of the text to a grey shade, and align the paragraphs to the right.
  • .post .left. p.postmetadata strong - Makes the 'Post Details' stand out by capitalising it, and changes the strong element to a block element to line up the post details with the content paragraphs.
  • .right - This is a little confusing, so I'll explain this in depth. Obviously, the background colour is now white, so that the content jumps off the page. The 'min-height' attribute though, is so that if the post content is actually shorter than the post details, it will not break the continuous white colour down the page.
  • .entry - Makes the content text a dark grey.
  • .entry p img - gives any images within the content area to breath, and also allows the text to wrap around the image.
  • a.more-link - The 'more-link' class is automatically added by wordpress to single out the 'more...' that we added into 'the_content()' function. We turn it capital, so the users assume it's not a regular/external link, and give it some space too.

That CSS should bring it to look something like this:

Step 5 - The jQuery.

So it's very important it looks all good without any JavaScript - The above compensates for us here. But to create our true newspaper style degrading headers, we need some tasty jQuery! Open up 'myTheme.js' and lets get cracking! What we want to achieve, is something like this (photoshop mockup):

Notice the difference? We're going to increase the size of the first 'hero' post's header, and change the colour also.

Then, the second or 'villain' post will be slightly grey with an even smaller size, and the consecutive posts after that will remain a uniform size.

We're going to tackle this by adding the classes 'hero' and 'villain' to our first and second '.post' divs respectively, to which we'll then style with a little additional CSS. We add the class to the '.post' divs and not the h2 elements because we want to change some of the contained content too, for example the size of the content and the additional icon on the more-link in the 'hero' post. Why hero and villain you ask? Because the Villain always comes after the Hero. And it's an easy concept to grasp.

It sounds complicated, but it's actually only 4 lines of (spaced out) code. This all goes into 'myTheme.js':

$(document).ready(function(){
	$(".post:first").addClass("hero");
	$(".post:nth-child(2)").addClass("villain");
});

Great! Non-intrusive JavaScript! I love it! It should be in 'myTheme.js'.

Explanation

We have just used a tiny bit of jQuery's incredibly powerful, valuable and versatile selectors. We have now unobtrusively added the classes '.hero' to the first '.post' div on the page, and the class '.villain' to the second '.post' div on the page. Let me explain how.

  • $(document).ready(function(){

    This is jQuery's super special function of initiating the JavaScript function that is defined after this line. When the $(document) is .ready() initiate the function(){} we are about to define. Using $(document).ready(function(){ is much faster than using the 'default': window.onload() function, because the window.onload() function waits for the entire document to load. This includes all images, iframes, etc. We only need to wait the the core XHTML document is finished loading to run our script - so we use jQuery's special $(document).ready(function(){ to make things go faster, and have less lag between initial browsing time and javascript initiation. Kinda confusing huh? To make it simple, jQuery's method is faster. Remember that.

  • $(".post:first").addClass("hero");

    Yay for powerful selectors! jQuery has an amazing array of selectors, some that are from CSS3, but we can use them now. This line, tells us to get: $() the first '.post' element: .post:first and add the class hero: .addClass("hero") to it. We can now style this in CSS, yet we still haven't touched or changed the XHTML code of the '.post' div in any way.

  • $(".post:nth-child(2)").addClass("villain");

    More super strong selectors! jQuery not only lets us select the :first element of a kind, but also lets us select any number of the elements! Using :nth-child(#) we can select any type of the element we want on a page. If we wanted the 30th <p> on the page, the markup would be $("p:nth-child(30)"). Simple to understand?

jQuery's selectors aren't limited to numbers though! There are many many more selectors that let you chose the exact element you need. You can view them by visiting the selector section on the jQuery docs.

Step 6 - The jQuery CSS.

Great. With all that out of the way, we can now focus on the visual side of things. No more explaining needed, let's delve into the CSS. Add or type this at the very bottom of 'style.css' in the 'myTheme' folder. For the 'more-link' to work, download this arrow from the famfamfam silk icon pack, and place it in the a new folder 'images' within the 'myTheme' folder.

/*-----jQUERY-----*/

.hero .left p.postmetadata{
margin-top: 30px;
}

.hero .left p.postmetadata strong{
margin-bottom: 20px;
}

.hero .right h2{
font-size: 46px;
font-style: italic;
font-weight: normal;
margin-bottom: 0.5em;
}

.hero .right p{
font-size: 14px;
}

.hero a.more-link{
background: url(images/arrow_right.png) no-repeat right bottom;
float: left;
padding-right: 20px;
}

.villain .left p.postmetadata{
margin-top: 20px;
}

.villain .left p.postmetadata strong{
margin-bottom: 15px;
}

.villain .right h2{
font-size: 32px;
font-weight: normal;
color: #747474;
}

.villain .right p img{
float: right;
padding: 0 0 7px 10px;
}

Explanation

You should all be pretty adequate now with CSS, so I'll do a very quick run through of this new CSS.
This is the CSS that changes the look of the '.hero' post.'

  • .hero .left p.postmetadata - We push it down a bit so it's in line with our new header size.
  • .hero .left p.postmetadata strong - We push everything under the bolded 'post details' down so it's in line with the content text.
  • .hero .right h2 - This makes our 'hero' header stand out. We make it bigger, and italicise it.
  • .hero .right p - Increase the font size of our hero content.
  • .hero a.more-link - Add the little green arrow from the famfamfam silk pack.

And also, the CSS that changes the '.villain' post.

  • .villain .left p.postmetadata - Does the same as the hero postmetadata, pushes it down.
  • .villain .left p.postmetadata strong - Does the same as the hero postmetadata alignement.
  • .villain .right h2 - Here we make the villain header grey, un-bolded and a little larger than the uniform posts.
  • .villain .right p img - The villain image has to stand out, right? We just float it to the right (so the text wraps around it) and change the padding accordingly.

Wrap Up

Well done! In this tutorial we've covered a basic method to spruce up our wordpress content using jQuery's selectors! They are not exclusive to jQuery however. You'll find all of these selectors in CSS3 (when all browsers support that!). We just love jQuery because they bring them to us now. Here is our final product.

Advertisement