Oct 21 2009

Sorting a Zend Navigation container by Page dates

I’ll introduce this topic with a warning – This article doesn’t show you how to completely reorder your entire Navigation, it does however show you how you could populate a new container from an existing one and reorder it.

Zend Navigation currently doesn’t allow you to nominate a default Navigation Container class. So while we could extend the Zend_Navigation_Container creating our own customised one, you’d almost have to duplicate the code for the Zend Page and Zend Container classes to do a thorough job, as they both call each other – so won’t know to use your new one.

My goal was to achieve:

  • a container of all pages in my navigation configuration (ignoring hierarchy)
  • exclude pages that had sub pages (so I only had the leaves on the branch so to speak)
  • order these pages by a date set for each page in the nav configuration

Step 1 – Add dates to Navigation configuration

You can add new properties to Zend Navigation Pages without needing to do anything. See my “dateadded” in the example below on some pages.

                    <security>
                        <label>Security</label>
                        <module>computers</module>
                        <controller>security</controller>
                        <action>index</action>
                        <pages>
		                    <password>
		                        <label>Password generator</label>
		                        <module>computers</module>
		                        <controller>security</controller>
		                        <action>password-generator</action>
		                        <dateadded>01/08/2009</dateadded>
		                    </password>
                            <encrypt>
		                        <label>Hash generator</label>
		                        <title>Hash generator (string encryption)</title>
		                        <module>computers</module>
		                        <controller>security</controller>
		                        <action>encrypt</action>
		                        <dateadded>25/08/2009</dateadded>
		                    </encrypt>
		                </pages>
                    </security>

Step 2 – Create a custom container type

By creating a custom container extending Zend_Navigation_Container we can add our own sorting function. The trick of this is converting the dates to the linux time stamp i.e. number of seconds since 1 January 1970. This is also a logical place to but build a function to extract lowest level pages from another container. This one class services all three of my requirements.

class Utilitiesman_Navigation_Container_Utilities extends Zend_Navigation_Container
{
	public function addLowestPages($page) {
		$iterator = new RecursiveIteratorIterator($page,RecursiveIteratorIterator::SELF_FIRST);
		foreach ($iterator as $page) {
			// don't add page if it has children
			if(!$page->hasPages()) {
				$lowestPages[] = $page;
			}
		}
		$this->addPages($lowestPages);
	}
 
    public function sortByDate($property = 'dateadded')
    {
        $newIndex = array();
        $index = 0;
 
        foreach ($this->_pages as $hash => $page) {
            $pageDate = $page->get($property);
            if(Zend_Date::isDate($pageDate)) {
                $date = new Zend_Date($pageDate);
                $timestamp = $date->getTimestamp();
                $newIndex[$hash] = $timestamp;                
            } else {
                // there wasn't a valid date for this page, use an incremental number start at 0
                $newIndex[$hash] = $index;
                $index++;
            }
        }
 
        //sort the array using those timestamp versions of the dates
        arsort($newIndex);
        $this->_index = $newIndex;
        $this->_dirtyIndex = false; // flag index as clean - prevent default sort
    }
 
}

Step 3 – Call it and render the result

This is all done within the context of a view script (the layout in my case) I should mention:

$containerByDate = new Utilitiesman_Navigation_Container_Utilities();
$rootPage = current($this->navigation()->getContainer()->getPages());
$containerByDate->addLowestPages($rootPage);
$containerByDate->sortByDate();
echo $this->navigation()->menu()->render($containerByDate);

To see a cool example of this in action check out the calculator section of my utilities man website, or any section mind you.

utilities man - calculators

My implementation is a little more complex than this though, I’m using a partial view script for the menu and I’m also only displaying pages under the section your on.

Share and Enjoy:
  • DZone
  • Digg
  • del.icio.us
  • Technorati

Aug 16 2009

Zend_Navigation Tricks: True tab navigation with sub menus – Part 3

Part 3: Implementing jsTree which uses jQuery (optional javascript expand/collapse)

