Category Archives: WordPress

WordPress, Responsive Lightbox with FancyBox and IE6, IE7, and IE8

A week or so back the client for a website I am developing in WordPress reported that the site was slow to load in Internet Explorer 8. At the time I confirmed the problem existed (using a Virtual Box VM with XP/IE8) but didn’t fix the issue. I’ve only just gotten around to looking at the actual source of the problem today. First up I downloaded and installed the Fiddler Web Debugger onto the VM so I could see what was going on when the site loaded in IE8. Here’s what displayed at the bottom of the Fiddler log:

Fiddler Log

Fiddler Log

A number of PNG images associated with FancyBox have failed to load which explains the delay in loading the site in IE8. Immediately I was thinking two things. First, it’s got something to do with the Responsive Lightbox plugin I am using for LightBox image effects, and secondly, there’s some conditional CSS classes that clearly are not working properly because the site loads fine in all other browsers. A quick peek at the source for the site shows that the FancyBox css file is here:

'/wp-content/plugins/responsive-lightbox/assets/fancybox/jquery.fancybox-1.3.4.js

I loaded that file up in my text editor and sure enough at the bottom of the file I see this:

#fancybox-loading.fancybox-ie6 div	{ background: transparent; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='fancybox/fancy_loading.png', sizingMethod='scale'); }

/* IE6, IE7, IE8 */

.fancybox-ie .fancybox-bg { background: transparent !important; }

.fancybox-ie #fancybox-bg-n { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='fancybox/fancy_shadow_n.png', sizingMethod='scale'); }
.fancybox-ie #fancybox-bg-ne { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='fancybox/fancy_shadow_ne.png', sizingMethod='scale'); }
.fancybox-ie #fancybox-bg-e { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='fancybox/fancy_shadow_e.png', sizingMethod='scale'); }
.fancybox-ie #fancybox-bg-se { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='fancybox/fancy_shadow_se.png', sizingMethod='scale'); }
.fancybox-ie #fancybox-bg-s { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='fancybox/fancy_shadow_s.png', sizingMethod='scale'); }
.fancybox-ie #fancybox-bg-sw { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='fancybox/fancy_shadow_sw.png', sizingMethod='scale'); }
.fancybox-ie #fancybox-bg-w { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='fancybox/fancy_shadow_w.png', sizingMethod='scale'); }
.fancybox-ie #fancybox-bg-nw { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='fancybox/fancy_shadow_nw.png', sizingMethod='scale'); }

They look like helper classes for early versions of Internet Explorer that don’t support CSS3 fully. The AlphaImageLoader filter allows images with alpha channel transparency to be loaded in IE6/7/8 while newer CSS3 compliant browsers can display them natively without the need for such tedious mucking about in CSS files. A bit of searching suggests that the DXImageTransform.Microsoft.AlphaImageLoader parameter src uses a path relative to the page the CSS is loaded in rather than relative to the location of the CSS file itself. So, in IE6/7/8 if a page is “foo.htm” then these CSS classes are trying to load “http://www.mysite.com/fancybox/fancy_shadow_n.png” but in reality the image is buried deep in the WordPress content folders.

I could have hardcoded the image locations into the calls but of course this would just break again if I moved the site to a different host. So for now, the fix was easy enough, just comment out that part of the CSS, upload the file back to the web host and hey presto the site loads perfectly in IE8. Of course, when a LightBox image is displayed in IE8 it doesn’t have pretty borders but that’s a minor problem I can live with.

Overriding Yoast SEO Plugin Page Title and META Description

I tend to use the Yoast SEO Plugin on most of my WordPress sites. It’s a useful tool that gives you more finely grained control of the on-page SEO for each WordPress post and page. However, if you’re creating custom page or post types or database driven pages it can be useful to be able to override the <title> ,META description, and Canonical URL generated by the Yoast plugin and replace them with your own.  As it turns out the plugin has a pretty good API and it’s a fairly simple matter to use the built in WordPress add_filter function to intercept various Yoast functions and replace them with your own.  To be able to do this you’re going to have to be using a WordPress child theme. Once you’ve done that open up the child theme’s functions.php file in the WordPress Editor.

When that is open add in this line:

add_filter('wpseo_title','change_yoast__page_titles',100);

This creates a filter that intercepts the Yoast plugin before it can output a page title and allows you to create your own. To do that we need to create a function called change_yoast_page_titles (you can change this function name to anything you like). We could change it to something like this:

function change_yoast_page_titles($title)
{
  global $pagename;
  $new_title=$title;
  if ($pagename=='widget')
  {
	global $widget_name;
	if (isset($widget_name))
		$new_title=$widget_name." | ".get_bloginfo('name');	
  }
  return $new_title;
}

