Tag Archives: Widgets

Announcing! Thesis Theme Tools Skins!

Thesis Theme Tools Skins Coming Soon!
Thesis Theme Tools Skins Design Samples

You might not have known it, but I have been writing skins for others for quite some time. Now I have decided to strike out on my own and offer them directly to you!

Thesis Theme Tools Skins will be launched on June 1, 2010. We will offer fresh new designs, innovative features, unheard-of user customizability, and rock-solid reliability and stability, all for reasonable prices.

Tired of the same old ho-hum skin designs that the others tout? Envious of the snazzy non-Thesis themes available?

Well, just wait until you see our designs! Created by the extremely talented Joel Thompson, our intent is to offer the best designs not only for Thesis, but to be found anywhere!

But it’s not all just a pretty face. As you may expect from Thesis Theme Tools, the leader in advanced customizations, our skins have advanced features that focus on easy customization and maximum flexibility so you can make your skin just like you want it to be.

You will see features such as:

  • Multiple widgetized areas
  • Custom sidebar widgets
  • Built-in slideshows
  • Built-in featured content galleries
  • Admin panels that let you upload and position your header, logo, footer graphics, and other graphics, as well as maintain tab panels, the footer, the copyright line, rotating galleries, and more!
  • And some big surprises never before seen in Thesis skins!

In the coming days, I will be previewing some of our new designs so you can get a taste of what is awaiting you on June 1st!

So buckle your seatbelt! You are in for the ride of your life!

New Article! Tutorial: Rotating Image Gallery for Pages and Sidebars

I have been asked many times how to put your own images into a rotating gallery. Until now the only choice you had was the NextGEN plugin, which has limitations, is complicated to set up, and lacks some important features.

Help is at hand! Enter the Rotating Image Gallery!

The new article, “Tutorial: Rotating Image Gallery for Pages and Sidebars” shows you how to use this versatile and simple method of putting your own images into a gallery.

A zip file with everything you need is available to make it easy for you to try it out for yourself!

The Rotating Image Gallery has these great features:

  • Easy to install and use.
  • Can be placed anywhere there is a hook, and even in a widget.
  • Any number of images of any size can be displayed.
  • Images can be clickable links.
  • Captions are optional, and can have links in them.
  • The Image Gallery can have optional directional arrows and a pause button.
  • Multiple galleries can be shown on the same page.
  • Loops to the beginning after showing the last image, rather than stopping.
  • You have complete control over slide speed, display time, captions, etc of every Image Gallery separately.
  • You can configure fonts, borders, etc in the custom.css file.
  • The JavaScript program is only 14k.
  • Gracefully degrades when JavaScript is turned off. The Image Gallery reverts to a box with scroll bars so the user can still see the images.
  • You can use the Image Gallery right out of the box! Included in the zip file are the images used in this tutorial.

So why not show off all your great photos and give it a whirl?

Tutorial: Rotating Image Gallery for Pages and Sidebars

Many of my clients have asked for a way to put their own images into a rotating gallery. There is no plugin that is entirely suitable for this purpose that I know of. The closest is the NextGEN gallery plugin, but it has only rigidly defined ways to use it, is complicated to set up, and lacks some important features.

What you need is a simple, easy to use, flexible image gallery that plays nice with Thesis.

This tutorial shows you how to implement a Rotating Image Gallery that can be placed anywhere on the Thesis page that there is a hook — and even in a widget. Shown above and in the sidebar are two instances of the Image Gallery. Note that each has different speeds, and that there are arrows and a pause control on the widget but not in the larger gallery.

The Rotating Image Gallery has these great features:

  • Easy to install and use.
  • Can be placed anywhere there is a hook, and even in a widget.
  • Any number of images of any size can be displayed.
  • Images can be clickable links.
  • Captions are optional, and can have links in them.
  • The Image Gallery can have optional directional arrows and a pause button.
  • Multiple galleries can be shown on the same page.
  • Loops to the beginning after showing the last image, rather than stopping.
  • You have complete control over slide speed, display time, captions, etc of every Image Gallery separately.
  • You can configure fonts, borders, etc in the custom.css file.
  • The JavaScript program is only 14k.
  • Gracefully degrades when JavaScript is turned off. The Image Gallery reverts to a box with scroll bars so the user can still see the images.
  • You can use the Image Gallery right out of the box! Included in the zip file are the images used in this tutorial.

The Rotating Image Gallery was developed from an idea at Catch My Fame. It is released under the Creative Commons Attribution-Share Alike 3.0 license, which means you are free to use and modify the code as long as you share it with others and attribute it to me.

It is mandatory that you download the zip file for this tutorial! It has everything you need — all files, folders and images — in a single zip file. Setting up the Rotating Image Gallery without downloading the zip file is not described in this tutorial! You can download it by clicking here.

Navigation in the Tutorial

This description of the Rotating Image Gallery is in 5 parts. If you want to skip to a particular section, just click on the links below:

How the Rotating Image Gallery works

There are four files used in the Rotating Image Gallery. Each has a full code listing below so you can see how it works. These files are:

  • The rotatingimages.js file, which is the JavaScript program that powers the Image Gallery.
  • for-custom_functions.php contains the functions that are put into the custom_functions.php file.
  • The for-custom.css file has two selectors that are placed in the custom.css file.
  • for-widget.php has only one line of code, which is put into a text widget if you are using the widget version of the Image Gallery.

The rotatingimages.js file

This program actually runs the Rotating Image Gallery. All the other files are necessary, but serve to support it. I modified it so that it would work with Thesis and the Image Gallery.

/*
* Rotating Image Gallery
* @author admin@catchmyfame.com - http://www.catchmyfame.com
* @version 1.2.2 - August 31, 2009
* @copyright (c) 2009 admin@catchmyfame.com (www.catchmyfame.com)
* @license Creative Commons Attribution-Share Alike 3.0
* @http://creativecommons.org/licenses/by-sa/3.0/
* @Modified by Mike Nichols - December 20, 2009
*/

