Andy on WordPress

Keyboard tapping since '83.

BuddyPress Components 1.0 Beta 1 — December 15, 2008

BuddyPress Components 1.0 Beta 1

After ten months of work, BuddyPress components and themes are available for download in their first beta release form.

We’re looking for testers, so if the project interests you, give it a shot and please report any bugs you find. Each component and theme will be upgraded to a final 1.0 version once it’s clear that it’s running with no major problems.

If you’re interested in testing BuddyPress without downloading and installing it, head on over to the demo site and register for an account there. The demo site runs the latest development release of BuddyPress.

For more information on the release, check out the blog post on the BuddyPress website.

Targeting IE 7.0 — November 3, 2006

Targeting IE 7.0

IE7The two main ones for me are conditional comments and the “first-child+html” fix found by Mark Hammond.

Conditional Comments

Conditional comments are small scripts that you place in your HTML. They check for the version of IE being used, and include whatever you put between the comments if conditions are satisfied. Here’s an example:

<!--[if IE 7]>
 Include my IE7 only stylesheet here.
<![endif]-->

Personally, I tend to stay well away from conditional comments. The idea of putting small scripts within HTML comments makes me shudder. It’s also basically a simple form of browser sniffing, and really, I don’t want to go back to those days thank you very much.

The “first-child+html” workaround

For now, my solution of choice is a little bit of CSS trickery to target IE7 specifically. I’ve used this workaround on this very site. I was having trouble with the logo being too close to the top of the window in IE7. What I wanted was to add an extra 20px of padding to the top of the logo in IE7 only:

#menuBar {
  float: right;
  display: inline;
  width: 240px;
}
   /* For IE7 */
   *:first-child + html #menuBar {
     padding-top: 20px;
   }

This worked a treat, and is perfect for the small fixes I need right now.

Mark Hammond goes on to note that this fix only reliably works when your page starts with a doctype and html element together (which is 99% of the time I would bet).

This of course exploits a bug in IE7, so there is no guarantee it will work in future updates. For now though, it provides the quick fixes I need until I can explore the browser further.

Who knows of any other workarounds for IE7? I’d be interested to hear how you are fixing your sites up to work with Microsoft’s latest.

CSS Tweak Dashboard Widget — May 31, 2006

CSS Tweak Dashboard Widget

Screenshot 1This is the first widget that I’ve ever made, it’s been really great to get into the guts of how they work.

For those of you that have never seen inside a widget, they are simply a combination of HTML, CSS and Javascript. So if you are a web developer, you most likely already have the knowledge and skills to make a fully functional dashboard widget.

Actually, I cheated a little with the CSS Tweak widget. Well, not so much cheated, but I didn’t code the whole thing in Textmate. I managed to be one of those lucky people who had an installed version of Dashcode on their new MacBook Pro. I used Dashcode to develop this widget from start to finish and I really only have great things to say about it.

Despite the program crashing a fair bit (which is understandable considering it is a pre/non-release version) it provides wysiwyg and debugging features that go a long way to help you set up your widget and get it working exactly how you want it. Plus, it has a gorgeous interface as you would expect from an Apple developed tool. 😉

Anyway, more about the widget itself. The widget will accept CSS files dropped onto it (which is annoyingly unintuative, but Apple fails to provide file input any other way). Once you drop a CSS file in, you are presented with tweaking options. You can choose to enable or disable any of the options, just the same as on the CSS Tweak website. Once you hit tweak, the CSS file is sent to the CSS Tweak server, tweaked, and then sent back and saved in the same location as your original file.

I hope that people find this tool useful. It will definately save time not having to visit a website, you can simply drop your file in from anywhere and you’re done.

This is of course the first version, and there will no doubt be a few bugs to iron out. Please let me know via email (andy [at] this domain) if you find anything out of whack. I should mention, you do need to be connected to the internet for this widget to work.

Download Download Widget

