Customising wp_nav_menu()

November 2nd, 2012

Ever wanted to use the convenient built-in menu support of WordPress, but been frustrated or confused by the inflexibility of the wp_nav_menu() structure? WordPress actually allows much deeper customisation when you dig a little deeper, with its custom Walker functions.

For minor customisations, such as removing the navbar’s container, wp_nav_menu has an array of options that can be passed to it which makes the task quite simple. For adding a css class to specific links in the navbar, you can use WordPress’s powerful ‘add_filter’ functionality. The shortcomings of these methods, though, is that they don’t offer a way to manipulate the actual order or structuring of the unordered list itself – in order to put in an extra <li> with a subheading, for instance, you’d need to resort to javascript or empty ‘custom links’ in the menu interface.

To allow control of this sort of thing, WordPress allows to you create customised ‘walker functions’. WordPress actually uses these functions to handle many of its looping structures – pages, categories, comments, and more. A great introduction for editing these other kinds of structures can be found
The walker function I’m going to be focusing on, though, is the WP_Nav_Walker function, located in wp-includes/nav_menu_template.php around line 174. Remember, though, as with Magento, you should never edit core files, because if you upgrade to the latest version of wordpress in the future, your customisations may be overwritten. Instead copy all the code for the Walker_Nav_Menu, go to your functions.php file, and paste it in there. Change Walker_Nav_Menu to your whatever you’d like, i.e. mytheme_nav_walker, and change ‘extends Walker’ to ‘extends Walker_Nav_Menu’.
Now you have a copy of the walker function that you can edit to your heart’s content. A good explanation and an example on editing this file can be found in the wordpress codex, at . This example shows you how to add conditional classes based on the ‘depth’ (for submenus). It overrides start_lvl() (called each time the walker encounters a new submenu), end_lvl() (called at the end of each submenu), start_el() (called for each item) and end_el() (called at the end of each item). As you can tell by looking at them, end_lvl() and end_el() are quite simple in themselves, merely adding a closing <ul> or <li> tag after indenting the code (for readability). Note that if you want to edit these functions, you should copy the original from nav_menu_template.php (as you have done) and edit that, since you don’t want to make it from scratch but simply modify it.
This example is great, but it didn’t tell me everything I needed to know. I wanted to take a wp_nav_menu, and wraps the links in groups of 3 without simply making a submenu and using ‘position: absolute’ to force a layout, like so:Screen shot 2012 11 02 at 11.13.211 Customising wp nav menu()
I also didn’t want to hard-code the menu; as it was for a CMS site, I wanted them to have a certain amount of control over it.
So I needed a way to keep track of how many elements had been processed – I needed access to the function actually controlling the loop, so I could have a counter. After a bit of digging, I found this: . This showed a ‘walk()’ function, that did exactly what I wanted, but looking in nav_menu_templates.php, I could see no reference to it at all. This was a problem, since (as mentioned earlier) I needed to copy the original function, and edit it. I searched through wp-includes until I found the function in class-wp-walker.php – this is the base walker class that all the other WordPress Walkers (including the Walker_Nav_Menu class we’re editing) inherit. I copied the walk() function into my functions.php, inside my custom class with the other functions. Here’s my edited function:

function walk( $elements, $max_depth) {
		$args = array_slice(func_get_args(), 2);
		$output = '';
		$counter = 1;
		if ($max_depth < -1) //invalid parameter 			return $output; 		if (empty($elements)) //nothing to walk 			return $output; 		$id_field = $this->db_fields['id'];
		$parent_field = $this->db_fields['parent'];
		// flat display
		if ( -1 == $max_depth ) {
			$empty_array = array();
			foreach ( $elements as $e )
				$this->display_element( $e, $empty_array, 1, 0, $args, $output );
			return $output;
		}
		/*
		 * need to display in hierarchical order
		 * separate elements into two buckets: top level and children elements
		 * children_elements is two dimensional array, eg.
		 * children_elements[10][] contains all sub-elements whose parent is 10.
		 */
		$top_level_elements = array();
		$children_elements  = array();
		foreach ( $elements as $e) {
			if ( 0 == $e->$parent_field )
				$top_level_elements[] = $e;
			else
				$children_elements[ $e->$parent_field ][] = $e;
		}
		/*
		 * when none of the elements is top level
		 * assume the first one must be root of the sub elements
		 */
		if ( empty($top_level_elements) ) {
			$first = array_slice( $elements, 0, 1 );
			$root = $first[0];
			$top_level_elements = array();
			$children_elements  = array();
			foreach ( $elements as $e) {
				if ( $root->$parent_field == $e->$parent_field )
					$top_level_elements[] = $e;
				else
					$children_elements[ $e->$parent_field ][] = $e;
			}
		}
		foreach ( $top_level_elements as $e )
		{
			if ($counter >=4)
			{
				$counter = 0;
				$output .= "</ul>\n";	
			}
			//start new list if necessary
			if ($counter == 0)
			{
				$counter++;
				$output .= "<ul class='menu'>";
			}
			$this->display_element( $e, $children_elements, $max_depth, 0, $args, $output );
			$counter++;
		}
		/*
		 * if we are displaying all levels, and remaining children_elements is not empty,
		 * then we got orphans, which should be displayed regardless
		 */
		if ( ( $max_depth == 0 ) && count( $children_elements ) > 0 ) {
			$empty_array = array();
			foreach ( $children_elements as $orphans )
				foreach( $orphans as $op )
					$this->display_element( $op, $empty_array, 1, 0, $args, $output );
		 }
		 return $output;
	}