(function($){
$.fn.extend({
rotatingImages: function(options)
{
var defaults =
{
transitionSpeed : 1500,
displayTime : 6000,
textholderHeight : .2,
displayProgressBar : 0,
displayThumbnails: 0,
displayThumbnailNumbers: 0,
displayThumbnailBackground: 0,
thumbnailWidth: '20px',
thumbnailHeight: '20px',
thumbnailFontSize: '.7em'
};
var options = $.extend(defaults, options);

return this.each(function() {
var randID = Math.round(Math.random()*100000000);
var o=options;
var obj = $(this);
var curr = 1;

var numImages = $('img', obj).length; // Number of images
var imgHeight = $('img:first', obj).height();
var imgWidth = $('img:first', obj).width();
var autopilot = 1;

$('p', obj).hide(); // Hide any text paragraphs in the rotating image gallery
$(obj).width(imgWidth).height(imgHeight);

// Build progress bar
if(o.displayProgressBar)
{
$(obj).append('<div id="progress'+randID+'" style="position:absolute;bottom:0;background:#bbb;left:'+$(obj).css('paddingLeft')+'"></div>');
$('#progress'+randID).width(imgWidth).height(5).css('opacity','.5');
}

// Move last image and stick it on the front
$(obj).css({'overflow':'hidden','position':'relative'});
$('li:last', obj).prependTo($('ul', obj));
$('ul', obj).css('left',-imgWidth+'px');
$('ul',obj).width(9999);

$('ul',obj).css({'list-style':'none','margin':'0','padding':'0','position':'relative'});
$('li',obj).css({'display':'inline','float':'left'});

// Build textholder div thats as wide as the rotating image gallery and 20%-25% of the height
$(obj).append('<div id="textholder'+randID+'" class="textholder" style="position:absolute;bottom:0px;margin-bottom:'+-imgHeight*o.textholderHeight+'px;left:'+$(obj).css('paddingLeft')+'"></div>');
var correctTHWidth = parseInt($('#textholder'+randID).css('paddingTop'));
var correctTHHeight = parseInt($('#textholder'+randID).css('paddingRight'));
$('#textholder'+randID).width(imgWidth-(correctTHWidth * 2)).height((imgHeight*o.textholderHeight)-(correctTHHeight * 2)).css({'backgroundColor':'#FFF','opacity':'0.5'});
showtext($('li:eq(1) p', obj).html());

// Prev/next button(img)
html = '<div id="btn_rt'+randID+'" style="position:absolute;right:0;top:'+((imgHeight/2)-15)+'px"><a href="javascript:void(0);"><img style="border:none;margin-right:2px" src="'+o.arrowRight+'" /></a></div>';
html += '<div id="btn_lt'+randID+'" style="position:absolute;left:0;top:'+((imgHeight/2)-15)+'px"><a href="javascript:void(0);"><img style="border:none;margin-left:2px" src="'+o.arrowLeft+'" /></a></div>';
$(obj).append(html);

// Pause/play button(img)
html = '<a href="javascript:void(0);"><img id="pause_btn'+randID+'" src="'+o.pauseButton+'" style="position:absolute;top:3px;right:3px;border:none" alt="Pause" /></a>';
html += '<a href="javascript:void(0);"><img id="play_btn'+randID+'" src="'+o.playButton+'" style="position:absolute;top:3px;right:3px;border:none;display:none;" alt="Play" /></a>';
$(obj).append(html);
$('#pause_btn'+randID).css('opacity','.5').hover(function(){$(this).animate({opacity:'1'},250)},function(){$(this).animate({opacity:'.5'},250)});
$('#pause_btn'+randID).click(function(){
autopilot = 0;
$('#progress'+randID).stop().fadeOut();
clearTimeout(clearInt);
$('#pause_btn'+randID).fadeOut(250);
$('#play_btn'+randID).fadeIn(250);
showminmax();
});
$('#play_btn'+randID).css('opacity','.5').hover(function(){$(this).animate({opacity:'1'},250)},function(){$(this).animate({opacity:'.5'},250)});
$('#play_btn'+randID).click(function(){
autopilot = 1;
anim('next');
$('#play_btn'+randID).hide();
clearInt=setInterval(function(){anim('next');},o.displayTime+o.transitionSpeed);
setTimeout(function(){$('#pause_btn'+randID).show();$('#progress'+randID).fadeIn().width(imgWidth).height(5);},o.transitionSpeed);
});

// Left and right arrow image button actions
$('#btn_rt'+randID).css('opacity','.75').click(function(){
autopilot = 0;
$('#progress'+randID).stop().fadeOut();
anim('next');
setTimeout(function(){$('#play_btn'+randID).fadeIn(250);},o.transitionSpeed);
clearTimeout(clearInt);
}).hover(function(){$(this).animate({opacity:'1'},250)},function(){$(this).animate({opacity:'.75'},250)});
$('#btn_lt'+randID).css('opacity','.75').click(function(){
autopilot = 0;
$('#progress'+randID).stop().fadeOut();
anim('prev');
setTimeout(function(){$('#play_btn'+randID).fadeIn(250);},o.transitionSpeed);
clearTimeout(clearInt);
}).hover(function(){$(this).animate({opacity:'1'},250)},function(){$(this).animate({opacity:'.75'},250)});

if(o.displayThumbnails)
{
// Build thumbnail viewer and thumbnail divs
$(obj).after('<div id="thumbs'+randID+'" style="position:relative;overflow:auto;text-align:left;padding-top:5px;"></div>');
$('#thumbs'+randID).width(imgWidth);
for(i=0;i<=numImages-1;i++)
{
thumb = $('img:eq('+(i+1)+')', obj).attr('src');
$('#thumbs'+randID).append('<div class="thumb" id="thumb'+randID+'_'+(i+1)+'" style="cursor:pointer;background-image:url('+thumb+');display:inline;float:left;width:'+o.thumbnailWidth+';height:'+o.thumbnailHeight+';line-height:'+o.thumbnailHeight+';padding:0;overflow:hidden;text-align:center;border:2px solid #ccc;margin-right:4px;font-size:'+o.thumbnailFontSize+';font-family:Arial;color:#000;text-shadow:0 0 3px #fff">'+(i+1)+'</div>');
if(i==0) $('#thumb'+randID+'_1').css({'border-color':'#ff0000'});
}
// Next two lines are a special case to handle the first list element which was originally the last
thumb = $('img:first', obj).attr('src');
$('#thumb'+randID+'_'+numImages).css({'background-image':'url('+thumb+')'});
$('#thumbs'+randID+' div.thumb:not(:first)').css({'opacity':'.65'}); // makes all thumbs 65% opaque except the first one
$('#thumbs'+randID+' div.thumb').hover(function(){$(this).animate({'opacity':.99},150)},function(){if(curr!=this.id.split('_')[1]) $(this).animate({'opacity':.65},250)}); // add hover to thumbs

// Assign click handler for the thumbnails. Normally the format $('.thumb') would work but since it's outside of our object (obj) it would get called multiple times
$('#thumbs'+randID+' div').bind('click', thumbclick); // We use bind instead of just plain click so that we can repeatedly remove and reattach the handler

if(!o.displayThumbnailNumbers) $('#thumbs'+randID+' div').text('');
if(!o.displayThumbnailBackground) $('#thumbs'+randID+' div').css({'background-image':'none'});
}
function thumbclick(event)
{
target_num = this.id.split('_'); // we want target_num[1]
if(curr != target_num[1])
{
$('#thumb'+randID+'_'+curr).css({'border-color':'#ccc'});
$('#progress'+randID).stop().fadeOut();
clearTimeout(clearInt);
//alert(event.data.src+' '+this.id+' '+target_num[1]+' '+curr);
$('#thumbs'+randID+' div').css({'cursor':'default'}).unbind('click'); // Unbind the thumbnail click event until the transition has ended
autopilot = 0;
setTimeout(function(){$('#play_btn'+randID).fadeIn(250);},o.transitionSpeed);
}
if(target_num[1] > curr)
{
diff = target_num[1] - curr;
anim('next',diff);
}
if(target_num[1] < curr)
{
diff = curr - target_num[1];
anim('prev', diff);
}
}

function showtext(t)
{
// the text will always be the text of the second list item (if it exists)
if(t != null)
{
$('#textholder'+randID).html(t).animate({marginBottom:'0px'},500); // Raise textholder
showminmax();
}
}
function showminmax()
{
if(!autopilot)
{
html = '<img style="position:absolute;top:2px;right:18px;display:none;cursor:pointer" src="'+o.arrowDown+'" title="Minimize" alt="minimize" id="min" /><img style="position:absolute;top:2px;right:18px;display:none;cursor:pointer" src="'+o.arrowUp+'" title="Maximize" alt="maximize" id="max" />';
html += '<img style="position:absolute;top:2px;right:6px;display:none;cursor:pointer" src="'+o.closeButton+'" title="Close" alt="close" id="close" />';
$('#textholder'+randID).append(html);
$('#min').fadeIn(250).click(function(){$('#textholder'+randID).animate({marginBottom:(-imgHeight*o.textholderHeight)-(correctTHHeight * 2)+24+'px'},500,function(){$("#min,#max").toggle();});});
$('#max').click(function(){$('#textholder'+randID).animate({marginBottom:'0px'},500,function(){$("#min,#max").toggle();});});
$('#close').fadeIn(250).click(function(){$('#textholder'+randID).animate({marginBottom:(-imgHeight*o.textholderHeight)-(correctTHHeight * 2)+'px'},500);});
}
}
function borderpatrol(elem)
{
$('#thumbs'+randID+' div').css({'border-color':'#ccc'}).animate({opacity: 0.65},500);
setTimeout(function(){elem.css({'border-color':'#ff0000'}).animate({'opacity': .99},500);},o.transitionSpeed);
}
function anim(direction,dist)
{
// Fade left/right arrows out when transitioning
$('#btn_rt'+randID).fadeOut(500);
$('#btn_lt'+randID).fadeOut(500);

// animate textholder out of frame
$('#textholder'+randID).animate({marginBottom:(-imgHeight*o.textholderHeight)-(correctTHHeight * 2)+'px'},500);

//?? Fade out play/pause?
$('#pause_btn'+randID).fadeOut(250);
$('#play_btn'+randID).fadeOut(250);

if(direction == "next")
{
if(curr==numImages) curr=0;
if(dist>1)
{
borderpatrol($('#thumb'+randID+'_'+(curr+dist)));
$('li:lt(2)', obj).clone().insertAfter($('li:last', obj));
$('ul', obj).animate({left:-imgWidth*(dist+1)},o.transitionSpeed,function(){
$('li:lt(2)', obj).remove();
for(j=1;j<=dist-2;j++)
{
$('li:first', obj).clone().insertAfter($('li:last', obj));
$('li:first', obj).remove();
}
$('#btn_rt'+randID).fadeIn(500);
$('#btn_lt'+randID).fadeIn(500);
$('#play_btn'+randID).fadeIn(250);
showtext($('li:eq(1) p', obj).html());
$(this).css({'left':-imgWidth});
curr = curr+dist;
$('#thumbs'+randID+' div').bind('click', thumbclick).css({'cursor':'pointer'});
});
}
else
{
borderpatrol($('#thumb'+randID+'_'+(curr+1)));
$('#thumbs'+randID+' div').css({'cursor':'default'}).unbind('click'); // Unbind the thumbnail click event until the transition has ended
// Copy leftmost (first) li and insert it after the last li
$('li:first', obj).clone().insertAfter($('li:last', obj));
// Update width and left position of ul and animate ul to the left
$('ul', obj)
.animate({left:-imgWidth*2},o.transitionSpeed,function(){
$('li:first', obj).remove();
$('ul', obj).css('left',-imgWidth+'px');
$('#btn_rt'+randID).fadeIn(500);
$('#btn_lt'+randID).fadeIn(500);
if(autopilot) $('#pause_btn'+randID).fadeIn(250);
showtext($('li:eq(1) p', obj).html());
if(autopilot)
{
$('#progress'+randID).width(imgWidth).height(5);
$('#progress'+randID).animate({'width':0},o.displayTime,function(){
$('#pause_btn'+randID).fadeOut(50);
setTimeout(function(){$('#pause_btn'+randID).fadeIn(250)},o.transitionSpeed)
});
}
curr=curr+1;
$('#thumbs'+randID+' div').bind('click', thumbclick).css({'cursor':'pointer'});
});
}
}
if(direction == "prev")
{
if(dist>1)
{
borderpatrol($('#thumb'+randID+'_'+(curr-dist)));
$('li:gt('+(numImages-(dist+1))+')', obj).clone().insertBefore($('li:first', obj));
$('ul', obj).css({'left':(-imgWidth*(dist+1))}).animate({left:-imgWidth},o.transitionSpeed,function(){
$('li:gt('+(numImages-1)+')', obj).remove();
$('#btn_rt'+randID).fadeIn(500);
$('#btn_lt'+randID).fadeIn(500);
$('#play_btn'+randID).fadeIn(250);
showtext($('li:eq(1) p', obj).html());
curr = curr - dist;
$('#thumbs'+randID+' div').bind('click', thumbclick).css({'cursor':'pointer'});
});
}
else
{
borderpatrol($('#thumb'+randID+'_'+(curr-1)));
$('#thumbs'+randID+' div').css({'cursor':'default'}).unbind('click'); // Unbind the thumbnail click event until the transition has ended
// Copy rightmost (last) li and insert it after the first li
$('li:last', obj).clone().insertBefore($('li:first', obj));
// Update width and left position of ul and animate ul to the right
$('ul', obj)
.css('left',-imgWidth*2+'px')
.animate({left:-imgWidth},o.transitionSpeed,function(){
$('li:last', obj).remove();
$('#btn_rt'+randID).fadeIn(500);
$('#btn_lt'+randID).fadeIn(500);
if(autopilot) $('#pause_btn'+randID).fadeIn(250);
showtext($('li:eq(1) p', obj).html());
curr=curr-1;
if(curr==0) curr=numImages;
$('#thumbs'+randID+' div').bind('click', thumbclick).css({'cursor':'pointer'});
});
}
}
}

var clearInt = setInterval(function(){anim('next');},o.displayTime+o.transitionSpeed);
$('#progress'+randID).animate({'width':0},o.displayTime+o.transitionSpeed,function(){
$('#pause_btn'+randID).fadeOut(100);
setTimeout(function(){$('#pause_btn'+randID).fadeIn(250)},o.transitionSpeed)
});
});
}
});
})(jQuery);

The for-custom_functions.php file

This file contains the functions necessary to load the JavaScript program and configure the images. They are placed in the custom_functions.php file.

/*================================================*/
/* ROTATING IMAGES GALLERY */
/* Version 1.0 */
/* Written by Mike Nichols December 20, 2009 */
/* Website: http://thesisthemetools.com/ */
/* Copyright (c) 2009 by Michael L Nichols */
/* License: Creative Commons Share-Alike 3.0 */
/* http://creativecommons.org/licenses/by-sa/3.0/ */
/*================================================*/

