Home Notes Web development

Development
Cookies and sessions in WordPress E-mail
Tuesday, 31 August 2010 10:11

Two points to note in working with cookies and sessions in WordPress:

  1. You can't set cookies from the template header file.  It has to be done from functions.php.
  2. You can't start a session from the template files.  That should be done from wp-config.php like so:

//start a session
if (!session_id())
 session_start();

 
WordPress plugins for convenient deployment E-mail
Monday, 02 August 2010 12:12

I've been developing small WordPress themes lately, and I want to share two plugins that allow me to quickly add widgets in a way so I don't have to reconfigure paths when moving from the development to the production server.

The two plugins are Widget Logic and PHP Code Widget.  You can see in the screenshot below how simple they are to use:

 

wp_widget_plugins

 
Find and replace text in MySQL E-mail
Thursday, 27 May 2010 00:10

Say you're moving a site from the development server to the production server, and the client has been making updates (adding content, etc.) while the site's been under development.  The problem is that they've been using absolute URLs (http://www.somesite.com/some/somepage.htm) instead of relative ones (some/somepage.htm), so you have to go in and change anywhere from several to several thousand links to either the new site's full URL, or make all the URLs relative.  What do you do?

You can do a simple find-and-replace in MySQL using the following statement:

UPDATE TABLE_NAME SET field_name = REPLACE(field_name, 'text being replaced', 'replacement text');

 
Yoast Breadcrumbs: Displaying slugs instead of titles E-mail
Sunday, 14 March 2010 11:24

I was asked recently how I modified the Yoast Breadcrumbs WordPress plugin to display page slugs instead of page titles.  I won't explain what I did here but only show what modifications I made to the breadcrumbs.php file.  I was working with v. 0.8.4 of the plugin.  Before making any modifications to newer versions, make sure the code looks similar to the original I've pasted here.

 

 

Original:

  // If this is a top level Page, it's simple to output the breadcrumb
  if ( 0 == $post->post_parent ) {
  
 
 
 
 
  $output = $homelink." ".$opt['sep']." ".bold_or_not(get_the_title());
  } else {
   if (isset($post->ancestors)) {

 

Modified code:

// If this is a top level Page, it's simple to output the breadcrumb
  if ( 0 == $post->post_parent ) {
   $temp = get_permalink();
   $temp = explode("/",$temp);
   $temp = array_reverse($temp);
   $temp = $temp[0];
 
   $output = $homelink." ".$opt['sep']." ".bold_or_not($temp);
  } else {
   if (isset($post->ancestors)) {

 

 

Original:

$links = array();   
   foreach ( $ancestors as $ancestor ) {
    $tmp  = array();
    $tmp['title']  = strip_tags( get_the_title( $ancestor ) );
    $tmp['url']  = get_permalink($ancestor);
    $tmp['cur'] = false;
    if ($ancestor == $post->ID) {
     $tmp['cur'] = true;
    }
    $links[] = $tmp;
   }
 
   
 
 
   $output = $homelink;
   foreach ( $links as $link ) {

 

Modified:

$links = array();   
   foreach ( $ancestors as $ancestor ) {
    $tmp  = array();
    $tmp['title']  = strip_tags( get_the_title( $ancestor ) );
    $tmp['url']  = get_permalink($ancestor);
    $temp = explode("/",$tmp['url']);
    $temp = array_reverse($temp);
    $tmp['title'] = $temp[0];
    $tmp['cur'] = false;
    if ($ancestor == $post->ID) {
     $tmp['cur'] = true;
    }
    $links[] = $tmp;
   }
 
   $output = $homelink;
   foreach ( $links as $link ) {

 
How to set a cookie using PHP or JavaScript E-mail
Friday, 22 January 2010 12:27

In my jQuery Woopra plugin, I have added the feature to exclude visits by cookies.  Since Woopra does not yet have the ability to set cookies itself like Google Analytics, you must set it yourself.  Thankfully it's pretty easy to do.  Below I will show you how to set a cookie to use with the jQuery Woopra plugin to exclude visits based on that cookie.

Place the following within <?php and ?> tags in a PHP file.

 
$value = 'true';
setcookie('woopraExclude', $value, time()+(365*24*60*60))
 

The code above sets a cookie with:

  1. name = woopraExclude
  2. value $value = 'true'
  3. expiration = current time plus one year

This is the method I use on my sites.  I've placed the code below in a plain HTML file that loads as the start page on all my browsers, ensuring that all my visits to my own domains don't count as visits in analytics.

To set a cookie with JavaScript, I recommend using the webtoolkit.cookies.js script that comes bundled with the jQuery Woopra plugin.  To set a cookie using that script, place the following within <script type="text/javascript"> and </script> tags:

 
var Cookie = new CookieHandler();
var excludeCookie = Cookie.setCookie('woopraExclude','true',365*24*60*60);
 

The code above sets a cookie with:

  1. name = woopraExclude
  2. value $value = 'true'
  3. expiration = current time plus one year

To make use of this cookie in your Woopra analytics code, you would initialize your Woopra tracking function as:

 
$.trackWoopra({cookie: 'woopraExclude'});
 

 
Speeding up your WordPress site with plugins E-mail
Thursday, 14 January 2010 20:00

It's somewhat ironic that at one end we're collecting more and more data, we're clammoring for more and more bandwidth and storage space and ways to access it.  Yet on the other hand we obsess over the kilobytes and even bytes we can shave off our webpages in order to have them load fractionally faster.  We minify, we GZip, we cache, we do all sorts of things...anyway, it's just an observation I thought was interesting.

I wrote earlier about ways to speed up your website.  Those were mainly .htaccess fixes.  If you use WordPress, however, a lot of the hard work is taken care of for you by some excellent plugins out there.  Here are a few I've tried, and my experience with them on WordPress 2.8.6:

 Autoptimize

Autoptimize is advertised as a do-it-all plugin for your WordPress site, and it works pretty well although I haven't tried all its features.

Observations and conflicts

  1. Optimization of JavaScript code broke Hackadelic Slider Notes on one of my pages.  Enabling the "Add try-catch wrapping?" option, however, fixed that issue.
  2. "Optimize CSS Code" breaks WP-Cufon
  3. I have enabled "Rewrite Image URLs" and changed the "Image Base URL" to use CoralCDN's nyud.net URL appendage, but I haven't noticed it working on the images on my WordPress site.
  4. I enabled "Rewrite JavaScript URLs" and "Rewrite CSS URLs" and they work fine.  (I'm using CoralCDN's nyud.net for these as well.)


 Free CDN

Free CDN lets you use Coral CDN to reroute several types of assets on your website, including CSS, JavaScript, images, and external content.

Observations and conflicts

  1. This plugin worked unreliably in my experience.  I tried to figure out which other plugin(s) it was conflicting with but couldn't narrow it down because it's most likely more than one.  When it was working, it screwed up CSS rendering and some JavaScript functionality.  It should be noted that this might not be the plugin's fault at all.  It has been noted elsewhere that CoralCDN is better for bigger assets (pictures, movies, MP3s) than smaller ones (images, CSS, and JavaScript files).  Using CoralCDN with Autoptimize works fine, so most likely the problem is with the plugin.
  2. It seems to conflict with one of either the Star Rating for Reviews or WP Movie Ratings plugins, or maybe both.  The Movies page on my blog shows up blank when this plugin is activated, and both of those plugins are used on only that page.


 JavaScript to Footer

JavaScript to Footer is a no-frills plugin that does just what the title says: It moves all your JavaScript to the footer of the page for faster loading.

Observations and conflicts

  1. Works as advertised.  There is nothing to configure, just turn it on and go.
  2. It breaks WP-Cufon, which makes me wish it let you configure which files it moves and which ones it leaves alone.

 GZIP Output

Another simple plugin with nothing to configure, GZIP Output does just what it says: It Gzips the HTML content of your WordPress site before sending it out.

Observations and conflicts

  1. I didn't find this plugin conflicting with any other plugins.  However, I think going the .htaccess route is a more efficient way than using a plugin for Gzipping your HTML content.

 Parallel Load

Parallel Load loads all your JavaScript files in parallel, with the additional option to move them to the footer of your webpage.

Observations and conflicts

  1. jQuery fails to load with this plugin enabled, so it won't work for me.

 My CDN

By the author of Parallel Load, My CDN rewrites your URLs to use a CDN.  You can specify different URL for CSS, JavaScript, and theme files.

Observations and conflicts

  1. Rewriting the URLs to use CoralCDN's nyud.net breaks the loading of CSS files, similar to Free CDN.  Again, since CoralCDN works fine with Autoptimize, the problem is most likely with the URL rewriting method used in the plugin (I am just speculating because I haven't looked inside the plugin code).
  2. The good news is that this plugin does not break the site altogether like FreeCDN does.  It's a much smaller plugin with fewer features, which means fewer chances for conflicts with other plugins.

Please remember that these are just my experiences with these plugins.  Yours might be different, depending on the version of WordPress and other plugins you're running.

 
WordPress plugin: Flash Header Rotator E-mail
Sunday, 20 December 2009 17:36

Flash Header Rotator is an extension of the Header Image Rotator plugin by Matthew Hough that allows embedding of Flash SWF files along with the image files the original plugin allows.  Please see the original plugin's site for documentation on its features.  Below I will only be outlining the extended Flash features I have added to it.

Features

  • Ease of use: Simply upload your swf files to the wp-content/header-images folder and they will be rotated along with any image files in there
  • SWFObject: The plugin uses SWFObject to allow for a more robust embedding.  It detects if SWFObject is already loaded from another plugin.  If not, it loads it for you.
  • It automatically detects the dimensions of the Flash movie, but also allows you to override them manually.
  • You can specify from the WordPress Administration panel the minimum version of Flash you want your site's viewers to have for the Flash movies to display.

Usage

All you need to do is activate the plugin and upload your files for the plugin to work.

  • If you would like to override the default dimensions, rename the movie file as:

filename_width_height.swf

So if you have a file named kiki.swf and you want to show it at 700x200, rename it kiki_700_200.swf.

In the WordPress Administration panel, under Settings > Flash Header Rotator, you can set the following options:

  1. The minimum Flash version required for your Flash movies to display.
  2. The CSS you want to apply to the <div id="flash-_-header"></div> that wraps the Flash movie.
  3. The plugin uses the wmode: 'transparent' parameter to render the background of Flash movies transparent.  Since most headers contain navigation links, this setting is on by default.  This setting can be turned off on the plugin settings page.
  4. The plugin lets you specify whether you want SWFObject to publish your movie statically or dynamically.  The default setting is static.  See the official documentation here for more details.

Download

Download Flash Header Rotator WordPress plugin

 
jQuery Woopra plugin part 2: Usage E-mail
Monday, 14 December 2009 20:11

I will document here how I am using this plugin, through which you can determine how best to use it for yourself.

pthesis.com

I tested the jQuery Woopra plugin on my own portfolio website, p()thesis.  I'll present the index.html code in bits and explain as I go along.

<head>
<title>Web developer and designer in Boulder, Colorado</title>
<meta content="en-us" http-equiv="Content-Language" />
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<script src="http://www.google.com/jsapi?key={your key}" type="text/javascript"></script>
<script type="text/javascript">google.load("jquery","1.2");</script>
<script type="text/javascript" src="includes/jquery.livequery.js">script> 
<script type="text/javascript" src="includes/jquery.google-analytics.js"></script>
<script type="text/javascript" src="includes/jquery.woopra-analytics-min.js"></script>
<script type="text/javascript" src="includes/webtoolkit.cookies.js"></script>
<script type="text/javascript" src="functions.js" mce_src="functions.js"></script>
<script type="text/javascript">
$.trackWoopra({cookie : 'woopraExclude'});
$.trackPage('UA-xxxxxxx-xx');
</script></head>

Pretty standard stuff:

  1. Declare meta content
  2. Load jQuery - I load it via GoogleAJAX APIs
  3. Load jQuery Livequery plugin, which I will be using for this plugin
  4. Load functions.js which contains the JavaScript functions used in the site
  5. Load jQuery Woopra plugin, either the standard or the minified version (I've also left in the jQuery Google Analytics plugin for demonstration purposes)
  6. Load the Webtoolkit Cookies script - this is only necessary if you want to exclude visits by cookies (See here for how to set a cookie using either PHP or this simple script)
  7. Initialize jQuery Woopra plugin with the cookie parameter to exclude visits from all visitors who have the cookie woopraExclude set:

<script type="text/javascript">
$.trackWoopra({cookie : 'woopraExclude'});
</script>

The next step is to load the page HTML content as usual.  At the bottom of the document is where all my JavaScript is:

<script type="text/javascript">
$(document).ready(function(){
...
   $('#pfolio').click(function(){
        $('#portfolio').show('slow')
...
   })
// location for analytics code
})
</script>

Here are the few lines that enable Woopra analytics on my site via the jQuery Woopra plugin.  I've left in the jQuery Google Analytics plugin code so you can see the similarities and differences in syntax between the two.

$('#refine_by').livequery(function(){$('#refine_by').track({
category : 'refine_by',
action : 'click'})})
    $('#refine_by').livequery(function(){$('#refine_by').trackEvent({
title : 'refine_by'})
})
    $('#sites ul li').livequery(function(){$('#sites ul li').not('#reset_sites').track({
category : 'site',
action : 'click',
label : function(element) {return element.text()}}
    )})
    $('#sites ul li').livequery(function(){$('#sites ul li').not('#reset_sites').trackEvent({
title : 'site',
label  : function(element) {return element.text()}
})})
    $('#categories ul li').livequery(function(){$('#categories ul li').track({
category : 'category',
action : 'click',
label : function(element) {return element.text()}
})})
    $('#categories ul li').livequery(function(){$('#categories ul li').trackEvent({
title : 'category',
label : function(element) {return element.text()}
})})

 


Let's go over a couple of these lines.

$('#refine_by').livequery(function(){$('#refine_by').trackEvent({
title : 'refine_by'})
})

refine_by

  1. $('#refine_by') - the element being tracked
  2. .livequery(function()($('#refine_by') - because the element is not created when the DOM is ready, I am using the livequery plugin to actively apply the tracking rule each time the #refine_by element gets created via AJAX.  If you're using jQuery 1.3 you can use the built-in live method to achieve the same purpose.
  3.  .trackEvent({title : 'refine_by'}) - the only parameter I'm passing through in this example is the title of the event

Now let's look at one of the more complex examples, where I'll be tracking the sites in the list in #sites ul li:

sites_ul_li

$('#sites ul li').livequery(function(){$('#sites ul li').not('#reset_sites').trackEvent({
title : 'site',
label  : function(element) {return element.text()}})
})

The main difference here is that I'm passing a function to the label property.  This particular function evaluates the text of the li element that is clicked on and stores it in Woopra.  This lets me track which site in the list the visitor has clicked on.

To track an a element I might use something like this:

$('div#site_details a').trackEvent({
title : 'site_details',
label : function(element) {return element.attr('href')}
})

I didn't use livequery in this statement because of where it was placed in my code.  I placed it where the a elements are created, so there's no need to apply the code to any elements that haven't yet been created.  The label property is now storing the URL of the a element being tracked.

Note that all a elements are being tracked, and whichever particular one is clicked, that one's URL will be returned.  So for example, in the example below, there are three a elements (in red).

site_details_a

 
«StartPrev12345678NextEnd»

Page 3 of 8