This is a completely optional step in this series and really has nothing to do with Zend Framework because by this based on the client side we have all the HTML we need.

What we’ll be doing is setting up jsTree a jQuery tree component that can do much more than we’ll be using it for, it’s probably overkill but the best I came across when I was looking on this occasion.

You need jQuery:

$this->headScript()->appendFile($this->baseUrl . '/scripts/jquery-1.3.2.min.js', 'text/javascript');

Setup the jsTree javascript and css files if $nav2Container is set (see Part 2)

// append nav2 menu components if $activeContainer is set for the menu
if(isset($nav2Container)) {
    $this->headScript()->appendFile($this->baseUrl . '/scripts/jstree/css.js', 'text/javascript');
    $this->headScript()->appendFile($this->baseUrl . '/scripts/jstree/tree_component.min.js', 'text/javascript');
    $this->headLink()->appendStylesheet($this->baseUrl . '/scripts/jstree/tree_component.css', 'screen');
}

Render the Style and Script files we setup earlier:

        echo $this->headStyle() . "\n";
        echo $this->headScript() . "\n";

Some of this code below is a repeat from previous parts but its better to see this all in context. I’ve added a couple bit of JavaScript to achieve the following:

< ?php
        	// render nav2 container and menu if not on the homepage
        	if(isset($nav2Container)) {
        ?>
        <div id="nav2Container">
        	< ?php 
        		$this->navigation()->menu()->setMinDepth(null)->setMaxDepth(null);
        		echo $this->navigation()->menu()->renderMenu($nav2Container,array('ulClass' => 'nav2'));
        	?>
        	<script type="text/javascript">
        	$(function () {
        			// setup each active <li> with an id
        			var $active_li = $(".nav2 li.active");
        			var $active_li_id = new Array();
            		for( var i = 0, n = $active_li.length;  i < n;  ++i ) {
                		var $element = $active_li[i];
                		$active_li_id[i] = "nav2_active_" + i;
                		$($element).attr("id", $active_li_id[i]);
            		};
        			// configure and initialise 
        			$(".nav2").tree({
              			data  : {type : "predefined"},
            	  		opened : $active_li_id,
        	      		path : "<?php echo $this->baseUrl . '/scripts/jstree/'; ?>",
              			ui : {theme_name : "toolbox"},
        	      		rules : {   
                			metadata : "mdata",
                			use_inline : true
              			}
        			});
        		});
        	</li></script>
        </div>
        < ?php
        	}
        ?>

I’m using version 0.9.8 of jsTree but I’m looking forward to version 0.9.9 which will apparently alleviate some of my design/performance concerns, as the script loads this default theme and then the custom theme, rather than just the custom theme.

If I’ve missed anything and this doesn’t work, please let me know!

Share and Enjoy:
  • DZone
  • Digg
  • del.icio.us
  • Technorati

Aug 16 2009

Zend_Navigation Tricks: True tab navigation with sub menus – Part 2

Part 2: Rendering the sub menus (relevant to the active tab).

This is where we employ another trick because the Zend_Navigation menu view helper does provide an option to render the active menu, but it is meant literally not the active branch of the menu like we’re trying to achieve.

In the layout we need to get the root level pages then we assume the 1st one is Home and root of all other navigation items. After this we loop through the pages below Home to find the active one and set this as the $nav2Container which we’ll use next.

layout.phtml

// find the active page/container under the rootPage (Home) for nav2 menu
$rootPage = current($this->navigation()->getContainer()->getPages());
$pages = $rootPage->getPages();
foreach($pages as $page) { 
	if($page->isActive(true)) { 
		$nav2Container = $page; 
	}
}

Now that we know what the root of this sub menu should be we can use the helpers to render it (this is also in your layout file).

if(isset($nav2Container)) {
    echo $this->navigation()->menu()->renderMenu($nav2Container,array('ulClass' => 'nav2'));
};
Share and Enjoy:
  • DZone
  • Digg
  • del.icio.us
  • Technorati

