Archive for the ‘Tutorials’ Category.

Implementing JSON templates for Ajax in Kohana 3.1

Over the last few days, I’ve been toying around with the Kohana PHP Framework.  I’ve attempted to learn various PHP frameworks on many occasions, but I always seemed to lose interest because of too much documentation, or a lack of documentation, or just being forced to add too much complexity to an otherwise simple web application.  For the first time, however, I’ve managed to get the hang of one, and as a learning exercise, I turned my personal website into a Kohana application.

One of the features I wanted was to have a single controller that was able to send the full HTML page (with header, navigation, content view and footer) to the client on regular (non-AJAX) requests, or switch to a simple JSON response containing just the new content for AJAX requests.  This is just a short example of how I was able to implement template switching in my main controller so my alternate JSON template would be used when a request was done via AJAX.

PLEASE READ THIS FIRST! We’re going to assume you understand about Kohana template controllers.

My two template views

First we’ll have a look at the HTML template with the full header, navigation & footer.  This is the one I will use when responding to all normal non-AJAX requests.  I simply named it template.php, and it’s located in application/views/miracleblue.

<!DOCTYPE html>
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title><?php echo $title ?></title>
		<?php foreach ($styles as $file => $type) echo HTML::style($file, array('media' => $type)), PHP_EOL ?>
		<?php foreach ($scripts as $file) echo HTML::script($file), PHP_EOL ?>
    </head>
    <body id="body" class="bgimage">
		<div style="width: 1px; height: 1px; position:absolute; display: block; overflow: auto;" id="preload">
			<img src="/blue_eyes_fade_title.jpg" onload="$(function(){imagesLoaded();});" />
		</div>
		<div id="loader" style="text-align: center;margin:auto;margin-top:300px;display:none;">
			<img src="/ajax-loader.gif" />
		</div>
		<script type="text/javascript">$("#loader").css("display","block");</script>
		<div style="width: 900px; margin: auto; height: 500px;" id="wrapper">
			<div id="nav" class="bgshadow">
				<?php foreach ($nav as $key=>$link) : ?>
					<a href="/<?php echo $key; ?>" class="<?php echo $link['class']; ?>"><?php echo $link['title']; ?></a>
				<?php endforeach; ?>
			</div>
			<div id="content" class="bgshadow">
				<div id="inner-content">
					<?php echo $content; ?>
				</div>
			</div>
			<div id="info">
				<a href="http://www.soundcloud.com/miracleblue" tip="Soundcloud"><img src="/orange_white_24.png" /></a>
				<a href="http://www.myspace.com/miracleblue" tip="Myspace"><img src="/myspace-icon24.png" /></a>
				<a href="http://www.facebook.com/miraclebluemusic" tip="Facebook"><img src="/facebook_icon.png" /></a>
				<a href="http://www.beatport.com/artists/miracleblue" tip="Beatport"><img src="/beatport_icon_24.png" /></a>
				<a href="http://itunes.apple.com/artist/miracleblue/id409867809" tip="iTunes"><img src="/itunes_icon_24.png" /></a>
			</div>
		</div>
		<script type="text/javascript">$("#wrapper, #content").css("display","none");</script>
    </body>
</html>

As you can see, it’s the full page.  It includes the header, footer, and everything in-between, renders it, and sends it to the client.  This is what gets sent when any normal request comes in.  However, when a request is received that contains the “Ajax” header (X-Requested-With: XMLHttpRequest), the main HTML template is swapped out for a really basic JSON template, that includes only the new page “title”, a “name” of the page (that corresponds with the relevant link in the navigation bar), and the new content html (which is a rendered view) to be put in the “inner-content” element.  Here’s an example of a fully rendered JSON packet.

{
	"name": "about",
	"title": "MiracleBlue - About Me",
	"content": "<p>This is some body content, to go in the page.<\/p>"
}

And here’s the template file, simply named ajax_template.php, in the same folder as the main template file.

<?php
    header("Content-Type: application/json");
    echo json_encode(array("name" => $name, "title" => $title, "content" => $content));
?>