/* ------------------------------------ */
/* Call JavaScript and JQuery in footer */
/* and configure the image galleries */
/* ------------------------------------ */
function rotating_images_foot() {
?>
<!-- call JQuery and JavaScript -->
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>

<script type="text/javascript" src="<?php bloginfo('template_url') ?>/custom/rotating_images/rotatingimages.js"></script>

<!-- Configure rotating gallery -->
<script type="text/javascript">

<!-- Configure rotating gallery for a widget begin -->
<!-- You can delete this if not using a widget -->
$(function(){
$('#image_gallery_widget').rotatingImages({
//time in milliseconds to transition between 2 images - default 1500
transitionSpeed : 2000,
//time in milliseconds to display each image - default 6000
displayTime : 10000,
//height of the caption. Fraction of height of images - default .2
textholderHeight : .14,
//display progress bar 0=no 1=yes
displayProgressBar : 0,
//URLs of the arrows and buttons
arrowRight: '<?php bloginfo('template_url') ?>/custom/rotating_images/arrows/rt.png',
arrowLeft: '<?php bloginfo('template_url') ?>/custom/rotating_images/arrows/lt.png',
pauseButton: '<?php bloginfo('template_url') ?>/custom/rotating_images/arrows/pause.png',
playButton: '<?php bloginfo('template_url') ?>/custom/rotating_images/arrows/play.png',
//do not change the following settings!
arrowUp: '<?php bloginfo('template_url') ?>/custom/rotating_images/arrows/up-clear.png',
arrowDown: '<?php bloginfo('template_url') ?>/custom/rotating_images/arrows/down-clear.png',
closeButton: '<?php bloginfo('template_url') ?>/custom/rotating_images/arrows/close-clear.png'
});
});
<!-- Configure rotating gallery for a widget end -->

<!-- Configure rotating gallery for a page or post begin -->
<!-- You can delete this if not using for a page or post -->
$(function(){
$('#image_gallery_page').rotatingImages({
//time in milliseconds to transition between 2 images - default 1500
transitionSpeed : 1000,
//time in milliseconds to display each image - default 6000
displayTime : 5000,
//height of the caption. Fraction of height of images - default .2
textholderHeight : .1,
//display progress bar 0=no 1=yes
displayProgressBar : 0,
//URLs of the arrows and buttons
arrowRight: '<?php bloginfo('template_url') ?>/custom/rotating_images/arrows/rt-clear.png',
arrowLeft: '<?php bloginfo('template_url') ?>/custom/rotating_images/arrows/lt-clear.png',
pauseButton: '<?php bloginfo('template_url') ?>/custom/rotating_images/arrows/pause-clear.png',
playButton: '<?php bloginfo('template_url') ?>/custom/rotating_images/arrows/play-clear.png',
//do not change the following settings!
arrowUp: '<?php bloginfo('template_url') ?>/custom/rotating_images/arrows/up-clear.png',
arrowDown: '<?php bloginfo('template_url') ?>/custom/rotating_images/arrows/down-clear.png',
closeButton: '<?php bloginfo('template_url') ?>/custom/rotating_images/arrows/close-clear.png'
});
});
<!-- Configure rotating gallery for a page or post end -->

</script>
<?php
}
add_action('thesis_hook_after_html','rotating_images_foot');

/* ------------------------------------------------ */
/* SET UP ROTATING IMAGE GALLERY FOR A PAGE OR POST */
/* ------------------------------------------------ */
function image_gallery_page_setup() {
?>
<div id="image_gallery_page">
<ul>

<!-- IMAGE SETUP FORMAT
<li>
<img alt="ALT-TITLE" src="<?php bloginfo(template_url)?>/custom/rotating_images/gallery/IMAGE-NAME" width="WIDTH" height="HEIGHT" />
<p>TEXT-IN-CAPTION (optional - delete this line if no description)</p>
</li>
-->

<li>
<img alt="bluebird in the snow"
src="<?php bloginfo(template_url)?>/custom/rotating_images/gallery/bluebird-in-snow.jpg"
width="500" height="353" />
<p>A bluebird in the snow</p>
</li>

<li>
<img alt="frosty leaves" src="<?php bloginfo(template_url)?>/custom/rotating_images/gallery/frosty-leaves.jpg" width="500" height="353" />
<p>Frosty leaves with red berries</p>
</li>

<li>
<a href="http://anxietypanichealth.com/"><img alt="frosty wood" src="<?php bloginfo(template_url)?>/custom/rotating_images/gallery/frosty-wood.jpg" width="500" height="353" /></a>
<p>This image is clickable. Try it!</p>
</li>

<li>
<img alt="lake with reflections" src="<?php bloginfo(template_url)?>/custom/rotating_images/gallery/reflected-trees.jpg" width="500" height="353" />
<p>A lake with snowy trees reflected in the water</p>
</li>

<li>
<img alt="surrealist snow" src="<?php bloginfo(template_url)?>/custom/rotating_images/gallery/surrealist-snow.jpg" width="500" height="353" />
<p>An example of a clickable link in a caption is <a href="http://anxietypanichealth.com/">my other blog</a>.</p>
</li>
</ul>
</div>
<?php
}
/*ADD THIS FUNCTION TO ANY HOOK WHERE YOU WANT IT TO APPEAR */
add_action ('thesis_hook_before_post','image_gallery_page_setup');

/* ------------------------------------------ */
/* SET UP ROTATING IMAGE GALLERY FOR A WIDGET */
/* ------------------------------------------ */
function image_gallery_widget_setup() {
?>
<div id="image_gallery_widget">
<ul>

<!-- IMAGE SETUP FORMAT
<li>
<img alt="ALT-TITLE" src="<?php bloginfo(template_url)?>/custom/rotating_images/gallery/IMAGE-NAME" width="WIDTH" height="HEIGHT" />
<p>TEXT-IN-CAPTION (optional - delete this line if no description)</p>
</li>
-->

<li>
<img alt="beautiful sunset" src="<?php bloginfo(template_url)?>/custom/rotating_images/gallery/lake.jpg" width="220" height="138" />
<p>A beautiful sunset over a lake</p>
</li>

<li>
<img alt="ripening cherries" src="<?php bloginfo(template_url)?>/custom/rotating_images/gallery/cherries.jpg" width="220" height="138" />
<p>Ripening cherries</p>
</li>

<li>
<a href="http://anxietypanichealth.com/"><img alt="yellow flowers" src="<?php bloginfo(template_url)?>/custom/rotating_images/gallery/flowers.jpg" width="220" height="138" /></a>
<p>This image is clickable. Try it!</p>
</li>

<li>
<img alt="butterfly" src="<?php bloginfo(template_url)?>/custom/rotating_images/gallery/butterfly.jpg" width="220" height="138" />
<p>Butterfly on a white flower</p>
</li>

<li>
<img alt="lake with clouds" src="<?php bloginfo(template_url)?>/custom/rotating_images/gallery/lake-w-clouds.jpg" width="220" height="138" />
<p>An example of a URL in the message is <a href="http://anxietypanichealth.com/">my other blog</a>.</p>
</li>
</ul>
</div>
<?php
}

The for-custom.css file

This file has only two selectors: one for the page/post version of the Rotating Image Gallery, and one for the widget version. These selectors are put into the custom.css file.

/*=============================================== */
/* ROTATING IMAGES GALLERY */
/* Version 1.0 */
/* Written by Mike Nichols December 20, 2009 */
/* Website: http://thesisthemetools.com/ */
/* Copyright (c) 2009 by Michael L Nichols */
/* License: Creative Commons Share-Alike 3.0 */
/* http://creativecommons.org/licenses/by-sa/3.0/ */
/*=============================================== */
/* image gallery in a widget */
#image_gallery_widget {
/* width and height must be the same size as images */
width:220px;
height:138px;
/* border if desired */
border:2px solid #999;
/* font size */
font-size: .7em;
/* font family if desired */
font-family: Georgia, serif;
/* bold or not */
font-weight: bold;
/* do not change these! */
overflow:scroll;
margin: 0;
padding: 0;
}

/* image gallery in a page or post */
#image_gallery_page {
/* width and height must be the same size as images */
width:500px;
height:353px;
/* border if desired */
border:4px double #000000;
/* font size */
font-size: 1.3em;
/* font family if desired */
/*font-family: Verdana, sans-serif;*/
/* bold or not */
font-weight: bold;
/* do not change these! */
overflow:scroll;
margin: 0;
padding: 0;
}

The for-widget.php file

This file is needed only if you are using the widget version of the Rotating Image Gallery. It contains one line of code, which is inserted into a text widget.

<?php image_gallery_widget_setup() ?>

Installing the Rotating Image Gallery

Installing the Rotating Image Gallery is very simple, and has only 3 steps, each of which is covered in detail. Following is an overview of the steps to install it:

  • Copy the rotating_images folder in the zip file to your /custom folder.
  • Insert the functions found in the for-custom_functions.php file into your custom_functions.php file.
  • Insert the selectors found in the for-custom.css file into your custom.css file.

If you are using the Rotating Image Gallery in a widget there are two additional steps, described in the next section.

STEP 1. Copy the rotating_images folder into your /custom folder

The “rotating_images” folder has these items in it:

  • The rotatingimage.js file, which is the JavaScript program that powers the Image Gallery
  • The /arrows folder containing all the buttons and arrows used.
  • A /gallery folder for your images. It already has all the images used this tutorial in it. Feel free to delete them and replace them with your own images.

All you have to do is to copy the entire /rotating_images folder to your /custom folder. Do not copy individual files!

Really, that’s all there is to this step!

STEP 2. Put the functions in for-custom_functions.php into the custom_functions.php file

The for-custom_functions.php file has three functions in it. You can put these functions anywhere you want in the custom_functions.php file, but I suggest putting them at the end. Here’s some information you need about copying them:
1. You must copy the rotating_images_foot function to custom_functions.php! It is used for both versions of the Image Gallery.
2. Copy the image_gallery_page_setup function if you will be using the Rotating Image Gallery for a post or a page.
3. Copy the image_gallery_widget_setup function if you will be using the Image Gallery in a widget.

STEP 3. Put the selectors in the for-custom.css file into custom.css

The for-custom.css file has two selectors. You can put these anywhere in the custom.css file, but I suggest putting them at the end. You do not have to copy both selectors unless you are using both the page/post version of the Image Gallery and the widget version:
1. Copy the image_gallery_page selector if you are using the post/page version.
2. Copy the image_gallery_widget selector if you are using the widget version.
3. It will not hurt anything if you copy both selectors to your custom.css file.

Installing the Rotating Image Gallery for a Widget

If you will be using the Rotating Image Gallery in a widget, there are two additional steps you must take:

  • Upload, install and set up a plugin that allows widgets to execute PHP code
  • Install a text widget and put the supplied code into it

STEP 1. Install a plugin that allows widgets to execute PHP code

Widgets do not execute PHP code without a little help from a plugin. I recommend the Exec-PHP plugin, but there are a few others that do the same thing. All you have to do is upload and activate it. The settings have only one check box, which must be checked.

STEP 2. Put the provided code into a text widget

Go to the Widgets panel in your WordPress dashboard. Put a text widget in the sidebar and location you want the Rotating Image Gallery to appear. Insert the one line of code provided in the file for-widget.php into the text widget and save it. The code is listed below for your convenience:

<?php image_gallery_widget_setup() ?>

Setting up the Rotating Image Gallery

Setting up your Image Gallery is not hard, but it does take a little care. There are three types of settings:

  • The properties for display time, speed, etc
  • The URL, size, etc of your images
  • The size of your image box, font choices, etc in the custom.css file

All these steps will be covered in detail in the following sections. Incidentally, the settings in the code listed above and the files in the zip file are the ones used in this tutorial.

STEP 1. Setting the properties for display time, speed, etc

This setting will probably only have to be done once unless you like to experiment. Note that each Image Gallery on a page can have different settings — the widget and the large Gallery at the top of this article have their own individual settings. Here are the steps to take:
1. Find the rotating_images_foot function in the provided code for the custom_functions.php file.
2. Find the “Configure rotating gallery…” comment for either the widget version or the page/post version.
3. Check and/or change the property settings in the section. Each property is commented, and there’s an explanation of each below the following code example. Here is what the property settings for the widget look like — the ones for the page/post are identical:

//time in milliseconds to transition between 2 images - default 1500
transitionSpeed : 2000,
//time in milliseconds to display each image - default 6000
displayTime : 10000,
//height of the caption. Fraction of height of images - default .2
textholderHeight : .14,
//display progress bar 0=no 1=yes
displayProgressBar : 0,

transitionSpeed is how fast the images move when changing from one to the next. If you set this too fast, images with a large file size may hesitate or stutter.
displayTime is how long the image is displayed. Setting it to a larger number makes the image stay visible longer.
textholderHeight determines how tall the caption box is. The number is a fraction of the height of the image. You may have to experiment with this number, especially if you have long captions that take two or more lines.
displayProgressBar You can choose to display a progress bar at the bottom of the image that shows how much longer the image has to display. It starts out all the way across the bottom and gets shorter as the view time decreases.

4. Do not change the section for the URLs unless you want to remove the arrows and pause buttons. That subject is covered in the following section.

How to remove the arrows, pause and other buttons in the properties section

The forward and backward buttons, pause button, and the little button and arrows that come up when the Image Gallery is paused can be removed so that they cannot be used. All you have to do is add “-clear” to the name of the image URL in the rotating_images_foot function in the custom_functions.php file. Note that the large Image Gallery at the top of the page has no arrows, pause button or other buttons and arrows, while the widget has all of them.

For example, this is what the arrowLeft property looks like when the left arrow appears:

arrowLeft: '<?php bloginfo('template_url') ?>/custom/rotating_images/arrows/lt.png',

To hide the left arrow, add “-clear” to the end of the file name (not the file extension!) in the property like this:

arrowLeft: '<?php bloginfo('template_url') ?>/custom/rotating_images/arrows/lt-clear.png',

STEP 2. Setting the URL, size, etc of your images

This setting is the same for both the page/post version of the Rotating Image Gallery and the widget version. Making the settings is not hard once you get the hang of it, though it may look complicated at first glance.

Here’s how to do it:
1. Select the right function to work on. If setting up a page/post Image Gallery, look for the image_gallery_page_setup function in the “SET UP ROTATING IMAGE GALLERY FOR A PAGE OR POST” section of the code provided for the custom_functions.php file. If setting up the widget version, look for the image_gallery_widget_setup function under the “SET UP ROTATING IMAGE GALLERY FOR A WIDGET” section.
2. There is an “IMAGE SETUP FORMAT” comment at the beginning of both versions. It is repeated here with comments right below it:

<!-- IMAGE SETUP FORMAT
<li>
<img alt="ALT-TITLE" src="<?php bloginfo(template_url)?>/custom/rotating_images/gallery/IMAGE-NAME" width="WIDTH" height="HEIGHT" />
<p>TEXT-IN-CAPTION (optional - delete this line if no description)</p>
</li>
-->

ALT-TITLE is a short description of the image. It is optional but highly recommended that you take the time to enter this information.
IMAGE-NAME is the file name of the image, for example “pickles.jpg”. Do not change any other part of the URL! It is set up so that it will find your images if you have put them in the /rotating_images/gallery folder (see below).
WIDTH and HEIGHT must be entered for each image. It seems redundant, but that’s the way it is!
TEXT-IN-CAPTION is the text shown in the caption under the image. If you make the caption long enough, it will wrap to two or more lines. If this happens, you will have to adjust the textholderHeight property, as described above.

And here is a fully set up image for the bluebird image shown in the larger Image Gallery at the top of the screen:

<li>
<img alt="bluebird in the snow"
src="<?php bloginfo(template_url)?>/custom/rotating_images/gallery/bluebird-in-snow.jpg"
width="500" height="353" />
<p>A bluebird in the snow</p>
</li>

How to get rid of the caption entirely

All you have to do is to delete the whole line with the paragraph tags in the item setup. If you were eliminating the caption in the example above, you would delete this line:

<p>A bluebird in the snow</p>

How to set up a clickable image

To get a clickable image, wrap the image URL in an HTML anchor tag. Using the “image setup format” example above, here’s what to do:

<li>
<a href="LINK-URL"><img alt="ALT-TITLE" src="<?php bloginfo(template_url)?>/custom/rotating_images/gallery/IMAGE-NAME" width="WIDTH" height="HEIGHT" /></a>
<p>TEXT-IN-CAPTION</p>
</li>

The only additional task is to fill in the “LINK-URL” which must be the full URL of the site you are linking to. Below is an example of the “Frosty Wood” image (the one of a piece of wood) in the large Image Gallery shown at the top of the screen:

<li>
<a href="http://anxietypanichealth.com/"><img alt="frosty wood" src="<?php bloginfo(template_url)?>/custom/rotating_images/gallery/frosty-wood.jpg" width="500" height="353" /></a>
<p>This image is clickable. Try it!</p>
</li>

How to set up a clickable link in the caption

All you have to do to get a link in your caption is to wrap some words in a standard HTML anchor tag. Once again, using the “image setup format” example, here is what you have to fill in:

<li>
<img alt="ALT-TITLE" src="<?php bloginfo(template_url)?>/custom/rotating_images/gallery/surrealist-IMAGE-NAME" width="WIDTH" height="HEIGHT" />
<p>TEXT-IN-CAPTION <a href="LINK-URL">LINK-DESCRIPTION</a></p>
</li>

LINK-URL is the URL of the site you want to link to. You must put in the full URL of the site, or you will get a 404 page!
LINK-DESCRIPTION are the words in the caption that will be linked and that the visitor will click on.

Here is an example of a completely set up image with a link in the caption. It is for the “Surrealist Snow” image shown in the large Image Gallery box at the top of this article:

<li>
<img alt="surrealist snow" src="<?php bloginfo(template_url)?>/custom/rotating_images/gallery/surrealist-snow.jpg" width="500" height="353" />
<p>An example of a clickable link in a caption is <a href="http://anxietypanichealth.com/">my other blog</a>.</p>
</li>

STEP 3. How to set up the selectors in custom.css

There are two selectors provided for your custom.css file: one for widgets and one for the page/post version. They are identical except for their names.

The selectors are heavily commented and contain only standard CSS properties. I won’t repeat the comments in the code so as not to bore you. I have put in a few properties for fonts, but you can add whatever other properties you want.

You may use the properties as-is, except you must set the height and width properties the same as the images that you entered above under Step 2 above! If you don’t your Image Gallery probably won’t work, or will appear as a box with scroll bars at the sides and bottom.

Preparing your images for the Rotating Image Gallery

All images within a Rotating Image Gallery must be the same size.

If they are not, your Image Gallery will at best look odd, or at worst not work at all. There are many programs available that can resize images, some of them free.

Determine the size that you want your Image Gallery to be

If putting the Image Gallery into the content column, be sure not to exceed the width you set in the Thesis Design Options. Likewise, if putting it into a widget, check the sidebar size to make sure your images are not too wide.

Optimize the size of your images for the best results

Images that have file sizes that are too large may cause stuttering or hesitation as they move into the image box. Make sure your images’ size is optimized for the web. There are many programs that will optimize them without significantly degrading their quality.

Note that you will put your own images into the /rotating_images/gallery folder. If you put them anywhere else they won’t be found!

Tips for using the Rotating Image Gallery

1. Setting the transition speed too fast can result in stuttering or hesitation as the image changes. Reset the transitionSpeed property in the rotating_images_foot function in the custom_functions.php file to a higher number.
2. Images that have file sizes that are too large may cause stuttering or hesitation, too. Make sure your images’ size is optimized for the web. There are many programs that will optimize them, many for free.
3. Captions that are too long will wrap to two or more lines. If these additional lines are not showing completely, change the textholderHeight property in the rotating_images_foot function in the custom_functions.php file to a larger value.

It is mandatory that you download the zip file for this tutorial! It has everything you need — all files, folders and images — in a single zip file. Setting up the Rotating Image Gallery without downloading the zip file is not described in this tutorial! You can download it by clicking here.

I hope you find this tutorial easy to follow, and that you give the Rotating Image Gallery a try. Be sure to download the zip file! As always, your comments are welcome. If you want to contact me directly by email, please click the “Contact” button in the menu.

©2009 Michael L Nichols. All rights reserved.

What next?

Your comments are always welcome, and are important to this blog’s community! Leave a comment now, or read the comments.

You can find several related articles in the “Related Articles” list below. In the footer you will find a lists of Popular Posts, Recent Posts, and you may browse by Categories, or tags. There’s also a Google Custom Search box to help you find just what you want.

Get free updates by RSS or email!

If you have enjoyed this article, please consider subscribing to article updates, using an RSS reader, or by email. It’s free and is a great way to make sure you don’t miss a single article! I also invite you to follow me on Twitter!

Why not share this article with others!

Share this article with your friends using your favorite social media service, such as StumbleUpon, or Digg. Check out the icons below under “Share This Article With Others” for other social media, including del.icio.us, Technorati, Sphinn, Friendfeed, FaceBook, MySpace andLinkedIn! You can also email or print the article, and even tweet it using Twitter!

You Too Can Have a Fat Footer!

Widgetized “fat” footers are a popular addition to blog sites. There have been several threads on the DIYthemes Forums about widgetized footers, but often they are complicated and hard to follow.

A new article, Tutorial: Widgetized “Fat” Footer, offers a solution that is simple to set up, needs no configuration and can be used right out of the box! It has been tested in both Thesis 1.5x and 1.6x.

The article shows you how to create a 3- or 4-widget footer like the ones at the bottom of this page and on the Thesis Theme Tools demo site.

The widgetized footer described in the article can contain any kind of widget, video, image, or other information that can be put in the sidebars — they are widgets just like any other widgets. The footer widget items appear in the WordPress widgets panel right along with the sidebars, so they are easy to set up.

Included is a link to a zip file that contains all the required code to put into your custom_functions.php and custom.css files.

So try it out! You too can have a “fat” footer — in less than 10 minutes!

Tutorial: Widgetized “Fat” Footer

There have been numerous threads in the DIYthemes Forums about making a widgetized “fat” footer. Most methods are fairly complicated, and the threads are often confusing.

Here is a solution that is simple to set up, needs no configuration and can be used right out of the box! It has been tested in both Thesis 1.5x and 1.6x.

This tutorial will show you how to put a 3- or 4- column widgetized footer on your site. The 3-column footer illustrated in Figure 1 is from the Thesis Theme Tools demo site:

Figure 1: 3-column widgetized "fat" footer

Figure 2 shows the 4-column footer at the bottom of the Thesis Theme Tools page:

Figure 2: 4-column widgetized "fat" footer

The widgetized footer in this article can contain any kind of widget, video, image, or other information that can be put in the sidebars — they are widgets just like any other widgets. The footer widget items appear in the WordPress widgets panel right along with the sidebars, so they are easy to set up.

There are two groups of code for the widgetized footer. One is put into your custom_functions.php file, and the other into your custom.css file. It does not matter where you put the code in these files.

Rather than copy the code shown below, you can get everything you need in a single zip file. Just download it by clicking here.

The code for custom_functions.php

Below is the code to put into your custom_functions.php file. Actually, there are two sets of code: one for the 3-column widgetized footer, and one for the 4-column footer. Both are included in the zip file. You need copy only the code for the number of columns that you want. Don’t put both into your custom_functions.php file!