Aug 16 2009

Zend_Navigation Tricks: True tab navigation with sub menus – Part 1

It is some what tricky with the Zend_Navigation menu helpers to set up your typical tab-based navigation with sub pages relevant to the tab your on, as seen below. But it’s not far difficult so don’t be put off, hopefully the view helpers will improve over time.

tab-menu-example

In the mean time this is a 3 part series in achieving the navigation I set up in utilitiesman.com as seen above.

Part 1: Setting up the navigation, and rendering the tabs.

Set up your navigation configuration, I’ve done this in xml.

< ?xml version="1.0" encoding="UTF-8"?>
<configdata>
    <nav>
        <label>Home</label>
        <module>default</module>
	<controller>index</controller>
	<action>index</action>
        <pages>
            <computers>
                <label>Computers</label>
                <module>computers</module>
                <controller>index</controller>
                <action>index</action>
                <pages>
                    <networking>
                        <label>Networking</label>
                        <module>computers</module>
                        <controller>networking</controller>
                        <action>index</action>
                        <pages>
		                    <ipaddress>
		                        <label>IP Address</label>
		                        <module>computers</module>
		                        <controller>networking</controller>
		                        <action>ipaddress</action>
		                    </ipaddress>
		                    <ping>
		                        <label>Ping</label>
		                        [... code removed for example ...]
		                    </ping>
     	                            [... code removed for example ...]
		                </pages>
                    </networking>
                    <security>
                        [... code removed for example ...]
                    </security>
                </pages>
            </computers>
            <measures>
                [... code removed for example ...]
            </measures>
        </pages>
    </nav>
</configdata>

In your bootstrap file you’ll need setup the navigation and load your navigation config:

$navigationConfig = new Zend_Config_Xml('./application/Config/navigation.xml');
$navigation = new Zend_Navigation($navigationConfig);

Assuming you’re making use of the Zend_Layout this would go in your template

$this->navigation()->menu()->setPartial(array('nav1.phtml','default'));
echo $this->navigation()->menu()->render();

This is my partial menu template which is where some minor trickery is performed to see the Home page and first level pages in a single <ul> for easy application of CSS to make the <li>’s look like tabs. This is the “nav1.phtml” referred to in the layout.

    echo '<ul id="nav1">';
    // loop root level (only has Home, but later may have an Admin root page?)
    foreach ($this->container as $page) {
        // check if it is active (not recursive)
        $isActive = $page->isActive(false);
        $liClass = $isActive ? ' class="active"' : '';
        echo '<li ' . $liClass . '>' . $this->menu()->htmlify($page) . '</li>', PHP_EOL;
        // loop next level
        foreach ($page as $page) {
            // check if it is active (recursive)
            $isActive = $page->isActive(true);
            $liClass = $isActive ? ' class="active"' : '';
            echo '<li ' . $liClass . '>' . $this->menu()->htmlify($page) . '</li>', PHP_EOL;
        }
    }
    echo '</ul>';

What the partial template above renders is something like this, neatly all in a single hieratical level..

<ul id="nav1">
    <li><a ...>Home</a></li>
    <li class="active"><a ...>Computers</a></li>
    <li><a ...>Measures</a></li>
</ul>
Share and Enjoy:
  • DZone
  • Digg
  • del.icio.us
  • Technorati

Aug 16 2009

Zend_Navigation Trick: Sub pages only breadcrumb

The most logical place to render your breadcrumb from is your master layout… However it’s unlikely you’ll ever want to render to on your home page right? I mean what is the point of seeing just “Home”.

This can be simply achieved using a partial template to render your breadcrumb. The code below should explain things for you, but leave a comment if you would like further explanation.

bootstrap.php

$navigationConfig = new Zend_Config_Xml('./application/config/navigation.xml');
$navigation = new Zend_Navigation($navigationConfig);

navigation.xml

