Perlessence

Blog


Site Redesign

April 07, 2008 00:31 Web Development

If you've been reading this blog for a while, you will (hopefully) notice something new: I have redesigned this site. When I was at SXSW, I was not only inspired by all the designers there, but it also underscored the need for a strong personal brand for people to remember me by. Here's the process by which perlessence.com got a facelift.

At SXSW (and in other social-professional arenas), it's common to meet other developers, talk shop for a bit, and then exchange contact info. I collected and handed out a bunch of Moo cards, but for most of these people, I can barely remember meeting them, let alone what they do and why I want to follow up with them. One technique I learned from Jakob to spark memories days or weeks later is to, right after the conversation, write on the business card how you met the person and what you talked about. But what about other people remembering who I am?

As a developer, a personal site is more than a vanity page: it's where potential employers and peers will go to see what kind of person you are in the technical arenas. A developer's site should therefore reflect their skillset as well as their personality.

The previous iteration of this site, while functional, failed to meet my needs in several ways:

At this point I knew what I wanted from my site and what about my current site was not working. I didn't know how to fix it, though! I can barely use Photoshop and have zero sense of color or style. At first I was going to outsource my redesign to a professional designer, but after getting some initial estimates, I decided that wasn't practical. However, I did get some help from Lea Alcantara's series of articles on the art of self branding. I spammed a few people I knew, from coworkers to family to significant other, for each of them to send me the three adjectives they think describe me best. The results were compiled in a spreadsheet, which allowed me to see repeated or similar words at a glance.

I was happy to see that most people thought of me in a very consistent way. It indicates to me that I already have a personal brand well defined through my behaviors; I just needed to express it in visual format. Most people gave some variant on intelligence, with an especial connotation of sharpness, wit, mental agility. There was also a set of terms around the concept of being reliable, especially in terms of attention to detail and consistency. At the same time, several people also labled me as eclectic and interesting. I let the results percolate in the back of my mind for a couple weeks while I started watching my behavior to see if these categorizations were accurate, and if so, was it the impression I wanted others to have of me. I decided that these aspects of me would be appropriate and relevant as the online expression of my personal brand.

Now that I had these concepts, how would I turn them into a design? I spent some time looking at site galleries trying to find an inspiration, but didn't see anything appealing. Finally I decided to pick colors first in the hope that the colors would evoke a layout. This, at least, was easy. My favorite colors are a deep purple and bright orange; a lot of my clothes, furniture/linens and even stuffed animals incorporate them. The colors definitely worked with the eclectic theme, but what about the other parts?

Inspiration struck me this morning in the shower: the shell that was the basis of the old website. Shell growth patterns follow a mathematical ratio called the Golden Ratio; when in spiral form, it is called the Golden Spiral. The capital letter P can be stylized to look like a spiral. And if there's anything that evokes the word intelligent, it's the stereotypical math nerd. Within an hour I had a logo based on my concept; you can see it in the upper left corner of the page and in the watermark at the bottom left corner of all pages.

I picked the lighter purple first, as it is as close to my favorite shade of purple as time, patience and Photoshop's Pantone palletes allowed. Jakob suggested using a darker purple for the main content areas; I lowered the brightness and saturation until I found a pleasing combination. Then I picked a shade of orange for content on the brighter purple and picked a secondary orange that is a little bit less bright for the deeper purple. The reason for two oranges was to make it look the same color regardless of which purple it was embedded in.

From there, the layout seemed obvious. I'm still experimenting with little touches; I just added the watermark after several hours of tweaking. The secondary pages, especially this blog, need styling badly. I finally built the Contact page and will be fleshing out the Projects page with more examples of my work over the next few days. Of course, I still need to verify XHTML and ADA compliance, finish writing blog software using Headlight (the MVC framework that powers this site), and so much more. A developer's job never ends...


daonut 0.1

March 24, 2008 20:51 Web Development PHP

daonut 0.1 is out! As of this build, you can create a MySQL database connection, correlate databases to DSN aliases and DSN aliases to database connection strings, and pass through raw SQL.

For version 0.2:


RSS Feeds with daonut

February 12, 2008 08:29 Web Development PHP

I've recently started work on a database abstraction layer that I call daonut. It's both a learning project as well as a useful utility that I need for building database applications. Ok, I guess I don't need it, but I'm lazy these days and it's easier to make an abstracted call than to manually open the MySQL connection, build and send a query, test for errors, etc. daonut was written based on similar syntax to Gaia's database layer, but with some of the calls tweaked to match my preferences. I didn't look at any of Gaia's code, partially for a learning experience, and partially so I could avoid any copyright issues. I'll have a more detailed post on daonut later, but I wanted to put up a couple examples of the syntax to (hopefully) whet your appetite for more.

include_once '/path/to/daonut/daonut.inc.php';
/* First it's an RSS feed from the internet */
DaoFactory::connect('RSS');
$dao = DaoFactory::create('Feeds.Corkd'); // My Cork'd cellar feed
$dao->execute();
echo "Total rows : " . $dao->affectedrows();
while ($row = $dao->fetchrow()) {
    var_dump($row);
}

/* Now it's a MySQL database */
DaoFactory::connect('MySQL', 'localhost', 'username', 'password');
$dao = DaoFactory::create('Feeds.Corkd'); // table 'corkd' on database 'feeds'
$dao->execute();
echo "Total rows : " . $dao->affectedrows();
while ($row = $dao->fetchrow()) {
    var_dump($row);
}

Set Game in JS with YUI

February 10, 2008 23:13 Web Development JavaScript

I grew up on a game called Set. For those of you too lazy to click, it's a pattern recognition card game. You start by laying out 12 cards. Each card has symbols with four attributes: shape (squiggles, pills, diamonds), color (red, purple, green), fill (solid, empty, semi-filled), and count (1, 2 or 3). The goal of the game is to make the most Sets of three cards. Here's where it gets tricky. Three cards constitute a set if, for each attribute, all the cards are either all the same or all different. See the end of the post for examples.

I used several elements of YUI to build this game. The Dom and Event utility classes were used for basic element manipulation and for attaching event listeners. I used the Button class for creating the playing cards. Each card on the playing field is a Button instance of type checkbox, since a card can toggle between selected and not. I used CSS in combination with the classes that YUI attaches to each button on certain events to change the border of the card to indicate it is selected. I used the focus property (and its yui-button-focus class) to highlight a button in the Find Third method.

The code went through many iterations, in a sort of agile development way. I only wrote code as I needed it, but I also did think ahead in the architecture and planned out the methods I knew I'd need. I found that it was easier--at least on such a small project--to code for functionality first and then go back and optimize as I learned what was and wasn't being reused. My rule of thumb, seconded by dormando in his Ops Mantras post, is that the second time I find myself writing the same/similar code, it's time to refactor it out.

The images for the cards were stolen (for testing purposes only!) from the Set official site and are still named according to their convention, which is a simple integer.gif (e.g., 81.gif). At first I have an array of objects hardcoded to the attribute values of each image this.cards[81] = {shape: 'squiggle', color : 'green', ... } but I found that I could dynamically create this array because of the way the cards were numbered. Rather than store each property as a string, I store an integer that maps to a global attributes array (e.g. shape : 0 corresponds to a squiggle) and translate for the few times that I need to show pretty text. Long-term, I plan on renaming the images to match the index values of the corresponding attributes (e.g., 3012.gif would be shape 3, color 0, count 1, fill 2). And even more long-term, it would be fun to play with PHP's image functions to dynamically generate the images.

The biggest challenge was actually finishing this project. If you view the JS source, you'll see I still have features I want to implement, but the game is fully functional with a couple of little addons. It was a nice challenge in algorithm design; as that's not my strength, I don't doubt it can be optimized further. Still, I'm happy with the way it turned out and hope you have fun with it.

Play game and view source code