Durable: Best Overall Design! — May 17, 2006

Durable: Best Overall Design!

Arena WPI am very honored to have been named the winner by the judges as the field contained many great designs this time around.

Well, actually to be honest I am a little surprised. There were designs in the competition that are aesthetically far more pleasing than Durable. I was sure that those designs would have the extra edge over the themes that concentrated on function over form. I guess that was where the multiple categories came into play, my personal favorite was Derek’s very beautiful Foliage Mod Theme which won “Most Creative Design”. Well done Derek.

That begs a question though, are people beginning to pick themes based not solely on the look and feel, but also the bundled functionality? I can’t help but think that people’s feelings towards what makes a good WordPress theme have changed quite a lot since the WordPress 1.5 competition. The boundaries of what theme authors can do with WordPress has been pushed since 1.5, simply because better documentation is now available, and we’ve had more time to fiddle around with the WordPress code.

Anyway, that was more of a brain dump than anything. It’s just great to see that judges really took time to look at the themes, judging functionality just as much as the look and feel.

Thanks to everyone who put in their free time to make this competition possible, your hard work is much appreciated.

Update: I have released a minor update to Durable. Version 0.2.1 is available for download and decreases page load times by 25%.

Creating a Dynamic Navigation Menu — April 2, 2006

Creating a Dynamic Navigation Menu

Dynamic MenuInstead of answering questions individually, I thought I would run through how I created the menu, so others can benefit.

Here is a step by step guide. You should have an HTML page ready to add code into, and have a blank external javascript file linked in the header to add the javascript functions to.

Step 1: The HTML

The menu is just a simple unordered list with the ID set as “menu”. Each sub-level of the menu is another unordered list within the parents list item. You can create as many levels as your heart desires, as the javascript we’ll write in the next step can handle this.

Here is the HTML I’ll use for the example:


<ul id="menu">
 <li><a href="fruit.htm" title="Fruit">Fruit</a>
   <ul>
     <li><a href="apple.htm" title="Apple">Apple</a>
      <ul>
       <li><a href="grannysmith.htm" title="Granny Smith">Granny Smith</a></li>
      </ul>
     </li>
     <li><a href="orange.htm" title="Orange">Orange</a></li>
     <li><a href="banana.htm" title="Banana">Banana</a></li>
   </ul>
 </li>
 <li><a href="veg.htm" title="Fruit">Vegetables</a>
   <ul>
     <li><a href="carrot.htm" title="Carrot">Carrot</a></li>
     <li><a href="onion.htm" title="Onion">Onion</a></li>
     <li><a href="peas.htm" title="Peas">Peas</a></li>
   </ul>
 </li>
</ul>

This will produce a vanilla HTML list which you can check out in example 1.

Step 2: Collapsing the Menu

The next step is to make that vanilla HTML list into something a little less rigid. This is where we’ll dip into some fancy DOM scripting.

The first thing we want to do is collapse the menu once it’s been loaded. We’ll do this by writing a recursive function called collapseMenu(), to traverse through each nested list in your menu, and hide it.


function collapseMenu(node) {
 if (!document.getElementById) return false;
 if (!document.getElementById("menu")) return false;
 if (!node) node = document.getElementById("menu");

 if (node.childNodes.length > 0) {
  for (var i=0; i<node.childNodes.length; i++) {
   var child = node.childNodes[i];
   if (child.nodeName == "UL") {
    child.style.display = "none";
   }
   collapseMenu(child);
  }
 }
}

For those who’re interested, a recursive function is one that calls upon itself.

In this function, we start at the very first node which is the <ul id=”menu”> node. We then count how many child nodes there are, and if there’s 1 or more, we check to see if any of the children are <ul> nodes. If so, then we hide them, by setting child.style.display = “none”.

Then there’s that recursive part, we call the same function again, but this time pass in the child as the starting node. This will go through and check all the grandchildren. The recursion will continue until there are no remaining child nodes to cycle through and everything is hidden.

