The Power of WordPress

Build a Newspaper Theme With WP_Query and the 960 CSS Framework

Aug 6th in Wordpress by Harley

WP_Query is a powerful tool to control what comes out of your loop. Today I'm going to teach you all how to use it to make a 3 columned newspaper theme that has all your main blog posts in the main column, and off to the side a set of posts with a certain category. We'll be using the 960 CSS framework for the basic layout and reset of our theme, it will chop a lot of work off what's needed!

Author: Harley

I'm Harley! I like to call myself a jQueryfied WordPress designer! What a mouthful, huh? I'm based in Australia and have been working with (X)HTML/CSS, Flash, Illustrator and Photoshop for over 3 years, and have found a now year and a half old obsession with WordPress and jQuery. Be sure to get some more info on me on my site!

Preface

Our plan of attack is to take out all posts with a shared assigned category, and place them off to the side separate from the main posts. We'll also look at a method for creating a 'featured post' without using jQuery or any JavaScript at all! I've also thrown together a .psd using the templates - that 960 provide for you on download - of what we're aiming to achieve today. Download the .psd here.

We assume that you have a live Wordpress installation, whether it be local or hosted. There are tutorials on running Wordpress locally here for Windows, and here for OS X.

Step 1 - The Necessities

Alrighty. So apart from the obvious need of a Wordpress installation, we're going to need a few extra things too. I got a whole bunch of files you're gonna need to have in your theme folder.

  • Everything must go in a theme folder withing wp-content/themes/, so create a folder named triColumnNews, and place everything proceeding in it!
  • 960 CSS Framework - This is kinda obvious too. Within your triColumnNews folder, create another folder named 960. Head over to 960 Grid System and pick up a copy of the framework. In the download you'll find some folders. Open the folder aptly named 'code' and copy the 3 CSS files (960.css, reset.css and text.css) into the 960 folder you created a second ago. That's all sweet now.
  • functions.php - We're gonna be needing a sidebar, so we need functions.php to register it.
  • images folder - Well duh... Every decent theme has some images! Create the folder images, and place bodyBg.png and searchBg.png in it.
  • index.php - An obvious concept... We'll work mainly on this.
  • page.php and single.php - Our index page will have 3 columns right? But I don't think individual pages require 3 columns. We change the sub template pages at the very end so that if you do go to a page, it's not all muddled due to the incorrect WP_Query on the index (incorrect for the specific page, not the index).
  • style.css - Copy that over and edit it accordingly if you wish.

Got all that? Good. You should be set for the rest of the tutorial now! Don't forget to activate the theme in WP-admin (wp-admin/themes.php).

Step 2 - HTML and basic Wordpress Code

I'm not going to give you all the Wordpress code just yet. I'm going to give you all the Wordpress code you need excluding the WP_Query's. They'll have a step in their own, because they definitely need explanation! It'd fill up the page WAY too much, so I've included it all in a .txt rather than here. Download it, and copy it into index.php. Or type it, whatever suits. Typing helps you remember what you're doing!

Some things to note

That's a whole lot of code to process, so I'll just snag out the interesting parts for you, and explain them.

  • head - This is all just Wordpress stuff. Stylesheet, RSS2 link, and some WP stuff.
  • #dateAndTime - Have you ever read a newspaper that doesn't have the date up top? Me neither. Let's not start now, hm? This displays the date in the format: (Thu 17th July 08). We'll float this way up top so it stays in the browser window at all times! Just because...
  • form id="searchform" - This is the searchform for the blog! I just stuck one in to fill up space and make it all the more convincing!
  • dynamic_sidebar - That basically explains it... It's the sidebar we want, named triNews so it can be identified in Dashboard.
  • Note - You can see that it's already starting to take shape in terms of layout (a very squewif layout, but not the reset!) - I've imported the 960 files using an @import in style.css, to save HTTPRequests, and it also gives our code parent power over the 960 code.
  • All the little funny classes... Read on.

The 960 classes

So I bet you're noticing all these little 'grid_5' and 'container_12' classes and going what the heck is that? Well let me explain to you. The number following 'grid_' is the number of columns we want that select div to be. Because we want 12 columns, we wrap the whole thing (using div#wrapper) with the 'container_12' class. In the basic CSS I provided you with, it has the imports for the three 960 files, so we already have half a layout when we've not coded any CSS at all!

This won't look too flashy. It hasn't been styled and it doesn't even have content:

Step 3 - WP_Querys

