Blog

Offshoot Mandatory Uniforms?

Your people forgot to call my people.

twins

And it only took us 5 hours to notice!

iPad Release Delayed For A Month :(

In an attempt to curb the high demand of the iPad sales in the US, Apple has delayed the international release date of the new gizmo to the end of May. But, for the first time ever, Canadians actually get an online pre-order date of May 10.

According to an article in The Toronto Star, Apple Headquarters had this to say about the delay “We know that many international customers waiting to buy an iPad will be disappointed, but we hope they will be pleased to learn the reason – the iPad is a runaway success in the U.S. thus far.”

LAME.

It better be less buggy when we get it!!!!

ipad_jobs

Nike + Tiger…together, forever, through everything

A bizarre new Nike ad is causing quite the stir among the advertising and golfing world. The ad, that’s been released in time for Tiger’s return at the Masters this weekend, features a sullen looking Tiger while a cryptic voice over from his late father is playing. Watch the ad below and let us know what you think.

Nike and Tiger, making the rebound from infidelity a good thing every step of the way.

Apple changes the world…yet again

Zut Alors!

Apple sells over 300,000 iPad devices on it’s opening day!!!!

Here are some more fun stats about the iPad
- Over 1 million apps and over 250,000 Ebooks were downloaded on the first day of sales
- Networks like CBS have already announced that it will offer episodes of shows for downloads
- Marvel, DC Comics and other publishers will offer comic book apps
- It looks like an iPhone on steriods

I don’t know how public transit commuters are suppose to add the iPad to the many things they already shlep on daily basis (laptop, lunch and the occasional extra pair of shoes)…BUT, I will admit that when it comes out in Canada I will most likely adore this thing to death.

I wonder if this will bring a revival to the literature industry? Tell us what you think!

ipad_hero_20100305

Hostname matching with Zend_Controller_Router_Route_Hostname

The Zend Framework offers and handy little tool for hostname matching. This means that you can introduce variables into your application’s URIs. For example, you may want to let users go to a URI like http://chris.yoursite.com or http://neil.yoursite.com and then use the “chris” or “neil” part to determine what content is displayed.

The first thing you have to do in order to use hostname matching, is to setup your server such that *.yoursite.com resolves to wherever your ZF application is running. In most cases this is probably just your domain. For example’s sake, let’s say we setup our server so that *.yoursite.com resolves to the ZF app running at yoursite.com

Once that’s in place, you can start using Zend_Controller_Router_Route_Hostname. Defining a hostname route is pretty straightforward:

 
$hostnameRoute = new Zend_Controller_Router_Route_Hostname(
    ':username.yoursite.com',
    array(
        'controller' => 'profile',
        'action'     => 'index'
    )
);

So what is happening here is that you’re telling the router that any time it see’s something like chris.yoursite.com, to take the “chris” part and store it in a variable called username, then route to the index action of the Profile controller. If you’re familiar with ZF and defining routes, this will seem pretty trivial.

Here’s where things get tricky. Our $hostnameRoute is matching the hostname, so this route will match any path since the hostname will be part of any path for your site. This is where route chaining comes into play. If you’re not familiar with route chaining, I suggest you read the Zend_Controller_Router_Route_Chain section of the ZF manual. You can find it here. The point of chaining the routes is so that you can first match the hostname and then match any number of subsequent routes.

Let’s put this all together with a concrete example, craigslist.org. When you go to craigslist.org it gives you the option to go to URIs like toronto.craigslist.org or ottawa.craigslist.org. From there you get URI’s like toronto.craigslist.org/msg and ottawa.craigslist.org/msg. What this means is that we want the hostname matching to be applied to _every_ URI first, then we’ll match the path to a route.

 
// let's load all the routes for the site (i like to use an ini file)
$routerConfig = new Zend_Config_Ini(
    APPLICATION_PATH . '/configs/routes.ini',
    APPLICATION_ENVIRONMENT
);
 
// create a new instance of the router
$router = new Zend_Controller_Router_Rewrite();
 
// add all of our routes into the router
$router->addConfig($routerConfig, 'routes');
 
// create our hostname route for our site
$hostnameRoute = new Zend_Controller_Router_Route_Hostname(
						':city.craigslist.org',
						array(
						      'module' => 'default',
					              'controller' => 'index',
					              'action' => 'index',
					          )
      					);
 
// loop through all the routes in the router and create
// a chain with the hostname route
foreach ($router->getRoutes() as $key => $route) {
 
	// this will overwrite the existing route with our route chain
	$router->addRoute($key, $hostnameRoute->chain($route));
 
}
 
// lastly, set the router on the front controller
$frontController->setRouter($router);

And that’s all there is to it. The trickiest part is getting the hang of the route chaining – once you’ve got that down, you’re good to go.

Hot Chip’s Hated (But Amazing!) Video

This video is amazing!

Cross Domain Scripting with jQuery and flXHR

We were recently asked to develop some javascript widgets that would read from a central REST based API. And of course, these widgets needed to be able to be put on any website. That’s all well and good until Cross Site Scripting rears it’s ugly head. As of right now, modern browser don’t allow AJAX calls to be made from one domain to another. There are a lot of potential security problems with cross domain scripting, though they’re not really my concern. For the purposes of this article, I’m only concerned with how we can work around these browser restrictions.

Luckily there are a few options. The first of which is to use JSONP. If you’re not familiar with JSONP, you can get caught up here. The problem with JSONP is that it only works for GET requests. In simple situations, that will probably suffice. But in more complex situations, where you might need to use POST, PUT, or DELETE, another solution is going to be needed. But more about that later… Back to JSONP. jQuery has a pretty simple JSONP implementation. Let’s take a look at a regular jQuery JSON GET request.

 
$.getJSON("test.js", function(json) {
    alert("JSON Data: " + json);
});

Nothing too out of the ordinary there. It makes a request to test.js and the callback function receives the results of the request as a json object. Suppose that test.js is now a different domain than the script that is calling it. This is when you need to use JSONP. With jQuery, making a JSONP request is quite easy. All you need to do is append a query string argument called jsoncallback, that is the name of the function that’s used as your JSONP wrapper. Let’s look at an example:

 
$.getJSON("http://someotherdomain.ca/test.js?jsoncallback=myFunction", function(json) {
    alert("JSON Data: " + json);
});

and where the GET request to http://someotherdomain.ca/test.js returns something like this:

 
myFunction({data: 'value'});

The trick with JSONP is that the server that you’re making the GET request to, has to be returning the JSON in a wrapper function and you need to know the name of that function. Alternatively, jQuery allows you to not specify the name of the callback function and use a ? as a placeholder instead. jQuery will then generate a unique callback function name and pass that as a parameter in the GET request.

 
$.getJSON("http://someotherdomain.ca/test.js?jsoncallback=?", function(json) {
    alert("JSON Data: " + json);
});

What gets sent to the server looks something like this: http://someotherdomain.ca/test.js?jsoncallback=12049583_dss. The code running on the someotherdomain.ca server will need to check that the jsoncallback query parameter exists and then return a response like:

 
12049583_dss({data: 'value'});

This can get tricky if you’re not in control of the code that you’re making requests to. JSONP isn’t a solution for all situations; it really only covers a subset of use cases for cross domain scripting. If you find that you’re unable to utilize JSONP, you may need to move to a more robust solution.

Enter flash proxies. Flash can make cross domain requests. All that’s required is that the server that you’re calling as a file in it’s root directory called crossdomain.xml. It will look something like this:

 
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
<!-- Policy file for xmlsocket://socks.mysite.com -->
<cross-domain-policy>
   <site-control permitted-cross-domain-policies="master-only" />
   <allow-access-from domain="*" />
   <allow-http-request-headers-from domain="*" headers="*" />
</cross-domain-policy>

The crossdomain.xml is a pretty powerful little file and care needs to be taken when using it. Now that the server can accept cross domain requests, we need to find the right flash proxy to make those requests. The best one that I could find is called flXHR. flXHR only requires the inclusion of a javascript file, then uses javascript to write a hidden swf to the dom, and then uses that swf to make the cross domain requests. It has an API identical to the XmlHttpRequest object, so if you’re comfortable working with the XmlHttpRequest object, you’ll already be comfortable working with flXHR. Plus, flXHR offers plugins for most of the major javascript frameworks. Since we were already using jQuery, let’s take a look at an example of using flXHR with jQuery.

First we include all the files we need:

 
<!-- include the flXHR file -->
<script type="text/javascript" src="flXHR.js"></script>
 
<!-- include the most recent version of jQuery -->
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
 
<!-- include an xhr jquery plugin, used from the flXHR jquery plugin -->
<script type="text/javascript" src="jquery.xhr.js"></script>
 
<!-- include the flXHR jquery plugin -->
<script type="text/javascript" src="jquery.flXHRproxy.js"></script>

Then let’s write the javascript to make the requests:

 
$(document).ready(function()  {
 
	// set up the domain that we're going to call and tell flXHR not to try to parse the response as XML..
	$.flXHRproxy.registerOptions("http://someotherdomain.ca/", {xmlResponseText:false});
 
	// set flXHR as the default XHR object used in jQuery AJAX requests
	$.ajaxSetup({transport:'flXHRproxy'});
 
	// make a post request
	$.post(
		"http://someotherdomain.ca/some-process.php",
		{param1: 'abc', param2: 'xyz'},
		function(json) {
			alert("JSON Data: " + json);
		},
		'json'
	);
 
});

And that’s about it! Now you’ll be able to make cross domain POST requests.

jQuery jScrollPane Plugin: Scrolling Divs not displaying properly

We’re just wrapping up a site for a client and they decided that they would prefer to have custom scroll bars, rather than the OS scroll bars that browsers will render by default. James did a little research and point me to the jQuery jScrollPane plugin. I took a quick look at the documentation – it looked good and seemed easy enough to implement. Once I got it into place on the site, I started to notice some problems. These problems aren’t so much related to the jScrollPane plugin, as they are to how the browser loads content.

I noticed that if I loaded a page, the scroll bars would display exactly as I would expect — however, if I did a shift+refresh, only part of the content would appear in the scrollable area. Other times, I’d notice that divs just wouldn’t appear at all.

Based on these issues and a fair amount of troubleshooting, I gathered up some important caveats for using the jScrollPane plugin.

  1. Always set a height on the div that you’re applying the scroll pane to.

    The jScrollPane plugin does a calculation to determine the height of the wrapping div that controls the scrolling. The best way that I found to ensure that the scroll bars will scroll the right amount of the content.

  2. Ensure that divs are not hidden when applying the jScrollPane

    Based on my googling, this appeared to be the most common problem that people were having. I found a few different ways to approach this problem, depending on your requirments.

    // you can explicitly set an element to show, 
    // prior to applying the scroll pane
     
    $(element).show().jScrollPane();

    OR

    // you can set the visibility to hidden, which leaves the
    // full element in the rendered page, then apply the 
    // scroll pane. After that, you can show/hide the element
    // as necessary. NB: you must reset the visibilty
     
    $(element).css('visibility', 'hidden')
    	.jScrollPane()
    	.hide()
    	.css('visibility', 'visible');

    Unfortunately I didn’t keep track of where I found these solutions, so please leave a comment if this solution is yours and I will give credit where credit is due.

  3. You may need to apply the scroll pane after the window is loaded, not just the document

    I found that when a particular div that I was using the jScrollPane on had a lot of images, using code like this:

    $(document).ready(function() {
     
    	$(element).jScrollPane();
     
    });

    would lead to only part of the content being considered scrollable, while the rest of the content was hidden. The reason here, was that the jScrollPane was calculating the height of the scrollable area, prior to the images being loaded in the div. Since the height of the images is part of what determines the final height of the div, the jScrollPane needs to be applied after the images have loaded. This is why it would load correctly when viewing a page that Firefox had already cached the images for, while doing a shift+reload (which does not use the cache) was causing only part of the content to show. My solution for this was to apply the jScrollPane once the window has loaded

    $(window).load(function() {
     
    	$(element).jScrollPane();
     
    });

    NB: depending on how long it takes for your entire page to load, you may notice some delay between the content being rendered and the scroll bars appearing. This can likely be alleviated by displaying a loading sequence until the window.load() method is called.

Hopefully these 3 points will help you avoid some common pitfalls!

Book Review — Zend Framework 1.8: Web Application Development by Keith Pope

I was recently approached by a representative from Packt Publishing to review their newst book on the Zend Framework, Zend Framework 1.8: Web Application Development by Keith Pope. The book is intended to be an introduction to the Zend Framework (ZF), and with the exception of chapters 4 and 5, I tend to agree. Chapters 4 and 5 do have their necessary place in the book, it’s just the nature of the content that leads them outside the realm of the introductory. The early chapters are a clear and concise introduction to the ZF and are even useful for the experienced ZF programmer offering a few tidbits and easier ways to do things in light of the 1.8 release. The later chapters are the most valuable for the experienced programmer and set a benchmark for the beginning programmer, showing them an example of how ZF is deployed in real world situations.

Anyone who has been following the Zend Framework and the speed at which they push out releases, may ask if this book will still be relevant. My answer to that questions is a definite yes. The 1.8 release was a milestone release for the ZF; currently at version 1.10, there haven’t been a number of signifcant changes since version 1.8. However, version 2.0 of the ZF will offer and number of changes and upgrades to a number of the core components. At that point, this book will need to be updated and improved, though just enough to get up to the 2.0 spec.

Before jumping into the review, you may want to check out the table of contents or a sample chapter.

The preface and first chapter of the book really highlight how easy it is to get a simple application up and running using the ZF. Within 3 pages of the first chapter, you’ve already got a functioning application (provided you’re following along with the examples). An important part of the first chapter, not only for programmers new to ZF but also those who are just new to the 1.8 release, is the new application configuration and the introduction of the Bootstrap classes. The way of bootstrapping applications changed pretty drastically in ZF 1.8 and you’ll see the important role is plays in development throughout chapters 1 – 4.

Chapter 2 covers all the basics of the ZF Model-View-Controller (MVC) architecture. You’ll probably need a little bit of background information about MVC architecture in order to get a full grasp of what’s going on here, but even without any knowledge of MVC, you should be able to continue following along. Really only the View and Controller ascpects are covered in any detail in Chapter 2. The Model aspect comes to light in chapter 3 and finds fruition in chapters 4 and 5. Chapters 4 and 5 start to delve outside of an introduction to the ZF and get into some of the more complex aspects of application development. In these chapters you start to see more of a picture of how Keith Pope builds a web application, which is understandable, an authors background is going to influence their writing. However I don’t think that the Service Layer pattern is strictly necessary for an introduction application development. I think that someone new to the ZF should probably re-read these chapters after reading the entire book and building at least one application. I think the importance of these chapters will come to light in retrospect.

Chapter 6 is a brief but very useful introduction to the Zend_Form component, which is arguably one of the more powerful aspects of the ZF when building web applications. While chapter 7 brings together the View aspect of the MVC showing the role that the forms play within views and really emphasising how ZF can speed up your application development. Chapters 8 and 9 cover some of the more complex parts of any web application: Authentication and Authorization. Authentication and authorization are two concepts that are often confused or conflated. Pope defines them very succintly by asking a couple simple questions to the requesting user. Authorization asks: “Can they do this?”, while Authentication asks: “Are they who they say they are?”. It’s important to keep these two concepts straight. The ZF’s concept of modules is introduced in chapter 10. Modules are a way for you to compartmentalize your application and can be reused between different applications. If your application is setup properly, modifications are only required to the application’s bootstrapping.

I found chapters 11 and 12 to be particularly useful, especially for the experienced ZF programmer. Chapter 11 covers the powerful caching that the ZF is capable of. ZF offers a number of different caching strategies, each suited to a particular purpose. Chapter 12 gets into the nitty gritty of testing. Testing is one of the most important aspects of web application development, especially when your application is live and used regularily. Pope gives a quick and handy introduction to PHPUnit (one of the most widely used testing frameworks for PHP) and then shows how ZF extends the functionality of PHPUnit. Ultimately at the end of chapter 12, you have all the tools necessary to test your entire application.

After getting through this book, you will have more than the tools necessary to build out a powerful web application using the Zend Framework. If you would like more information about the book or are interested in purachasing it, you can check it out on the Packt Publishing website

Relive The Wizard Part Deux

Relive The Wizard This February 25th
Yes, it’s that time again!

Time to find out who is Toronto’s Mario Kart King or Queen and to see if The Creeper can keep his title. This February 25th, we’ll crown the next Mario Kart King or Queen of Toronto (or The World, if that’s what you’re into). Races start at 7:30pm sharp!!!

If you’re interested in attending or entering as a contestant then RSVP here: http://www.relivethewizard.com

See everyone this Thursday.