What we’re going here is accessing the WordPress global $pagename and testing if it’s ‘widget’. Then if that is true we’re testing for the existence of the variable $widget_name and creating a new title that concatenates that and your WordPress site name. If the page name isn’t widget or the variable $widget_name isn’t set then the title is left at the default set by Yoast. This all ties in nicely with our recent post about displaying child database records on a custom WordPress page type.

Other useful Yoast filters are those that can replace the META description and the canonical URL. The canonical URL is especially useful if you’re tying together custom URL parameters and re-write rules. Filters to replace the META description and canonical URL can be created like this:

add_filter('wpseo_metadesc','change_yoast_description',100,1);
add_filter('wpseo_canonical','change_yoast_canonical',100,1);

And suitable functions to make the actual changes to the description and URL could look something like this:


function wpseo_metadesc($description)
{
  global $pagename;
  $new_description=$description;
  if ($pagename=='widget')
  {
	global $widget_name;
	if (isset($widget_name))
		$new_description='All you could ever want to know about '.$widget_name;	
  }
  return $new_description;
}

function change_yoast_canonical($url)
{
  global $pagename;
  $new_url=$url;
  if ($pagename=='widget')
  {
        global $widget_name;
	if (isset($widget_name))
		$new_url=str_replace(" ","-",$widget_name).'/';	
  }
  return $new_url;
}

Displaying Child Records from a Custom MySQL Table in WordPress

In the last entry I ran through displaying group of records from a custom MySQL table and part of that included creating links suitable for the selection and display of child records. If we tie that in with reading custom URL parameters in WordPress we can create a set of database driven pages to display child records. If we again use the example that we want to create some pages about widgets, we’d have custom MySQL table containing all the information about each type of widget. In WordPress we want to display a list of all the widget types and be able to click on a link for each widget type and drill down and see the detailed information for each type. Our URL structure would look like this:

http://www.our-site.com/widgets/
http://www.our-site.com/widgets/blue-widgets/
http://www.our-site.com/widgest/red-widgets/

I’ve already covered how you’d display all the widget types using a ShortCode so in this entry I’ll show how we create the detail page for each type of widget.

Create a Custom Page Type Template

You’ll need to be using a WordPress Child Theme and you’re going to need to create a new custom Page Type Template. The easiest way to do that is to copy the page.php template from your parent theme into the folder for your child theme and rename it. In our case we’ll rename it to widget.php. Then open up widget.php in the WordPress editor and at the top of the file just under then opening <?php tag you have to enter the following code:

<?php

/*
Template Name: Widget Template
*/

Once you’ve done that your new page type template will appear in the Template dropdown when you add a new page in WordPress.

Create a New Page

Now that we’ve created the custom page template we can create a new page in WordPress using the custom template. Go to the Pages->Add New and give your new page a title. The page title needs to be the pagename we’re going to use in our new re-write rules (if you’re not sure what that means then you need to read this entry again). Remember that the new re-write rule looks like this:

array('widgets/([^/]+)/?$' => 'index.php?pagename=widget&widget_name=$matches[1]');

So we’re going to title our new page Widget (because of the pagename=widget part of the new re-write rule). Make sure to select the custom template we created above in the Page Attributes info box on the right of the screen. Click the Publish button to publish the new page. If you view the published page you should see exactly nothing because, of course, we still haven’t put any code in our new page type template to pull data from the database.

Add the Database Code to the Custom Page Type Template

In this case I’m modifying the standard page template for the Reponsive WordPress Template. Your template may look at bit different but the general principles will still apply. Open up the widgets.php file in the editor a enter the following just below the PHP title block.

$page_content= "<p>Oops.  I think you've come here by mistake.</p>";
$page_title='';

$widget_name='';
if(isset($wp_query->query_vars['widget_name'])) 
{
	$widget_name= urldecode($wp_query->query_vars['widget_name']);
}

Here we’ve set some default values for the page title and page content. Then we’re checking for the existence of the URL parameter widget_name which is stored in the WordPress query_vars array and if it does exist it’s getting stored in the $widget_name variable. Now let’s add this code:

if ($widget_name!='')
{

	$widget_name=str_replace("-"," ",$widget_name);
	global $wpdb;
	$authors=$wpdb->get_results("select * from widgets where name='".addslashes($widget_name)."'");
	foreach ($widgets as $widget)
	{
          $page_title='<h1 class="entry-title post-title">Information about '.$widget_name.'</h1>';
	  $description=$widget->description;
          $price=$widget->price;
          $image=$widget->image_link;
          $page_content='<p>Description: '.$description.</p>';
          $price='<p>Price :'.$price.'</p>';
	}
}