This is where all the magic happens! We have three WP_Querys:

  • theirNews - So we have split news, right? We want this section to only show posts with the category 'theirNews'. On my part, (of my test blog) I've given about 7 of my posts this category. You should go give them some too. You also need to find the category ID of theirNews category, but I'll quickly take you through how to find that later.
  • featured - Remember I said I'll show you how to make a featured post without jQuery? Here's the solution in a nutshell: only show the most recent post to date in it's own query loop.
  • main - the trick with this is that we don't want the category of theirNews in here, nor do we want the first post. It's easy, you'll see in a minute.

Step 3:1 - theirNews

So we want a column of wordpress content from only a single category. How do we do that? Using the vast range of parameters WP_Query provides us with, it's easy to do so. Replace the theirNews comment in index.php with:

<?php 
	$theirNews = new WP_Query();
	$theirNews->query('category_name=theirNews&showposts=7');
	while($theirNews->have_posts()) : $theirNews->the_post();
?>

	
	<!-- LOOP CONTENT HERE -->
	
<?php endwhile; ?>

Query! Let's jump right into it.

  • $theirNews is the variable query we'll be using for the 'theirNews' section. This defines a new query, the whole basis of WP_Query.
  • query(); - Here are our specific parameters. We only want to show maximum 7 posts, all under the category name 'theirNews'. You can change these variables around of course, 7 is just the number of posts I have the category assigned to.
  • The rest of the code is a shortened loop, that is specified using our $theirNews variable.

We need some specific loop code.

	<div class="post">
		<h4><?php the_title(); ?></h4>

		<div class="entry">
			<?php the_content('<br />Read complete article'); ?>
		</div>
	</div>

Simply the title wrapped in a h4 tag, with the content wrapped in a div classed 'entry'. Great! You've done your first WP_Query out of the 3, that should now list only categories with the name 'theirNews'

First Query

Step 3:2 - featured

We only want to show 1 post, that doesn't have the category 'theirNews'. Only 1. Since you now understand the fundamentals of WP_Query, I'll give you the full code (replace the FEATURED POST comment with):

<div id="featuredPost" class="post">
	<?php
		$featured = new WP_Query();
		$featured->query('showposts=1&cat=-59');
		while($featured->have_posts()) : $featured->the_post();
	?>
		<h2><?php the_title(); ?></h2>

		<em class="postMetaData">Posted under <?php the_category(', '); ?>.</em>
		<div class="entry">
			<?php the_content('Read complete article'); ?>
		</div>
	<?php endwhile; ?>

</div><!-- end div#featuredPost -->

This is our featured post, so I have aptly named the div 'featuredPost', but because later on we'll also want styles from regular posts, I've included the class 'post'.