3-column code for custom_functions.php

If you download the zip file, this code is in the “widgetized footer 3 col.php” file.

/*---------------------------------*/
/* WIDGETIZED FOOTER - 3 COLUMNS */
/* Mike Nichols - October 17, 2009 */
/*---------------------------------*/

/*-----------------------------------------*/
/* register sidebars for widgetized footer */
if (function_exists('register_sidebar')) {
$sidebars = array(1, 2, 3);
foreach($sidebars as $number) {
register_sidebar(array(
'name' => 'Footer ' . $number,
'id' => 'footer-' . $number,
'before_widget' => '',
'after_widget' => '',
'before_title' => '<h3>',
'after_title' => '</h3>'
));
}
}

/*-----------------------*/
/* set up footer widgets */
function widgetized_footer() {
?>
<div id="footer_setup">

<div class="footer_items">
<?php if ( !function_exists('dynamic_sidebar') || !dynamic_sidebar('Footer 1') ) : ?>
<?php endif; ?>
</div>

<div class="footer_items">
<?php if ( !function_exists('dynamic_sidebar') || !dynamic_sidebar('Footer 2') ) : ?>
<?php endif; ?>
</div>

<div class="footer_items">
<?php if ( !function_exists('dynamic_sidebar') || !dynamic_sidebar('Footer 3') ) : ?>
<?php endif; ?>
</div>

</div>
<?php
}
add_action('thesis_hook_footer','widgetized_footer');

4-column code for custom_functions.php

If you download the zip file, this code is in the “widgetized footer 4 col.php” file.

/*---------------------------------*/
/* WIDGETIZED FOOTER - 4 COLUMNS */
/* Mike Nichols - October 17, 2009 */
/*---------------------------------*/

/*-----------------------------------------*/
/* register sidebars for widgetized footer */
if (function_exists('register_sidebar')) {
$sidebars = array(1, 2, 3, 4);
foreach($sidebars as $number) {
register_sidebar(array(
'name' => 'Footer ' . $number,
'id' => 'footer-' . $number,
'before_widget' => '',
'after_widget' => '',
'before_title' => '<h3>',
'after_title' => '</h3>'
));
}
}

/*-----------------------*/
/* set up footer widgets */
function widgetized_footer() {
?>
<div id="footer_setup">

<div class="footer_items">
<?php if ( !function_exists('dynamic_sidebar') || !dynamic_sidebar('Footer 1') ) : ?>
<?php endif; ?>
</div>

<div class="footer_items">
<?php if ( !function_exists('dynamic_sidebar') || !dynamic_sidebar('Footer 2') ) : ?>
<?php endif; ?>
</div>

<div class="footer_items">
<?php if ( !function_exists('dynamic_sidebar') || !dynamic_sidebar('Footer 3') ) : ?>
<?php endif; ?>
</div>

<div class="footer_items">
<?php if ( !function_exists('dynamic_sidebar') || !dynamic_sidebar('Footer 4') ) : ?>
<?php endif; ?>
</div>

</div>
<?php
}
add_action('thesis_hook_footer','widgetized_footer');

The code for custom.css

Following is the code for your custom.css file. It is the same for both 3- and 4-column footers. If you download the zip, it is in the “widgetized footer.css” file.

/*---------------------------------*/
/* WIDGETIZED FOOTER               */
/* Mike Nichols - October 17, 2009 */
/*---------------------------------*/

/* footer widget area setup */
#footer_setup {
	/* widgetized footer background (not footer background) */
	background: #EEEEEE;
	/* widget padding */
	padding: 16px;
	/* margin at bottom of widgets */
	margin-bottom: 25px;
	/* do not change this! */
	overflow: hidden;
}

/* widget item setup */
#footer_setup .footer_items {
	/* contents alignment */
	text-align: left;
	/* widget width */
	width: 210px;
	/* space between widgets */
	padding-right: 10px;
	/* text color */
	color: #2361A1;
	/* do not change these! */
	display: inline-block;
	float: left;
	height: 100%;
}

/* widget item headers*/
#footer_setup .footer_items h3 {
	/* font size */
	font-size: 1em;
	/* bold or not */
	font-weight: bold;
	/* uppercase or not */
	text-transform: uppercase;
	/* space out the letters*/
	letter-spacing: 0px;
	/* font color*/
	color: #000000;
	/* padding under header text */
	padding-bottom: 3px;
	/* border under header text */
	border-bottom: 3px solid #ffdf00;
	/* distance between border and widget text */
	margin-bottom: 5px;
}
	
/* do not change these! */
#footer_setup .footer_items ul li { list-style: none; }
#footer_setup .footer_items ul { margin: 0px; padding: 0px; }

How to use and customize the widgetized footer

The code shown above is ready to run and needs no configuration. However…

Important! Your widgetized footer will not appear until you put at least one widget into it! From your WordPress admin panel go to Appearance > Widgets. Along with the sidebars you will see items for the footer. Just set them up like you would the sidebars. You can put any number of widgets into each footer column, but be aware that this will make your footer very tall.

Customizing the widgetized footer

There are several things that can be customized in the widgetized footer, particularly the headers. You will also want to set width of the widgets. Please note that there are several selectors and properties that you should not change or your footer will look very strange! Following are some of the more common customizations:

1. Background
In Figure 1 the widgetized footer has a white background, and in Figure 2 it has a gray background. You can give it any color background you want, or even display it over an image! The setup for the background is in the first selector, “#footer_setup.” This controls only the background behind the widgets, though. If you want the entire footer section to have a background color, you will need to customize the Thesis “#footer” selector. The code you would use in custom.css looks like this:

.custom #footer { 	
	height: 400px;
	width: 1018px;
	background: #000000;
}

Change the height and width of the footer area to suit, and of course change the footer color.

2. Width of widgets
The size of the widgets may be too narrow or too wide for your page setup. If too wide, they may even wrap around to a second row. The widget width is set in the “#footer_setup .footer_items” selector. You will have to experiment until you get this right.

3. Color, font and border of the widget headings
These are set in the “#footer_setup .footer_items h3” selector. The properties are all commented so I will not repeat them here. The most common font customizations are included, but you can add more, such as the font family.

Customizing the widgets in the widgetized footer

The widgets in the widgetized footer are not customized like the ones in the sidebars. Instead, they are governed by the footer’s selectors. The footer’s font color by default is gray and all links are underlined. Following are the footer selectors that apply to the widgetized footer. They are set up with “Thesis blue” links and underlining only when the cursor hovers over a link:

/* footer font styles */
.custom #footer a {
	font-size: .9em;
	border-bottom: none;
	/* default Thesis link color */
	color: #2361A1;
}
.custom #footer a:visited {
	text-decoration: none;
	/* default Thesis link color */
	color: #2361A1;
}
.custom #footer a:link {
	text-decoration: none;
	/* default Thesis link color */
	color: #2361A1;
}
.custom #footer a:hover {
	text-decoration: underline;
	/* default Thesis link color */
	color: #2361A1;
}

Conclusion

Remember you can get the files needed for the widgetized footer in a single zip file. Just download it by clicking here.

I hope this article has been instructive and that you will try out the widgetized “fat” footer on your site! As always, your comments are welcome. If you wish, you can contact me by email by clicking on the “Contact” button in the menu.

©2009 Michael L Nichols. All rights reserved.

What next?

Your comments are always welcome, and are important to this blog’s community! Leave a comment now, or read the comments.

You can find several related articles in the “Related Articles” list below. In the footer you will find a lists of Popular Posts, Recent Posts, and you may browse by Categories, or tags. There’s also a Google Custom Search box to help you find just what you want.

Get free updates by RSS or email!

If you have enjoyed this article, please consider subscribing to article updates, using an RSS reader, or by email. It’s free and is a great way to make sure you don’t miss a single article! I also invite you to follow me on Twitter!

Why not share this article with others!

Share this article with your friends using your favorite social media service, such as StumbleUpon, or Digg. Check out the icons below under “Share This Article With Others” for other social media, including del.icio.us, Technorati, Sphinn, Friendfeed, FaceBook, MySpace andLinkedIn! You can also email or print the article, and even tweet it using Twitter!

New Menu! Vertical Multilevel Dropdown Menu

You’ve probably noticed the vertical menu at the top of the left sidebar. It is used for supplementary navigation to help you quickly find anything on this site.

It is an example of the Vertical Multilevel Dropdown Menu described in a new tutorial.

You can use the Vertical Menu as your main menu or as a supplement to another menu system. It is completely compatible with beta versions of Thesis 1.6.

The Vertical Multilevel Dropdown Menu offers these outstanding features:

  • Easy to set up and use.
  • Any kind of URL, document or file can be put in the menu — no restrictions and no conditional php!
  • Dropdown menus with as many items and dropdown levels as you want.
  • Menu items may be in any order you want.
  • Dropdown menus have a sliding effect that is very appealing
  • Completely configurable as to size of menu items, font characteristics, colors, etc. with CSS.
  • Includes support for most major browsers, including most versions of Internet Explorer.
  • SEO friendly: Its unordered list is generated within the HTML of the page, so Google’s and other bots can read and index it.
  • Very fast execution. Uses Google libraries for speed.
  • In browsers with JavaScript disabled, the main tabs are still usable (but not the dropdowns)

Why don’t you give the Vertical Menu a try? You’ll find it’s an easy way to draw readers into your site so they stay longer, improving your SEO and page ranking.

Tutorial: Vertical Multilevel Dropdown Menu

Many people have requested a Vertical Multilevel Dropdown Menu to use either as the main menu, or as a supplement to navigation. In response to these requests, I have developed the menu described in this article.

You can see the Vertical Menu in action in the top left sidebar of this site. I use it for supplementary navigation to give the reader quick and complete access to the full site. The menu has both single and multiple dropdowns. If you pull down the item “About” it appear as a single dropdown:

Figure 1: Single Dropdown of Vertical Menu
Figure 1: Single Dropdown of Vertical Menu

The “Tricks” menu item has two levels, as shown in Figure 2:

Figure 2: Two Levels of Dropdowns
Figure 2: Two Levels of Dropdowns

The Menu is also capable of more levels, as shown in Figure 3 from the Thesis Theme Tools demo site:

Figure 3: Three Levels of Dropdowns
Figure 3: Three Levels of Dropdowns

The Vertical Multilevel Dropdown Menu offers these features:

  • Easy to set up and use.
  • Any kind of URL, document or file can be put in the menu — no restrictions and no conditional php!
  • Dropdown menus with as many items and dropdown levels as you want.
  • Menu items may be in any order you want.
  • Dropdown menus have a sliding effect that is very appealing
  • Completely configurable as to size of menu items, font characteristics, colors, etc. with CSS.
  • Includes support for most major browsers, including most versions of Internet Explorer.
  • SEO friendly: Its unordered list is generated within the HTML of the page, so Google’s and other bots can read and index it.
  • Very fast execution. Uses Google libraries for speed.
  • In browsers with JavaScript disabled, the main tabs are still usable (but not the dropdowns)

The Vertical Menu is based on an idea from the Dynamic Drive’s CSS Library that I modified for use with Thesis.