< ?xml version="1.0" encoding="UTF-8"?>
<configdata>
    <nav>
        <label>Home</label>
        <module>default</module>
		<controller>index</controller>
		<action>index</action>
        <pages>
            <computers>
                <label>Computers</label>
                <module>computers</module>
                <controller>index</controller>
                <action>index</action>
                <pages>
                    <networking>
                        <label>Networking</label>
                        <module>computers</module>
                        <controller>networking</controller>
                        <action>index</action>
                        <pages>
                [...]
        </pages>
    </networking></pages></computers></pages></nav>
</configdata>

layout.phtml

echo $this->navigation()->breadcrumbs()->setPartial(array('breadcrumb.phtml', 'default'));

breadcrumb.phtml

// only render if there is more than 1 page in the breadcrumb
if (count($this->pages) > 1) {
    $links = array();     
    foreach ($this->pages as $page) {
        $links[] = $this->breadcrumbs()->htmlify($page);
    }
    echo implode(' &gt; ', $links);
}
Share and Enjoy:
  • DZone
  • Digg
  • del.icio.us
  • Technorati

Aug 3 2009

Visual history of the internet (according to Australians)

The Australian Interactive Media Industry Association (AIMIA) have created a visual record of the popularity of internet sites to Australians from 2001-2009.

Openning the site you’ll find the flash application with play through the past 9 years in a matter a seconds in which you can watch the rise of fall of sites over time, and also see their popularity all at once…

History of the Australian Web

History of the Australian Web

They’ve also prepared a report of the top 100 sites with their statistics for each of these years as a PDF you can download.

Share and Enjoy:
  • DZone
  • Digg
  • del.icio.us
  • Technorati

Jul 28 2009

$50 off Dreamhost hosting – Promo code GIVEME50OFF

I’ve had my hosting with Dreamhost now for a little over a and have been very happy with!!! I was previously using Site Ground but converted for the following reasons:

  • Dreamhost allows you to host unlimited domains, databases, email etc under your account
  • Dreamhost allows complete control of your DNS (so you can point a domain/sub domain to your home test/dev server)
  • Dreamhost has shell access – YES REALLY!! Mind you you won’t need it with how much you can do through their web interface…
  • Dreamhost has Subversion (SVN) so you can setup source code repositories to manage all your source code…

I’d highly suggest them to anyone looking for a LAMP (Linux, Apache, MySQL, PHP) new hosting provider! I’ve also arranged a promotion code that will get you $50 off… To put that in perspective that is nearly half of a years worth of hosting which is currently $119… It’s not valid if you sign up for less than a year though…

Sign up now using the promo code GIVEME50OFF when signing up…

Or if you’re not convinced, check out their features first, they sell themselves..

Share and Enjoy:
  • DZone
  • Digg
  • del.icio.us
  • Technorati

May 7 2009

Software I couldn’t live without…

Over the years we all build up our own collections of tools which help us be more productive little soldiers. We realise a need for something to help us to achieve an end goal, or a lot of the time just ask ourselves “surely there is a faster and easier way of doing this”.

The list of software below would easily be worth a significant amount of money considering the hours I’ve spent doing the research and comparisons. I only wish more people would publish such a comprehensive list, so I encourage you to comment and share other products or links to your own lists!

Virtualising desktops/servers:

  • VMware Server or VMware Player – Free products allowing you to create either virtual servers or desktops which runs on top of an existing operating system. So you don’t need extra hard ware to trial a new operating system, or to have a dedicated development environment, or perhaps just a used for testing applications without tainting your base system.
  • VMware Converter – Creates a Virtual machine from a physical (P2V – Physical to Virtual) one, which is useful if you have an old server you want to decommission, but want to retain a copy of it ‘just in case’.
  • Parallels Workstation – Achieves basically the same virtualised environment as the VMware products however it’s not as popular. I started using this a couple of years ago because at the time VMware’s product weren’t supporting Vista as a base OS, while this product ran very smoothly on it!