The changes I made were relatively simple – at the beginning of the function, I initialised my counter: ‘$counter = 1;’
Then, I edited the foreach loop that handled the top-level elements (as I only wanted to split those, and leave submenus untouched):

foreach ( $top_level_elements as $e )
		{
			if ($counter >=4)
			{
				$counter = 0;
				$output .= "</ul>\n";	
			}
			//start new list if necessary
			if ($counter == 0)
			{
				$counter++;
				$output .= "<ul class='menu'>";
			}
			$this->display_element( $e, $children_elements, $max_depth, 0, $args, $output );
			$counter++;
		} 

The display_element function is the function that calls start_lvl, end_lvl, start_el, and end_el, as necessary. Each time it runs for the top level elements, I’ve simply incremented it, and for every 3rd element, I’ve closed off the list and opened a new one on the next iteration. The reason I do this in the following iteration and not at the end of the current one is to prevent extra </ul> tags
So that’s the editing done. Remember, you can remove start_lvl(), etc., from functions.php if you’re not editing them – your class will just inherit the default from nav_menu_temlate.php. So how do you use it now? Well, that’s the easy part. In my template:

<?php wp_nav_menu( array('menu' => 'Footer Nav', 'walker' => new mytheme_walker_nav_menu )); ?>

Tutorial 1 Magento The Beginning

October 29th, 2012

We are going to have tutorials in how to skin a Magento shop and customise it to work for you. We are going to talk about how we would go about customising a Magento shop for our clients. This should give you the basics which will help you grasp the fundamentals not make you an expert overnight.

The first stage is to find suitable hosting package which will enable you to host a Magento shop and have great speed and the power not to discourage new customers from purchasing a product from your website. We use a company called Nubule which are great and provide a one click Magento installer to easily install Magento to the specified domain of your choice. Nublue is an award winning hosting company which we found to be reliable and great in providing help and support.

Once you have successfully installed Magento on your server then using a program like Dreamweaver you can start working on the files which will enable you to customise Magento. The two folder that you need to work with are the App and the Skin folder.

1. We will use a theme called “Modern Theme” as our base theme which we will duplicate the folder and rename in the App folder and Skin folder.

To find the Modern Theme please direct yourselves to this location and copy the folder and rename it to something more relevant.

The Modern Theme in the App folder is located – app/design/frontend/default/modern

The Modern Theme in the Skin folder is located – skin/frontend/default/modern

Once you have copied these two folders and renamed them to something more relevant then upload them to the server. Remember both of the folders need to be identical, one controls the pages , layout, navigation etc. Whilst the Skin folder controls the CSS and contains the image folder.

The next step would be to go into your dashboard and go to System > Design and then click on Add Design Change.

Here you will be able to select the design folder you have created and should mirror the Modern theme.

Using wordpress template hierarchies to control CMS sites

October 19th, 2012

If you’ve ever made a content manageable site for a less technically-savvy client, then chances are you’ve used custom templates. You’ll probably have one for the home page, and one for the content pages, and maybe one for the contact page. But what if the client wants to add a new page, and they use the wrong template? Hopefully they’ll realise quickly, and change to the appropriate template.
Some larger sites, however, end up having many layouts, and therefore many custom template, and they can become confusing to some users. This highlights the importance of naming your templates clearly and descriptively. It can help, though, to trim down the number of custom templates available to the client in the first place.
This can be done by utilising the template hierarchy built into wordpress. The full list can be found here:
This structure means that say, for instance, the home page (which is a static page) is going to have a unique layout complete with calls to action, etc, which don’t need to show up on any other pages. Instead of making a custom template file, you simply create home.php and fill it out exactly like you would the template page – just leaving out the Template Name comment at the top of the file. Now, you create the Home page inside the wordpress admin area, leave the template on ‘default’, and publish it.
When somebody visits your site wordpress automatically searches for the home.php file and applies it only to the home page. Any other pages will still use (for the time being) the index.php template. So, now you’ve created a custom template that the client does see, or need to see.
The same can be done for every other page by using either page-{slug}.php or page-{id}.php (e.g. page-contact.php). Personally, I would advise using the page id, as the user may change the page slug (if, for instance, they change the page name to contact us instead of contact). If you want to make it bullet-proof, you could always use both, though I’ve never found that necessary.
Make sure that page.php (the default page template) is styled as well, as any new pages the client adds will look like this one (since they won’t have their own page-{ID}.php).
This method is not just for pages, though. A quick look at the hierarchy shows that it can be done for archives, custom posts, categories, etc. If you want a particular category of posts to show up differently, category-{slug} or {id}.php will control that for you, with any categories that don’t have their own file automatically falling back to archive.php by default. The same goes for custom posts (though these MUST use single-{post-type}.php
But what if you want posts from a certain category to have their own single.php? At the moment, WordPress doesn’t support this very well, but there’s a good workaround if these posts are only going to be part of one category.
Firstly, create your single-{category-id} or {category-slug}.php files, as well as a single-default.php. Then, open single.php, clear it out, and paste the following php:

$post = $wp_query->post;
if ( in_category('11') ) {
include(TEMPLATEPATH . '/single2.php');
} else {
include(TEMPLATEPATH . '/single-default.php');
}

Replace the ’11′ with the appropriate category id (which can be found by going to posts>categories>your-category in the wordpress admin area, and looking at the address bar). The above can be extended with as many else if lines as necessary, but make sure you always include else { include(TEMPLATEPATH . ‘/single-default.php’); } at the bottom!

Using this templating solution, the only time you really need to use page templates is when you want to give the client a choice of layouts (such as sidebar on the left, or sidebar on the right). This will result in much less confusing template choices for the client, and hopefully, less chance of them breaking the site you’ve made. Always ensure, though, that the default templates 1) exist and 2) have been styled!