Rather than copy the files shown below, I recommend you get everything — all files and the arrow graphic — in a single zip file. You can download it by clicking here.

Navigation in the Tutorial

This description of the Vertical Multilevel Dropdown Menu is in 6 parts. If you want to skip to a particular part, just click on the links below:

How the menu works

There are four separate groups of code and one image that make this menu work:

  • A JavaScript file that does the actual work of building the menu
  • A CSS file that styles the menu
  • A set of functions to put into your custom_functions.php file
  • A line of code to put into a text widget
  • An arrow image

These are listed and described below to help you understand how the menu works. All this code and the arrow are included in the zip file.

The JavaScript that builds the dropdowns

The following JavaScript does the actual work of building the multiple levels of the menu. I made some minor modifications to it, but it’s basically a script provided by Dynamic Drive. If you choose to create a file from the code below rather than use the zip file, you must name the file “ddsmoothmenu.js”.

//** Smooth Navigational Menu- By Dynamic Drive DHTML code library: http://www.dynamicdrive.com
//** Menu created: Nov 12, 2008 - last update July 27th, 09 (v1.31)
//** Modified by Mike Nichols Oct 6, 09 for the Vertical Multilevel Dropdown Menu

var ddsmoothmenu={

//Specify the full URL to down arrow image
//Replace YOUR-DOMAIN-NAME with your domain name and check your Thesis path
arrowimages: {down:['downarrowclass', '', 23], right:['rightarrowclass', 'http://YOUR-DOMAIN-NAME/wp-content/themes/thesis_151/custom/images/v-right-arrow.gif']},

//Duration of slide in/out animation in milliseconds - default is 300
//overtime is the speed the menu draws on the screen
//outtime is the speed the menu is removed from the screen
transition: {overtime:300, outtime:300}, 

///////Stop configuring beyond here///////////////////////////
shadow: {enable:true, offsetx:5, offsety:5},

detectwebkit: navigator.userAgent.toLowerCase().indexOf("applewebkit")!=-1, //detect WebKit browsers (Safari, Chrome etc)
detectie6: document.all && !window.XMLHttpRequest,

getajaxmenu:function($, setting){ //function to fetch external page containing the panel DIVs
	var $menucontainer=$('#'+setting.contentsource[0]) //reference empty div on page that will hold menu
	$menucontainer.html("Loading Menu...")
	$.ajax({
		url: setting.contentsource[1], //path to external menu file
		async: true,
		error:function(ajaxrequest){
			$menucontainer.html('Error fetching content. Server Response: '+ajaxrequest.responseText)
		},
		success:function(content){
			$menucontainer.html(content)
			ddsmoothmenu.buildmenu($, setting)
		}
	})
},


buildmenu:function($, setting){
	var smoothmenu=ddsmoothmenu
	var $mainmenu=$("#"+setting.mainmenuid+">ul") //reference main menu UL
	$mainmenu.parent().get(0).className=setting.classname || "ddsmoothmenu"
	var $headers=$mainmenu.find("ul").parent()
	$headers.hover(
		function(e){
			$(this).children('a:eq(0)').addClass('selected')
		},
		function(e){
			$(this).children('a:eq(0)').removeClass('selected')
		}
	)
	$headers.each(function(i){ //loop through each LI header
		var $curobj=$(this).css({zIndex: 100-i}) //reference current LI header
		var $subul=$(this).find('ul:eq(0)').css({display:'block'})
		this._dimensions={w:this.offsetWidth, h:this.offsetHeight, subulw:$subul.outerWidth(), subulh:$subul.outerHeight()}
		this.istopheader=$curobj.parents("ul").length==1? true : false //is top level header?
		$subul.css({top:this.istopheader && setting.orientation!='v'? this._dimensions.h+"px" : 0})
		$curobj.children("a:eq(0)").css(this.istopheader? {paddingRight: smoothmenu.arrowimages.down[2]} : {}).append( //add arrow images
			''
		)
		if (smoothmenu.shadow.enable){
			this._shadowoffset={x:(this.istopheader?$subul.offset().left+smoothmenu.shadow.offsetx : this._dimensions.w), y:(this.istopheader? $subul.offset().top+smoothmenu.shadow.offsety : $curobj.position().top)} //store this shadow's offsets
			if (this.istopheader)
				$parentshadow=$(document.body)
			else{
				var $parentLi=$curobj.parents("li:eq(0)")
				$parentshadow=$parentLi.get(0).$shadow
			}
			this.$shadow=$('
').prependTo($parentshadow).css({left:this._shadowoffset.x+'px', top:this._shadowoffset.y+'px'}) //insert shadow DIV and set it to parent node for the next shadow div } $curobj.hover( function(e){ var $targetul=$(this).children("ul:eq(0)") this._offsets={left:$(this).offset().left, top:$(this).offset().top} var menuleft=this.istopheader && setting.orientation!='v'? 0 : this._dimensions.w menuleft=(this._offsets.left+menuleft+this._dimensions.subulw>$(window).width())? (this.istopheader && setting.orientation!='v'? -this._dimensions.subulw+this._dimensions.w : -this._dimensions.w) : menuleft //calculate this sub menu's offsets from its parent if ($targetul.queue().length<=1){ //if 1 or less queued animations $targetul.css({left:menuleft+"px", width:this._dimensions.subulw+'px'}).animate({height:'show',opacity:'show'}, ddsmoothmenu.transition.overtime) if (smoothmenu.shadow.enable){ var shadowleft=this.istopheader? $targetul.offset().left+ddsmoothmenu.shadow.offsetx : menuleft var shadowtop=this.istopheader?$targetul.offset().top+smoothmenu.shadow.offsety : this._shadowoffset.y if (!this.istopheader && ddsmoothmenu.detectwebkit){ //in WebKit browsers, restore shadow's opacity to full this.$shadow.css({opacity:1}) } this.$shadow.css({overflow:'', width:this._dimensions.subulw+'px', left:shadowleft+'px', top:shadowtop+'px'}).animate({height:this._dimensions.subulh+'px'}, ddsmoothmenu.transition.overtime) } } }, function(e){ var $targetul=$(this).children("ul:eq(0)") $targetul.animate({height:'hide', opacity:'hide'}, ddsmoothmenu.transition.outtime) if (smoothmenu.shadow.enable){ if (ddsmoothmenu.detectwebkit){ //in WebKit browsers, set first child shadow's opacity to 0, as "overflow:hidden" doesn't work in them this.$shadow.children('div:eq(0)').css({opacity:0}) } this.$shadow.css({overflow:'hidden'}).animate({height:0}, ddsmoothmenu.transition.outtime) } } ) //end hover }) //end $headers.each() $mainmenu.find("ul").css({display:'none', visibility:'visible'}) }, init:function(setting){ if (typeof setting.customtheme=="object" && setting.customtheme.length==2){ //override default menu colors (default/hover) with custom set? var mainmenuid='#'+setting.mainmenuid var mainselector=(setting.orientation=="v")? mainmenuid : mainmenuid+', '+mainmenuid document.write('') } this.shadow.enable=(document.all && !window.XMLHttpRequest)? false : this.shadow.enable //in IE6, always disable shadow jQuery(document).ready(function($){ //ajax menu? if (typeof setting.contentsource=="object"){ //if external ajax menu ddsmoothmenu.getajaxmenu($, setting) } else{ //else if markup menu ddsmoothmenu.buildmenu($, setting) } }) } } //end ddsmoothmenu variable //Initialize Menu instance(s):

The CSS that styles the menu

Following is the CSS file that styles the menu. You have complete control over the fonts, the menu colors and borders, the item size and spacing, and the dropdown items’ size, among other things. The values in the CSS are those that I used to style the menu on this site, but you are completely free to change anything you wish.

Note that the code is heavily commented to help you find what you need. Also note that there are several warnings not to change certain parts of the code. Of course, no one will be watching you and slap your hands if you do so, but the Menu will behave very strangely!

If you choose to create a file from the code below rather than use the zip file, you must name the file “ddsmoothmenu-v.css”.

/* Smooth Navigational Menu- By Dynamic Drive DHTML code library: http://www.dynamicdrive.com */
/* Modified and annotated by Mike Nichols Oct 6, 2009 for the Vertical Multilevel Dropdown Menu */

/* COLORS
#FFFFFF	- white	
		- menu items default
#888888	- gray			
		- submenu item dividers
#EFCF00	- light gold			
		- hovered-over menu item
#CDB91A	- dark gold
		- selected menu item
*/
/* Main class definition */
.ddsmoothmenu-v ul{
	/* Main Menu Item widths */
	width: 235px;
	/* font size */
	font-size: .9em;
	/* font bold or not*/
	font-weight: bold;
	/* font if different from default */
	/*font-family: Verdana, Arial, sans-serif;*/
	/* do not change these! */
	list-style-type: none;
	margin: 0;
	padding: 0;
}

/* Top level menu links style */
.ddsmoothmenu-v ul li a{
	/* font color */
	color: #FFFFFF;
	/* underline or not */
	text-decoration: none;
	/* height of menu bars */
	padding: 6px;
	/* set the distance between menu bars */
	margin-bottom: -8px;
	/* menu item borders */
	border-bottom: 1px dotted #888888;
	border-right: 1px dotted #888888;
	/* do not change these! */
	display: block;
	overflow: auto; /*force hasLayout in IE7 */
}

/* default background and font color of menu items*/
.ddsmoothmenu-v ul li a:link, .ddsmoothmenu-v ul li a:visited, .ddsmoothmenu-v ul li a:active{
	/* background */
	background: #FFFFFF;
	/* font color */
	color: #000000;
}

/* background and font color of currently selected menu item */
.ddsmoothmenu-v ul li a.selected {
	/* background */
	background: #CDB91A;
	/* font color */
	color: white;
}

/*background and font color of menu items on mouseover (hover state)*/
.ddsmoothmenu-v ul li a:hover{
	/* background */
	background: #EFCF00;
	/* font color */
	color: #000000;
	/* underline or not */
	text-decoration: none;
}

/*Sub level menu items */
.ddsmoothmenu-v ul li ul{
	/*Sub Menu Items width */
	width: 220px;
	/* font weight */
	font-weight: bold;
	/* font size */
	font-size: 1em;
	/* do not change these! */
	position: absolute;
	top: 0;
	visibility: hidden;
}

/* ====== DO NOT CHANGE ANYTHING BELOW THIS LINE ===== */
/* positioning of pulldowns */
.ddsmoothmenu-v ul li{
	position: relative;
	left:-15px;
}

/* Hack for IE \*/
* html .ddsmoothmenu-v ul li { float: left; height: 1%; }
* html .ddsmoothmenu-v ul li a { height: 1%; }
/* End */

The functions to put into custom_functions.php

Following are three functions that you place into your custom_functions.php file. The first function links the menu’s CSS file into the head of your post/page HTML document. The second function links the required JQuery file and the JavaScript file into the foot of your post/page HTML document.

The third function actually describes your menu items. It consists of simple unordered HTML lists that become a part of the HTML when your page is rendered, so Google and other search bots will index them. If you choose to create a file from the code below rather than use the zip file, you must name the file “for-custom_functions.php”.

/* --------------------------------------------------- */
/* FUNCTIONS FOR THE VERTICAL MULTILEVEL DROPDOWN MENU */
/* Created by Mike Nichols - Oct 6, 2009 */
/* --------------------------------------------------- */

/* Link menu css in document head */
function vertical_menu_head() {
?>
<link rel="stylesheet" type="text/css" href="<?php bloginfo(template_directory)?>/custom/vertical-menu/ddsmoothmenu-v.css" />
<?php
}
add_action('wp_head','vertical_menu_head');

/* Link menu JavaScript and JQuery in footer */
function vertical_menu_foot() {
?>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>

<script type="text/javascript" src="<?php bloginfo(template_directory)?>/custom/vertical-menu/ddsmoothmenu.js"></script>

<script type="text/javascript">
ddsmoothmenu.init({
mainmenuid: "smoothmenu",
orientation: 'v',
classname: 'ddsmoothmenu-v',
contentsource: "markup"
})
</script>
<?php
}
add_action('thesis_hook_after_html','vertical_menu_foot');

/* define the menu items */
/* this will be called from the widget */
function vertical_menu() {
?>
<div id="smoothmenu" class="ddsmoothmenu-v">
<ul>

<!-- First level menu item shows on main menu list -->
<!-- It is set to your home page -->
<li><a href="<?php bloginfo('url');?>">Home</a></li>

<!-- First level menu item with one dropdown -->
<li><a href="#">TAB 2 WITH 1 DROPDOWN&nbsp;</a>
<!-- this is the dropdown -->
<ul>
<li><a href="#">DROPDOWN 1 ITEM 1</a></li>
<li><a href="#">DROPDOWN 1 ITEM 2</a></li>
<li><a href="#">DROPDOWN 1 ITEM 3</a></li>
<li><a href="#">DROPDOWN 1 ITEM 4</a></li>
</ul>
</li>

<!-- First level menu item with one dropdown -->
<li><a href="#">TAB 3 WITH 1 DROPDOWN&nbsp;</a>
<!-- this is the dropdown -->
<ul>
<li><a href="#">DROPDOWN 1 ITEM 1</a></li>
<li><a href="#">DROPDOWN 1 ITEM 2</a></li>
<li><a href="#">DROPDOWN 1 ITEM 3</a></li>
<li><a href="#">DROPDOWN 1 ITEM 4</a></li>
</ul>
</li>

<!-- First level menu item with no dropdown -->
<li><a href="#">TAB 4</a></li>

<!-- First level menu item with three dropdowns -->
<li><a href="#">TAB 5 WITH 3 DROPDOWNS&nbsp;</a>
<ul>
<!-- this is the first level dropdown -->
<li><a href="#">DROPDOWN 1 ITEM 1</a></li>
<li><a href="#">DROPDOWN 1 ITEM 2&nbsp;</a>
<!-- this is the second level dropdown -->
<ul>
<li><a href="#">DROPDOWN 2 ITEM 1</a></li>
<li><a href="#">DROPDOWN 2 ITEM 2</a></li>
<li><a href="#">DROPDOWN 2 ITEM 3&nbsp;</a>
<!-- this is the third level dropdown -->
<ul>
<li><a href="#">DROPDOWN 3 ITEM 1</a></li>
<li><a href="#">DROPDOWN 3 ITEM 2</a></li>
<li><a href="#">DROPDOWN 3 ITEM 3</a></li>
<li><a href="#">DROPDOWN 3 ITEM 4</a></li>
<li><a href="#">DROPDOWN 3 ITEM 5</a></li>
</ul>
</li>
<li><a href="#">DROPDOWN 2 ITEM 4</a></li>
</ul>
</li>
</ul>
</li>

<!-- First level menu item with no dropdown -->
<li><a href="#">TAB 6</a></li>

</ul>
<br style="clear: left" />
</div>
<?php
}

Widget code

The great majority of people will use the Vertical Menu in a widget. There is one line of code to enter into a text widget. Using the Menu in a widget is fully described below:

<?php vertical_menu() ?>

The Menu’s arrow image file

Figure 4
Figure 4

The menu uses an image to indicate that there is a dropdown or multiple levels on a menu item. It is contained in Figure 4. If you copy the menu arrow image, be sure to name it “v-right-arrow.gif.” The arrow is also found in the zip file.

Getting a plugin to execute PHP in a widget

The Vertical Menu can be used in two ways: placed in a widget or in a CSS box. The great majority of people will use it in a widget, since using it in a CSS box is impractical and difficult to implement (if anybody really wants to give it a go, though, just contact me and I’ll tell you how). The Vertical Menu on this page is in a widget.

Widgets will not execute PHP code without help, so you will need a plugin that allows you to do so. My favorite is Exec-PHP by Sören Weber. It is available either from the WordPress Plugins page or from the author’s plugin page. You may also download and install it directly from your WordPress admin panel’s plugin page. Be sure to activate the plugin! You should visit the plugin’s settings page under Settings on the WordPress admin panel. You probably won’t have to change anything, but you need to check it anyway.

Setting up the Vertical Multilevel Dropdown Menu

There are 5 steps for setting up your menu. Each step is not difficult, but the instructions must be followed to the letter. Most of the problems people experience when setting up the menu are because they skip a step or do not follow the directions.

Step 1: Set up a folder on your server

Figure 5: The vertical-menu folder created within the /custom folder
Figure 5: The vertical-menu folder created within the /custom folder

Create a new folder named “vertical-menu” in your /custom folder. When you are finished your folders should look like figure 5.

Step 2: Copy files into the /custom/vertical-menu folder

Figure 6: Required files copied into the /custom/vertical-menu folder
Figure 6: Required files copied into the /custom/vertical-menu folder

Copy the “ddsmoothmenu.js” and “ddsmoothmenu-v.css” files into the /custom/vertical-menu folder. If you downloaded the zip file, they are contained in a folder named “put-in-vertical-menu-folder.”

When you finish your custom folder should look like Figure 6.

Step 3: Upload the arrow image and set it up

1. Upload the arrow image to your /custom/images folder. It is named “v-right-arrow.gif.” If you downloaded the zip file, it is in the folder named “put-in-custom-images.”

2. Change the path to your arrow image in the file “ddsmoothmenu.js” to the full URL, not the relative URL of the arrow file. Right at the top of the file is the place to do it — you will see three lines that look like this:

//Specify the full URL to down arrow image
//Replace YOUR-DOMAIN-NAME with your domain name and check your Thesis path
arrowimages: {down:['downarrowclass', '', 23], right:['rightarrowclass', 'http://YOUR-DOMAIN-NAME/wp-content/themes/thesis_151/custom/images/v-right-arrow.gif']},

The third line is where you make your changes.

Substitute your domain name for “YOUR-DOMAIN-NAME” in the URL for the arrow image. Double-check that the Thesis folder is named the same as yours. If your arrow doesn’t appear on the menu, then you’ve gotten the URL wrong. Note that this is the only hard-coded URL required in the Menu setup. When you upgrade Thesis, make sure to remember to change this URL!

Step 4: Put the three functions into your custom_functions.php file

Copy and paste the three functions in the file “for-custom-functions.php” into your custom_functions.php file. It does not matter where these functions go. (Note that the “for-custom_functions.php” file is not uploaded to your server.)

Step 5: Install a text widget and insert the code

Widget setup is simplicity itself. From your WordPress admin panel, go to Appearance > Widgets. Drag a text widget to where you want the menu to appear. Put the contents of the “put-in-text-widget” file — one single short line — into the text widget and save (the file is found in the zip file or can be copied above). (Note that the “put-in-text-widget” file is not uploaded to your server.)

You’re finished with the setup. Now you’re ready to try it out!

How to Set Up Your Menu Items

The Menu is just an HTML unordered list with the following structure. Adding menu items is simple, but you have to follow instructions carefully:

Main Menu Items
	First Level Dropdown Items
		Second Level Dropdown Items
			Third Level Dropdown Items
				...

1. Basically, you will be doing two things when setting up a menu item: putting in the item’s URL, and putting in its menu description. Figure 7 shows a sample line before it has been set up:

Figure 7: Menu Item Before Setup
Figure 7: Menu Item Before Setup

2. The URL for your menu item replaces the pound sign (#). The description for the menu item — the word(s) that actually show on the menu — replace the example words. For example, if I am setting up Thesis Theme Tool’s About page, it would look like the when I am finished. Remember that you can put any URL into any menu item:

<li><a href="http://thesisthemetools.com/about/">About</a></li>

3. Adding more menu items follows the same procedure. Just replace the pound sign with your URL and the example description with your description.

4. Note that the first tab is already set up as your home tab. You may change it if you wish.

Figure 8: Nesting of unordered lists in the function
Figure 8: Nesting of unordered lists in the function

5. When editing dropdowns, make sure that you observe the way the lists are constructed: The unordered list for dropdowns come right before the line item’s “</li>” tag. This tag is placed after the end of the unordered list. In Figure 8 you will see the nesting of the tags represented by red lines.

Adding a Single Tab Item with No Dropdown

1. Copy a line with no dropdowns, such as the Home page line, “TAB 4” or “TAB 6” lines.
2. Paste the line in the code where you want the menu item to appear.
3. Replace the URL or pound sign with your URL, and the description with your description.

Adding a Single Tab Item with One Dropdown

1. Copy a group of lines with a single dropdown, such as the “TAB 3” or “TAB 4” lines. Be sure to copy all the lines associated with the tab.
2. Paste the lines in the code where you want the menu item to appear.
3. Replace the URLs or pound signs with your URL, and the descriptions with your descriptions.

Adding a Single Tab Item with Multiple Dropdowns

1. Copy a group of lines with a multiple dropdowns, such as the “TAB 5” group. Be sure to copy all the lines associated with the tab.
2. Paste the lines in the code where you want the menu item to appear.
3. Delete any submenus that you don’t need. Be sure to delete all the lines associated with the unneeded submenus, but observe the menu’s structure and don’t delete too many!
4. Replace the URLs or pound signs with your URL, and the descriptions with your descriptions.

Deleting or Rearranging Menu Items

Menu items can be deleted or rearranged easily,
1. Cut the line or group of lines associated with the menu item. Make sure you get all the lines, but be sure you don’t cut the lines of other groups! If you are unsure of which lines to cut, take a look at Figure 8 again.
2. If you are moving the menu item, find the place you want it and paste it there.

Usage tips for the Vertical Multilevel Dropdown Menu

1. The menu lines have been commented and indented in the code to better show you the menu structure. I suggest you not erase these lines to make working with the menu easier.
2. Keep the file “for-custom-functions.php” so you can copy its menu lines when you need them.
3. Be careful about long menu descriptions for dropdowns. If they are too long, they may get cut off in the dropdown.
4. Remember that browsers with JavaScript turned off will only see the main menu items. You need to make these main menu items point to the more important areas of your site, and/or go to pages that have links to the dropdown’s items.
5. Add a non-breaking space after menu item description with a dropdown or multiple level to keep the arrow from being right up against the last letter. The code is “&nbsp;” without the quotes. For example, in the “Tricks” item of the vertical menu on this site, I put a non-breaking space after the “TRICKS” word. Also take a look at the “vertical_menu” function, where I put a non-breaking space after each menu item with dropdowns:

		<li><a href="http://thesisthemetools.com/tricks/">TRICKS&nbsp;</a>

Troubleshooting Your Menu

1. The menu does not appear

You didn’t download and activate a PHP plugin, you forgot to put the required code into a widget, or you renamed the “vertical_menu” function in custom_functions.php.

2. I can’t select items on the menu because the dropdowns disappear

The JavaScript for the menu is very fast — sometimes too fast. You can slow it down by changing the value of two variables in the “ddsmoothmenu.js” file in your /custom/vertical-menu folder.

Look for these lines in the file. They are near the top:

//Duration of slide in/out animation in milliseconds - default is 300
//overtime is the speed the menu draws on the screen
//outtime is the speed the menu is removed from the screen
transition: {overtime:300, outtime:300}, 

Changing the “overtime” variable in the fourth line to a smaller number will draw the dropdowns faster, allowing you to move your cursor faster. Try something like 200 first, then keep going down incrementally until the problem gets better. The “outtime” variable can be made larger to keep the dropdowns on the screen longer, again allowing you to move your cursor faster. Start at 400 and go up incrementally.

3. I can’t select items on the menu because the dropdowns disappear

You are moving your cursor too fast and/or in a curve. Move it slower and in a straight line over the dropdown items.

4. The menu flickers or the dropdowns appear and disappear

The solution is the same as item 2, above. There is a balance between how fast the menu draws and how fast the dropdowns disappear. You just have to find it.

5. Nothing happens when I click on a menu item, or all that appears in the browser address is a pound sign

You haven’t set up the menu correctly, or you didn’t delete unneeded menu items. Review the instructions in the “How to Set Up Your Menu Items” section above.

6. The menu looks like “slats” in Internet Explorer

Usually this is due to padding and margin issues in the “ddsmoothmenu-v.css” file. IE interprets these differently from every other browser. Unfortunately, this doesn’t happen with everybody’s copy of IE — just on some of them. You may want to experiment with the padding and margin values of the selectors to see if it solves your problem.

7. The menu does not let me pull the dropdown all the way down in Internet Explorer

This usually is due to the menu moving too fast for Internet Explorer. Try the solution in item 2, but make both the “overtime” and “outtime” variables a larger number.

Conclusion

Remember that you can get everything everything needed for the Vertical Menu — all files and the arrow graphic — in a single zip file. Just download it by clicking here.

I hope you try out the Vertical Multilevel Dropdown Menu. It works very smoothly, and has been trouble-free for me this site. As always, your comments are welcome. You can also contact me by email by clicking the “Contact” button at the top of the page.

©2009 Michael L Nichols. All rights reserved.

What next?

Your comments are always welcome, and are important to this blog’s community! Leave a comment now, or read the comments.

You can find several related articles in the “Related Articles” list below. In the footer you will find a lists of Popular Posts, Recent Posts, and you may browse by Categories, or tags. There’s also a Google Custom Search box to help you find just what you want.

Get free updates by RSS or email!

If you have enjoyed this article, please consider subscribing to article updates, using an RSS reader, or by email. It’s free and is a great way to make sure you don’t miss a single article! I also invite you to follow me on Twitter!

Why not share this article with others!

Share this article with your friends using your favorite social media service, such as StumbleUpon, or Digg. Check out the icons below under “Share This Article With Others” for other social media, including del.icio.us, Technorati, Sphinn, Friendfeed, FaceBook, MySpace andLinkedIn! You can also email or print the article, and even tweet it using Twitter!

Adding a Sidebar Image

One of the things that most Thesis newbies want to know right away is how to put an image into a sidebar. It is an easy task that takes only a few minutes. Following is a step-by-step guide to putting both a non-clickable and a clickable image into a sidebar.

Make sure your image is the right size

Images that are too big will overflow the boundaries of the sidebar. Size your image to fit. The maximum width will be the width of the sidebar you defined in Design Options. It’s a good idea to make the width a little smaller. Images will be centered in the sidebar.

Set up a text widget

You will put your image into a text widget. Here’s how to get a text widget ready to accept your image code:

1. From your Admin page go to Appearance > Widgets.

2. Look for “Text” in the available widgets on the left, then drag it to your sidebar. Drag and drop the new text widget into the desired location.

3. Click the arrow to the right in the text widget bar to open it, if necessary.

4. Enter a title if you want.

Adding a non-clickable image to the widget

This is for when you only want a non-clickable image in the sidebar, like a cute picture of your dog.

1. Enter the following code into the large text area of the widget:

<img src="FULL-PATH-TO-IMAGE" align="middle" alt="DESCRIPTION-OF-IMAGE">

2. Change “FULL-PATH-TO-IMAGE” to the full URL of the image. A relative URL will not work. For example, to put the RSS icon in my sidebar into a text widget, I would type the following:

<img src="http://thesisthemetools.com/wp-content/themes/thesis/custom/images/rss-widget.jpg" align="middle" alt="RSS icon">

3. “DESCRIPTION-OF-IMAGE’ is a description of the image. It’s good SEO practice to provide a description.

4. Save the widget, then refresh your blog page to see your new widget.

Adding a clickable image to the widget

This is for when you want a clickable image in the sidebar. When the image is clicked, it takes the user to a URL of your choice. You would use this for RSS buttons or ads, for example.

1. Put the following code into the large text box:

<a href="CLICKABLE-LINK"><img src="FULL-PATH-TO-IMAGE" align="middle" alt="DESCRIPTION-OF-IMAGE"/></a>

2. “CLICKABLE-LINK” is the URL you want the user to be taken to when they click the image.

3. “FULL-PATH-TO-IMAGE” is the URL of the image. As discussed above, it requires the full path to the image, not a relative path.

4. “DESCRIPTION-OF-IMAGE’ is a description of the image. It’s good SEO practice to provide a description, and it helps you remember what the image is.

5. Save the widget, then refresh your blog page to see your new widget.

I hope this short tutorial has been helpful to you. As you see, working with code is not hard, and it’s mostly just cut-and-paste. As always, your comments are welcome. If you want to email me directly, click the “Contact” button in the button bar.

©2009 Michael L Nichols. All rights reserved.

What next?

Your comments are always welcome, and are important to this blog’s community! Leave a comment now, or read the comments.

You can find several related articles in the “Related Articles” list below. In the footer you will find a lists of Popular Posts, Recent Posts, and you may browse by Categories, or tags. There’s also a Google Custom Search box to help you find just what you want.

Get free updates by RSS or email!

If you have enjoyed this article, please consider subscribing to article updates, using an RSS reader, or by email. It’s free and is a great way to make sure you don’t miss a single article! I also invite you to follow me on Twitter!

Why not share this article with others!

Share this article with your friends using your favorite social media service, such as StumbleUpon, or Digg. Check out the icons below under “Share This Article With Others” for other social media, including del.icio.us, Technorati, Sphinn, Friendfeed, FaceBook, MySpace andLinkedIn! You can also email or print the article, and even tweet it using Twitter!

Early Rising Dogs

Got a couple of articles written today, but had a lot of other obligations that cut into my time. I also spent a lot of time in the Forum today, and had to troubleshoot a problem a user was having with the Contextual Submenus.

It didn’t help that my wife’s dog, who is used to getting up at 5:30 am, woke me barking to go out at that evil hour, then again an hour later to eat. I’ve been dragging all day. Sure will be glad when she gets back!

Today I:

  • Finished the article on Google Webmaster Tools setup.
  • Wrote an article on how to find Widget names so they can be styled in custom.css.
  • Updated the Index page for yesterday’s and today’s new articles.
  • Set up a new subdomain for demos, and took screenshots of that process, loading WordPress with Fantastico, and installing Thesis.

Tomorrow I will keep at it, and hope to:

  • Translate several of my code and Forum snippets into short articles.
  • Work on menu organization — I can see it will get out of hand if I don’t think about it now.
  • Tinker with my 404 and Contact forms to make them more useful.
  • Keep thinking about a way to reduce the php code needed to make the Contextual Submenu and Button Bar functions. They’re already getting big!

And as I have time and opportunity (and need a break):

  • Continue thinking and research what it would take to do video tutorials. Find out about post-processing and pro-con of storing on server or with a service like Vimeo.
  • Contact HostGator about some necessary server setting changes for enabling teaser images.
  • Bring into DEVONthink Thesis-related bookmarks from Safari.

New Articles on Google Webmaster Tools and Widgets!

Two new articles have been posted today that might be of interest to you:

Google Webmaster Tools Setup” shows you how to set up Google Webmaster Tools in Thesis in 5 easy steps and is fully illustrated with helpful images. It also gives you an overview of what Webmaster Tools can do for you, as well as listing sources of help.

How to Find Widget Names for custom.css” shows you how to find widget names in your source code so you can style them in your custom.css. It has several illustrations and code snippets to get you going.

Look for several more articles on Widgets soon!

How to Find Widget Names for custom.css

If you want to style your widgets in custom.css, the first thing you have to do is find their names so you can address them. This is not at all obvious, though once you know how to do it, it’s easy. Here’s how:

Bring up the page with your widgets in a browser and then view its source. Usually this is found under the “View” menu pulldown at the top of the page and is named “View Source” or “Page Source.” Then find “widget.”

There will be three kinds of widget names you will find, two for text widgets and one for other kinds of widgets.

The first kind of text widget name will be a long string of numbers after an “id.” If you have a lot of text widgets, it helps to identify which one it is by looking for the header between the <h3> tags. If you have not given a header name to your text widgets, you might have to temporarily name them in order to tell them apart. Though the long string of numbers seems random, it never changes:

Text widget with a long number
Text widget with a long number

In your custom.css file, you would address the text widget like this:

.custom #text-283725271.widget {

The header for the same text widget would be addressed:

.custom #text-283725271 h3 {

The second kind of text widget has a shorter number, often one digit. It looks like this:

Text widget with a short number
Text widget with a short number

Other kinds of widgets will be listed by name. In the following example, we see the categories widget listed as “widget_categories.”

Other widgets are found by name
Other widgets are found by name

You would address this kind of widgets in your custom.css like this:

.custom li.widget_categories {

I hope this helps you with your widget customization. Remember, you are welcome to make comments or email me using the “Contact” button.

©2009 Thesis Theme Tools. All rights reserved.

What next?

Your comments are always welcome, and are important to this blog’s community! Leave a comment now, or read the comments.

You can find several related articles in the “Related Articles” list below. In the footer you will find a lists of Popular Posts, Recent Posts, and you may browse by Categories, or tags. There’s also a Google Custom Search box to help you find just what you want.

Get free updates by RSS or email!

If you have enjoyed this article, please consider subscribing to article updates, using an RSS reader, or by email. It’s free and is a great way to make sure you don’t miss a single article! I also invite you to follow me on Twitter!

Why not share this article with others!

Share this article with your friends using your favorite social media service, such as StumbleUpon, or Digg. Check out the icons below under “Share This Article With Others” for other social media, including del.icio.us, Technorati, Sphinn, Friendfeed, FaceBook, MySpace andLinkedIn! You can also email or print the article, and even tweet it using Twitter!