Web application infrastructure:

  • XAMPP for Windows – One of many packaged WAMP stacks (Windows Apache MySQL PHP) available. This can be easily installed on to a USB key and taken around with you which is what I do. A single executable is run off the USB to load your Web server and Database server. It also comes packaged with a lot of other little useful packages such as phpMyAdmin (a web based MySQL server interface).
  • Zend Server – Zends replacement for  Zend Core which was a stable and well supported WAMP stack, and my preferred for enterprise depolyments. My one grievence with Zend Core was that it doesn’t include MS SQL support which has apparently been addressed in Zend Server.

Managing source code:

  • Subversion (SVN) – An open source revision control system and source code repository. If you’re not using one you should be (regardless of the size of your projects) it makes life so much easier in tracking changes to your code over time. When I started using this I was running up my own virtual server with SVN setup, these days my web hosting is with Dream Host who offer unlimited subversion repositories.
  • TortoiseSVN – Subversion doesn’t have a GUI it’s all command line… So TortoiseSVN is my preferred client interface in to my subversion repositories. It integrates in to windows explorer so you see lots of extra options when you right click.
  • WebSVN – A web-based (PHP) reviewing interfaced in to your subversion repositories and the code they contain. Something that might become a little more useful down the track once you’re more familiar with Subversion and want even more readily available access to see your code. If you’re setting this up I’ve already produced some instructions for Dream Host and Ubuntu.

Tracking issues:

  • JIRA – An  issue/bug tracking product which is ideal for large development projects with numerous developers. It has highly flexiable workflows and triggers and can store nearly any conceivable data template. I’ve used it with large open source projects like Zend Frameworks issue tracking system and have even implemented in one goverment agency as a Change Management System managing RFCs/CRs. It’s expensive but they have a personal edition for up to 3 users.

Programming, testing and documenting:

  • Zend Studio – My preferred  PHP Integrated Development Environment (IDE)! It comes in two flavours at the moment the original one which is awesome and the new one based on the Eclipse platform (Zend Studio for Eclipse) which should be even better ( a work in progress). Run with Zend Core/Zend Platform it offers step-through code debugging. Without this you’ll need to setup the largely undocumented Zend Debugger.
  • XAMPP – My preferred portable WAMP  (Windows Apache, MySQL, PHP) stack. However the stack comes with a lot more than just that… You’ll also find an FTP server and a heaps of other useful built-ins! I keep one of these on a USB stick for a development environment where ever I go…
  • FireBug – Is a Firefox plugin
  • FirePHP – Enables you to utilise the FireBug console for information/error messages etc. There messages are passed in the HTTP Header so they don’t actually effect the display of your web application. It’s also supported by the Zend_Log component in Zend Framework
  • Notepad++ – A light weight and very popular tool which offers syntax highlighting for every programming language I know, plus many more I don’t know! You’ll also be able to track down a portable version which is handy on a USB for those moment where you need a editor a little more powerful that just plain old Notepad… Also supports plugins for some of those functions it doesn’t perform out of the box (like a file explorer).

Web applications:

  • WordPress – By far the most popular blogging software that exists! There would be easily 10’s of millions of blogs out there using this product including this blog you’re reading now. There are also millions of free themes available so to get yourself start you don’t even need to do any coding.. And start thinking it doesn’t quite offer what you’re try the 10’s of millions of free plug-ins available.
  • Gallery 2 – An online Gallery with an endless list of features and p
  • OS Commerce – One of the more popular open source online store applications. Definitely a great product for what is it and especially considering it is free and there are a lot of themes/plugins available across the Internet. However it’s administration/management interface leaves a little to be desired… I hopeful this is being addressed in version 3 their next major release! Although this has been under development for a number of years now (but it looks like its nearly there).

Web application frameworks/libraries:

  • Zend Framework – In my opinion the best PHP Application Development Framework on the market! Well worth a look with an abundance of components to solve most of the heart ache in getting a application quickly of the ground…
  • jQuery -  A Javascript framework which provides a lot of useful low level functionality, which is then built on by the 1000’s of community submitted plugins, some of which are effectively self contained solutions e.g. a LightBox equivalent.
  • YUI – Standard for Yahoo User Interface and is probably one of the most comprehensive Javascript frameworks I’ve seen. This framework does provide just your low level functional but provides your end solutions like managing data tables or menus.