That code is fairly easy to understand. If $widget_name is set then we’re removing the hyphens from it and use it with the $wpdb object to do a SELECT on the widgets table. The returned data is then stored in the $page_content variable while the page title is stored in the $page_title variable. Now that the data has been retrieved we need to display it at the correct point in the template file. The $page_title should be echoed like this:

<?php responsive_entry_top(); ?>

<?php echo $page_title; ?>

<div class="post-entry">

Then you can put the page content a bit further down the page like this:

<div class="post-entry">
<?php 
if ($page_content!="<p>Oops.  I think you've come here by mistake.</p>")
{
  the_content( __( 'Read more &#8250;', 'responsive' ) );
}
?>
<?php echo $page_content; ?>
<?php wp_link_pages( array( 'before' => '<div class="pagination">' . __( 'Pages:', 'responsive' ), 'after' => '</div>' ) ); ?>
</div>

Once you’ve done that save the custom page template. To test if the custom page is working load up the page that contains the complete list of widgets (the one we created in this posts) and click on the detail links for one of the widgets. You should then be taken to the details page for the widget you clicked on.

Displaying Data from a Custom Table in WordPress

As part of a recent WordPress development project I needed to be able to display data from a custom MySQL database table in WordPress. This data was master product data what would link to child records via custom URL parameters. I’ve covered how read the custom query vars in WordPress . Continuing with the widgets example in that post basically I wanted to create a page of widgets that would link to detail page for each different type of widget. I also wanted to be able to allow the WordPress user to maintain all other content on that page. The solution was to implement the widgets table in a WordPress ShortCode. A shortcode is a short macro code (such as [widget_table]) that can be inserted into a normal WordPress page or post. It will be parsed by WordPress before being displayed an replaced with some other text. In our case we want the [widget_table] shortcode to be replaced by the data we want to display from the custom MySQL widget table.

To create a shortcode it’s simply a matter of adding this code to your child template’s functions.php file:

add_shortcode('widget_table','generate_widget_table');
//[widget_table]
function generate_widget_table($atts) 
{
	return "widget table goes here";
}

Now, if we put the short code [widget_table] in a WordPress post or page and view the page we’ll see the text “widget table goes here”. Of course, that’s not very useful because we’d really like to display some data from our custom MySQL table that contains all of our widget information. To do that we need to make use of the WordPress global database object, $wpdb. We can use that to run a SQL query against our custom table and it will return an array of objects representing each row selected. Each one of those objects has a property representing each column selected from the table. Knowing that we can replace our generate_widgets_table function with something that looks like this:

function generate_widget_table($atts) 
{
	global $wpdb;
	$widgets=$wpdb->get_results("select distinct(name) from widgets order by name asc");
        if ($widgets!=null)
        $content="no widget records selected";
        {
	    $content= '<table>';
	    foreach ($widgets as $widgets)
	    {		
		    $content.= '<tr>';
	    	    $content.= '<td>'.$widget->name.'</td>';
		    $widget_url=str_replace(" ","-",$widget_name);		
		    $content.= '<td><a href="/widgets/'.$widget_url.'/">View More Information about the '.$widget->name.'</a></td>';
		    $content.= '</tr>';
	    }
	    $content.= '</table>';
        }
	return $content;
}

Notice that we iterate through the returned $widgets array and construct a link for each type of widget selected. The link is of the form “/widgets/widget-name/”. This form of URL can be used directly with the custom URL parameters we defined in this post to select individual widget records. Note also that we test that some data is actually selected (using the $widgets!=null test) and display some useful feedback. You might also notice that the generate_widget_table function has a parameter passed to it called “$atts”. While it’s not used in this example it does allow your WordPress users to pass your shortcode some parameters to refine your query or similar. I’ll cover how that works in a future post.

Reading Custom URL Parameters in WordPress

To be able to pull data from custom tables in WordPress you’re almost always going to need some custom URL parameters to select the right data.  For example, let’s assume we are a company that sells widgets, and we have several types of widgets including “Blue Widgets” and “Red Widgets” and “Black Widgets”.  What we want from our new Amazing New WordPress Site is to display a page listing all of the types of widgets we sell and for users to be able to click on a link for each widget type and drill down and see more details on each type of widget.  The URL structure for such a site might look like this (in mod_rewrite permalink form):

http://www.our-site.com/widgets/
http://www.our-site.com/widgets/blue-widgets/
http://www.our-site.com/widgets/red-widgets/

To be able to pull the data for blue widgets from a custom MySQL table we must get some information from the URL the user is requesting. If your WordPress install is using mod_rewrite permalinks then this can be pulled from the URL by adding rewrite rules to WordPress. To do this you must have created a WordPress child theme. Once that is done open the child theme’s functions.php file and add the following code:

/*
* Add re-rewite rules for widget pages.  Remember to refresh permalinks if changing this
*/
function add_rewrite_rules($aRules) {
$aWidgetPage = array('widgets/([^/]+)/?$' => 'index.php?pagename=widget&widget_name=$matches[1]');
$aRules = $aWidgetPage + $aRules;
return $aRules;
}

// hook add_rewrite_rules function into rewrite_rules_array
add_filter('rewrite_rules_array', 'add_rewrite_rules');

The add_filter call allows us to add rules to the WordPress rewrite rule array. The function add_rewrite_rules adds the actual rewrite rule itself. Note that you must refresh WordPress permalinks after you’ve added this code for it to work correctly. Basically the rule we’ve added passes everything after the /widgets/ part of the URL as the URL parameter “widget_name” to a WordPress page called “widget”. The URL parameter will automatically be added to the WordPress query_vars array. Of course we’re going to have to create a WordPress page called “widget” and once we’ve done that the widget_name URL parameter is going to be available for use. You can access it via PHP (perhaps from a custom page template) using this code:

$widget_name='';
if(isset($wp_query->query_vars['widget_name'])) 
{
	$widget_name= urldecode($wp_query->query_vars['widget_name']);
}

Once you’ve read the widget_name parameter you can use it to access database information. Of course you’re going to need to make sure widget_name is unique in your database table. If it’s not you might like to consider embedding a database ID in your product links and parsing that out of the URL parameter. You could do that pretty simply by creating product links that look like this:

http://www.our-site.com/widgets/blue-widgets-1/
http://www.our-site.com/widgest/red-widgets-2/
http://www.our-site.com/widgest/purple-widgets-3/

And then exploding them out of the URL parameter like this:

$widget_name='';
if(isset($wp_query->query_vars['widget_name'])) 
{
	$widget_name= urldecode($wp_query->query_vars['widget_name']);
        $widget_array=explode("-",$widget_name);
        $widget_id=$widget_array[count($widget_array-1)];
}

Next post I’ll cover how to create the master list of widgets including pulling the records from a custom table putting that information in a ShortCode that can be used in any WordPress post or page.

Flexing My WordPress Muscles

The last couple of weeks have seen me having a bit of fun with WordPress.  I have to be a secret squirrel about the exact details so please excuse the vagueness for the time being. I’ll be able to disclose what I’ve been working on full in the next few months. All I can say for now is that I’ve been building a new website for the Australian national association that represents a major hobby. They approached me to find a better way of publishing their annual journal online and to (perhaps) give their website a facelift. Their old site (still is) built in frames and uses image links for all site navigation. Their journal is available for download via various PDF files but I couldn’t actually get most of it to download at all in Chrome or Firefox. So, things were horribly broken.

Given that the hobby this organisation represents is one that my partner is interested in I was prepared to help them out so after a few discussions with their president I started building something for them in WordPress.  The reasoning behind this was to give them a much better way of managing their own content and to give them a system that could be maintained and modified by any reasonably competent web developer.  Right now to produce web updates they need to edit raw HTML files and email the files to a third party so they can be FTP’d to their web-server.  Yuck.

I’ve used WordPress several times in the past, but mostly just as a simple content management system. I’ve never really tried to extend it other than via a plugin that enabled me to insert some simple PHP into posts. I’ve never looked at child templates, I’ve never looked at custom post types, and never looked at extending it via PHP.  This new website looked like an ideal opportunity to learn a bit about WordPress as I tried to meet the key requirements for this new site:

  1. Move all static content from the old website into the WordPress platform.
  2. Create a conservative yet modern and attractive design for the site that did not require the hiring of a graphic designer (I know this is silly, but they don’t have much money to spend).
  3. Make yearly journal PDF’s available via download but move journal table of contents into web-pages.
  4. Create a list of journal authors and list the articles they have written for the journals.
  5. Create a list of journal articles including titles, keywords, and (of course) associated them with the relevant journal.
  6. Make the journal table of contents, article titles and keywords, and author names searchable via the WordPress search function.

I was confident that items 1 and 2 could be accomplished via vanilla WordPress functionality.  Points 3 through 6 were going to require some custom database tables, a way of pulling data from those tables, and a way of displaying the data in WordPress pages.  Point 6 was going to require a bit of massaging of the built in WordPress search engine.  Even though I’ve only spend a couple of dozen hours completing the new website I learned enough about WordPress in that time to be hellishly impressed with it.  And keen to use it again on some projects of my own.  So I’ve decided to write a bit about what I did and how I did it and have created a new WordPress blog category for these new posts.  Stay tuned for more posts over the next few days.