<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>MichaelAHeap.com</title>
	
	<link>http://michaelaheap.com</link>
	<description>Reinventing The Wheel, One Step At A Time</description>
	<lastBuildDate>Fri, 27 Aug 2010 18:19:31 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/Michaelaheapcom" /><feedburner:info uri="michaelaheapcom" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Working with DOMDocument</title>
		<link>http://feedproxy.google.com/~r/Michaelaheapcom/~3/swUlGEPu4wc/</link>
		<comments>http://michaelaheap.com/2010/08/27/working-with-domdocument/#comments</comments>
		<pubDate>Fri, 27 Aug 2010 18:17:59 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[DOMDocument]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[phpQuery]]></category>

		<guid isPermaLink="false">http://michaelaheap.com/?p=894</guid>
		<description><![CDATA[Nowadays, most of the services we need to access programatically provide an API or an RSS feed of their data for us to pull in and parse. However, some sites still don't provide the data, be it because they're a bit behind the times or they just don't want to make it easy for us&#8230


Related posts:<ol><li><a href='http://michaelaheap.com/2010/08/12/php-5-3-anonymous-lambda-functions/' rel='bookmark' title='Permanent Link: PHP 5.3: Anonymous (Lambda) Functions'>PHP 5.3: Anonymous (Lambda) Functions</a> <small>A month or so ago I started work at a...</small></li>
<li><a href='http://michaelaheap.com/2010/04/15/howto-codeigniter-partial-library/' rel='bookmark' title='Permanent Link: HowTo: Codeigniter Partial Library'>HowTo: Codeigniter Partial Library</a> <small>This assumes you have moved both the application and system...</small></li>
<li><a href='http://michaelaheap.com/2010/05/16/jquery-log-function/' rel='bookmark' title='Permanent Link: jQuery Log Function'>jQuery Log Function</a> <small>While looking through some old starred items in Google Reader,...</small></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Nowadays, most of the services we need to access programatically provide an API or an RSS feed of their data for us to pull in and parse. However, some sites still don't provide the data, be it because they're a bit behind the times or they just don't want to make it easy for us to scrape their data.</p>
<p>Thankfully, there's a built in PHP class called <a href="http://www.php.net/manual/en/class.domdocument.php">DOMDocument</a>, which is designed for parsing and traversing html and xml documents (though if you're on PHP5, I'd recommend using simplexml, which <a href="http://jamieonsoftware.com/blog/entry/screen-scraping-with-php">Jamie has run though</a> over on his blog)</p>
<p>I'm going to assume that you've already got the html of the page you want to parse using cURL or something similar, and have it in a string called <code>$html</code> ready to work with.</p>
<p>First of all, we need to start by creating the DOMDocument object and loading our HTML string into it.</p>
<pre class="brush: php;">
$dom = new DOMDocument();
@$dom-&gt;loadHTML($html);
</pre>
<p>Usually, I'm 100% against using the <code>@</code> sign to supress error messages, but in this case I make an exception as DOMDocument spits out errors if you feed it malformed HTML (and you don't have any control over the input)</p>
<p>Now that we have our object ready, we can start work. For example. imagine we wanted to find all of the links on the page that have a class of "external" (and only external). First, we'd need to grab all of the <code>a</code> tags.</p>
<pre class="brush: php;">
$nodes = $dom-&gt;getElementsByTagName('a');
</pre>
<p>This returns a <a href="http://www.php.net/manual/en/class.domnodelist.php">DOMNodeList</a> which only has one method and one property. The property us <code>length</code>, which we can use to see how many tags on the page matched our query. The method is <code>item</code> which we can use to access the node at a specific index e.g.<code>$node = $nodes->item(0);</code>. However in this case, we'll use a <code>foreach</code> loop to work with each node (which is actually an instance of <a href="http://www.php.net/manual/en/class.domelement.php">DOMElement</a>)</p>
<pre class="brush: php;">
foreach($nodes as $node){
	// Do our thing
}
</pre>
<p>Now, we have control over the individual node and we can access all of it's properties. DOMElement is actually a subclass of <a href="http://www.php.net/manual/en/class.domnode.php">DOMNode</a>, which provides us with a few more methods. From DOMNode, we have a few publicly accessible properties which we can use such as <code>nodeName</code> and <code>nodeValue</code>, but most of the useful functionality comes from DOMElement.</p>
<p>In DOMElement, we have <code>hasAttribute</code>, <code>getAttribute</code> and <code>setAttribute</code> which do exactly what you think they do. In this case, we're most interested in <code>getAttribute</code>, as we'll use it to get the value of the class attribute which we need to test.</p>
<pre class="brush: php;">
$matches = array();
foreach($nodes as $node){
	if ($node-&gt;getAttribute(&quot;class&quot;) == &quot;external&quot;){
		$matches[] = $node;
	}
}
</pre>
<p>We loop through all of the available nodes and check the value of it's class attribute. If it's external, push it into an array which we can then work with later (to pull out the href etc).</p>
<p>It's worth noting that though we're working with links here, if we were working with a <code>
<div></code> tag or another block level element, we can access the node's children by accessing <code>$node->childNodes</code> which is a DOMNodeList like we've already encountered.</p>
<h2>But It Could Be Easier</h2>
<p>Indeed it could! I actually did this research in order to write a PHP class which allows jQuery-like traversal of a DOM in PHP, but it looks as though someone's already beaten me to the punch. You can check out the <a href="http://code.google.com/p/phpquery/">phpQuery project</a> over on Google code, which takes away the complexity of using DOMDocument and lets you use css selectors on a page like you would with jQuery. </p>


<p>Related posts:<ol><li><a href='http://michaelaheap.com/2010/08/12/php-5-3-anonymous-lambda-functions/' rel='bookmark' title='Permanent Link: PHP 5.3: Anonymous (Lambda) Functions'>PHP 5.3: Anonymous (Lambda) Functions</a> <small>A month or so ago I started work at a...</small></li>
<li><a href='http://michaelaheap.com/2010/04/15/howto-codeigniter-partial-library/' rel='bookmark' title='Permanent Link: HowTo: Codeigniter Partial Library'>HowTo: Codeigniter Partial Library</a> <small>This assumes you have moved both the application and system...</small></li>
<li><a href='http://michaelaheap.com/2010/05/16/jquery-log-function/' rel='bookmark' title='Permanent Link: jQuery Log Function'>jQuery Log Function</a> <small>While looking through some old starred items in Google Reader,...</small></li>
</ol></p><img src="http://feeds.feedburner.com/~r/Michaelaheapcom/~4/swUlGEPu4wc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://michaelaheap.com/2010/08/27/working-with-domdocument/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://michaelaheap.com/2010/08/27/working-with-domdocument/</feedburner:origLink></item>
		<item>
		<title>PHP 5.3: Anonymous (Lambda) Functions</title>
		<link>http://feedproxy.google.com/~r/Michaelaheapcom/~3/4haHFNGx8-Q/</link>
		<comments>http://michaelaheap.com/2010/08/12/php-5-3-anonymous-lambda-functions/#comments</comments>
		<pubDate>Thu, 12 Aug 2010 17:41:02 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[lambda]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[php 5.3]]></category>
		<category><![CDATA[sublive]]></category>

		<guid isPermaLink="false">http://michaelaheap.com/?p=913</guid>
		<description><![CDATA[A month or so ago I started work at a company called LiveLenz, who are a realtime sales provider for various POS systems. The project I've been working on is called Sublive, which is a piece if reporting software for Subway franchises. As a part of that system, I needed to provide detailed stats for&#8230


Related posts:<ol><li><a href='http://michaelaheap.com/2010/04/15/howto-codeigniter-partial-library/' rel='bookmark' title='Permanent Link: HowTo: Codeigniter Partial Library'>HowTo: Codeigniter Partial Library</a> <small>This assumes you have moved both the application and system...</small></li>
<li><a href='http://michaelaheap.com/2010/05/12/javascript-control-structures/' rel='bookmark' title='Permanent Link: Javascript Control Structures'>Javascript Control Structures</a> <small>I stumbled across http://eloquentjavascript.net/ and decided to have a flick...</small></li>
<li><a href='http://michaelaheap.com/2010/08/27/working-with-domdocument/' rel='bookmark' title='Permanent Link: Working with DOMDocument'>Working with DOMDocument</a> <small>Nowadays, most of the services we need to access programatically...</small></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>A month or so ago I started work at a company called <a href="http://livelenz.com/">LiveLenz</a>, who are a realtime sales provider for various POS systems. The project I've been working on is called <a href="http://www.sublive.com">Sublive</a>, which is a piece if reporting software for Subway franchises.</p>
<p>As a part of that system, I needed to provide detailed stats for certain situations, such as a list of all transactions that had a discount code used. At first, I had one method per drilldown, all of which shared 90% of the same code. I tried and I tried, but I couldn't work out a way to abstract out the changes.</p>
<p>The only changes in the code were that the number of items counted differed depending on the section. E.g. On the sandwich breakdown all units with a specific PLU counted, but on the discount one, only items that had a discount applied are counted.</p>
<p>As the criteria used changed with every drill down, and wasn't just a case of comparing a field to a value. Passing in the field to check and the expected outcome as strings wasn't going to cut it.</p>
<h3>How To Solve It</h3>
<p>My first option was a giant if/else statement, or a switch. Pass in a parameter or two to the function and run whatever filter was needed. While this could have worked, it couples the two functions far too tightly for my liking, and I'm putting logic that belongs in multiple functions into one.</p>
<p>Another option was to conditionally define a function <code>filter</code> which took multiple optional parameters and automatically run it in the drilldown. Again, while this would have worked it's not a very clean way to do it.</p>
<p>Enter <a href="http://php.net/manual/en/functions.anonymous.php">lambda functions</a>. By passing a function as a parameter, we can filter the data as selectively as we like. By default, <code>$__filter</code> will be null, so we can check if there is a filter to run at all. If there is a filter, run it and handle the response however you want.</p>
<h3>Short Example</h3>
<p>Imagine we're selling things online. We have a model that returns all of the transactions made by a specific customer. We want to use all of this data to generate statistics - some for all the transactions returned, and some only for items that match our filter.</p>
<p>You can be as generic or as specific with your filters as you like. For example, this one will only return data for items that have a price of over £5.</p>
<pre class="brush: php;">
function over_five($__transaction_ids) {
        $filter = function($__item){
            return $__item-&gt;sale_price &gt; 5;
        };
        $r = $this-&gt;_filter_data(
                model::get_transactions($__transaction__ids),
                $filter
        );
    }
</pre>
<p>While that's a nice simple example, we can also make things more complicated by passing in variables to be used in the function with <code>use</code>. You simply tell the lambda function that you want to use a variable that's in the current scope, and pass it into your new function.</p>
<pre class="brush: php;">
function discounted($__transaction_ids, $__code) {
        $filter = function($__item) use ($__code){
            return $__item-&gt;discount_code == $__code;
        };
        $r = $this-&gt;_filter_data(
                model::get_transactions($__transaction__ids),
                $filter
        );
    }
</pre>
<p>Of course, the two filter functions are useless without the function that actually applies them to the data and gives us something back. This is a very contrived example, but hopefully it'll show how lambda functions can be used to filter out data we don't want.</p>
<pre class="brush: php;">
function _filter_data($__transactions, $__filter){
        // Some stats that we're gonna collect about the data
        $r = array();
        $r['total_items'] = 0;
        $r['matching_items'] = 0;
        $r['transaction_count'] = 0;
        $r['items_to_output'] = array();

        foreach ($__transactions as $k =&gt; $transaction){
            foreach($transaction as $item){
                    // Anything that's done every iteration goes before
                    // we try and filter the data
                    $r['total_items']++;

                    // If we have a filter provided
                    if (!is_null($__filter)){

                        // We pass in our item, and if it doesn't pass
                        // the filter skip the rest of this iteration
                        if (!$__filter($item)){
                            continue;
                        }

                    }

                    // Everything that we need to do if it matches
                    // the filter gets done down here
                    $r['matching_items']++;
                    array_push($r['items_to_output'], $item);
            }

            $r['transaction_count']++;
        }
       return $r;
    }
</pre>
<h3>Notes</h3>
<p>It's important to note that this only works in PHP 5.3 onwards. In previous versions, you would either have to use if/else or conditionally defined functions.</p>
<p>Additionally, you could also do all of your filtering within mySQL itself. Unfortunately this wasn't possible in this situation, as the database contains massive amounts of data. Running 6 big queries on the same page when I could have run one generic one and filtered it wasn't an option <img src='http://michaelaheap.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>


<p>Related posts:<ol><li><a href='http://michaelaheap.com/2010/04/15/howto-codeigniter-partial-library/' rel='bookmark' title='Permanent Link: HowTo: Codeigniter Partial Library'>HowTo: Codeigniter Partial Library</a> <small>This assumes you have moved both the application and system...</small></li>
<li><a href='http://michaelaheap.com/2010/05/12/javascript-control-structures/' rel='bookmark' title='Permanent Link: Javascript Control Structures'>Javascript Control Structures</a> <small>I stumbled across http://eloquentjavascript.net/ and decided to have a flick...</small></li>
<li><a href='http://michaelaheap.com/2010/08/27/working-with-domdocument/' rel='bookmark' title='Permanent Link: Working with DOMDocument'>Working with DOMDocument</a> <small>Nowadays, most of the services we need to access programatically...</small></li>
</ol></p><img src="http://feeds.feedburner.com/~r/Michaelaheapcom/~4/4haHFNGx8-Q" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://michaelaheap.com/2010/08/12/php-5-3-anonymous-lambda-functions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://michaelaheap.com/2010/08/12/php-5-3-anonymous-lambda-functions/</feedburner:origLink></item>
		<item>
		<title>Barcamp Blackpool: Round 2</title>
		<link>http://feedproxy.google.com/~r/Michaelaheapcom/~3/vsveL7V9UsY/</link>
		<comments>http://michaelaheap.com/2010/07/06/barcamp-blackpool-round-2/#comments</comments>
		<pubDate>Tue, 06 Jul 2010 09:20:05 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[Events]]></category>
		<category><![CDATA[barcamp]]></category>
		<category><![CDATA[blackpool]]></category>
		<category><![CDATA[tagwalk]]></category>

		<guid isPermaLink="false">http://michaelaheap.com/?p=910</guid>
		<description><![CDATA[This weekend was the second barcamp organised by the lovely Gemma Cameron in Blackpool. Blackpool being Blackpool, there's no shortage of cheap B+B's so I headed up on the Friday night and checked in at Balmoral like I did last year. Rich Quick decided he'd organise a bit of something on the Friday night at&#8230


Related posts:<ol><li><a href='http://michaelaheap.com/2009/11/09/barcamp-blackpool/' rel='bookmark' title='Permanent Link: Barcamp Blackpool'>Barcamp Blackpool</a> <small>A little late, but this is the first chance I've...</small></li>
<li><a href='http://michaelaheap.com/2009/10/13/phpnw09-10th-11th-october-2009/' rel='bookmark' title='Permanent Link: PHPNW09 &#8211; 10th &#038; 11th October 2009'>PHPNW09 &#8211; 10th &#038; 11th October 2009</a> <small>I spent this weekend at PHPNW's second annual conference in...</small></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>This weekend was the second barcamp organised by the lovely <a href="http://twitter.com/ruby_gem">Gemma Cameron</a> in Blackpool. Blackpool being Blackpool, there's no shortage of cheap B+B's so I headed up on the Friday night and checked in at Balmoral like I did last year.</p>
<div id="attachment_911" class="wp-caption alignright" style="width: 235px"><a href="http://michaelaheap.com/wp-content/uploads/2010/07/IMG_0081.jpg"><img class="size-medium wp-image-911" title="Fun Times!" src="http://michaelaheap.com/wp-content/uploads/2010/07/IMG_0081-225x300.jpg" alt="Annamarie, Jack and Rich on a carousel" width="225" height="300" /></a><p class="wp-caption-text">Fun Times!</p></div>
<p><a href="http://twitter.com/richquick">Rich Quick</a> decided he'd organise a bit of something on the Friday night at The Counting House, so about 7ish I decided to take a walk up the promenade to the pub. I'd been there for about 20 minutes when Rich and his band of merry men (<a href="http://twitter.com/jack_franklin">Jack</a>, <a href="http://twitter.com/houghster">Chris</a> and <a href="http://twitter.com/pauldunn_">Paul</a>) appeared. We had a few pints and were eventually joined by <a href="http://twitter.com/lallyd">Lally</a>, <a href="http://twitter.com/annamaflea">Annamarie</a>, <a href="http://twitter.com/binarykitten">Kat</a> and <a href="http://twitter.com/sonniesedge">Charlie</a>. We headed down to South Pier and met up with a few others for a drink before they called it a night/went to meet others and we headed back up to The Counting House. This is where things start to get blurry. After several pints/whiskeys/shots, an awesome rendition of Lady Gaga's song Alehandro by Jack and a mission to Walkabout, I made it back to the B+B for a few hours sleep before #bcblackpool started. Next time, I'll definitely by following <a href="http://twitter.com/alistair">Alistair</a>'s lead and bailing quite early on the preparty.</p>
<h3>The Day</h3>
<p>I arrived just in time for the opening talk and speed dating. It's a nice idea, especially at barcamps like Blackpool where there's quite a few first time attendees. The only thing I can say about it is that the dating rounds were a bit short, and usually ended after only one person had introduced themselves and what they do.</p>
<p>This year the sessions were 45 minutes long, compared to the 20 minutes last year. I've got to say, it's great to see organisers taking feedback into account when planning the event. While 45 minutes is a bit long for some people, we're pretty good at innovating and the day saw people doubling up on sessions and running two per slot when they knew theirs wouldn't be anywhere near 45 minutes long. Maybe 30 minutes next year, including 5 mins questions and 5 mins to move around?</p>
<p>The first session I saw this time was probably the one I found most useful. <a href="http://twitter.com/bwaine">Ben Waine</a> showed us xdebug, and how easy it is to install and configure. No more print_r and pre tags! It's been something I've been meaning to take a look at since I saw <a href="http://twitter.com/derickr">Derick Rethans</a> talk about it at PHPNW09, but Ben's talk gave me the kick I needed.</p>
<p>The second most useful talk I saw was also PHP related, though the concept can be applied to any language. <a href="http://twitter.com/phpcodemonkey">Jeremy Coates</a> did a talk on Continuous Integration using <a href="http://hudson-ci.org/">Hudson</a>. I'd previously looked at <a href="http://www.phpundercontrol.org/about.html">phpUnderControl</a>, but Hudson looks much easier to set up and run with. Again, it's something I've been looking into, but it's overkill for the projects that I work on. Maybe in future when I start working with a team of developers again it'd be useful, but as a sole coder, I don't really need it.</p>
<p><a href="http://twitter.com/timhastings">Tim Hastings</a> pulled out Tag Walk to show us all again, and didn't disappoint. From following twitter during the talk, it seemed as though it came across as a sales pitch to a few people but I didn't see it at all. From my point of view, it was a great introduction to see how we can use the relationship between tweets to add context to other tweets that previously had no real meaning (the Elvis example was a great one). Tim and <a href="http://twitter.com/jreast">Jason</a> are also working on another top secret project that looks very promising, so keep an eye on @timhastings and @jreast for news on it.</p>
<p>I *finally* made it to Lalita's talk on British Sign Language after a few failed attempts, which was lucky as apparantly the talk is being retired now, and a new more advanced one is being planned! I'd say that it was the most fun session of the day. We learnt the alphabet, a few common words and of course, some swearwords. Lally also inadvertantly taught us how to say "dead dog" which made me laugh.</p>
<p>Finally, how can we forget Jack's talk on jQuery tips and tricks? I met Jack the night before and warned him that I'd be heckling him a lot, so it was quite entertaining seeing his face drop a little when he saw me sat at the back of the room. Looking back, I probably overdid it a little and will tone things down in future, but he took it as a bit of a laugh and responded well (including his little win when I said something just as it popped up on the slides). Overall, it was a great presentation - full of things I wish I'd known when I first started out.</p>
<p>Jack doing the jQuery talk also meant that I didn't do a talk this weekend, for the first time ever. It was great not having to hack code and examples together, and just being able to focus and enjoy the sessions being presented.</p>
<p>We had loads of goodies, including BCBlackpool pink USB pens courtest of <a href="http://twitter.com/mountrec">Mount Recruitment</a>, who did a session on recruitment agencies that I really enjoyed. He covered why recruiters usually don't call back if you don't get the job, why they're still useful even if they don't know anything about your subject area, and how sometimes recruiters can help you earn *more* money than you would if you just apply yoruself. There are a lot of cowboys out there, but there are a few decent recruiters who make life easier for us - Grant at mountrec is one of them.</p>
<p>There was also BCBlackpool rock, and some awesome tshirts courtesy of Paypal. Plus of course the pies at lunch, buffet in the evening and beer behind the bar. So, thanks to all our sponsors for contributing, we couldn't have done it without you!</p>
<h3>Evening Time</h3>
<p>Evening entertainment was provided by Paul Sylvester, magician extrordinaire. After he wowed us last year, I wondered what was coming this time. A few new tricks, lots of audience participation and some great banter meant that it was an awesome show. I'm just a bit gutted that he didn't bring along the guillotine this year <img src='http://michaelaheap.com/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> </p>
<p>After we drank the bar dry and got kicked out of the venue, we headed out to find another place to drink. I managed to call shotgun as Lally was driving, however I got overruled by Annamarie. <img src='http://michaelaheap.com/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' />  Still, a lift up to The Corner House (again) while everyone else walked went down very well. After a few pints (and a quick nap) in the pub, we met up with Tim and Jason, then Gem and a few others in a bar I can't remember the name of. Again, we carried on drinking more alcohol until we realised it was almost 4am and time to call it a night.</p>
<p>This was without a doubt the drunkest barcamp I've ever been to, and I loved every minute it. It was well organised, with a good mix of new and experienced barcampers. We've had two in 6 months, but I'm looking forward to the next one already!</p>
<h3>Other writeups around the web!</h3>
<ul>
<li><a href="http://blog.jackfranklin.co.uk/post/769714018/barcamp-blackpool-2-review">Jack Franklin</a></li>
<li><a href="http://www.jordanh.net/2010/07/barcamp-blackpool">Jordan Hatch</a></li>
<li><a href="http://ashinyworld.blogspot.com/2010/07/bar-camping-in-blackpool.html">LouLouK</a></li>
<li><a href="http://www.designsbysteve.co.uk/blog/barcamp-blackpool-2">Steve Daniels</a></li>
<li><a href="http://jonatkinson.co.uk/bcblackpool/">Jon Atkinson</a></li>
<li><a href="http://www.shredcreative.co.uk/blog/">Dan Coverdale</a></li>
</ul>


<p>Related posts:<ol><li><a href='http://michaelaheap.com/2009/11/09/barcamp-blackpool/' rel='bookmark' title='Permanent Link: Barcamp Blackpool'>Barcamp Blackpool</a> <small>A little late, but this is the first chance I've...</small></li>
<li><a href='http://michaelaheap.com/2009/10/13/phpnw09-10th-11th-october-2009/' rel='bookmark' title='Permanent Link: PHPNW09 &#8211; 10th &#038; 11th October 2009'>PHPNW09 &#8211; 10th &#038; 11th October 2009</a> <small>I spent this weekend at PHPNW's second annual conference in...</small></li>
</ol></p><img src="http://feeds.feedburner.com/~r/Michaelaheapcom/~4/vsveL7V9UsY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://michaelaheap.com/2010/07/06/barcamp-blackpool-round-2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://michaelaheap.com/2010/07/06/barcamp-blackpool-round-2/</feedburner:origLink></item>
		<item>
		<title>Designing for the Web</title>
		<link>http://feedproxy.google.com/~r/Michaelaheapcom/~3/s-P_4iwa8rg/</link>
		<comments>http://michaelaheap.com/2010/05/26/designing-for-the-web/#comments</comments>
		<pubDate>Wed, 26 May 2010 15:43:37 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[Review]]></category>
		<category><![CDATA[book]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[fivesimplesteps]]></category>

		<guid isPermaLink="false">http://michaelaheap.com/?p=890</guid>
		<description><![CDATA[I'm a firm believer that if you're naturally a backend coder, you most probably suck at interface/graphics design and vice versa (unless of course, you're Shaun Inman). Being a backend guy myself, I know that we just don't think the same way as frontend dev's. However, that doesn't mean that we'll never be able to&#8230


No related posts.]]></description>
			<content:encoded><![CDATA[<p>I'm a firm believer that if you're naturally a backend coder, you most probably suck at interface/graphics design and vice versa (unless of course, you're <a href="http://www.shauninman.com">Shaun Inman</a>). Being a backend guy myself, I know that we just don't think the same way as frontend dev's. However, that doesn't mean that we'll never be able to design a good looking site ourselves - just that it'll take a bit more effort and research. This is where Designing For The Web by Mark Boulton comes in.</p>
<p><a href="http://www.sanchothefat.com">Rob O'Rourke</a> picked up a copy last summer, and after flicking through it at work I decided to buy a copy myself when it was on offer. It then sat on my shelf for months and months, until I realised it was time to redesign this blog and I picked it up.</p>
<p>As it turns out, design is just a set of rules. I like rules - it means that something is either right or wrong, no middle ground. The book takes you through the basics of typography and colour theory, and how to use them to great effect on your site. </p>
<p>There's also a section on "going it alone", setting up your own freelance business. I'll be re-reading it as I've just set up "Definitely Not Robots" as my own development house.</p>
<p>Designing For The Web is online in html form now at <a href="http://designingfortheweb.co.uk/">http://designingfortheweb.co.uk/</a>, but I'd recommend picking up a hard copy. It's published by <a href="http://fivesimplesteps.co.uk/">Five Simple Steps</a>, and the quality of the book is just outstanding. Solid, glossy pages. And of course, being able to read a book and not a screen always helps.</p>
<p>Finally, just a quick heads up. You might want to keep an eye out of the Five Simple Steps site, as there are a few more books being published by them this year. Most noteably, <a href="http://www.stuffandnonsense.co.uk/">Andy Clarke</a> will be publishing <a href="http://hardboiledwebdesign.com/">Hardboiled Web Design</a> with them, which will definitely be worth a read.</p>


<p>No related posts.</p><img src="http://feeds.feedburner.com/~r/Michaelaheapcom/~4/s-P_4iwa8rg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://michaelaheap.com/2010/05/26/designing-for-the-web/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://michaelaheap.com/2010/05/26/designing-for-the-web/</feedburner:origLink></item>
		<item>
		<title>jQuery Log Function</title>
		<link>http://feedproxy.google.com/~r/Michaelaheapcom/~3/rjGjJkF56lw/</link>
		<comments>http://michaelaheap.com/2010/05/16/jquery-log-function/#comments</comments>
		<pubDate>Sun, 16 May 2010 18:35:18 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[console]]></category>
		<category><![CDATA[firebug]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[plugin]]></category>

		<guid isPermaLink="false">http://michaelaheap.com/?p=896</guid>
		<description><![CDATA[While looking through some old starred items in Google Reader, I noticed a snippet of jQuery that you could use to log the objects returned by jquery selectors and inspect them in the console. While it was very useful, there was a lot of room for expansion. After looking at the Console API for Firebug&#8230


Related posts:<ol><li><a href='http://michaelaheap.com/2010/05/12/javascript-control-structures/' rel='bookmark' title='Permanent Link: Javascript Control Structures'>Javascript Control Structures</a> <small>I stumbled across http://eloquentjavascript.net/ and decided to have a flick...</small></li>
<li><a href='http://michaelaheap.com/2010/08/27/working-with-domdocument/' rel='bookmark' title='Permanent Link: Working with DOMDocument'>Working with DOMDocument</a> <small>Nowadays, most of the services we need to access programatically...</small></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>While looking through some old starred items in Google Reader, I noticed <a href="http://happygiraffe.net/blog/2007/09/26/jquery-logging/">a snippet of jQuery</a> that you could use to log the objects returned by jquery selectors and inspect them in the console. While it was very useful, there was a lot of room for expansion.</p>
<p>After looking at the <a href="http://getfirebug.com/wiki/index.php/Console_API">Console API</a> for Firebug (as that's where most of my JS development takes place) I decided to expand the initial snippet a little. Fortunately, the guys working on the webkit console have been keeping their API consistant with the Firebug one, so this snippet will work in either FF or Chrome <img src='http://michaelaheap.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<pre class="brush: jscript;">
jQuery.fn.log = function  (msg, type) {
		if (typeof lastSelector == 'undefined'){ lastSelector = '--'; }

		if (lastSelector != this.selector.slice(0,lastSelector.length)){
			if (lastSelector != '--'){ console.groupEnd(); lastSelector = '--'; }
			else{ lastSelector = this.selector; }
			console.group(&quot;%s (%s)&quot;, msg, this.selector);
		}

		if (type == undefined){ type=&quot;log&quot;; }
		switch(type){
			case &quot;log&quot;:
			console.log(this);
			break;
			case &quot;warn&quot;:
			console.warn(this);
			break;
			case &quot;info&quot;:
			console.info(this);
			break;
			case &quot;error&quot;:
			console.error(this);
			break;
			case &quot;time&quot;:
			console.time(msg);
			break;
			case &quot;timestop&quot;:
			console.timeEnd(msg);
			case &quot;profile&quot;:
			console.profile(msg);
			break;
			case &quot;profilestop&quot;:
			console.profileEnd(msg);
			break;
		}
		return this;
}
</pre>
<h3>Example Usage</h3>
<pre class="brush: jscript;">
$(&quot;a&quot;).log(&quot;Link Slice Test&quot;).slice(0,3).log().eq(0).log();
</pre>
<p>The above code will create a new group named "Link Slice Test" and any log statements created will be logged within it. Note that the group receives the name provided in the first call to log();</p>
<p><a href="http://michaelaheap.com/wp-content/uploads/2010/05/jqlog_ex.png"><img src="http://michaelaheap.com/wp-content/uploads/2010/05/jqlog_ex.png" alt="" title="jqlog_ex" width="776" height="78" class="aligncenter size-full wp-image-905" /></a></p>
<p>There are some other formatting options: info, warn and error. To apply these styles, you pass them as a parameter to the log function. e.g.:</p>
<pre class="brush: jscript;">
$(&quot;a&quot;).log(&quot;Link Slice Test&quot;, &quot;info&quot;).slice(0,3).log(&quot;&quot;, &quot;warn&quot;).eq(0).log(&quot;&quot;, &quot;error&quot;);
</pre>
<p><a href="http://michaelaheap.com/wp-content/uploads/2010/05/jqlog_ex2.png"><img src="http://michaelaheap.com/wp-content/uploads/2010/05/jqlog_ex2.png" alt="" title="jqlog_ex2" width="763" height="97" class="aligncenter size-full wp-image-906" /></a></p>
<p>Finally, there's a little profiling option if people want to use it. This time, the name you pass in is the name used for the timer, and must be specified when starting and stopping the timer.</p>
<pre class="brush: jscript;">
$(&quot;a&quot;).log(&quot;Recolour&quot;, &quot;time&quot;).css(&quot;background&quot;, &quot;red&quot;).log(&quot;Recolour&quot;, &quot;timestop&quot;);
</pre>
<p><a href="http://michaelaheap.com/wp-content/uploads/2010/05/jqlog_ex3.png"><img src="http://michaelaheap.com/wp-content/uploads/2010/05/jqlog_ex3.png" alt="" title="jqlog_ex3" width="582" height="43" class="aligncenter size-full wp-image-907" /></a></p>
<p>In this case, we can see that it took 3ms to change the background colour of every link on the page to be red. You can also use "profile" and "profilestop" which in addition to providing the overall time, gives a breakdown of the time spent in every function called between the two points.</p>
<p>Hopefully some of you will find this useful - it was a good excuse for me to dig into the console API and apply what I found in a way that I'll use in future <img src='http://michaelaheap.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>


<p>Related posts:<ol><li><a href='http://michaelaheap.com/2010/05/12/javascript-control-structures/' rel='bookmark' title='Permanent Link: Javascript Control Structures'>Javascript Control Structures</a> <small>I stumbled across http://eloquentjavascript.net/ and decided to have a flick...</small></li>
<li><a href='http://michaelaheap.com/2010/08/27/working-with-domdocument/' rel='bookmark' title='Permanent Link: Working with DOMDocument'>Working with DOMDocument</a> <small>Nowadays, most of the services we need to access programatically...</small></li>
</ol></p><img src="http://feeds.feedburner.com/~r/Michaelaheapcom/~4/rjGjJkF56lw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://michaelaheap.com/2010/05/16/jquery-log-function/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://michaelaheap.com/2010/05/16/jquery-log-function/</feedburner:origLink></item>
		<item>
		<title>Javascript Control Structures</title>
		<link>http://feedproxy.google.com/~r/Michaelaheapcom/~3/W4LsdcQQLa4/</link>
		<comments>http://michaelaheap.com/2010/05/12/javascript-control-structures/#comments</comments>
		<pubDate>Wed, 12 May 2010 08:18:48 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[construct]]></category>
		<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://michaelaheap.com/?p=904</guid>
		<description><![CDATA[I stumbled across http://eloquentjavascript.net/ and decided to have a flick through. Knew most of it, but there are two very useful constructs I didn't know about: labels and with(). Labels Labels look a bit like a goto statement, but are infinitely more useful. There's been a few times that I've needed to break out of&#8230


Related posts:<ol><li><a href='http://michaelaheap.com/2010/08/27/working-with-domdocument/' rel='bookmark' title='Permanent Link: Working with DOMDocument'>Working with DOMDocument</a> <small>Nowadays, most of the services we need to access programatically...</small></li>
<li><a href='http://michaelaheap.com/2010/05/16/jquery-log-function/' rel='bookmark' title='Permanent Link: jQuery Log Function'>jQuery Log Function</a> <small>While looking through some old starred items in Google Reader,...</small></li>
<li><a href='http://michaelaheap.com/2010/08/12/php-5-3-anonymous-lambda-functions/' rel='bookmark' title='Permanent Link: PHP 5.3: Anonymous (Lambda) Functions'>PHP 5.3: Anonymous (Lambda) Functions</a> <small>A month or so ago I started work at a...</small></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>I stumbled across <a href="http://eloquentjavascript.net/">http://eloquentjavascript.net/</a> and decided to have a flick through. Knew most of it, but there are two very useful constructs I didn't know about: labels and with().</p>
<h3>Labels</h3>
<p>Labels look a bit like a goto statement, but are infinitely more useful. There's been a few times that I've needed to break out of a nested loop statement and had to resort to the following hacky code:</p>
<pre class="brush: jscript;">
var breakOut = false;
for(i=0; i &lt; object.length; i++){
	for(j=0; j &lt; object_two.length; j++){
		breakOut = true;
		break;
	}

	if (breakOut){ break; }
}
</pre>
<p>While this works, it doesn't look very nice and results in you having to use an extra variable. In PHP, you can use <code>break 2;</code> to break out of two loops at the same time, but unfortunately it's not supported in javascript. This is where labels come in handy. Imagine the code we used above, but we give each loop a name, and tell the break statement which loop to break out of:</p>
<pre class="brush: jscript;">
loopI: for(i=0; i &lt; object.length; i++){
	loopJ: for(j=0; j &lt; object_two.length; j++){
		break loopI;
	}
}
</pre>
<p>Some people may not like the use of labels, but personally I think that the code is much easier to read than the code that uses a temporary variable. Of course, using labels gets more and more useful as you start to nest more and more loops (imagine using four nested loops and wanting to break out of the top one <sup><a href="#fn-1">[1]</a></sup>)</p>
<h3>with()</h3>
<p>This one has a slightly more limited use case, but is still quite useful nonetheless. It's designed for when you're working with an object, and will be accessing the object's properties quite a lot.</p>
<p>Take a look at this code:</p>
<pre class="brush: jscript;">
var car = {
	&quot;colour&quot;: &quot;red&quot;,
	&quot;name&quot;: &quot;bertha&quot;,
	&quot;output&quot;: function(){
		return this.name + &quot; is a &quot; + this.colour + &quot; car!&quot;;
	}
}
</pre>
<p>While this is only a small example, imagine that the car had ten properties. Typing <code>this.propery</code> over and over could get repetitive, which is where with() comes in. You pass the object as a parameter and within the with() block, all of the objects properties are available as standard variables. Going back to the above code, it now looks like:</p>
<pre class="brush: jscript;">
var car = {
	&quot;colour&quot;: &quot;red&quot;,
	&quot;name&quot;: &quot;bertha&quot;,
	&quot;output&quot;: function(){
		with(this){
			return name + &quot; is a &quot; + colour + &quot; car!&quot;;
		}
	}
}
</pre>
<p>While there's not really been a reduction in code in this example, hopefully you can see how it could be useful in some situations. You can also pass it an object that already exists such as:</p>
<pre class="brush: jscript;">
with(car){
	alert(name);
}
</pre>
<h3>Why?</h3>
<p>I've not come across either of these constructs before, and though they're quite rare it's handy to know what they both do as there are situations that they'd come in handy (or they wouldn't exist). Hopefully one day you'll come across them to, and know what they're for instead of having to run to Google and see what turns up.</p>
<h3>Footnotes</h3>
<p><a name="fn-1"></a><sup>1.</sup> Though if you are using four, you're probably doing it wrong.</p>


<p>Related posts:<ol><li><a href='http://michaelaheap.com/2010/08/27/working-with-domdocument/' rel='bookmark' title='Permanent Link: Working with DOMDocument'>Working with DOMDocument</a> <small>Nowadays, most of the services we need to access programatically...</small></li>
<li><a href='http://michaelaheap.com/2010/05/16/jquery-log-function/' rel='bookmark' title='Permanent Link: jQuery Log Function'>jQuery Log Function</a> <small>While looking through some old starred items in Google Reader,...</small></li>
<li><a href='http://michaelaheap.com/2010/08/12/php-5-3-anonymous-lambda-functions/' rel='bookmark' title='Permanent Link: PHP 5.3: Anonymous (Lambda) Functions'>PHP 5.3: Anonymous (Lambda) Functions</a> <small>A month or so ago I started work at a...</small></li>
</ol></p><img src="http://feeds.feedburner.com/~r/Michaelaheapcom/~4/W4LsdcQQLa4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://michaelaheap.com/2010/05/12/javascript-control-structures/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://michaelaheap.com/2010/05/12/javascript-control-structures/</feedburner:origLink></item>
		<item>
		<title>HowTo: Codeigniter Partial Library</title>
		<link>http://feedproxy.google.com/~r/Michaelaheapcom/~3/hlzPBkYhs4I/</link>
		<comments>http://michaelaheap.com/2010/04/15/howto-codeigniter-partial-library/#comments</comments>
		<pubDate>Thu, 15 Apr 2010 14:55:35 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[codeigniter]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[partial]]></category>
		<category><![CDATA[theme]]></category>

		<guid isPermaLink="false">http://michaelaheap.com/?p=899</guid>
		<description><![CDATA[This assumes you have moved both the application and system libraries into their own folders outside the webroot. (See the user guide) You'll want to start off by grabbing a copy of the library from github. You need to put the file in ./application/libraries/ and add it to the autoload file located at (see the&#8230


Related posts:<ol><li><a href='http://michaelaheap.com/2010/04/15/codeigniter-partial-library/' rel='bookmark' title='Permanent Link: Codeigniter Partial Library'>Codeigniter Partial Library</a> <small>Back in August, I started to play around with Codeigniter...</small></li>
<li><a href='http://michaelaheap.com/2010/08/12/php-5-3-anonymous-lambda-functions/' rel='bookmark' title='Permanent Link: PHP 5.3: Anonymous (Lambda) Functions'>PHP 5.3: Anonymous (Lambda) Functions</a> <small>A month or so ago I started work at a...</small></li>
<li><a href='http://michaelaheap.com/2009/11/02/custom-wordpress-taxonomies/' rel='bookmark' title='Permanent Link: Custom WordPress Taxonomies'>Custom WordPress Taxonomies</a> <small>I can't think of any practical applications apart from the...</small></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><em>This assumes you have moved both the application and system libraries into their own folders outside the webroot. (See the <a href="http://codeigniter.com/user_guide/general/managing_apps.html">user guide</a>)</em></p>
<p>You'll want to start off by grabbing a <a href="http://github.com/mheap/Codeigniter-Partial-Library">copy of the library</a> from github. You need to put the file in <code>./application/libraries/</code> and add it to the autoload file located at <code></code> (see the <a href="http://codeigniter.com/user_guide/general/autoloader.html">user guide</a> for more details)</p>
<p>Once you have the file and it's being loaded, we can start making some changes. I started with an empty Codeigniter download, and added the partial library to it. The next step was to make the site render using the library and not the build in functions. To do this, we need to extend our base controller using MY_Controller. There are <a href="http://michaelaheap.com/2009/07/11/codeigniter-setup/">a few</a> <a href="http://codeigniter.com/wiki/MY_Controller_-_how_to_extend_the_CI_Controller/">resources</a> around on how to do this, so I'll just skip ahead to when we have our MY_Controller set up and our controller now extends it instead of the base Controller.</p>
<p>Next, we want to hijack the function that actually shows our page and run the partial library's output function. </p>
<pre class="brush: php;">
function _output(){
	$this-&gt;partial-&gt;outputPage();
}
</pre>
<p>This means that <code>$this->load->view</code> will no longer output the view to the page.</p>
<p>Your MY_Controller should now look like this:</p>
<pre class="brush: php;">
&lt;?php if (!defined('BASEPATH')) exit('No direct script access allowed');

class MY_Controller extends Controller{

	function MY_Controller(){
		parent::Controller();
	}

	function _output(){
		$this-&gt;partial-&gt;outputPage();
	}

}
</pre>
<p>Great! Now all of the leg work is done and it's time to start adding content to our pages. Let's go back to the <code>Welcome.php</code> Controller. We need to replace <code>$this->load->view()</code> with <code>$this->partial->register()</code>. However, <code>$this->partial->register()</code> takes three parameters instead of two. To call it, use the following format:</p>
<pre class="brush: php;">
$this-&gt;partial-&gt;register($title, $view, $data);
</pre>
<p>You'll notice, it's very similar to the original syntax:</p>
<blockquote><p>
<code>$title</code>: The label that you give to that section of the page. Examples include "navigation" or "content".<br />
<code>$view</code>: The view file to be loaded. In this case, it'll be <code>welcome_message.php</code><br />
<code>$data</code>: The data array that you pass into views normally.
</p></blockquote>
<p>We're now back at square one, the welcome message should be loaded when you access the application. "What was the point in doing all this then?" I hear you ask. Well, currently the entire page is stored in that one view file. Really, we only want the content to be in there and for the header and footer to be placed there magically.</p>
<p>So, let's create two files: <code>./application/views/pageheader.php</code> and <code>./application/views/pagefooter.php</code>. I'm going to take everything from the top of the file up to &lt;body> and move it to <code>pageheader.php</code> and move everything from &lt;body> to the end of the file and place it in <code>pagefooter.php</code></p>
<p>If you save all off these files and refresh, you should see just the welcome_message.php file on it's own<br />
<a href="http://michaelaheap.com/wp-content/uploads/2010/04/ci_basic.png"><img src="http://michaelaheap.com/wp-content/uploads/2010/04/ci_basic-300x166.png" alt="Codeigniter with No Styling" title="Basic" width="300" height="166" class="aligncenter size-medium wp-image-900" /></a></p>
<p>The next step is to include the <code>header.php</code> and <code>footer.php</code> files that you just created. This is where MY_Controller comes in. The partial library has two special functions, <code>header</code> and <code>footer</code>. They take two arguments each:</p>
<pre class="brush: php;">
function header($__view, $__data=array())
function footer($__view, $__data=array())
</pre>
<p>Both functions take a view file and a data array as parameters. They do not accept labels as they are given special labels internally. If we use those two functions in MY_Controller to set out header and footer to the files we just created, our page should start taking shape again.<br />
<a href="http://michaelaheap.com/wp-content/uploads/2010/04/ci_style.png"><img src="http://michaelaheap.com/wp-content/uploads/2010/04/ci_style-300x150.png" alt="" title="ci_style" width="300" height="150" class="aligncenter size-medium wp-image-901" /></a></p>
<p>After adding the header and footer, your MY_Controller.php constructor should look as follows:</p>
<pre class="brush: php;">
function MY_Controller(){
	parent::Controller();
	$this-&gt;partial-&gt;header(&quot;pageheader&quot;);
	$this-&gt;partial-&gt;footer(&quot;pagefooter&quot;);
}
</pre>
<p>And there you have it, your controllers content are now framed. For example, if we create <code>function hello()</code> and that in turn loads <code>hello_message.php</code> it will put the contents of hello_message in the middle of our header and footer. No matter how many controllers or functions we add, they will always have a header and footer (unless we disable the header and footer, but that's an example for another time!)</p>
<p><a href="http://michaelaheap.com/assets/ci_partial_intro.zip">Here's the sample code</a> if you want to take a look at the code inside an application. I'm going to put together an example that's a bit more complicated and utilises <code>$data</code> in the header and footer, and some additional functions within the library such as <code>registerScript</code> and <code>registerStylesheet</code> along with some example views that make use of them</p>


<p>Related posts:<ol><li><a href='http://michaelaheap.com/2010/04/15/codeigniter-partial-library/' rel='bookmark' title='Permanent Link: Codeigniter Partial Library'>Codeigniter Partial Library</a> <small>Back in August, I started to play around with Codeigniter...</small></li>
<li><a href='http://michaelaheap.com/2010/08/12/php-5-3-anonymous-lambda-functions/' rel='bookmark' title='Permanent Link: PHP 5.3: Anonymous (Lambda) Functions'>PHP 5.3: Anonymous (Lambda) Functions</a> <small>A month or so ago I started work at a...</small></li>
<li><a href='http://michaelaheap.com/2009/11/02/custom-wordpress-taxonomies/' rel='bookmark' title='Permanent Link: Custom WordPress Taxonomies'>Custom WordPress Taxonomies</a> <small>I can't think of any practical applications apart from the...</small></li>
</ol></p><img src="http://feeds.feedburner.com/~r/Michaelaheapcom/~4/hlzPBkYhs4I" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://michaelaheap.com/2010/04/15/howto-codeigniter-partial-library/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://michaelaheap.com/2010/04/15/howto-codeigniter-partial-library/</feedburner:origLink></item>
		<item>
		<title>Codeigniter Partial Library</title>
		<link>http://feedproxy.google.com/~r/Michaelaheapcom/~3/ALFTnsYdg88/</link>
		<comments>http://michaelaheap.com/2010/04/15/codeigniter-partial-library/#comments</comments>
		<pubDate>Thu, 15 Apr 2010 14:55:29 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[codeigniter]]></category>
		<category><![CDATA[library]]></category>
		<category><![CDATA[partial]]></category>
		<category><![CDATA[theme]]></category>

		<guid isPermaLink="false">http://michaelaheap.com/?p=898</guid>
		<description><![CDATA[Back in August, I started to play around with Codeigniter at work, and it quickly became my framework of choice. I quickly realised that there were some features that I considered essential missing from Codeigniter. Fortunately, there's an easy way to extend the core, and so my Codeigniter Theme Library was born. There were a&#8230


Related posts:<ol><li><a href='http://michaelaheap.com/2010/04/15/howto-codeigniter-partial-library/' rel='bookmark' title='Permanent Link: HowTo: Codeigniter Partial Library'>HowTo: Codeigniter Partial Library</a> <small>This assumes you have moved both the application and system...</small></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Back in August, I started to play around with Codeigniter at work, and it quickly became my framework of choice. I quickly realised that there were some features that I considered essential missing from Codeigniter. Fortunately, there's an easy way to extend the core, and so my <a href="http://michaelaheap.com/2009/08/12/codeigniter-theme-library/">Codeigniter Theme Library</a> was born. </p>
<p>There were a few <a href="http://michaelaheap.com/2009/08/12/codeigniter-theme-library/#comments">comments</a> left on the post with suggestions. The main one was from <a href="http://philsturgeon.co.uk/">Phil Sturgeon</a> (of <a href="http://www.pyrocms.com/">pyroCMS</a> fame) who mentioned that it was really more of a layout library than a theme library. He was right, and this release renames the class and removes some of the functions that were specific to my project.</p>
<p>Feel free to <a href="http://github.com/mheap/Codeigniter-Partial-Library">grab a copy</a> and test it out. There's still no documentation (despite earlier promises), so if you want a pointer in the right direction take a look at my post on <a href="http://michaelaheap.com/2010/04/15/howto-codeigniter-partial-library/">getting to grips with the partial library</a></p>


<p>Related posts:<ol><li><a href='http://michaelaheap.com/2010/04/15/howto-codeigniter-partial-library/' rel='bookmark' title='Permanent Link: HowTo: Codeigniter Partial Library'>HowTo: Codeigniter Partial Library</a> <small>This assumes you have moved both the application and system...</small></li>
</ol></p><img src="http://feeds.feedburner.com/~r/Michaelaheapcom/~4/ALFTnsYdg88" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://michaelaheap.com/2010/04/15/codeigniter-partial-library/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://michaelaheap.com/2010/04/15/codeigniter-partial-library/</feedburner:origLink></item>
		<item>
		<title>Canvas, ProcessingJS + HasCanvas</title>
		<link>http://feedproxy.google.com/~r/Michaelaheapcom/~3/8h2w9DQRzY0/</link>
		<comments>http://michaelaheap.com/2010/04/06/canvas-processingjs-hascanvas/#comments</comments>
		<pubDate>Tue, 06 Apr 2010 16:08:48 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Review]]></category>
		<category><![CDATA[hascanvas]]></category>
		<category><![CDATA[ide]]></category>
		<category><![CDATA[processingjs]]></category>
		<category><![CDATA[rob-orourke]]></category>

		<guid isPermaLink="false">http://michaelaheap.com/?p=889</guid>
		<description><![CDATA[HTML5 is the newest incarnation of HTML, the markup language of the web. With it, comes the introduction of a few new tags such as &#60;video>, &#60;audio> and perhaps most interestingly, &#60;canvas>. I'm a relative newcomer to Canvas, but I'm in intrigued to see just how quickly (if at all) it will replace Flash as&#8230


Related posts:<ol><li><a href='http://michaelaheap.com/2010/05/12/javascript-control-structures/' rel='bookmark' title='Permanent Link: Javascript Control Structures'>Javascript Control Structures</a> <small>I stumbled across http://eloquentjavascript.net/ and decided to have a flick...</small></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>HTML5 is the newest incarnation of HTML, the markup language of the web. With it, comes the introduction of a few new tags such as &lt;video>, &lt;audio> and perhaps most interestingly, &lt;canvas>. I'm a relative newcomer to Canvas, but I'm in intrigued to see just how quickly (if at all) it will replace Flash as the main provider of interactivity online.</p>
<p>Canvas is exactly what it says on the tin, a blank canvas for you to draw onto via Javascript. For example, let's take a look at the code to draw a smiley face:</p>
<pre class="brush: jscript;">
ctx.beginPath();
ctx.fillStyle = 'yellow';
ctx.moveTo(125,75);
ctx.arc(75,75,50,0,Math.PI*2,true); // Outer circle
ctx.stroke();
ctx.fill();

ctx.moveTo(110,75);
ctx.arc(75,75,35,0,Math.PI,false);   // Mouth
ctx.stroke();

ctx.beginPath();
ctx.fillStyle = 'black';
ctx.moveTo(65,65);
ctx.arc(60,65,5,0,Math.PI*2,true);  // Left eye
ctx.fill();

ctx.moveTo(95,65);
ctx.arc(90,65,5,0,Math.PI*2,true);  // Right eye
ctx.fill();
</pre>
<p><a href="http://mozilla.doslash.org/stuff/canvas/shell.html">via Mozilla</a></p>
<p>While it's not too bad for simple things such as this, it gets less clear-cut for more complicated applications. For example, check out this code for determining where the mouse is on the page:</p>
<pre class="brush: jscript;">
// Get the mouse position relative to the canvas element.
  if (ev.layerX || ev.layerX == 0) { // Firefox
    x = ev.layerX;
    y = ev.layerY;
  } else if (ev.offsetX || ev.offsetX == 0) { // Opera
    x = ev.offsetX;
    y = ev.offsetY;
  }
</pre>
<p><a href="http://dev.opera.com/articles/view/html5-canvas-painting/">via dev.opera</a></p>
<p>As the canvas specification hasn't yet been ratified by the W3C, it is down to the browser vendors to implement it as best they see fit. This leads to inconsistancy in code and more work for us as developers.</p>
<h2>ProcessingJS</h2>
<p>This is where <a href="http://processingjs.org/">Processing.js</a> comes in handy. Processing.js is a Javascript port of the <a href="http://processing.org/">Processing</a> graphics library from Java. Pioneered by John Resig (of <a href="http://www.jquery.com">jQuery</a> fame) and now developed by an <a href="http://processingjs.org/community">ever-growing community</a>, it aims to be a direct port of the library between languages. The <a href="http://processingjs.org/reference">documentation</a> is pretty good, if a little technical at times. </p>
<p>Where this library comes into it's own is standardisation. Imagine the piece of code above for getting the current mouse position. In Processing.js, we don't need to check what browser we're using etc, we just know that <a href="http://processingjs.org/reference/mouseX">mouseX</a> and <a href="http://processingjs.org/reference/mouseY">mouseY</a> . Additionally, there are some built in variables and functions to deal with <a href="http://processingjs.org/reference/mousePressed">mouse</a> <a href="http://processingjs.org/reference/mousePressed()">events</a> (as opposed to having to register your own listener using Canvas).</p>
<p>For example, to make a basic canvas we can draw on to using the mousePressed variable:</p>
<pre class="brush: jscript;">
void draw(){
	if (mousePressed) {
		line(mouseX,mouseY,pX,pY);
	}

	pX = mouseX;
	pY = mouseY;
}
</pre>
<p>Or to fill the canvas with white when we click using the MouseDown() function:</p>
<pre class="brush: jscript;">
void mousePressed() {
	fill(255);
}
</pre>
<p>Now that we have consistent syntax to be working with, there's only one more thing to do. When developing canvas sketches, you quickly end up with folders full of html files with canvases on, javascript files containing the drawings etc. Wouldn't it be nice if you could just load up one page, type in your code and see what happens? If you get bored, close it down and then just go back to the page later and it's there waiting for you. Well, someone else though that and decided to build a web app for it.</p>
<h2>HasCanvas</h2>
<p>Enter HasCanvas, a web-based IDE from <a href="http://sanchothefat.com/">Rob O'Rourke</a> for making processing.js sketches. Rob's put together <a href="http://sanchothefat.com/portfolio/63/hascanvas">his own post</a> on his blog explaining why he built it and how it works, but the first paragraph is what makes it most useful for me.</p>
<blockquote><p>Back in March when I started playing with Processing.js I was making page after page of sketches and it quickly got tiresome. What happened next I guess you could say was a “moment of clarity” in the words of Samuel L. I knew exactly what I wanted to make and after 2 weeks of hacking in the evenings HasCanvas was born.</p></blockquote>
<p>The login system for HasCanvas is handled using rpxnow and it allows you to sign in using a huge number of services including your Google account, Twitter account or OpenID account.</p>
<p>HasCanvas takes away all of the initial hurdles you come up against when first playing with processing.js - you literally go to http://hascanvas.com/yoursketchname and start developing. If you're logged in, your sketch will automatically be saved every time it is run so you can continue developing it in future.</p>
<h2>So We Can Use This Now?</h2>
<p>Honestly, I'm not totally sure. There's some awesome examples out there already demonstrating you can do with canvas, ranging from <a href="http://hascanvas.com/hc10">little sketches</a>, to <a href="http://f1results.socialminds.com.br">data visualization</a> to creating <a href="http://mugtug.com/sketchpad/">full blown apps</a>.</p>
<p>However, it just <em>doesn't work</em> in Internet Explorer. The F1 results visualization gives us this message when we try and view the site in IE, an approach I'm sure a lot of other developers will take too:</p>
<blockquote><p>Works with the latest versions of: Firefox, Safari, Chrome, Android, iPhone OS. Does NOT work with Ineternet Explorer!</p></blockquote>
<p>However there are some developers who are trying to add Canvas support to IE as it stands now, and they're collaborating on the <a href="http://code.google.com/p/explorercanvas/">excanvas</a> project. On their website, they say you can simply include the excanvas JS file and then use it like any other canvas. I'm quite interested to see if Processing.js and excanvas play nicely together, but I'll need to find some time to set up a test as HasCanvas doesn't support Internet Explorer either.</p>


<p>Related posts:<ol><li><a href='http://michaelaheap.com/2010/05/12/javascript-control-structures/' rel='bookmark' title='Permanent Link: Javascript Control Structures'>Javascript Control Structures</a> <small>I stumbled across http://eloquentjavascript.net/ and decided to have a flick...</small></li>
</ol></p><img src="http://feeds.feedburner.com/~r/Michaelaheapcom/~4/8h2w9DQRzY0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://michaelaheap.com/2010/04/06/canvas-processingjs-hascanvas/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://michaelaheap.com/2010/04/06/canvas-processingjs-hascanvas/</feedburner:origLink></item>
		<item>
		<title>Internet Research Report: Amazon, eBay and Play</title>
		<link>http://feedproxy.google.com/~r/Michaelaheapcom/~3/x1KAwbbSzLM/</link>
		<comments>http://michaelaheap.com/2010/04/02/internet-research-report-amazon-ebay-and-play/#comments</comments>
		<pubDate>Fri, 02 Apr 2010 16:14:49 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[Projects]]></category>
		<category><![CDATA[report]]></category>
		<category><![CDATA[seebuyplay]]></category>
		<category><![CDATA[university]]></category>

		<guid isPermaLink="false">http://michaelaheap.com/?p=847</guid>
		<description><![CDATA[This semester, the bulk of my time at university has been spent working as part of a team on an Internet Systems project. For most of the team, this is their first real experience at building a web application. However before we started designing the system, we were tasked with going out and analysing three&#8230


Related posts:<ol><li><a href='http://michaelaheap.com/2010/02/28/a-remarkable-life-logging-project/' rel='bookmark' title='Permanent Link: A Remarkable Life Logging Project'>A Remarkable Life Logging Project</a> <small>Let me start out by showing you a snippet of...</small></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>This semester, the bulk of my time at university has been spent working as part of a team on an Internet Systems project. For most of the team, this is their first <em>real</em> experience at building a web application.</p>
<p>However before we started designing the system, we were tasked with going out and analysing three existing systems. In addition to this, the report had a cap of 1500 word (+/- 10%). Unfortunately this meant that I couldn't go into as much detail as I would have liked in some sections. In any case here's my report - It scored 80%, and the main criticism it received was that there were no references (maybe you can help out - I know <strong>someone</strong> has said these things, but not who).</p>
<p><span id="more-847"></span></p>
<h2>Introduction</h2>
<p>For our group project, we are building an online e-commerce system. As the main focus of these systems is to sell their products, I have decided to take a look at some already successful sites for inspiration – namely play.com, amazon.com and ebay.co.uk. I intend to analyse these sites and evaluate their navigability, clarity and usability. By determining the components of these sites that work well, we should be able to combine them and make our system a success.</p>
<p>I have chosen Play, Amazon and eBay as they cover a wide range of marketplace models. Play manage all of their own stock, Amazon are both a retailer and a marketplace for others to sell their goods, and EBay are entirely user driven. All of the models have their strengths and weaknesses, which I will discuss further.</p>
<h2>Review</h2>
<p>eBay sell a huge variety of goods every day, and rely on their users to categorise the items correctly. This means that they need to provide a huge number of categories, and hundreds more subcategories. I'm not sure if the number of categories are a help or a hinderence. Personally, I find them useful but I'm used to wading through a large amount of information daily. An average user may be a little intimidated by the number of options.<br />
Items sold can either be fixed price, or run as an auction. They can be in GBP, USD or a multitude of other currencies. All of these different combinations need to be presented on screen in a similar way so that the user does not get confused.</p>
<p>eBay both excels and fails at this, as while the “important” functions such as purchasing the item and checking the users feedback are in a consistent location, the description of the product is created by the seller. Recently, eBay addressed this by adding metadata to certain categories (such as Laptops<sup><a href="http://cgi.ebay.co.uk/Macbook-White-13-2-2Ghz-Brand-New-Boxed-Never-been-used_W0QQitemZ260554430810QQcmdZViewItemQQptZUK_Computing_Apple_Laptops_ET?hash=item3caa41195a#ht_742wt_1165">[1]</a></sup>) which contains important information.</p>
<p>Amazon blur the line between them selling their own items and items being sold by others. Both appear in search results, both show an identical product screen. Underneath the price, it shows “X new, Y used”. If you click on new or used, it brings up a grid of sellers, the condition of the product and the price. If Amazon stock the product, they will be at the top of the “New” grid.</p>
<p>The item description contains important metadata about the product – in this case I was viewing a book and it displayed the publisher, ISBN, the fact it was a paperback and the language of the text. If there product is available in multiple formats (e.g. DVD and Blu-ray) then a box is shown with a link to alternative versions of the product.</p>
<p>Amazon's best (and most dangerous as a customer) feature is it's 1-click purchasing. If you're signed in and go to the homepage, there will be a box of recommendations for you. This means that from going to the site to owning the product, it's only 2 clicks. I think this has played a huge part in Amazon's success, as most other sites require 3 or 4 clicks before you get to the product you're looking for, then another 3 or 4 to purchase it.</p>
<p>The system I will be producing is the most similar to Play.com in my opinion. The staff of the site will be responsible for adding and managing products, and users will be able to purchase items at a fixed price. Play also shows user ratings and reviews.</p>
<p>There is a big emphasis on showing the user more related products on Play.com. This is presumably to maximise sales. It shows products related to the one being viewed, the top 10 in that category and a countdown to an upcoming product.</p>
<h2>Analysis</h2>
<p>All three of the sites are quite busy, trying to show the user as many products as possible and hoping something may catch their eye. This must be a tried and tested method as all 3 sites are quite big – but I don't like it personally. The amount of data that each site collects about their customers, they should be able to show a handful of products that the customer is interested in after only a few purchases. For example, all Amazon needs to show on their homepage is their top 10 sellers, top 10 preorders and my recommendations. That's 30 options that might catch my eye, and anything else I need is accessible via categories.</p>
<p>In the systems investigated, there was a common user flow. The homepage contained lots of items that the user may be interested in. These items linked directly to the product page as to hook the user in quickly. All of these items are generated based on sales data for that particular customer and the site's customers as a whole. All of the data aggregation and analysis can be done at an SQL level.</p>
<p>If the user wanted something specific, they would first choose a fairly broad category, and then a much more specific subcategory. Once a category was selected, they could either browse for their item or search for it within the category. The provided list of products can then be sorted alphabetically, by price or by any metadata we may have associated with the product. Again, all of this can be done at an SQL level with a combination of JOIN, WHERE, field IN and ORDER BY statements.</p>
<p>While I agree that Amazon's 1-click purchasing system is outstanding, we won't be incorporating a similar system. I'm intending on using Paypal to handle all card transactions as we will not be handing a huge volume of payments. We will also not be storing card details as there is a lot of legal details to handle, which are outside the scope of the project.</p>
<p>If there’s one thing that I noticed on all of the sites, is that they had “ugly” uri’s. While they may have made perfect sense to the browser and server, the user had no idea what data was being sent back and forth. For example, compare the following URI’s:</p>
<ul>
<li>http://example.com/product.php?id=2083729&amp;col=red&amp;_track=swh82eb2sj2&amp;_ref=goog</li>
<li>http://example.com/product/2083729/jacket/red/</li>
</ul>
<p>Which do you think the user will prefer and remember? While the former has more information, the same information could have been sent using sessions, leaving the URI clear for information pertaining to the current page access. While most people won’t pick up on it, the second URI is a “guessable” link. What would happen if we changed “red” to “black”, would it show us the same jacket, but black? It’s small considerations like this that enhance the users experience tenfold.</p>
<h2>System Requirements</h2>
<p>Based on my research and subsequent analysis, I have determined that for our site to be successful it needs to have the following features as a minimum:</p>
<ul>
<li>Ability to browse/search stock</li>
<li>Shopping cart functionality</li>
<li>Admin interface for product management</li>
<li>Product pictures/descriptions</li>
</ul>
<p>While the end user will knowingly use the above features, there are a few more that I will include that they will use without realising. This includes things such as:</p>
<ul>
<li>Constant layout for easy navigation</li>
<li>All information no more than 4 clicks from homepage maximum (Preferably 3)</li>
<li>Shopping cart and account management on every page.</li>
</ul>
<p>To enhance the user’s experience on the site, I may leverage technologies such as AJAX and Javascript to enhance the site. I do not believe that we should cater for the lowest possible browser (generally considered to be Internet Explorer 6), but that we should give our users the best possible experience possible, and have the site degrade gracefully in browsers that do not support the latest technologies. However, I will not use Flash, Silverlight or any other plugin based technology as it does not degrade gracefully. Small additions such as a countdown to the postage cut off, or the price changing in place as you change the quantity should be enough to both impress the user, and make the site much more usable.</p>
<p>If there is time, there are a few additional components to the site I would like to add - the main one being user profiling. Amazon does this perfectly, and there’s always something I’d like waiting for me on the home page. However, around Christmas time and birthdays, the suggestions become a little skewed as I buy gifts for other people. I’d love to be able to check a box that says “This isn’t for me!” and while it’d be recorded in my purchase history, it wouldn’t influence the recommendation engine.</p>
<h2>Summary</h2>
<p>There are a variety of models that my ecommerce solution could follow, but given that our team is relatively new to web application development and we have a short amount of time to design and build the system, I would like to build a shop (Play.com) as opposed to a marketplace (eBay).</p>
<p>I would recommend using a web framework to the team, as that will take care of clean URI’s and keep our code organised at the same time. I would also recommend using a javascript framework (jQuery is my personal favourite) to ensure that any enhancements we make work in every browser.</p>
<p>While our main focus is to have a database of products and the capacity to sell them, there are a lot of additional features that would make the site almost infinitely more useful. We will be implementing the minimum requirements first, additional sections such as customer profiling and a mailing list should definitely be included in the project.</p>
<p>This should be quite an interesting first project for us as a team, as the minimum requirements are clearly stated, but the problem is quite open ended. It’s up to us to decide how best to solve the problem.</p>


<p>Related posts:<ol><li><a href='http://michaelaheap.com/2010/02/28/a-remarkable-life-logging-project/' rel='bookmark' title='Permanent Link: A Remarkable Life Logging Project'>A Remarkable Life Logging Project</a> <small>Let me start out by showing you a snippet of...</small></li>
</ol></p><img src="http://feeds.feedburner.com/~r/Michaelaheapcom/~4/x1KAwbbSzLM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://michaelaheap.com/2010/04/02/internet-research-report-amazon-ebay-and-play/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://michaelaheap.com/2010/04/02/internet-research-report-amazon-ebay-and-play/</feedburner:origLink></item>
	</channel>
</rss>
