Hostingheaderbarlogoj
Join InMotion Hosting for $3.49/mo & get a year on Tuts+ FREE (worth $180). Start today.
Advertisement

Tabbed Content using jQuery and WP_Query

by
Gift

Want a free year on Tuts+ (worth $180)? Start an InMotion Hosting plan for $3.49/mo.

Wordpress provides a huge array of information about your blog and it's content. Showing lots of this information can become space consuming. A great looking solution to this is tabbed content!

In this tutorial, we'll take the WordPress Newspaper Layout we worked on previously and extend it with tabs.

Preface

Right! We'll be using a nice and powerful combination of jQuery's animation and .bind function blended nicely with Wordpress's versatile WP_Query() and Wordpress exclusive conditional tags. If you're like me, you like to see the finished product before anything:

If you're wanting to do only this tutorial, you will need the latest version of jQuery for this tutorial. Download it here. Otherwise, it should already be in with this theme I've prepared, which you can download here: myTheme.

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. Activating the theme I prepared previously - myTheme - would be a big help to. We'll be extending on this, so open index.php and let's get editing!

Step 1 - New Structural HTML.

We need some new HTML, obviously. This is simple. We only need some extra divs to wrap everything that we're working with. Place this following code just above <div id="wrapper">:

<div id="container">
	<div id="header">
		<h1>iBlog - Wordpress and jQuery together in <em>Harmony.</em></h1>
	</div>
		

And we need to add a final </div> just before the closing </html>

Step 2 - Conditional tags

So we love the Tabbed Content we're about to make, but we only want it on our first page for show's sake! How is it possible to have exclusive code on the first page you ask!? Simple. Wordpress's conditional tags. This is a valuable lesson to learn! The conditional tags provide a very powerful means of customising your themes that little bit more! They are very self explanatory, but I'll give a basic rundown below the code. Add this just under our brand new h1 element in index.php.

<?php if(is_home()) {include(TEMPLATEPATH.'/tabbedContent.php'); } ?>

You get what this is, right? if(is_home()) is our condition here, so if the page currently being browsed is the home, include our tabbedContent.php file. Which we will create next.

Step 3 - tabbedContent.php (HTML)

So now we've asked Wordpress to include tabbedContent.php when the page is home, but we still need the actual file and content! Create a new file in our 'myTheme' directory, and name it tabbedContent.php. Type or paste the following into this new file:

<div id="tabsAndContent">
			<ul id="tabsNav">
				<li><a href="#recentArticles">Recent Articles</a></li>
				<li><a href="#monthlyArchives">Monthly Archives</a></li>
				<li><a href="#searchArea">Search</a></li>
			</ul>
			<ul id="tabContent">
				<li id="recentArticles">
					<ul>
						
						<!-- WP_QUERY GOES HERE -->
						
					</ul>
				</li>
						
				<li id="monthlyArchives">
					<ul>
						
						<!-- WP_ARCHIVES GOES HERE -->
						
					</ul>
				</li>
						
				<li id="searchArea">
					
					<!-- WP SEARCH GOES HERE -->
					
				</li>
			</ul>
		</div> <!-- div#tabsAndContent -->

Great. At the moment, this is just raw HTML without any Wordpress or jQuery additions. Not a great deal of this is new, but let me explain the layout a little.

  • #tabsNav - These are the clickable tabs! We've added a href attribute of their corresponding content <li>. Making sure the hrefs match the ID name of their corresponding content list item!
  • #tabContent - We use a <ul> not unlike Wordpress's sidebars, because it's easy to style and is essentially a list of content anyway! I think the contents of this element are self explanatory.

Step 4 - tabbedContent.php (Wordpress functions)

Now that's done, it's still gonna look kinda empty. So we need to replace the <-- --> comments with actual content! We'll start with WP_Query(), wp_get_archives(), and a search form.

4.1 - WP_Query()

Yet another valuable lesson to learn. It's fantastic if you want to do things like we're doing, or a 'Featured Post'. Basically, It's a simplified loop anywhere on the page. It's great. So cut out the comment tag for our WP_Query, and type the following:

<?php $recent = new WP_Query("showposts=5");
	while($recent->have_posts()) : $recent->the_post();?>
		<li>
			<a href="<?php the_permalink();?>" title="Link to <?php the_title(); ?>"><?php the_title(); ?></a>
		</li>
<?php endwhile; ?>

WP_Query() is fantastic. Yes, it's a loop. Not the entire thing though. All we're simply doing, is telling the immanently following loop to show us a list of the 5 latest posts. The string within the brackets of WP_Query can be anything... filter by dates, categories, tags, limit, etc. It's a fantastic tool to understand, and yet another valuable lesson to take away from this!

4.2 - Archives

If you're a frequent wordpress themer, you should know how to do this. It's a basic call for a list of monthly archives. And to match the WP_Query section, we only want 5 of them (automatically in descending order). Simply switch the <-- WP_ARCHIVES GOES HERE --> in tabbedContent.php with the following:

		<?php wp_get_archives('type=monthly&limit=5'); ?>

4.3 - Search

We'll only be using a very simple input and search, using the default search I always use in my own templates. Replace the WP SEARCH comment with this:

<form method="get" id="searchForm" action="<?php bloginfo('home'); ?>">
	<p>
		<input type="text" value="<?php echo wp_specialchars($s, 1); ?>" name="s" id="s" />
		<input type="submit" id="searchSubmit" value="Search!" />
	</p>
</form>

Great, so now you should have a new file within the myTheme directory called tabbedContent.php, and the conditional tag in index.php. If you've followed everything correctly, your theme should look something like this:

Not so pretty yet... Or tabbed, or jQueried or CSSed at all for that matter. But it's a start, and good to know our wordpress code works! We're done with tabbedContent.php, so you can close that now!

Step 5 - CSS

We need our tabs to blend in, become part of the page. At the moment, they are ugly sides. We need to make the page for people without JavaScript enabled first, for graceful degredation. You'll need some images if you want to make it as pretty just as much as I do. Here is a list of them (right click and save as into the images folder within the myTheme directory!)

Either type, or paste this massive slab of CSS. Nothing new here, we just align the tabs up with the 'Post Details', and align the content up with the main content white column, and use the :hover instance a few times.

/*------TABS------*/

#container{
	width: 600px;
	margin: 0 auto;
}

h1{
	font-size: 1.3em;
	text-transform: uppercase;
	color: #949494;
	letter-spacing: 1px;
}

#tabsAndContent ul, #tabsAndContent li{
	padding: 0
}

ul#tabsNav{
	float: left;
	width: 200px;
	list-style: none;
}

ul#tabsNav li{
	background: url(images/tabsNavBg.png) no-repeat center #a8a8a8;
}

ul#tabsNav li:hover{
	background: url(images/tabsNavHover.png) no-repeat center #eee;
}

ul#tabsNav *:focus {
	 outline: none
}

ul#tabsNav li.active{
	background: url(images/tabsNavActive.png) no-repeat center #fff;
}

ul#tabsNav li.active a{
	color: #303030;
}

ul#tabsNav li a{
	padding: 1em 15px;
	margin: 0 0 1em 0;
	display: block;
	width: 170px;
	text-decoration: none;
	color: #7e7e7e;
	font: 11px/20px Georgia;
	text-transform: uppercase;
}

ul#tabsNav a:hover{
	color: #0a0a0a
}

ul#tabContent{
	margin: 1em 0 0;
	background: url(images/tabContent.png) no-repeat top right#fff;
	min-height: 180px;
	width: 350px;
	float: left;
	list-style: none;
	padding: 0 25px;
	font-family: "Helvetica Neue", Arial, Helvetica, Geneva, sans-serif;
}

#tabContent>li{
	width: 350px;
	list-style: none;
	padding: 0 25px 20px 0;
}

#tabContent li ul li{
	list-style: none;
}

#tabContent li ul li a{
	display: block;
	border-bottom: 1px solid #e7e7e7;
	padding: 10px 0;
}

