Monthly Archives: December 2006

24 Ways: CSS Production Notes from Subversion

0
Filed under Knowledge, Markup, System

I came across a great article about creating CSS production notes by Andy Clark. It’s a great idea to show co-workers the information and notes about a file but in my production environment I often use subversion so I’ve merged the two. If you use subversion and a dynamic language such as PHP there’s no reason why you can’t show the subversion log for the current file in the same way. Here’s a quick little PHP script that does exactly that. Feel free to use and edit it as much as you like, just let me know if you make a big improvement so I can post it here. Enjoy:

<?php

/**
 * A quick PHP script to produce the notes markup from subversion logs.
 * @see http://24ways.org/2006/css-production-notes
 */

//the current file in the repository, you could use $_SERVER['PHP_SELF']
$file = ‘/home/jeff/subversion/myproject/trunk/index.php’;

//retrieve the log from subversion
$exec = array(
        ‘cmd’=> ’svn log –xml –verbose ‘ . escapeshellarg($file), //command
        ‘output’=>null,
        ‘return’=>null
);
exec($exec['cmd'],$exec['output'],$exec['errors']);

//make it a string.
$log = join($exec['output']);

//create the notes
$notes = ”;
$xml = new SimpleXMLElement($log);

//build the notes
foreach ($xml->xpath(’//logentry’) as $entry) {
    $message = nl2br($entry->msg);

    $notes .=
<<<NOTE
<li>
    <blockquote cite=”{$entry->author}”>
        <p>{$message}</p>
        <p class=”date”>{$entry->date}</p>
    </blockquote>
</li>
NOTE;

}

$notes = ‘<ul>’.$notes.’</ul>’;

//do whatever you need with it.
echo $notes;

?>

Holidays are coming, posts may not be.

0
Filed under Miscellaneous

I’ve been trying to keep up with at least one good long post a week but with the holidays approaching I’ll be spending some much needed time with the family and with the added need to work on my next book (which I’ll be announcing in the new year), I may not be posting as frequently. I will if I can, but if not I’ll try and make it up in the new year with a few extra posts here and there.

Disabled? No Pizza For You!

2
Filed under Behaviour, Knowledge

This past weekend my wife and I decided to check out the new Boston Pizza that was recently built near our house. It’s one of only a few new popular restaurants in town so we were told the line has been crazy long with more than an hour wait at times. We decided that before we went, we would check out the on-line menu too see what they had. That way, if the line was too long we could just order takeout and go home to enjoy our meal. The domain name BostonPizza.com wasn’t hard to guess so I pulled up the site and we proceeded to peruse the menu (I decided on a small hawaiian and my wife chose the Ultimate Pepperoni pizza). While browsing the menu I also noticed that the main navigation used a ‘drop-down’ effect:

BostonPizza.com Dropdown Navigation

Being the curios web developer I am, I decided to investigate a little further to see how it was done and if it was a semantic list a la suckerfish (though I had to work quickly as my wife was getting hungry after looking at the photos of pizza).

Read More »

Doing it Asynchronously

16
Filed under Behaviour, Knowledge

Regardless of what you’ve heard about Web 2.0, why it’s cool, why it’s not really 2.0, or why the term Web 2.0 may actually be important, one thing is certain. It’s very shagadellic and it’s all about asyncronicity baby!

Yes that’s right, everyone is doing it asynchronous now, newbies and hackers alike. And why not? It’s all the rage! I mean, how boring was the way your grandparents did it? So mundane, always following the same routine:

  1. Load
  2. Wait for a response
  3. Click
  4. Repeat

Are you really happy with the result of a simple load, wait, click, repeat? Maybe you enjoy the repetitiveness since you’re web site ’seems’ to enjoy it equally, but what if there’s more?. To enjoy the best experience of asyncronicity, all you need are the Ajax twins: XmlHttpRequest and ActiveXObject(”Microsoft.XMLHTTP”) — but that’s where it begins to get a little complicated. It seems these two have been taking over the minds of many a young web developer, corrupting their thoughts with wild imaginative fantasies. Now, day-in and day-out, 24/7, all the web developers can think about is:

  1. Load
  2. Wait for a response
  3. Click
  4. Click
  5. Click
  6. Click
  7. Click
  8. Click
  9. Click

Going with the flow

All these asynchronous communications change the very nature of your application’s flow. You can’t rely on that mundane load, wait, click, repeat cycle because the page never fully loads again, only little pieces of it do. For instance, take this common simple administration tool for a news item list on a website:

Common News Tool

The ‘check mark’ and ‘x’ symbols represent the ‘active’ state of the items in the list.

To ‘activate’ an item, the user would simply click the check box or the x and several things may happen. If you’re using the traditional workflow, your web application will probably do something like this where the page is forced to reload:

Traditional Application Flow

This is a typical “Web 1.0″ application flow. You click, a request is sent to the server, it responds, and the entire page is reloaded to reveal the new change. Often, you’re left sitting at the top of the page and forced to scroll down to even see the change. What fun.

Alternatively, if you’re going asynchronous with Ajax, you’ll end up with something that looks a little more like this, where only small protions of the page change using the appropriate DOM scripting:

Ajax Application Flow

No reloading except for the manipulation of the page with your favorite DOM methods. So where’s the problem? We’ll it’s not really a problem — if you know what you’re doing. The thing you have to remember is that you’re doing things asynchronously now. Requests are going out every time you click the buttons, but they don’t necessarily come back in the same order. Huh? Let me explain with an example. Click this button several times quickly in succession:

Requests

    Notice the order of the requests coming back? The request number represent the order you clicked the button but the order of the list represents the order they were completed by the server. When you click the button, a request is sent to the server and in this case all I’m doing is simulating some server traffic by sleeping the PHP script for a random time:

    <?
    header("Cache-Control: no-cache, must-revalidate");
    sleep( $time = (2/rand(1,8)) );
    echo "$time";
    die();
    ?>
    

    and then sending back the $time before completing the request. If you wait at least 2 seconds between each button click, it’ll probably return requests in the same order because the initial request will complete before the following request. But, if you click it quickly several times quickly in succession, in this case less than 2 seconds apart, you may have a request of 1.5 seconds followed by a request of 0.5 seconds. When that occurs, the second request will finish and complete before the earlier request! This demonstrates asynronous in action - it’s out of sync and out of order, running at the same time as other requests.

    Handling Asynchronous Requests

    If you check out the JavaScript I’m using to do the request it looks something like this:

    var counter=0;
    function doRequest(e){
        var num = ++counter;
        new Ajax.Request("http://jeffreysambells.com/openprojects/PHP/sleeper.php",
        {
            onComplete:function(t){
                e.innerHTML += "<li>Request <strong>" + num + "</strong> <em>(took " + t.responseText + " seconds)</em></li>";
            }
        });
    }
    

    All it does is make an Ajax request (using the Prototype library Ajax object, since it’s already loaded in my blog) and then processes the result when complete. The key thing to remember is that the action you want to take as a result of the request must be placed on the onComplete handler of the Ajax object (or onSuccess in the case of prototype if you’re doing error handling). I often see Ajax rookies doing something similar to:

    var counter=0;
    function doRequest(e){
        var num = ++counter;
        new Ajax.Request("http://jeffreysambells.com/openprojects/PHP/sleeper.php");
        e.innerHTML += "<li>Request <strong>" + num + "</strong> <em>(took " + t.responseText + " seconds)</em></li>";
    }
    

    which is just plain wrong. As I demonstrated earlier, The XmlHttpRequest object is asynchronous, this means that the

    new Ajax.Request("http://jeffreysambells.com/openprojects/PHP/sleeper.php");
    

    line will execute, but may not return before the

    e.innerHTML += "<li>Request <strong>" + num + "</strong> <em>(took " + t.responseText + " seconds)</em></li>";
    

    line executes. If you want your script to wait until the request is complete, you must handle the remaining script from within the onComplete handler by splitting your JavaScript code into objects and methods, then calling the appropriate one when each request is complete.

    In the ‘wrong’ way above, there’s the additional problem of using t.responseText, which isn’t in the scope of the doRequest() function, but we’ll discuss that mistake another time.

    It’s that simple. Nothing too complicated just a complete shift in the ‘top down execution’ approach you’re probably more familiar with. All you have to do is remember that the A in Ajax means Asynchronous. That’s the key.

    If you’d like to learn more about Ajax, I’d suggest first reading the original Ajax article by Jesse James Garrett at Adaptive Path “Ajax: A New Approach to Web Applications” and the many excellent resources over on ajaxian.com but in the mean time have fun with Ajax — the more you do it the better you’ll get.

    The Tabular Data Enigma

    6
    Filed under Knowledge, Markup, Style

    Did you know that tabular data doesn’t really exist? Yes it’s true! Recently at work, I was discussing the advantages of semantic markup with a colleague and stumbled upon an interesting conundrum. In the conversation, we agreed that table based design layouts are bad, and that tables should be used for tabular data. I think you’ve probably heard the same elsewhere and would probably agree as well. The sticky point however was that my colleague then proceeded to state that the application he was working on, which used <table> tags to markup the output, was semantically correct because it was a file browser of sorts which was ‘tabular data’. I proceeded to point out it would be more correct to use the proper list tags (ordered <ol> or unordered <ul>) as it was a list of files. Frustrated with my response, he asked: “then what is tabular data?” and suddenly I found myself without a clear and concise answer. Read More »

    Digg Killed the Web Star

    0
    Filed under Miscellaneous

    My site was down for a short while this morning as another site sharing this server got dugg. Everything seems to be back and happy now as he moved it to another server.