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

Create an FAQ Accordion for WordPress With jQuery UI

by
Gift

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

Creating an FAQ section for your WordPress website is incredibly simple. We're going to use WordPress Custom Post Types for the questions & answers. Then we'll use a jQuery UI accordion to make a nice cross-browser accordion widget. Finally we'll assign a shortcode so that we can put our FAQ on any page or post.

We'll be creating this:


Step 1 Create the Directory and Files

  1. Create a new folder inside your theme folder called faq
  2. Inside the 'faq' folder, create a new file called faq.php
  3. Create another file called faq.js

Step 2 Include the faq.php File

In your functions.php (located in the root directory of your theme) – include the faq.php file you created at the top.

/* functions.php */
include('faq/faq.php');

Step 3 Create the Custom Post Type

  1. To register the Custom Post Type, we are going to hook into the init action. We are using an anonymous function as the second parameter to help keep everything encapsulated in one place. This helps with readability and maintainability.
  2. Set up $labels and $args as seen below.
  3. At the end we call register_post_type('FAQ', $args)
  4. Now if you go into your Admin area you will see a new option in the menu – FAQ (as seen in the image below)
  5. Click Add New Question and enter a few Questions and Answers so that we have something to work with later on. Use the title field for the question, and the main content field for the answer. This allows us to enter any type of content into our answer (such as images & videos) as well as text.
/* Register the Custom Post Type */
/* faq.php */
add_action('init', function() {

	$labels = array(
		'name' => _x('FAQ', 'post type general name'),
		'singular_name' => _x('Question', 'post type singular name'),
		'add_new' => _x('Add New Question', 'Question'),
		'add_new_item' => __('Add New Question'),
		'edit_item' => __('Edit Question'),
		'new_item' => __('New Question'),
		'all_items' => __('All FAQ Questions'),
		'view_item' => __('View Question'),
		'search_items' => __('Search FAQ'),
		'not_found' => __('No FAQ found'),
		'not_found_in_trash' => __('No FAQ found in Trash'),
		'parent_item_colon' => '',
		'menu_name' => 'FAQ'
	);

	$args = array(
		'labels' => $labels,
		'public' => true,
		'publicly_queryable' => true,
		'show_ui' => true,
		'show_in_menu' => true,
		'query_var' => true,
		'rewrite' => true,
		'capability_type' => 'post',
		'has_archive' => true,
		'hierarchical' => false,
		'menu_position' => null,
		'supports' => array('title', 'editor', 'page-attributes')
	);
	register_post_type('FAQ', $args);
});

Step 4 Include jQuery, jQuery UI, and faq.js

  1. Load jQuery
  2. Load jQuery UI
  3. Load the stylesheet for the jQuery UI library
  4. Load our custom script faq.js
add_action( 'wp_enqueue_scripts', 'wptuts_enqueue' );
function wptuts_enqueue() {
	wp_register_style('wptuts-jquery-ui-style', 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.21/themes/south-street/jquery-ui.css');
	wp_enqueue_style('wptuts-jquery-ui-style');

	wp_register_script('wptuts-custom-js', get_template_directory_uri() . '/faq/faq.js', 'jquery-ui-accordion', '', true);
	wp_enqueue_script('wptuts-custom-js');
}

You'll notice we only used one wp_enqueue_script call, because it's important the JavaScript files are loaded in order as they are dependent on each other. Setting jquery-ui-accordion as a dependency makes sure this happens.


Step 5 Setup the Shortcode

Because we want to be able to put our FAQ Accordion on any page/post, we're going to generate a shortcode. Using a shortcode means that we only have to type [faq] inside any post/page in the WordPress Editor to display our FAQ.

add_shortcode('faq', function() {
	return "Shortcode test";
});

Step 6 Get the FAQ Questions & Answers

We can get the data from our custom post type by using the get_posts() function.

  1. numberposts – Here you can limit how many FAQ questions are retrieved
  2. orderby and order – Allows us to change the order of the questions
  3. post_type – This is how we tell WordPress to only fetch our custom post type
add_shortcode('faq', function() {
	$posts = get_posts( array(
		'numberposts' => 10,
		'orderby' => 'menu_order',
		'order' => 'ASC',
		'post_type' => 'faq'
	)); //array of objects returned
});
/* example */
echo $posts[0]->post_content; // will output the answer from the first faq question.

Step 7 Generate the Markup for the jQuery UI Accordion

This is the markup needed for the jQuery UI Accordion :

<!-- Markup needed for jQuery UI Accordion -->
<div id="wptuts-accordion">
	<h3><a href="">Question Will Go Here</a></h3>
	<div>Answer will be in this div.</div>
</div>

We can generate this by looping over the $posts array.

  1. First we use $faq to store the start of our HTML – we open up a div with an id of wptuts-accordion
  2. Next we start looping through all the posts and adding the result of sprintf to the $faq variable.
  3. sprintf will replace %1$s with the value retrieved from $post->post_title and %2$s with the value returned from $post->post_content
  4. We run $post->post_content through wpautop() to ensure it displays as it was authored in the admin area.
  5. Finally we close off the div and return $faq to output the HTML onto our page.
	$faq  = '<div id="wptuts-accordion">'; // the container, before the loop

	foreach ( $posts as $post ) {
		$faq .= sprintf(('<h3><a href="">%1$s</a></h3><div>%2$s</div>'),
			$post->post_title,
			wpautop($post->post_content)
		);
	}

	$faq .= '</div>'; // finish off by closing the container

	return $faq;

The Full Shortcode

add_shortcode('faq', function() {

	$posts = get_posts(array(  //Get the FAQ Custom Post Type
		'numberposts' => 10,
		'orderby' => 'menu_order',
		'order' => 'ASC',
		'post_type' => 'faq',
	));

	$faq  = '<div id="wptuts-accordion">'; //Open the container
	foreach ( $posts as $post ) { // Generate the markup for each Question
		$faq .= sprintf(('<h3><a href="">%1$s</a></h3><div>%2$s</div>'),
			$post->post_title,
			wpautop($post->post_content)
		);
	}
	$faq .= '</div>'; //Close the container

	return $faq; //Return the HTML.
});

Final Step

Phew! If you have got this far, well done – you're nearly there! At the moment we've managed to output all the data needed for our accordion, all that's left to do is place this in faq.js:

(function(){
	jQuery("#wptuts-accordion").accordion();
})();
Advertisement