Same deal with the WP_Query. This time the parameters show only 1 posts that isn't from the category 59. Category 59 is the ID of the category 'theirNews'. I need to tell you how to get it!

  1. Open up WP-Admin.
  2. Click on manage.
  3. Click on Categories.
  4. Click on the category 'theirNews' (or whatever you've called it).
  5. Check the URL of the page. It should be something like this:
    Category ID
    See how it's got &cat_ID=59 at the end? This is your category number. Mine is 59, make sure you change it to whatever the ID of your 'theirNews' category!
  6. Remember that number, we'll need it in the next Query too.

The difference with the featured post is mainly the h2. Because it's the second largest header on the page. Way up in the 'theirNews' section we wrapped in in a h4 element, because after the main column's posts it'll be the next header on the page. All for styling sake.

Step 3:3 - main

Our last WP_Query. This one will be all posts excluding posts contained by the 'theirNews' category (You need the ID. Mine was 59, can you remember yours?). But because we're already showing the first post overall (the feature post), we don't want to show it again, right? So we need to offset the posts by 1 - easy to do with WP_Query's powerful parameters.Replace the MAIN WP QUERY comment in index.php with this:

<?php
	$main = new WP_Query();
	$main->query('posts_per_page=5&offset=1&cat=-59');
	while($main->have_posts()) : $main->the_post();
?>
	<div class="post">
		<h3><?php the_title(); ?></h3>
		<em class="postMetaData">Posted under <?php the_category(', '); ?>.</em>

		<div class="entry">
			<?php the_content('<br />Read complete article'); ?>
		</div>
	</div>
<?php endwhile; ?>
  • posts_per_page - Is exactly what it is... When you get onto adding next and previous pages it overrides what you set in WP-Admin. I have 3 as the default, and couldn't be bothered changing so I made it 5 for the main column.
  • offset - Remember how I said we need to not show the first post, because we already have it in the featured post section.
  • cat=-59 - We need to specify which category not to include - theirNews - and for me, it has the ID of 59. The '-' right before the number basically counts for exclusion.

So that's all the HTML and Wordpress code we need. It will still look basic, but it will have the general 3 column layout we're after!

Pre CSS

Step 4 - CSS

Now because all our layout is pretty much done, it's mainly only styling that's needed! Download all this CSS, and paste it into your style.css. There are a few things that override the default 960 code. We don't need to use !IMPORTANT because the new code is actually higher up the hierarchical ladder than the 960 code. We use the 960 code as a sort of 'base' that we build up from. If you decorate the foundations of a house, do you still see the raw foundations? This 'decoration' is mainly on headers, but some general styling is used for text content etc. One major override is the body font. We specify Georgia, when the default is actually Helvetica. Fonts are really up to your preference, I've just used Georgia to be different! Once you've pasted and read through all the CSS, the front page should look complete!

Step 5 - Sub Template Files (optional)

I'm only including this section so I don't get a zillion questions asking why individual pages return the information that should be on the main page! So our index page has 3 columns - But what would you fill 3 columns with in a specific single page? Whatever you want! Though I'd suggest the content of the post... So I'm going to explain just how page.php and single.php work, in case you want to extend the theme. If you want to split index.php into header, sidebar and footer, do so now! Otherwise, we'll steam onwards:

  1. Open up single.php.
  2. Copy all the code from index.php into single.php.
  3. Scroll down til you get to div#theirs.
  4. Delete the whole div. While you're at it, delete the featured post too!
  5. All you should have left is div#main.grid_5. Change the 5 to a 9 to compensate for the 4 columns we just got rid of.
  6. Don't forget to change the end div comment so you don't get confused later on!

So now you should have an empty main column. We're going to fill this up with a regular loop:

<?php if(have_posts()) : while(have_posts()) : the_post();?>
	<div class="post">
		<h2><?php the_title(); ?></h2>
		<em class="postMetaData">Posted under <?php the_category(', '); ?>.</em>

		<div class="entry">
			<?php the_content('Read complete article'); ?>
		</div>
	</div><!-- end div.post -->
<?php endwhile; ?>
<?php endif; ?>

Naw... The regular old boring loop. Feel free to spruce this single page up to whatever you want your single posts to look like. This provides the basic template for Wordpress to display a single post.

Step 5 Part 2

So that's a single post, but we still have links to single pages in the navigation and footer. If you click them, they will return the same as the index. Not cool. All we need to do though, is copy everything from single over to page.php, and it should be sweet. Easy huh? These Pages should look something like this:

Single

Wrap up

So you've just had a glimpse at what WP_Query can do. I strongly suggest visiting the Query_posts docs page, which has all the same parameters as WP_Query. You can narrow your loop down to any specific post using any combination of the parameters separated by a &.

I hope you guys have had as much fun as I have creating a Newspaper looking theme! You can View the final product here! Enjoy!


Related Posts

Check out some more great tutorials and articles that you might like

Enjoy this Post?

Your vote will help us grow this site and provide even more awesomeness

User Comments

( ADD YOURS )
  1. Philo August 6th

    Nice Tutorial! ;)


  2. Dan August 6th

    Not bad. Nice use of the 960


  3. Razvan August 6th

    Good tut, thanks!


  4. Braden Keith August 6th

    Question: With wordpress, how could I make it so that I can put the recent blog articles are listed on a page outside of wordpress?

    Example: http://example.com/wordpress is where the blog is, but on the index of example.com I want to have the recent blog posts at the footer of the page (like nettuts does with the related sites, archives, most talkative users links at the bottom)

    How can I make this work?

    thanks.


  5. Nate August 6th

    Great tutorial. Thanks for sharing.


  6. Ben Griffiths August 6th

    Nice and easy on the eyes theme - also going to check out this 960 framework :) Thanks!


  7. Gabe Diaz August 6th

    Very nice!


  8. Lucas August 6th

    Such a great tutorial


  9. Marvin August 6th

    very nice! great idea/tut and realization!


  10. Jonathan August 6th

    @Braden
    You can add this to your header to pull in wordpress header and sidebar and footer or whatever you want

    <?php
    /* Short and sweet */
    define('WP_USE_THEMES', false);
    require('./wpdir/wp-blog-header.php'); get_header(); ?>

    Or you can grab your rss feed like so

    < ?php
    require_once (ABSPATH . WPINC . '/rss-functions.php');

    // here's where to insert the feed address
    $rss = @fetch_rss('http://www.yoursite.com/feed/');
    if ( isset($rss->items) && 0 != count($rss->items) ) {
    ?>
    <ul>
    <?php
    // here's (5) where to set the number of headlines
    $rss->items = array_slice($rss->items, 0, 5);
    foreach ($rss->items as $item ) {
    ?>
    <li>
    <a href='<?php echo wp_filter_kses($item['link']); ?>’>
    <?php echo wp_specialchars($item['title']); ?>
    </a>
    </li>
    <?php } ?>
    </ul>
    <?php } ?>

    Should do the job - Hope That Helps


  11. Jonathan August 6th

    @Braden
    Sorry couldn’t remember off hand but here is the source for the above code which is currently in moderation if you can’t see it.

    Great Tut. Love the 960 framework, but I’m personally moving to 990 as more and more users have bigger screens.


  12. Braden Keith August 6th

    @Jonathan
    Thank you very much for that helpful link.


  13. Connor August 6th

    cool…


  14. Braden Keith August 6th

    Jonathan I still can’t figure out how to do this still.


  15. Braden Keith August 6th

    Wait, wait, no I got it.
    http://bigsquaredot.com/blog/2007/03/12/display-wordpress-entries-on-static-pages/ helped me out. Thanks though.


  16. Mark Abucayon August 6th

    I like it, that is very helpful. thanks


  17. Taylor Satula August 6th

    Very nice very nice… ;)


  18. insic August 6th

    this layout is darn hard to achieve when you are designing it with a start from scratch css. this cant be finish without scratching your head.


  19. Mike August 7th

    A seriously useful tutorial that is actually greater than the sum of its parts because of the possibilities it opens up.

    Such a refreshing change from all the very pretty but ultimately useless flashwannabe javascript tuts.


  20. Harley Alexander August 7th

    Hey thanks for the great feedback guys!

    I just realised something, when using pagination, you may have to add the parameter ‘posts_per_page=%’. WP_Query is what the_post uses to query the database, and we’re editing it directly. So you need to re-specify how many posts to display per page, else page 2, 3 and onwards will display the same content as the first page!

    Heh, 20 comments and no questions to ask! Must be a keeper tutorial!

    ~Harley


  21. Lamin Barrow August 7th

    Simple and clean theme. It appeals to me very much. :)


  22. Jonathan August 7th

    @Braden
    Glad you came right ;-)


  23. James August 7th

    Grrr… Does this mean I’m gonna have to learn how to use CSS frameworks!? … I’m being totally honest, I think they’re bloated and unecessary… Just IMO.

    Nicely written tut though! :)


  24. Jeffrey Way August 7th

    @James - I agree 100%. I’m thinking about writing an article on it actually. I think they’re unnecessary and prefer to create my own simple reusable stylesheet. Personally, that’s all I need.


  25. Shane August 8th

    @James - I agree with you too :)

    Although frameworks may help some designers and developers, you’re right in saying that they have a rather bloated feel.

    I also don’t like the class/ids used - they’re not particularly semantic. I understand the reasons for their naming convention, but it doesn’t feel as good using a class called ‘container_12′.

    It may take away some of the pain of troubleshooting CSS issues, but I think it takes out some of the understanding that makes CSS ‘fun’ in a way that makes it fun too.


  26. Wordpress is truely the king of blogging. Great tutorial and I recently learned of the 960 framework. Great stuff!


  27. Fabian August 9th

    Really great tutorial! 960 works great in combination with wordpress :D


  28. Juan Antonio August 11th

    QUESTION to Harley Alexander : May you add comments on this theme!! I do not really know how to work with the “960 grid” to make it work perfectly!!

    I would like to see also bigger images, the result is great!!!!

    What’s the text.css for?


  29. Taylor Satula August 21st

    I don’t know. I don’t like the960 fw


  30. Rene Visco August 24th

    I wonder if using Blueprint CSS framework will work in the replacement of 960 CSS framework?


  31. Erin C August 24th

    Ruh-roh - up in Section 4 - CSS - the link to ‘all this css’ is being denied - could not load from Google’s cache - new link please, this looks really cool thank you!


  32. ninjai August 30th

    nice, i wanna have a try.


  33. Danh ba web 2.0 September 12th

    Amazing ! I like it very much.
    Thanks for share


  34. Andrew — Ukrnet September 17th

    Very cool tut!

    Thanks for it dude!


  35. Webmaster October 23rd

    wow

    this is great , thank you very much


  36. elmanu November 4th

    excelent !


  37. Jon Ng November 6th

    Hi, Harley Alexander! I like your WP themes and would love to use it, but I wonder how I put my post place in “theirnews” column, I can’t find Categories that contain that name, or I must do something by hand, edit code for example. Sorry, I dont know how to program :(

    Regards!


  38. Johan November 13th

    Hmm. Did everything according to the tutorial, but there is still some things i can’t work out. For ex. What to do with the functions.php file? Don’t get it with the triNews sidebar and dashboard either :(
    Anyway, really nice tutorial and well written. Mad props!!


  39. yongming November 17th

    it’s nice tutorials. now i can build my own news blogs
    thanks!!!


Add Your Comment

( GET A GRAVATAR )
  • Gravatar

    Your Name November 22nd

Arrow