#tabContent li ul li a:hover{
	background: url(images/tabContentHover.png) no-repeat center bottom;
}

form{
	padding: 30px;
	
}

form input{
	background: url(images/searchInputBg.png) repeat-x #ddd;
	border: 2px solid #cbc6c9;
	border-right: 0;
	padding: 5px;
	margin-right: 0;
	color: #fff;
	font: 16px Georgia, "Times New Roman", Times, serif;
}

#searchSubmit{
	border-left: 0;
	border-right: 2px solid #cbc6c9;
	margin-left: 0;
	position: relative;
	left: -3px;
	color: #00416c;
}

#searchSubmit:hover{
	background: url(images/tabContentHover.png) no-repeat center;
	color: #003459;
	cursor: pointer;
}

If this all goes according to plan, it should look rather nice, something similar to this (with your own content of course):

Now that we've made sure the page looks OK for those sans JavaScript, we can move onto catering for those who do!

Step 5 - jQuery

My personal favourite section of the tutorial! jQuery time! Lets put into words what we need to happen:

  1. Hide all list items we don't want to see initially, showing only our first content section, the WP_Query section.
  2. Add the class 'active' to the first tab, because it's corresponding section is open.
  3. When a tab is clicked, do the following in order:
    • Remove the active class from the currently active tab
    • Add the class active to the tab that has just been clicked
    • Get the href attribute of the a within the clicked tab, and make it our new variable 'target'
    • Then have the target reveal itself, and the previous showing area hide itself with some animation

This may seem like a hard thing to achieve, but thanks to jQuery's write less do more attitude, I've managed to cut what we need down to only 9 lines of js code! This goes within the $(document).ready(function(){ });, underneath th hero and villain script.

//And our little animated sliding area uptop of the design.
	
	$('#tabContent>li:gt(0)').hide();
	$('#tabsNav li:first').addClass('active');
	$('#tabsAndContent #tabsNav li').bind('click', function() {
		$('li.active').removeClass('active');
		$(this).addClass('active');
		var target = $('a', this).attr('href');
		$(target).slideDown(400).siblings().slideUp(300);
		return false;
	});

A basic breakdown of our code:

  • $('#tabContent>li:gt(0)').hide(); - This, as we wanted in our word version of the script, hides all content items greater than zero, with out items starting at 0.
  • $('#tabsNav li:first').addClass('active'); - We add the class 'active' to the first tab, because if only the first content area is showing, we don't want the second tab to be active do we!?
  • $('#tabsAndContent #tabsNav li').bind('click', function() { - The .bind function! All this does, is when the parameter event happens (click in our case) it binds the following function to the element. and the function is:
    • $('li.active').removeClass('active'); - Take the class active off it's current holder.
    • $(this).addClass('active'); - add the class to this, a useful selector when you're within a function, and is specific to the element clicked.
    • var target = $('a', this).attr('href'); - Create our variable 'target' from the tab's child a element's href attribute, once again using this in a selector.
    • $(target).slideDown(400).siblings().slideUp(300); - Our animation! Now that we have our target, we'll slide it down in four tenths of a second (or 40 milliseconds), and slide any visible siblings away into the abyss in almost a third of a second (30 ms).
    • return false; - This is important! You don't want the browsers history to have a million previous links simply from clicking tabs, do you? Each time the URL changes to #recentArticles or something like that, it adds another entry to the browser history. return false; nullifies this, so no URL changes and no history is added.

So that's all the jQuery, CSS, HTML, and Wordpress we'll need. You should have something resembling this:

Yes it should animate, yes the active button should change, and yes, you've just created your very own tabbed dynamic content, and implemented it into a Wordpress theme with Wordpress content!

To finish up.

We've gone through a lot in this tutorial. Overall, some important lessons we learnt are:

  • WP_Query(); - A powerful tool for getting content outside the main loop.
  • Wordpress conditional tags - fantastic for further customising your theme.
  • .bind function - to easily link a function to a specific element with an event.
  • jQuery animation - Incredibly easy to implement, and as pretty as a garden of roses.
Advertisement