That should be pretty self-explanatory.  The javascript that makes the AJAX request also processes the returned JSON accordingly.  You would, naturally, implement your own processing routines, so we won’t be going into that here.

Switching the template

The way to do this conditional template-switching is actually very simple, but I haven’t seen this technique documented anywhere, so someone who is still new to the Kohana framework (like me) may be hesitant to try figuring it out on their own, just in case it goes horribly wrong and – you know – accidentally brings on the apocalypse and the end of mankind (hey, it could happen!).

So, to avoid that, let me show you exactly how it’s done.  In your template controller class (the one that extends Controller_Template), you should have defined a public variable $template that points to your main HTML template view file.  This will be the default template view for all normal requests.  In your before() method, at the very start of the method before any other code, is where the template switch happens.  Then in your after() method, you need to manually call render() on your content view.  Here’s an example of what mine looks like.

<?php
	defined('SYSPATH') or die('No direct script access.');

	class Controller_Miracleblue extends Controller_Template
	{

		// Define our default HTML template
		public $template = 'miracleblue/template';

		public function before()
		{
			// Switch template to JSON version if request is AJAX
			if ($this->request->is_ajax())
			{
				$this->template = 'miracleblue/ajax_template';
			}
			// NOW we can call the parent method
			parent::before();
			// And do other stuff
			if ($this->auto_render)
			{
				// Do stuff here
			}
		}

		public function after()
		{
			// Manually render the string of the inline view on AJAX requests
			if ($this->request->is_ajax()) {
				$this->template->content = $this->template->content->render();
			}
			// Otherwise, continue as normal
			else {
				if ($this->auto_render)
				{
					// Do stuff here
				}
			}
			parent::after();
		}
	}
?>

There you go.  The paths to your template files should be modified accordingly to your own filenames and paths, of course.  It is very important to note that you NEED to call render() manually in your after() method.  This will convert the HTML view for your inline content into a string, which is then fed to the json_encode() function in your AJAX template.  Leaving this out could result in the end of the world, so don’t forget ;)

Using Asual’s jQuery Address plugin [version 1.4.x]

Internet
Photo by transCam
Oh, hello there!  I bet you thought you’d never see another blog post on here again, didn’t you?  Thought I had abandoned this blog for good?  Well, quite frankly, so did I for a little while.  The good news is, we were both wrong!

This is just a short example on the basic usage of the jQuery Address plugin by Asual, which provides AJAX applications with deep-linking and state/history management.  If you have ever come across this plugin and tried to figure it out, chances are you found the official documentation to be of little or no help.  You are not alone.  I had been wanting to integrate it into my personal website – for which I required deep linking and state management – for about a week.  Finally, yesterday, I became determined to figure out enough about how the plugin worked in order to get the functionality I needed out of it.

In my website, I wanted to use jQuery Address for deep-linking and history management, but I also wanted it to take advantage of HTML5′s new pushState method in browsers that support it, and only use location.hash as a fallback method for dynamically changing the displayed URL (jQuery Address supports both these methods).  The reason I want to avoid using hashed URLs for deep-linking when possible is because the only way to read any data contained in a hash segment is with Javascript.  This is because the hash segment of a URL is not visible to the server; only the browser can use it.  Therefore, having a hashed URL requires the user to have javascript enabled in order for the application to know what content the user is requesting.  I know some of you are probably asking why we should care about users who don’t enable javascript in their browsers, however that is not the point of this blog post.

What I wanted to achieve

I have a main navigation bar with a set of links which point to real URLs which I want to load dynamically via AJAX when clicked.  Since they are real URLs, they point to real content, and can be loaded directly without AJAX.  My server-side logic will return a full HTML page for normal requests, and JSON-encoded data containing only the dynamic content to be inserted into the page for AJAX requests.

Loading the plugin

In order to enable jQuery Address to use HTML5 pushState functionality, we need to set one of the plugin’s configuration parameters called “state”, which points to the base path of your website or application.  In this case, my base path is the webroot “/”.  You can set this and other configuration parameters in query-string format, like so:

<script type="text/javascript" src="jquery.address.js?state=/"></script>

The code that makes it happen

Here’s an edited snippet of the code that I wrote for my site that makes it all happen, explained step-by-step in the comments:

$(document).ready(function(){
	// Add jQuery Address functionality to the links in the navbar
	$("#nav a").address();
	// Our event responder that triggers whenever the address is changed (including on first load!)
	$.address.change(function(event) {
		// Set shortcut to URI value
		var uri = event.value;
		// Run ajax call and get JSON data
		$.getJSON(uri, function(data){
			// All parsing and processing of returned data should happen here
		});
	});
})

Voila!

You can see a live, working example of the code and how I have implemented it over on my main website.  Feel free to take a look at the full code, which is in the main.js file.

I hope this helps you to have a basic understanding of how to make this plugin Just Work™ so you can start using it.  As always, leave questions and feedback in the comments!

PHP Classes: A very quick guide to the basics

Will code for foodOkay, so you know what a class is, by definition.  But now you’re asking, “how the heck do they work?  What exactly is a method?  What can I use them for?”

A real basic explanation of what a class actually does goes like this:  A class is like a container for storing functions and variables.  The functions and variables stored in a class can be re-used many times for different purposes in a single script.  It’s often very handy to use a class to store a collection of functions that are related to eachother (that do different operations on the same task), for instance you could have a class containing your database-related functions.

Here’s one way to look at it:

Let’s say you currently own an iPod.  Your iPod stores a collection of your favourite Jazz music.  It has functions for adding new music & deleting existing music in the collection.  It also has functions for playing, pausing, seeking and skipping songs contained in the collection.

Your friend, John, also has an iPod.  His iPod stores a collection of his Hard-rock music, and has all the same functions that your iPod has.  Both devices are exactly the same, and have all the same features, but they are separate devices working on separate data!

So basically, the iPod is a class, add() delete() play() pause() skip() etc are its methods, and $music is a property which will have the music collection data as its value.

Okay, enough theory!  Show me something with code!

So what do I mean when I say that a class can be re-used?  Well, this is how we would go about creating Your iPod and John’s iPod in PHP:

$myiPod = new iPod();
$johnsiPod = new iPod();

When we do this (calling new on a class, like new iPod()), it’s called Creating an instance.  Think of it like cloning, but for functions.  So now we have $myiPod and $johnsiPod, which are Instances of the iPod class!

Okay, now let’s add some jazz to $myiPod

$myiPod->add($jazz);

See what we did there?  We called a method (function) of our iPod class on the $myiPod instance of the class!  Now the instance $myiPod contains Jazz music in its collection.  But $johnsiPod does not!  But they’re both the same!  Is it starting to make sense?  Yes?  GOOD! Let’s continue.

Remember that $music property that we have in our iPod class?  Remember that it’s basically a variable stored in a class, just like a method is simply a function?  Well, we can access those too, and in the same manner!  Check this out:

$myiPod->music;

We just accessed the music property!  That means we can get its value.  But did you know we can also SET its value?  Just like a regular variable.  Let’s say, for no apparent reason, we wanna set the music property in the $myiPod instance to a string that just says “O hai thar!”.  It’ll over-write our entire jazz music collection with a single string of text, but hey, this is just for the sake of examples.

$myiPod->music = "O hai thar!";

Now let’s see what happens when we echo out the music property’s new value!

echo $myiPod->music;

It will print “O hai thar!” – Do you see now?  It really is just like a regular variable.  But remember, we’re doing all this to the $myiPod instance of the iPod class!  If we were to echo the value of $johnsiPod->music, it would give us nothing, because since we haven’t set the value of music for $johnsiPod nor have we called add($hard_rock) on $johnsiPod, its value is empty.  Even though both $myiPod and $johnsiPod are instances of the same class, they are completely separate from eachother.  Calling methods on $myiPod will NOT affect $johnsiPod.  This is one of the main features of Object-Oriented Pogramming that makes it so useful – Code is truly RE-USABLE!

And there we have it.  A really, really big explanation of the absolute basics of OOP in PHP.  Later I’ll start going into some of the slightly more advanced stuff, so if the way I’ve explained it here was enough to give you a good understanding of the basics then you should check back every so often for my next article!

Until next time, happy coding =]