Valid set:
- Color : same (all red)
- Shape : different (one pill, one diamond, one squiggle)
- Fill : different (one empty, one solid, one semi-filled)
- Count : different (one, two, three shapes)
1 empty red pill 3 solid red diamonds 2 semi red squiggles
Invalid set
- Color : FAIL (two are green, one is purple)
- Shape : FAIL (two are diamonds, one is a pill)
- Fill : FAIL (two are empty, one is semi-filled)
- Count : same (all two shapes)
2 semi green diamonds 2 empty green pills 2 empty purple diamonds

Code Blind Spots

January 19, 2008 09:53 Web Development

I found this nugget on Slashdot in my morning RSS reading. Blizzard evidently uses a signed int to store the amount of money your character has. A player discovered this and posted a screenshot of the error message. So the question is: why did the Blizzard programmers think to trap and handle this error, but it didn't occur to them to make the gold field an UNsigned int?

Every coder I know has had moments like this, where we realize that we've coded defensively for every possible outcome except for one glaringly obvious situation. For example, a couple months ago at Gaia we ran out of user IDs because we used a signed medium int. No one ever thought that we'd have more than 8 million users. But given that user IDs are always positive, was there any reason to use a signed int? My particular weakness is race conditions: I'm not good at telling when one can occur or how to solve it. In the end, it's something to fix and laugh about, as long as it doesn't cause too much financial ruin!


Cleaning up code

November 24, 2007 23:06 Web Development

One of the problems in a company that started with a bunch of junior developers is legacy code. As the devs have grown more skilled and knowledgeable, the code has been refactored or scrapped and rewritten from scratch. Often times, the old version was left behind; usually it's because people forgot to remove the old stuff, but sometimes there are still dependencies that are outside the scope of the new code or the belief that the old code should be kept "just in case" or for a rollback. I try to devote one day a week to cleaning up the codebase. I just finished removing a legacy rails-like framework that used to power Gaia's profile system and was left behind when profiles were moved to our standard MVC framework.

Cleaning up code is usually a thankless job, but I find it satisfying, especially when I get to delete a lot of files. Why bother cleaning up old code? The biggest reason I've found is so when we make changes to one component, we don't have to worry about what is and isn't active that might break. It also helps when grepping through the codebase for something, that only current files will match. Given that we're using a couple different systems, some of which can't talk to each other, getting all our code into one framework would help immensely in code reuse and speed up development.

I start by using my knowledge of the codebase and what is/isn't being used to identify potential areas for cleanup. Once I find an area, I read through the relevant code and identify the dependencies. In PHP, this means anything from other PHP files and HTML dependencies such as image/CSS/JS files. The tricky part comes when some files are dynamically included (see snippet below).

include_once DIR_CLASSES . $myclass . '.class.php';

After getting a feel for how spaghetti'd the code is, I start grepping. I take one of the dependencies, see where it's called in the codebase and if nowhere except the code I'm removing, I know it's safe to remove the file. Sometimes it's still called in other areas that are still in use. If so, I either leave the file as is or move it to a new location relevant to the remaining area that's calling it and change all references. I test the site at regular intervals to ensure everything is working as designed. Then QA does another runthrough before it's okayed to push live.

Once I'm done removing obsolete code, it'll be time to hit up the images, CSS, and JS and to organize those files. And after that, I'd like to convert repeated code into reusable models and refactor the relevant apps. I estimate I have about a year's worth of work :D


git in a multi-repo directory structure

October 30, 2007 23:54 Web Development git

I'm using git for version control both at Gaia and here at home. I'm also using Jakob's Headlight MVC framework, checked out with git. The problem I'm encountering is that the application code is under the repo root. This makes it difficult to separate the applications code I'm writing from the changes I'm making to the core Headlight source. Off the top of my head, I want to say that I add the applications directory to the Headlight exclude list and then make a repo for tracking my application code inside that directory. I have access to a git expert and will be checking with him on what to do.

Update October 31, 2007 10:16 : I'm runnning one repo called headlight_core that will hold all the changes I make to Headlight. I have a second repo that is my website that will pull from that repo. Long term, I will have a third repo that is my staging environment which the production site will pull from.


Fun with JS: Element.parentTag

June 21, 2007 16:31 Web Development JavaScript

