It seems like I started this WordPress Featured Content tutorial forever ago. Well in this tutorial I finish it.
I have shown you how to do pretty much anything with WordPress in this tutorial. All of those things I have missed have already been covered in my basic WordPress Theme Tutorial or in my WordPress Plugin Tutorial.
Like always the code follows the video. You can do what ever you want with it under the GNU license.
Code From the Video
ntt_featured_content2.php
<?php
Plugin Name: NTT Featured Content
Plugin URI: http://www.newthinktank.com/wordpress-featured-content-plugin/
Description: It displays a featured content slider on a web page. It was created to show how to create widgets and plugins.
For it to function the Featured Picture must have the same name as the title of the post. That post also must be in the category named Featured.
Version: 2.0
Author URI: http://www.newthinktank.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
<?php
// __FILE__ reference to the plugin file itself
// The second parameter is the function to call when plugin is activated
register_activation_hook( __FILE__, ‘ntt_featured_content_install’ );
function ntt_featured_content_install()
// Verify that the current wordpress version is at least 3
if ( version_compare( get_bloginfo( ‘version’ ), ‘3.0’, ‘<‘ ) )
// Deactivate your plugin
deactivate_plugins( basename( __FILE__ ) );
// Create a variable that stores the number of featured posts
// Set this to 0 by default
$ntt_featured_images = array(
‘num_featured_posts’ => 0
update_option( ‘$ntt_featured_images’, $ntt_featured_images);
<?php
// Called if plugin is deactivated
register_deactivation_hook( __FILE__, ‘ntt_featured_content_uninstall’);
function ntt_featured_content_uninstall()
<?php
// When wordpress checks to see if anything should be added to the editing
// screens my function is called to create the meta box
add_action( ‘add_meta_boxes’, ‘ntt_mbe_image_create’ );
function ntt_mbe_image_create() {
// add_meta_box tells wordpress to display a meta box
// 1st parameter: the div id that surrounds the meta box
// 2nd parameter: the name displayed for your meta box
// 3rd parameter: function that displays your meta box
// 4th parameter: the page to display your meta box on (‘post’, ‘page’)
// 5th parameter: where to display the meta box (‘normal’, ‘side’)
// 6th parameter: priority of meta box (‘high’, ‘low’)
// 7th parameter: arguments to pass to the function above if any
add_meta_box( ‘ntt-image-meta’, ‘Set Image’, ‘ntt_mbe_image_function’, ‘post’, ‘normal’, ‘high’ );
<?php
function ntt_mbe_image_function( $post ) {
// Outputs a message to the user
echo ‘Define your Featured Content Image Here. The dimensions of the image must be 576 × 240! <br /><br />To display the Featured image don\’t forget to mark this post under Featured in your categories.<br /><br />’;
// Check if the current post is in the Featured category
if( in_category(‘Featured’) ){
echo ‘In featured Category<br /><br />’;
} else {
echo ‘Not in featured Category<br /><br />’;
// Retrieve the number of currently Featured posts
$postsFeatured = get_term_by(‘name’, ‘Featured’, ‘category’);
echo “Featured Posts: “, $postsFeatured->count, “<br /><br />”;
// Check if a meta value has already been assigned for the featured image
// get_post_meta returns a value from a custom field
$ntt_mbe_image = get_post_meta( $post->ID, ‘_ntt_mbe_image’, true );
<!– Creating the input field for the featured image
esc_url() sanitizes the image url and encodes HTML entities –>
<br /><br /><input id=”ntt_mbe_image” type=”text” size=”75″ name=”ntt_mbe_image” value=”<?php echo esc_url( $ntt_mbe_image ); ?>” />
<input id=”upload_image_button” type=”button” value=”Media Library Image” class=”button-secondary” /> <br />
<?php
// Get an object that contains all posts in the category Featured
$postsFeatured = get_term_by(‘name’, ‘Featured’, ‘category’);
// if( in_category(‘Featured’) AND ($ntt_posts_featured > 5) ){
// Make sure I only retrieve a maximum of 15 posts
$ntt_posts_featured = (($postsFeatured->count) > 15) ? 15 : ($postsFeatured->count);
// Call the function that will create the featured content
ntt_make_fc_pages($ntt_posts_featured);
<?php
// This function creates all of the featured content code
function ntt_make_fc_pages($ntt_num_fc_pages) {
// Figure out how many featured content pages I should make
// knowing I need a minimum of 5 posts per page
$ntt_fc_pages = floor($ntt_num_fc_pages / 5);
$ntt_fc_info = array();
// Get the url for the plugin
$ntt_plugin_directory = WP_PLUGIN_URL.’/’.str_replace(basename( __FILE__),””,plugin_basename(__FILE__));
// Issue a custom query that outputs the titles for all featured articles
// To issue queries I need to hijack $wp_query. So, I can use it later
// on the page I’m saving it to a temporary variable
$tempWPQuery = $wp_query;
$wp_query = null;
// Create a new WP_Query Object
$wp_query = new WP_Query();
// Get the total number of posts to retreive
$postsFeatured = $ntt_fc_pages * 5;
// Issue a query that returns all posts in the category Featured
$wp_query->query(‘posts_per_page=’.$postsFeatured->count.’&category_name=Featured’);
// Cycle through all of the posts
$ntt_post_num = 1;
while ($wp_query->have_posts()):
$wp_query->the_post();
// Output the title of the post
$ntt_fc_info[$ntt_post_num][0] = get_the_title($post->ID);
// Retrieve the value of the excerpt and trim it to 330 characters
$ntt_long_excerpt = get_the_excerpt();
$ntt_short_excerpt = substr($ntt_long_excerpt, 0, 330);
$ntt_fc_info[$ntt_post_num][1] = $ntt_short_excerpt;
// Output the link url for the post
$ntt_fc_info[$ntt_post_num][2] = get_permalink($post->ID);
// Retrieve the url for the featured image which is saved as a meta value
$ntt_post_id = get_the_ID();
$ntt_featured_image = get_post_meta( $ntt_post_id, ‘_ntt_mbe_image’, true );
$ntt_fc_info[$ntt_post_num][3] = $ntt_featured_image;
$ntt_fc_info[$ntt_post_num][4] = ‘<img src=”‘ . $ntt_featured_image . ‘” alt=”‘ . $ntt_fc_info[$ntt_post_num][0];
$ntt_fc_info[$ntt_post_num][4] .= ‘” title=”‘ . $ntt_fc_info[$ntt_post_num][0] . ‘” class=”ntt_featured_thumb” /></div>’;
$ntt_post_num++;
endwhile;
// Reset wp_query to the default
$wp_query = null;
$wp_query = $temp;
for ($ntt_i = 1; $ntt_i <= $ntt_num_fc_pages; $ntt_i++)
$ntt_start_post = ($ntt_i * 5) – 4;
$ntt_end_post = ($ntt_i * 5);
// Initialize beginning of page with the first title of first post
$ntt_fc_page = ‘<div class=”ntt_text_div”><div class=”ntt_article_title”>’ . $ntt_fc_info[$ntt_start_post][0] . ‘</div><div class=”ntt_horz_rule”></div><div class=”ntt_article_excerpt”>’;
for ($ntt_j = $ntt_start_post; $ntt_j <= $ntt_end_post; $ntt_j++)
$ntt_fc_page .= ‘<p title=”‘;
// Replace spaces in the title with dashes
$ntt_temp_title = str_replace(‘ ‘, ‘-‘, $ntt_fc_info[$ntt_j][0]);
// Make all the characters in the title lowercase
$ntt_temp_title = strtolower($ntt_temp_title);
// Place title into the title attribute for the paragraph
$ntt_fc_page .= $ntt_temp_title . ‘”>’;
// Retrieve the post excerpt
$ntt_fc_page .= $ntt_fc_info[$ntt_j][1] . ‘</p>’;
$ntt_fc_page .= ‘</div><div class=”ntt_read_more”>’;
// Create the read more tag and give it the first post url link
// This will be changed dynamically by JQuery
$ntt_fc_page .= ‘<a href=”‘ . $ntt_fc_info[$ntt_start_post][2] . ‘”>Read More</a>’;
$ntt_fc_page .= ‘</div></div><div class=”ntt_featured_pic”>’;
for ($ntt_j = $ntt_start_post; $ntt_j <= $ntt_end_post; $ntt_j++)
// Get the featured image, link to post and post title
$ntt_fc_page .= ‘<a href=”‘ . $ntt_fc_info[$ntt_j][2] . ‘” class=”ntt_link_to_post” alt=”‘ . $ntt_fc_info[$ntt_j][0] . ‘”><img src=”‘ . $ntt_fc_info[$ntt_j][3] . ‘” alt=”‘ . $ntt_fc_info[$ntt_j][0] . ‘” /></a>’;
$ntt_fc_page .= ‘</div><div class=”ntt_thumb_box”>’;
// Create all of the thumbnails for the FC slider
for ($ntt_j = $ntt_start_post; $ntt_j <= $ntt_end_post; $ntt_j++)
$ntt_fc_page .= ‘<div class=”ntt_thumbnail_frame”>’;
$ntt_fc_page .= $ntt_fc_info[$ntt_j][4];
// Place the left button on the screen
$ntt_fc_page .= ‘</div><div class=”ntt_left_button”><img src=”‘;
// Get the left button image by looking in the plugin directory
$ntt_fc_page .= $ntt_plugin_directory . ‘images/fc_left_arrow.png” alt=”Back” /></div><div class=”ntt_right_button”><img src=”‘;
// Get the right button image by looking in the plugin directory
$ntt_fc_page .= $ntt_plugin_directory . ‘images/fc_right_arrow.png” alt=”Next” /></div>’;
// Store the total number of featured slide pages in a hidden input
$ntt_fc_page .= ‘<input type=”hidden” name=”ntt_total_fc_pages” value=”‘ . $ntt_fc_pages . ‘” class=”ntt_total_fc_pages”>’;
// Get the location of the wordpress url folder
$ntt_wordpress_url = get_bloginfo(‘wpurl’);
// Pass the location of the WordPress url folder to the JS file with a
// hidden input tag
$ntt_fc_page .= ‘<input type=”hidden” name=”ntt_wp_url_dir” value=”‘ . $ntt_wordpress_url . ‘” class=”ntt_wp_url_dir”>’;
// When programming on a localhost you must reference the file directly
$ntt_print_to = ‘/Library/WebServer/Documents/wordpress/wp-content/plugins/NTTFeaturedContent2/js/featured_data’ . $ntt_start_post . ‘.txt’;
/* Use the following if you’re hosting this plugin not on localhost
$ntt_print_to = $ntt_wordpress_url . ‘/wp-content/plugins/NTTFeaturedContent2/js/featured_data’ . $ntt_start_post . ‘.txt’; */
// Open the file I’m going to write to. If it doesn’t exist make it
$ntt_fc_page_to_write = fopen($ntt_print_to, “w”);
// Write the updated info to the file
fwrite($ntt_fc_page_to_write, $ntt_fc_page);
// Close the file after finished with the file
fclose($ntt_fc_page_to_write);
// When the post is saved call my function
add_action( ‘save_post’, ‘ntt_mbe_image_save_meta’ );
function ntt_mbe_image_save_meta( $post_id ) {
//verify the metadata is set
if ( isset( $_POST[‘ntt_mbe_image’] ) ) {
// update_post_meta() updates the value of the image
// esc_url_raw() sanitizes the url but doesn’t encode HTML entities
update_post_meta( $post_id, ‘_ntt_mbe_image’, esc_url_raw( $_POST[‘ntt_mbe_image’] ) );
<?php
// admin_print_scripts-post.php displays the post editor
// This is saying to call the custom function when the post editor is loaded
add_action(‘admin_print_scripts-post.php’, ‘ntt_mbe_image_admin_scripts’); add_action(‘admin_print_scripts-post-new.php’, ‘ntt_mbe_image_admin_scripts’);
function ntt_mbe_image_admin_scripts() {
// wp_enqueue_script is used to embed javascript into a page
// The array contains built in wordpress scripts that the javascript needs // to work
wp_enqueue_script( ‘ntt-image-upload’, plugins_url( ‘/NTTFeaturedContent2/ntt-meta-image.js’ ), array( ‘jquery’,’media-upload’,’thickbox’ ) );
featured_content.js
$(document).ready(function(){
// Define the number of featured content pages
var ntt_num_featured_pages = $(‘.ntt_total_fc_pages’).val();
var ntt_post_content_html1 = ”;
var ntt_post_content_html2 = ”;
var ntt_post_content_html3 = ”;
var ntt_wordpress_url = $(‘.ntt_wp_url_dir’).val();
// Used to check if content is updated
var ntt_content_updated = 0;
// Go get all of the content that is going to be used
get_featured_content(ntt_num_featured_pages);
// Returns the first child thumbnail image location
var first_child_thumb = ($(‘.ntt_thumb_box div img’).length);
// This will be used to track the current featured content
var rotator_index = first_child_thumb;
// This will hold the id for function calls to setInterval
// When I make a new setInterval call it will be used to delete
// the older one
var ntt_set_interval_id = ”;
// Holds the value of the current featured content on screen
// I set it up to hold either the values of 1,2, or 3
// You can see this in use in the function grab_next_feat_content
var featured_content_being_shown = 1;
// Call the function that will setup all of the default styling
ntt_setup_featured_content();
// Changes all of the content in the featured content tool when the next
// arrow is clicked
function grab_next_feat_content()
if (featured_content_being_shown == 1)
if(ntt_num_featured_pages >= 2)
// Copy the featured content stored in another file to the page
$(‘.ntt_featured_content’).html(ntt_post_content_html2);
featured_content_being_shown = 2;
ntt_content_updated = 1;
else if (featured_content_being_shown == 2)
if(ntt_num_featured_pages == 3)
// Copy the featured content stored in another file to the page
$(‘.ntt_featured_content’).html(ntt_post_content_html3);
featured_content_being_shown = 3;
ntt_content_updated = 1;
} else
// Copy the featured content stored in another file to the page
$(‘.ntt_featured_content’).html(ntt_post_content_html1);
featured_content_being_shown = 1;
ntt_content_updated = 1;
else if (featured_content_being_shown == 3)
// Copy the featured content stored in another file to the page
$(‘.ntt_featured_content’).html(ntt_post_content_html1);
featured_content_being_shown = 1;
ntt_content_updated = 1;
if(ntt_content_updated == 1) // Check to see if featured content changed
// Eliminate the previously set setInterval() call
// If this isn’t done you will have multiple timers which isn’t fun
clearInterval(ntt_set_interval_id);
rotator_index = first_child_thumb;
// Call the function that provides the default styling
ntt_setup_featured_content();
} // End if statement that checks if featured content changes
ntt_content_updated = 0;
// Changes all of the content in the featured content tool when the previous
// arrow is clicked
function grab_last_feat_content()
if (featured_content_being_shown == 1)
if(ntt_num_featured_pages == 3)
// Copy the featured content stored in another file to the page
$(‘.ntt_featured_content’).html(ntt_post_content_html3);
featured_content_being_shown = 3;
ntt_content_updated = 1;
} else if (ntt_num_featured_pages == 2)
// Copy the featured content stored in another file to the page
$(‘.ntt_featured_content’).html(ntt_post_content_html2);
featured_content_being_shown = 2;
ntt_content_updated = 1;
else if (featured_content_being_shown == 2)
// Copy the featured content stored in another file to the page
$(‘.ntt_featured_content’).html(ntt_post_content_html1);
featured_content_being_shown = 1;
ntt_content_updated = 1;
else if (featured_content_being_shown == 3)
// Copy the featured content stored in another file to the page
$(‘.ntt_featured_content’).html(ntt_post_content_html2);
featured_content_being_shown = 2;
ntt_content_updated = 1;
if(ntt_content_updated == 1) // Check to see if featured content changed
// Eliminate the previously set setInterval() call
// If this isn’t done you will have multiple timers which isn’t fun
clearInterval(ntt_set_interval_id);
// Set the featured content to the first thumb and everything else
rotator_index = first_child_thumb;
// Call the function that provides the default styling
ntt_setup_featured_content();
} // End if statement that checks if featured content changes
ntt_content_updated = 0;
function ntt_setup_featured_content()
// Make all excerpts invisible
$(‘.ntt_article_excerpt p’).css({opacity: 0.0});
// Show the first excerpt
$(‘.ntt_article_excerpt p:first’).animate({opacity: 1.0});
// Dims the first child thumbnail
// You have to surround the variable with a plus
$(‘.ntt_thumb_box div:nth-child(‘+first_child_thumb+’)’).animate({opacity: 0.4});
$(‘.ntt_thumb_box div:nth-child(‘+first_child_thumb+’)’).addClass(‘selected’);
$(‘.ntt_thumbnail_frame img’).bind(‘click’, change_featured_content);
ntt_set_interval_id = setInterval((function () {
rotate_images();
// arguments.callee returns the function that called the function in
// which it lies. In effect this continues to execute the setInterval
// function over and over
return arguments.callee;
})(), 4000);
// Bind the arrows so that when clicked they grab the new content
$(‘.ntt_right_button img’).bind(‘click’, grab_next_feat_content);
$(‘.ntt_left_button img’).bind(‘click’, grab_last_feat_content);
// If there is only one set of featured content don’t show arrows
// Also remove their click events
if (ntt_num_featured_pages == 1)
$(‘.ntt_right_button img’).css({opacity: 0.0});
$(‘.ntt_left_button img’).css({opacity: 0.0});
$(‘.ntt_right_button img’).unbind(‘click’);
$(‘.ntt_left_button img’).unbind(‘click’);
function rotate_images()
// Grabs the image that lies in the same zero based position as the value
// of rotator_index.
var sibling_img =$(‘.ntt_thumbnail_frame:eq(‘+rotator_index+’) img’);
// Triggers a click event on the image so that the featured content changes
sibling_img.trigger(‘click’);
// Cycles through all of the available featured content available
if (rotator_index <= 0)
// first_child_thumb equals the total number of images available to
// cycle through
rotator_index = first_child_thumb;
}else rotator_index–;
function change_featured_content(e){
e.preventDefault(); // Prevents the link from opening the pict
// Set all thumbs back to defaults
$(‘.ntt_thumb_box div’).removeClass(‘selected’);
$(‘.ntt_thumb_box div img’).removeClass(‘selected’);
$(‘.ntt_thumb_box div’).animate({opacity: 1.0});
$(‘.ntt_thumb_box div img’).animate({opacity: 1.0});
$(this).addClass(‘selected’); // this is the item that was clicked
$(this).parent().addClass(‘selected’);
$(this).animate({opacity: 0.4});
var pict_title = $(this).attr(‘title’);
// Link destination of full size
var pict_fullsize = $(this).attr(‘src’);
// Retrieves the alt for the thumbnail clicked
var alt_thumb_clicked = $(this).attr(‘alt’);
// Retrieve the URL for the anchor that surrounds the featured picture
var url_to_post = $(‘.ntt_link_to_post:[alt=”‘+alt_thumb_clicked+’”]’).attr(“href”);
// Hide all anchor tags if the alt isn’t the same as the featured pic
$(‘.ntt_link_to_post:[alt!=”‘+alt_thumb_clicked+’”]’).hide();
// Show the anchor tag if the alt is the same as the featured pic
$(‘.ntt_link_to_post:[alt=”‘+alt_thumb_clicked+’”]’).show();
// Cut the src tag from the beginning of the featured picture
var photo_preview = pict_fullsize.replace(/.*src=/, ”);
// Change main title above the excerpt
$(‘.ntt_article_title’).html(pict_title);
// Get the url for the post that is stored in the link that surrounds
// the featured image
// var link_to_post = $(‘.ntt_link_to_post’).attr(“href”);
// Change the href for the Read More link
$(‘.ntt_read_more a’).attr(“href”, url_to_post);
// Change the src value of the featured image and set its opacity to 0
$(‘.ntt_featured_pic a img’).attr({
src: photo_preview,
style: ‘opacity:0.0;’
// Increase the opacity of the featured pick from 0 to 100% over a 2
// second period
$(‘.ntt_featured_pic a img’).animate({opacity: 1.0}, 2000);
var pict_name_for_excerpt = pict_title.toLowerCase().replace(‘ ‘, ‘-‘);
// Makes all of the paragraph excerpts disappear
$(‘.ntt_article_excerpt p’).css({opacity: 0.0});
// Turns the opacity up for the paragraph associated with the same title
// as the main picture
$(‘.ntt_article_excerpt p:[title=”‘+pict_name_for_excerpt+’”]’).css({opacity: 1.0});
// Grabs all of the data stored in outside files and saves that information
// to a variable for use when the arrows are clicked on
// ntt_wordpress_url contains the location of the WordPress URL
// ntt_wordpress_url is referenced on line 9 above.
// ntt_wordpress_url received its value buy passing it through a hidden tag
function get_featured_content(ntt_num_content_blocks)
if (ntt_num_content_blocks == 2)
$.get(ntt_wordpress_url + “/wp-content/plugins/NTTFeaturedContent2/js/featured_data1.txt”, function(data){
ntt_post_content_html1 = data;
$.get(ntt_wordpress_url + “/wp-content/plugins/NTTFeaturedContent2/js/featured_data6.txt”, function(data){
ntt_post_content_html2 = data;
} else if (ntt_num_content_blocks == 3)
$.get(ntt_wordpress_url + “/wp-content/plugins/NTTFeaturedContent2/js/featured_data1.txt”, function(data){
ntt_post_content_html1 = data;
$.get(ntt_wordpress_url + “/wp-content/plugins/NTTFeaturedContent2/js/featured_data6.txt”, function(data){
ntt_post_content_html2 = data;
$.get(ntt_wordpress_url + “/wp-content/plugins/NTTFeaturedContent2/js/featured_data11.txt”, function(data){
ntt_post_content_html3 = data;
} else {
$.get(ntt_wordpress_url + “/wp-content/plugins/NTTFeaturedContent2/js/featured_data1.txt”, function(data){
ntt_post_content_html1 = data;
// This will change in upcoming versions
// It sends the browser to the featured image when that image is clicked
// In the future it will open an article, movie, or image gallery
$(‘.ntt_featured_pic img’).click(function(e) {
var pict_location = $(this).attr(“src”);
$(‘.ntt_featured_pic’).html(pict_location);
$(location).attr(‘href’,pict_location);
ntt_fc_style2.css
.ntt_featured_content {
position: relative;
.ntt_text_div {
background-color: #000f2e;
.ntt_article_title {
font: bold 24px/30px Georgia, serif;
text-align: center;
text-shadow: #6b6a6a 1.5px 1.5px 1px;
.ntt_horz_rule {
font-size: 1px;
.ntt_article_excerpt {
font: 12px/17px Georgia, serif;
.ntt_article_excerpt p{
font: 12px/17px Georgia, serif;
.ntt_read_more a{
font: bold 14px/17px Helvetica, sans-serif;
color: #FFF;
text-shadow: #6b6a6a 1px 1px 0px;
text-transform:uppercase;
text-decoration: none;
.ntt_featured_pic a img{
.ntt_thumb_box {
background-color: #000f2e;
.ntt_thumbnail_frame {
margin: 10px 47px 0px 0px;
overflow:hidden;
/* background-image:url(‘./images/fc_thumb_bg.png’); */
.ntt_featured_thumb {
.ntt_left_button {
filter: alpha(opacity=50);
.ntt_right_button {
filter: alpha(opacity=50);
.ntt_left_button img:hover{
opacity: 0.6;
.ntt_right_button img:hover{
opacity: 0.6;
Your email address will not be published.
This content was originally published here.