Step 3: Bringing Those Links to Life

As it stands right now, the HTML we created in step one has no javascript associated with it. By removing the javascript completely from the HTML and placing it in an external file we are paving the way for graceful degradation. This means that if any of your users have javascript turned off, the menu will not collapse, and they will be able to use your navigation as though it was a static list.

So, we want to create a function called prepareMenu() that will go through and find every anchor within the menu, and add an “onclick” event to each one.


function prepareMenu() {
 if (!document.getElementById || !document.getElementsByTagName) return false;
 if (!document.getElementById("menu")) return false;
 if (!menu.getElementsByTagName("a")) return false;

var links = document.getElementById("menu").getElementsByTagName("a");
 for (var i=0; i<links.length; i++) {
  links[i].onclick = function() {
   toggleMenu(this.parentNode.getElementsByTagName("UL")[0], this.href);
   return false;
  }
 }
}

For every link within the menu, we have added an “onclick” event, which calls the function toggleMenu(). To this function, we will pass the nested list which represents the sub menu items, and also the “href” (destination) of the link.

Here is the code for toggleMenu() which will handle the hiding and displaying of sub-menus when a link is clicked:


function toggleMenu(node, link) {
 if (!document.getElementById) return false;
 if (!link) return false;
 if (!node) location.href = link.href;

 if (node.style.display == "") {
  node.style.display = "none";
 } else {
  node.style.display = "";
 }
}

This is pretty straightforward, the function will check the display property of the node, if it is hidden then display it, if not then hide it. One small detail however is that if the node passed to this function is null, then the links href is followed. This means that if the link clicked has no submenu, then the function will direct the user to the links location rather than trying to display a non-exisistent sub-menu.

Step 4: Add the OnLoad Events

Right now we have our functions ready to go, but they are not being called at all by our code. This means they will quite happily sit in your javascript file doing absolutely nothing. We need to add two “onload” events so that when the page has finished loading, both collapseMenu() and prepareMenu() are executed.

We can add multiple “onload” events using the excellent addLoadEvent() function written by Simon Willison:


function addLoadEvent(func) {
 var oldonload = window.onload;
 if (typeof window.onload != 'function') {
  window.onload = func;
 } else {
  window.onload = function() {
   oldonload();
   func();
  }
 }
}

You can add this function directly into your main javascript file, or you can create a separate javascript file with just this function, and include it with a <script> tag in the header of your HTML.

Now that we have Simon’s function to use, we can add two lines to the top of our javascript file:


addLoadEvent(collapseMenu);
addLoadEvent(prepareMenu);

This will ensure that when the page has finished loading, both the collapse and prepare menu functions are executed.

Now that we have most of the javascript and HTML in place, you should see something like example 2 when you load your page and click around the menu.

Although this is a perfectly adequate menu, it’s a little boring. Now is the time to snazz up the menu with a little extra javascript and some CSS love.

Step 5: Bring on the Goodies

For the menu I made for the Durable WordPress Theme, whenever you clicked a top level node of the menu, all the other levels would collapse. This meant that the menu wouldn’t ever get too big, and would only allow the user to see one level at a time.

To collapse the top level nodes when any top level node is clicked, we need to add a check to toggleMenu() and create another function hideTopLevels():


function hideTopLevels() {
 if (!document.getElementById) return false;
 if (!(node = document.getElementById("menu"))) return false;

 if (node.childNodes.length > 0) {
  for (var i=0; i<node.childNodes.length; i++) {
   var child = node.childNodes[i];
   for(var j=0; j<child.childNodes.length; j++) {
    var grandchild = child.childNodes[j];
    if (grandchild.nodeName == "UL") {
     if (grandchild.style.display == '') {
      grandchild.style.display = "none";
     }
    }
   }
  }
 }
}

Now we must add a quick check in toggleMenu() that will call this function if we have clicked a top level node:

Add in these lines after if (!node) return false;


if (node.parentNode.parentNode.id == "menu") {
 hideTopLevels();
}

Now you should have something like example 3 where top level nodes will collapse when another is clicked.

Finally, we can really spice up the menu by adding transitional effects using the Script.aculo.us javascript library and adding some nice CSS styles.

Download Script.aculo.us and link the javascript files in the <head> section of your HTML. If you are unsure how to do this, follow the Scriptaculous installation instructions.

Once you’ve got Scriptaculous linked and ready for use, we can change a couple of lines in toggleMenu() and hideTopLevels() so that the effects are used:

In toggleMenu() change:


if (node.style.display == "") {
 node.style.display = "none";
} else {
 node.style.display = "";
}

To this:


if (node.style.display == "") {
 Effect.BlindUp(node, {duration: 0.2});
} else {
 Effect.BlindDown(node, {duration: 0.2});
}

Then in hideTopLevels() change:


grandchild.style.display = "none";

To this:


Effect.BlindUp(grandchild, {duration: 0.2});

Your list should now be displaying some pretty cool looking transitions, rather than jumping from hiding to displaying.

I’ve added some CSS to my final example, but you are free to style the list any way you like to suit your own taste. Here is the final version with the transitions added, some new content, and my own example CSS linked above.

You are free to edit whatever you like and take this code away to use on your own site. I hope you enjoyed the walk through!

A zipped up version of the menu is availiable for download.

UPDATE: Now includes latest version of Prototype and Scriptaculous which fixes the drop down effects bug mentioned in the comments below.

Technorati Tags: , , , ,

A Javascript Revival? — February 18, 2006

A Javascript Revival?

I’ve been working a lot with Javascript lately for projects at work, mainly due to the AJAX-enabled components of one of our latest products.

I’ve generally avoided Javascript over the last year or so, whenever I wrote basic functions, they always seemed bloated and very specific to a task or scenario. Plus, javascript has got a pretty bad name over the last ten years, let’s be honest. It’s been used to do some downright horrible things.

I guess in the early days of new technology, we tend to concentrate of what can be done that’s “cool” rather than what can be done that’s useful for the user. Maybe we’re seeing the same thing with AJAX right now, but I guess that’s all part of a technologies life cycle and difficult to avoid.

So anyway, the big change in my feelings towards Javascript has been the Document Object Model. The DOM has changed everything. Well, not so much just the DOM, but more so that almost all browsers now support a standard W3C DOM architecture.

This standard DOM has gone a long way to improving reusability of code. For example, I wrote a basic javascript validator not so long ago that will validate a form with any number or type of input elements. The only variable that needs to be passed to the function was the form node, the script would then just iterate through each child node and run the validation test. In the past, you may have had to pass the ID of each input element that you wanted to validate, making the script somewhat cumbersome. By relying on the DOM for the validator, it made the script essentially drag-and-drop like.

There is also the move to writing object oriented Javascript. Many of the libraries released in the last year like Prototype and Scriptaculous are written in an object oriented fashion. This means that the scripts are easily extendable and are designed in a way that is well thought out and logical. It may also make many other established programmers who once ‘poo-pooed’ Javascript sit up and take note.

I’m going to be studying the DOM and object oriented Javascript a lot more over the coming months as I think there is real potential in this area for UI developers.

Technorati Tags:

Getting into Ruby on Rails — October 22, 2005

Getting into Ruby on Rails

It’s refreshing to see a web language that is truly object oriented, and a framework that strictly adheres to the “Model, View, Controller” method of development.

If you haven’t heard of Ruby on Rails yet, then you should go and check out this online video of a simple blogging application being produced in 15 mins. Take note that not a single line of SQL is written. Truly remarkable.

I’ll be writing more about rails once I have finished the book and have a grasp of everything it has to offer as a framework. So far, it seems to be killing PHP development in every area.

%d bloggers like this: