Home Notes Web development

Development
jQuery Woopra plugin part 1: Introduction E-mail
Monday, 14 December 2009 16:04

Taking inspiration from Christian Hellsten's jQuery Google Analytics plugin, and using it as a starting point, I have developed a jQuery plugin to implement Woopra analytics in your application (download).  Right now, in version 1.1.5:

It adds the following methods to jQuery:

  • $.trackWoopra(options) - Adds Woopra tracking on the page from which it's called.  This is the only required method to enable Woopra tracking.
  • $.woopraEvent(options) - Tracks an event using the given parameters
  • $('a').trackEvent(options) - Adds event tracking to element(s)

This method is required, and can be used simply as:

<script type="text/javascript">
$.trackWoopra();
</script>

or:

<script type="text/javascript">
$.trackWoopra({
domain : 'http://www.mydomain.com',
url : 'http://www.myurl.com',
title : 'My page',
cookie: 'someCookie'});
</script>

All parameters in example above are optional:

  • domain - use it to specify root domain (to enable tracking of sub-domains)
  • url and title parameters must be passed in together as a pair; use them to give pages custom names in Woopra
  • cookie allows you to exclude visitors who have the cookie set (someCookie in this case)

See here for more information on using these optional parameters.  (The cookie feature is not yet built into Woopra, so you won't see any information on that on the Woopra site.  Once they implement it into the core, I will remove this add-on feature and incorporate their implementation.  You can learn more about how to use my current implementation here.)

Used like:

<script type="text/javascript">
$.woopraEvent({
title : 'category_click',
label : 'Category1',
url : 'url1'
event_name : 'click'});
</script>

This method is best called from the next one, $.trackEvent(options).

Takes the following parameters:

  • title - required.  Name for the event being tracked.
  • event_name - optional.  Name of event you want to bind to.  Default is 'click'.
  • as many (key,value) pairs as you want your event to have

Example usage:

<script type="text/javascript">
$('#content #links a').trackEvent({
title : 'Links_hover',
label : function(element) {return element.text()},
url : function(element) {return element.attr('href')},
event_name : 'mouseover'});
</script>

Similar to the jQuery Google Analytics plugin, you can enter functions as property values, and they will be evaluated for the element that is the target of the event triggered.  However, whereas Google Analytics takes a specified number of parameters in its event tracking object, Woopra lets you specify custom properties and values, so this plugin was modified to accomodate for that.

In this example, everytime a visitor hovers over a link (<a> element) inside #content #links, a 'mouseover' event will be registered in Woopra, with the following properties:

  1. title: Links_hover
  2. label: the text between the <a> and </a> tags
  3. url: the url in the href attribute of the link clicked

Version 1.1.5 - added ability to exclude visits with cookies, similar to Google Analytics.

Version 1.1 - removed setTracker property which is no longer supported by Woopra.  To download older releases, visit the official jQuery plugin page.


View jQuery Woopra plugin part 2: Usage

Download

Download jQuery Woopra plugin


 
How to: Check Google Analytics event tracking E-mail
Wednesday, 25 November 2009 17:52

Google Analytics offers Event Tracking, which is useful for tracking JavaScript and Flash events.  But there's at least a day's delay before you can get analytics to show up, so if you're testing your own or a client's site, it could take a while to get things right.

There is, however, a way to check if your event-tracking code is working on your pages.  This way you don't have to wait to log in to Analytics the next day and see if your events registered.

Required ingredients

  1. Implementation of Google Analytics tracking code in the website you want to track
  2. Mozilla Firefox
  3. Firebug extension for Firefox

What to do

It's really quite simple:

  1. Load up your website and start up Firebug.  If you have screenspace you would want to pop Firefox out of the browser window into its own window.
  2. Enable the Net panel in Firebug.
  3. Once you've got the website up, click around or do whatever to trigger the events are you want to track.
  4. If event tracking is working, you should see an entry like the following upon triggering your event:
  5.  

    Firebug Net panel

     

  6. Go ahead and click the "+" button to the left and select "Params", which will show you something like:
  7.  

    Firebug Net panel

     

  8. What you're looking for is the highlighted entry, because this shows you the parameters you entered in your event-tracking code.  In my case, the code was:
  9. page_Tracker._trackEvent('site' , 'click' , 'Pkstore');

  10. So now you know that event-tracking is working for this event.  You can check other events in the same way.
 
Speeding up your websites E-mail
Thursday, 29 October 2009 17:31

I've run YSlow on several websites, including my own, and it gives some good suggestions for speeding up your website.  So here are a few tips I've found from around the web for generally speeding up a website:

ETags and Expires Headers

Update

I have changed the code below to the following, from this page:

<IfModule mod_headers.c>
Header unset ETag
FileETag None
<FilesMatch "(?i)^.*\.(ico|flv|jpg|jpeg|png|gif|js|css)$">
Header unset Last-Modified
Header set Expires "Fri, 21 Dec 2012 00:00:00 GMT"
Header set Cache-Control "public, no-transform"
</FilesMatch>
</IfModule>


These can be added by adding the following to your .htaccess file (from here):

<IfModule mod_headers.c>
Header unset ETag
Header unset Last-Modified
</IfModule>
FileETag None

<FilesMatch "\.(ico|gz|JPG|jpg|jpeg|png|gif|js|css|swf)$">
Header unset Cache-control
Header set Expires "Wed, 28 Apr 2010 20:00:00 GMT"
</FilesMatch>

The first of these requires mod_headers, and the latter mod_expires to be enabled on your Apache server.

Gzip


Update

If your site runs on cPanel and you have access to it, you can also turn on compression - either only for certain extension or for all files - by going into Optimize Website from the main cPanel screen.  You'll see the following:

cPanel

If you don't have access to cPanel, you can use the following in your .htaccess file (instead of what's posted below).  This will compress all content except for file extension types you specify:

SetOutputFilter DEFLATE
SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ \
    no-gzip dont-vary
SetEnvIfNoCase Request_URI \
    \.(?:exe|t?gz|zip|bz2|sit|rar)$ \
    no-gzip dont-vary
SetEnvIfNoCase Request_URI \.pdf$ no-gzip dont-vary
In this example the following extensions are excluded: exe, tar.gz, zip, bz2, sit, rar, and pdf

This requires that mod_gzip or mod_deflate be enabled on your server.  I found several solutions to add this to your site, so I'll list them all:

To compress all text and HTML:

AddOutputFilterByType DEFLATE text/html text/plain text/xml

To compress certain file types by extension:

<Files *.html>
SetOutputFilter DEFLATE
</Files>

Here's the other route:

AddOutputFilterByType DEFLATE text/html text/css text/plain text/xml application/x-javascript
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html

There's also the PHP route, which is to add the following to the top of each of the files you want to compress:

if (substr_count($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip'))
ob_start("ob_gzhandler");
else ob_start();

It seems there are plugins available for both WordPress and Joomla to help with compression and mini-fication:

Finally, this seems to be the most popular place to test whether your site is being transmitted compressed.  (Here's another site.)These are the most effective site-wide changes you can make.  Other than that, you can individually compress JavaScript and CSS files, and optimize your site's images.

 
AEI Dish Network E-mail
Monday, 05 October 2009 19:18

AEI Dish Inc. is a Dish Network regional installer for satellite TV and satellite Internet.  AEI Dish Network has been in business since 1997.

The website was developed on WordPress with Thesis, with heavy JavaScript (with jQuery) and PHP customizations.

 

The three feature boxes and sidebar on the right are instituted via the Improved Include Page plugin.

 

Other features include:

  • Custom font for headers is implemented via Cufon, and incorporated using the WP-Cufon plugin
  • Header image is specified via a custom field, so each page can have its own unique header
  • Dynamic drop-down menus are CSS-only based, with a small jQuery solution for potential IE problems
  • Yoast Breadcrumbs plugin modifed to display slugs instead of page titles

AEI Dish Network


Carousel

The carousel is uses the jCarousel Lite jQuery plugn, and I hand-coded the entire functionality.  All code and content are stored in the WordPress page and not in any back-end file, so upgrading is not an issue.

 

Carousel


Accordion

The accordion uses the Hackadelic Sliding Notes plugin for WordPress.

 

Accordion


Feature boxes

The sidebar on the left is also implemented via Improved Include Page, so each page can have its own unique sidebar.

 

Support

 
Lutsey Land Company E-mail
Sunday, 26 July 2009 14:46

This is a website I converted from a PSD design to a fully-functional WordPress theme based on the Thesis framework.

Lutsey Land Company

The site makes use of several basic in-built WordPress features, including:

  • custom fields
  • hooks
  • permalinks
  • pages

The following WordPress plugins are used:

 
Displaying meta keywords in articles E-mail
Saturday, 16 May 2009 23:12

It took a while but I found what I was looking for: an extension that allowed me to display meta keywords within articles.  The bonus is it turns each one into a link with which you can browse other articles sharing that keyword.

I made one small and easy tweak.  By default the plugin only displays the tags in individual article view.  I modified the SearchTag.php file from:

if ((JRequest :: getVar('view')) == 'article'){

to:

if (((JRequest :: getVar('view')) == 'article') || ((JRequest :: getVar('view')) == 'frontpage')) {

Now the tags appear on the frontpage as well.

 
sh404SEF and RSS E-mail
Sunday, 03 May 2009 00:12

Like many Joomla! users out there I use the sh404SEF component for SEO-friendly URLs.  When I decided today to activate the RSS feed for this site, I ran into a certain problem.

The sh404SEF component was renaming the RSS URL:

index.php?format=feed&type=rss

to index.php/feed/rss.html, which just wasn't working.

I wanted to use FeedBurner to syndicate the feed, and I was able to find an easy solution to the sh404SEF problem in this forum post.  The solution, shown below, involves creating a custom redirect in sh404SEF for the proper feed URL, and supplying that to FeedBurner.  From there the FeedBurner URL takes over and you can syndicate your RSS feed to the world.

(image below is from the forum post linked to above)

sh404SEF custom redirect

 
Joomla! Code display - harder than I thought E-mail
Thursday, 23 April 2009 15:43

Update

Finally, got one working!  It took a while but I got Highlight Code with Jumi working after modifying the helper file.  Specifically, I had to remove references to:

$mainframe->getCfg('live_site')
 
//and
 
$mainframe->getCfg('absolute_path')

And replace them with the relative path of the files in question.  I also didn't like how the plugin hid the code by default and gave the user a JavaScript function to expand/collapse the codebox.  I got rid of that by disabling the JavaScript file and modifying the helper file as follows (note the commented lines near the bottom):
class highlightHelper {
 function add_tags() {
  global $mainframe;
  $document = &JFactory::getDocument();
  $plugin = &JPluginHelper::getPlugin('content', 'cdchilicode');
  $pluginParams = new JParameter($plugin->params);
  $document->addStyleSheet('plugins/content/highlight/highlight.css', 'text/css');
//  $document->addScript('plugins/content/highlight/highlight.js');
  $style = 'display: block;max-height:'.$pluginParams->get('height', "350px").
    ';width:'.$pluginParams->get('width', "650px");
  $mainframe->addCustomHeadTag('<style type="text/css">div.highlight { '.$style.' } </style>');
 }
}
 
function highlight_replacer(&$match) {
  global $mainframe, $loaded_script, $highlight_id;
  $db = &JFactory::getDBO();
  
  $plugin = &JPluginHelper::getPlugin('content', 'cdchilicode');
  $pluginParams = new JParameter($plugin->params);

if ($match[2] && !file_exists("components/com_jumi/jumi.php")) {
   return '<p class="highlight_error">'.JText::_('ERROR_JUMI_COMP').'</p>';
  }($match[1] == "html") {
   $lang = "html4strict";
  }
  else {
   $lang = $match[1];
  }
  if ($match[1] == "html4strict") { $match[1] = "html"; }
  
  if (!file_exists("libraries/geshi/geshi/".$lang.".php")) {
   return '<p class="highlight_error">'.str_replace("%s", $lang,
    JText::_('ERROR_LANG_NO_EXISTS')).'</p>';
  }
 
  if (!$match[2]) {
   $code = $match[3];
   $code = str_replace("</p>", "<br />", $code);
   $code = str_replace("</div>", "<br />", $code);
   $code = str_replace("<br />", "\r\n", $code);
   $code = preg_replace("#<(.*?)>#is", "", $code);
   $code = html_entity_decode($code, ENT_QUOTES, "UTF-8");
  }

elseif ($match[2] > 0) {
   $db->setQuery("Select custom_script from #__jumi where id='$match[2]'");
   $code = $db->loadResult();
  }
 
else {
   $db->setQuery("Select custom_script from #__jumi where alias='$match[2]' limit 1");
   $code = $db->loadResult();
  }

$geshi = new GeSHi($code, $lang);
//$geshi->enable_line_numbers(GESHI_NORMAL_LINE_NUMBERS,37);
  $geshi->enable_keyword_links(false);

$highlight_id++;
  $out = '<div id="highlight-'.$highlight_id.'" class="highlight">'.
    $geshi->parse_code().'</div>';
//  if ($pluginParams->get('hidde', 1)) {
//   $out = '<a class="highlight_mostrar" id="highlight-mostrar-'.
    $highlight_id.'" href="javascript:mostrar_ocultar('.$highlight_id.')">'.
    str_replace("%s", $match[2], JText::_('MOSTRAR_OCULTAR')).'</a>'.$out;
//  }
  return $out;
 }


I have spent the better part of two hours trying to implement a simple code display into my Joomla! installation, with still no success.  There are 12 plugins listed here in the Extensions directory, 7 of which are v1.5 native.

I have gone through all of them.  I have read their documentation, peeked into and tweaked the PHP files, but still no go.  Either some error shows up or nothing happens at all.  I didn't realize something so simple would end up being so hard!

 
«StartPrev12345678NextEnd»

Page 4 of 8