Why use CSS3 Transitions?

October 15th, 2012

You may have heard about CSS3 transitions, and how you should never use them (or CSS3 in general) in commercial sites without a fallback because it’s not compatible across all browsers especially the older ones.

We think, though, that it’s important to start learning and practicing this technology now, because in the future, it could well send jQuery animations the way of Flash.

If you looked across the industry now, it wouldn’t seem like anything could knock jQuery from its perch, but it wasn’t too long ago when we all thought that about Flash.

So why use CSS3 transitions? CSS3 transitions can add an effect from one style to another and not use Flash or Javascript to create transitions.

But what is the reasons for using CSS3 transitions in the first place? CSS3 transitions will offer smoother user experience compared to Javascript animations because everything can be handled by the browser engine.

This bring us on to our next point where mobile devices are getting faster and more people are browsing through the internet using their mobile devices. With the introduction of the lighting fast 4G network we need to ensure that websites are developed to work on the mobile devices. CSS3 transitions will be help produce smoother transitions on mobile devices as mobile devices are not powerful like desktop computers.

There are many other benefits such as the load speed can be significantly reduced the file size of your HTML document can be significantly reduced too because we are not calling Javascript or Flash.

There are issue with cross compatibility issues with Flash, Javascript and CSS3 so they are all bad as each other. But obviously there are greater benefits with using CSS3 hence we have discovered a great solution in using CSS3 so that it is cross browser compatible. Features such as rounded corners, drop shadows etc can be produced and work on Internet Explorer 6 to 9. supports the following elements of CSS3:

  • multiple background images
  • linear-gradient as background image
  • border-radius
  • box-shadow
  • border-image

In the near future we may see a change in how transitions work on website and CSS3 being the major preference over jQuery or Flash that have been so dominate in the past.

Tutorial 2 – Adding A Language Pack To Magento

October 8th, 2012

Today we will be taking you through how to install a language pack in magento so you can change the language to whatever language you might require. For this guide we will be installing the language pack for UK English which will change all the default American spellings to UK spellings.

The first thing we need to do is download the En_GB (British) language pack, which you can download from this link . The main difference is that CART and TAX will be translated to BASKET and VAT.

To download other language packs, you can visit the following link to find language packs for different countries.

The most important thing to remember is that these language packs are not a translation service – they only replace the phrases that can be changed using the inline translation service. However they do save a lot of time and effort. Also these translations are never going to be 100% and as Magento evolves the translation csv will have to be amended as well.

When you have downloaded a language pack and extracted the zip file it will create a folder (en_GB for UK) and a file called translate.csv inside that folder. The next step is to put the folder containing this file into the correct locale folders. This will need to be done in the following locations:

app>locale

and also into your theme directory

app>design>frontend>default>theme>locale

This will then apply the translations.

Hopefully this will help anyone who is struggling with the translations in magento. You can also add other languages to another ‘website’ in your magento store. All you will need to do is change the store view default language and it should be fine.

Thank you for visiting Web Design GM and our blog.

Contact Us Today...

If you have any questions about our services or want to arrange a free no obligation consultation contact us today or call 02920 290 080 for Cardiff and 01179 000 482 for Bristol.

Bit Torrent Study Discovers Most File Sharers Are Now Monitored

Ever heard of torrents or used Bit Torrent to download movies, music or shared files over the internet? Researchers have discovered that anyone who does use Bit Torrent to download files over the World Wide Web will most probably be monitored. Studies were carried out by Birmingham University and they have discovered that if someone [...]
» more

Cardiff: 02920 290 080 Bristol: 01179 000 482