General productivity:

  • Xmarks (previously Foxmarks) – A browser plugin and free web service that supports bookmark syncronisation, allowing you to syncronise your bookmarks across multiple computers. They’ve recently been adding a lot more features I haven’t really paid attention to as well like password syncronisation and site recommendations.
  • myVidoop – A secure online password manager that provides browser integration with assisted log in. It is also an openID provider, not that all that many sites are using this. This doesn’t mean I trust them with my bank passwords still, but it does help me manage the millions of forums I have membership with!
  • Allway Sync – An automatic file synchronisation tool which is really easy to set and forget. I use this for backing up some directories from my laptop to my NAS periodically in case the laptop dies or is stolen (God forbid, Touch wood etc).. Free provided it doesn’t need to regularly synchronising too many files!
  • Gadwin PrintScreen – A ‘printscreen’ / screen capture tool on steriods, and better yet there is a freeware version! The selling point for me is you can configure it so that when it you push Print Screen it open a screen selection tool so you can crop, and that cropped version can be saved to the clipboard as a GIF for example.

Update history:

  1. 21 May 2009 – Added Gadwin PrintScreen, Notepad++ and revised Zend Core to Zend Server thanks to some feedback.
Share and Enjoy:
  • DZone
  • Digg
  • del.icio.us
  • Technorati

May 7 2009

MS Access: Update rows using another table

My problem was I wanted to update data in one table based on the data in another table. In this senario I had two identical tables in my MS Access database. Table1 is the original and Table2 has been imported from Excel. This MS Excel spread is an exported version of Table1 which was updated off network. Changes made to the Cash column now need to be reflected in the original Table1 .

I’m by no means an MS Access expert but know this is easily achievable through normal programming languages including directly through SQL. But my goal was to simply achieve this using the MS Access interface. A quick trawl of the internet didn’t turn up any results so I quickly worked it out for myself and am sharing for future googlers!

MS Access update muliple rows

Share and Enjoy:
  • DZone
  • Digg
  • del.icio.us
  • Technorati

Apr 27 2009

Making the switch, Hotmail to GMail

So you’d like to stop using Hotmail in place of GMail because it’s easier to access on your iPhone? Well you’ve probably read a lot of articles on the internet telling you to:

Which  you try, only to find that Microsoft seems to have responded to number of people doing this by either disabling it or now making it a paid service (according to one article I read)… So instead you’ll get this error message which makes little sense:

You’re only able to forward mail to a custom domain or an e-mail address that ends in hotmail.com, msn.com, or live.com. Please try again.

Few people know this (at least I didn’t anyway) but Microsoft has finally come to the table with POP access to your Hotmail account.

POP allows mail clients like Outlook or Thunderbird to download your emails using a recognised standard thats been around since I was a boy…

GMail also have the ability to download emails from other POP account in to your GMail account… You see where I’m going with this now don’t you!

In GMail:

  1. Go to Settings (top right).
  2. Then the Accounts tab.
  3. Then the Add a mail account you own link.

On the following screen start entering the following:

  • Email: youremailaddress@hotmail.com
  • Username: youremailaddress@hotmail.com
  • Password: yourpassword
  • POP Server: pop3.live.com
  • Port: 995

I also checked the following checkboxes:

  • Leave a copy of retrieved message on the server.
  • Always use a secure connection (SSL) when retrieving mail.

Now all your Hotmail emails in your inbox will be brought in to GMail. GMail will also continue to download you emails for you as they arrive in your Hotmail account.

If you’re trying to access your hotmail on your iPhone like I was an alternative is the application mbox mail (which access hotmail with your all folders) however I’m going to go back to using the normal iPhone mail client…

Share and Enjoy:
  • DZone
  • Digg
  • del.icio.us
  • Technorati