Here at Gaia we have a swapSubmit function that allows you to style submit buttons by using JavaScript to change the submits to buttons and storing their value in a hidden field. It's one of the standard techniques for handling this particular problem. The problem is that it requires the form to have an ID so it can identify all the button within. Now, I know that according to web standards the form should have an ID anyway, but I've never been fond of having markup that isn't used. So as a purely theoretical exercise I decided to write a function to get around that.

The function uses recursive calls and element.parentNode to find the first parent of the calling element that is of type 'tag'. For example, I could do an onclick on a button with this function to find the form that contains the button. I wrote the function as an extension to the Element class so it can be attached to anything.

Here's how you could make a form button get the form it is in. This example would alert 'foo'.

<form id="foo">
    <button name="finder" type="button" onclick="alert(this.parentTag('form').id);">Find my form!</button>
</form>

I also got bored and decided to add a second parameter to the function to find not the first matching parent element, but the topmost one in the document. I don't really see much use for it, but it was easy to add in. It wouldn't be difficult at all to add functionality to find the Nth parent up from the calling element either.

<div id="foo">

    <div id="bar">
        <div id="baz">
            <div id="quux">
                <a href="#" onclick="alert(this.parentTag('div'))">I print 'quux'</a>
                <a href="#" onclick="alert(this.parentTag('div', true))">I print 'foo'</a>

            </div>
        </div>
    </div>
</div>

Functional version of the above code (changed divs to fieldsets to stay within the example code):

I print 'quux' I print 'foo'

Here's the actual function. Feel free to use it.

Element.prototype.parentTag = function(tag, find_top) {

    var found_node; // Holds the current found node

    // Checks for matching tags
    var nodeMatch = function(tag, node) {
        return (node.tagName.toLowerCase() == tag.toLowerCase());
    }

    var bubbleTagMatch = function(tag, cur_node) {

        parent = cur_node.parentNode;

        // If we've reached the top of the tree, get out of here
        if (parent == document) {
            return found_node;
        }

        if (find_top) {
            if (nodeMatch(tag,parent)) {
                found_node = parent;
            }
            return bubbleTagMatch(tag, parent);
        }
        else {
            return (nodeMatch(tag, parent)) ? parent : bubbleTagMatch(tag, parent);
        }

    }

    // Start the recursion with the calling tag
    return bubbleTagMatch(tag, this);

}

Handling arrays in a static class

June 17, 2007 00:42 Web Development PHP

I'm creating a class to manage layout configuration on my site. It does things like set the page title, site name, includes JavaScript and CSS files, etc. This is modeled after Gaia's LayoutManager class, but much simpler because it doesn't have Gaia's site-specific stuff in it. Like Gaia's LayoutManager, it is a static class, all public methods and properties are static; this allows the class to manage site stuff without carrying an instance around. However, there is one big problem: PHP evidently doesn't know how to handle class properties that are arrays when called in a static context.

Finally, I solved the problem using a variation on Gaia's solution. I created a separate data container class that holds all the information. Then, each setter calls a method in the LayoutManager class that checks if a static class property is an instance of the LayoutManagerContainer and if not, creates an instance of the container class and stores it in the static class property; either way, the container object is returned. Then I can access the properties I want directly within the class. To get the data container values from outside the LayoutManager, I wrote a getter method that takes a parameter name and returns the appropriate value from the stored data container.

class Foo {

    private static $data;

    public static function addToArray($var) {
        $data = self::data();
        $data->my_array[] = $var;
    }

    private function data() {
        if (!is_a(self::$data, 'FooContainer')) {
            self::$data = new FooContainer();
        }
        return self::$data;
    }

    public static function get($param) {
        $data = self::data();
        if (property_exists(self::$data, $var)) {
            return $data->$var;
        }
    }

}

class FooContainer {
    public my_array = array();
}

Foo::addToArray('hello');
Foo::addToArray('goodbye');
$data = Foo::get('my_array'); // $data = array('hello', 'goodbye');
© Probably a million other people from whom I've subconsciously stolen this layout. Also, Karen Ziv (me). Don't steal my stuff.