Web Development

Visualize your Web page in 3D with Tilt

Here’s something cool for front end developers: a Firefox plugin that turns a page’s DOM tree into a 3D visualization that you can interact with. From the Mozilla website:

Tilt is a Firefox extension that lets you visualize any web page DOM tree in 3D. It is being developed by Victor Porof (3D developer responsible with the Firefox extension itself), along with Cedric Vivier (creating a WebGL optimized equivalent to the privileged canvas.drawWindow, see #653656) and Rob Campbell (who first thought about creating a 3D visualization of a webpage). Everything started initially as a Google Summer of Code project, but now, with an enthusiastic team behind it and so many new features and ideas, it has become an active Developer Tools project.

Tags: , , , , , , ,

Browser Prefixes are Good

I’ve seen some grumbling on Twitter recently about browser prefixes being bad. They’re not. Browser prefixes let browser manufacturers introduce CSS features that have been proposed but that are not yet part of an official specification. Considering how many years that can take, it’s not a bad solution.

The grumbling isn’t about the introduction of draft declarations though, it’s about the browser prefixes. Some people—including some people at Opera and Microsoft—seem to think it would be a good idea to get rid of those prefixes altogether. Apparently the risk of future compatibility can be sacrificed at the altar of saving two lines of code.

As it stands right now I can, for example, round the corners of a box with the follow code:


/* This example uses a non-semantic class name. Get over it. */
div.rounded {
border-radius: 5px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
}

One day, after the spec has been finalized, I’ll be able to do the same thing with just:


/* Still not semantic. Oi vey! */
div.rounded {
border-radius: 5px;
}

Of course, to support those damn legacy browsers I’ll probably stick to the three line version, as egregious as that is. Here’s the thing, though. If the spec does change and is then finalized after said change, Mozilla and WebKit can simply implement the final version correctly using “border-radius” and their legacy browsers will ignore that and use the browser specific versions (-moz and -webkit respectively). Meanwhile Opera will have to change how their existing implementation of border-radius works.

While it’s very unlikely that border-radius will change, it’s not impossible. And other bleeding-edge features of CSS3 stand a greater chance of changing before being finalized. A few lines of saved code are just not worth even the relatively minor risk of having to hack around different implementations of the same feature and the headaches that would case.

Box model anyone?

Tags: , ,

Design & Developer Jobs in Austin

Looking to hire a web designer or developer in the Austin area? Are you a web designer or developer looking for work in the Austin area? Here are a few helpful resources:

AIGA Austin Job Board

Be sure to read the AIGA Standards of Professional Practice. To post a job, go here.

Refresh Austin job board

Before posting a job, be sure to read their job posting guidelines. The Refresh Austin guys also run the Austin Web Design & Develop Meetup, which is a great place to meet designers and developers in the area.

Door 64

This one is geared primarily towards developers. Anybody can view jobs but you have to become a member to post jobs. Membership is free.

CraigsList

I’ve listed this one last for reason. As a job seeker you can expect to find a lot of crap job offers that pay either a fast food wage or a stake in the company (read: work for free). If you’re looking to hire someone, either know what you’re doing or avoid this option. Roughly 80% of your applicants will not be qualified. You can find good people and good jobs there though so I wouldn’t totally dismiss the site.

Of course there are non-local boards you can check out too:

And there are a few staffing agencies worth talking to:

I’ve had the best luck, again on both sides of the fence, with Aquent. If you’re going to a talent agency, I’d start with them.

Tags: , , , ,

Web Application Development: the Changing Battlefield of Web Design

From Google:

In order to continue to improve our products and deliver more
sophisticated features and performance, we are harnessing some of the
latest improvements in web browser technology. This includes faster
JavaScript processing and new standards like HTML5. As a result, over
the course of 2010, we will be phasing out support for Microsoft
Internet Explorer 6.0 as well as other older browsers that are not
supported by their own manufacturers.

We plan to begin phasing out support of these older browsers on the
Google Docs suite and the Google Sites editor on March 1, 2010. After
that point, certain functionality within these applications may have
higher latency and may not work correctly in these older browsers.
Later in 2010, we will start to phase out support for these browsers
for Google Mail and Google Calendar.

Google Apps will continue to support Internet Explorer 7.0 and above,
Firefox 3.0 and above, Google Chrome 4.0 and above, and Safari 3.0 and
above.

I think you can expect to see more of this as the big boys go after one another. Apple’s supporting HTML5 for video over Flash players. Google has a browser-based OS coming out and leveraging HTML5 makes a lot of sense there as well. That’s a shot directly at Microsoft. Frankly, if the club being used is an open standard, I’m okay with that.

Aside from those guys fighting wars on a battlefield the rest of us are sitting on, it also raises an interesting discussion about website development versus web application development. While I fully support progressive enhancement for website development, it’s harder to achieve for web apps. From a practical standpoint there is the simple issue of cost. For instance, how much manpower should Google throw into alternative content for the Flash charts in Google Analytics? That’s just one item in one app across their entire suite.

Tags: , ,

IE Compatibility VPC Images

Or ‘Why I Don’t Like Microsoft, Part 1’

For years Microsoft has made VPC images available that designers and developers could install using virtualization solutions like VirtualBox, VMWare or Parallels. Sometime around August 2009 they broke those images, requiring activation. This meant that, in order to test in various versions of Microsoft’s operating system and with various versions of Internet Explorer, you had to purchase an expensive license for each copy. This of course completely negated the purpose of having the images to begin with.

When Alan Burke ran into the activation problem he started a thread on the VirtualBox forums. Nobody knew what was going on. After a fair amount of back-and-forth, Pete LePage, an Internet Explorer Product Manager, popped in to say that Microsoft has never officially supported any virtual hosting application other than VPC:

Since we started shipping the VPC images in late 2006, we have never officially supported other VM hosting applications other than Microsoft VPC, and Microsoft Legal required us to add that part into the EULA.

That completely misses the point. The problem wasn’t with the EULA and I don’t need officially supported images. I just need images that I can install and test on without purchasing thousands of dollars worth of licenses.

Pete also said:

If there is enough demand, we may be able to get additional images built, I’d ask that you email me at plepage@microsoft.com along with the VPC software you’re running so we can have a better idea of the numbers and needs.

I emailed him and never heard back. A few days ago he responded to a more well-known designer, Veerle Pieters, in the comments section of a flickr photo she posted when she ran into the same activation issue:

Yep, we are aware of the issue, and we haven’t been able to find a good fix yet. We’ve figured out what the problem is at this point, why they used to work and why they now require activation. The question is how we fix that – it’s a combination of technology and policy.

For those who think it’s Microsoft trying to screw over non-Mac users, please believe me it isn’t. I have been gathering comments from folks to try to use to push the changes – so please keep them coming. Please shoot me an email and I can see what I can do to help!

It should be noted that this is almost six months after the problem first appeared. If Microsoft wanted to fix it, it would be fixed. I emailed Pete in August 2009 like he asked and I never heard back from him. I also have yet to get a reply in Veerle’s flickr thread either. Pete asking for people to email him has all the appearance of Microsoft’s standard M.O. as it removes the discussion from the public view. Not replying to those emails, not providing any sort of status updates and not doing anything for six months just reinforces that negative perception.

This is a real pain point for developers and it has real consequences for Microsoft. IE browsers are already on the bottom of my testing list and I’ve already decided IE users can have a less visually rich experience as long as they get the same content.

I don’t have infinite resources. The more difficult it is to test on their products, the less I’m able to do. It becomes a situation where, even if I want to provide a richer experience for IE users, I can’t.

Tags: ,

Quick Tip: Pay Attention

Bar Chart

If you have a website you should be keeping track of who’s visiting it and what they’re doing while they’re there. Google Analytics is a great tool for doing just that. If your site is built with WordPress, like mine is, you can also install a plugin like Site Stats, which will create a new page for your dashboard full of useful information like:

  • Who is sending you traffic (referrers)
  • Which posts and pages are the most popular
  • What search engine terms are leading people to your site
  • What sites are linking to you

If you want to grow your audience this is essential information to have.

Tags: , , , ,

class.pagination.php

Download this file

I’ve been meaning to simplify my work / life by creating some classes that I can use to streamline a lot of the projects that I work on. I found myself with some time this week and finally took a small step in that direction by creating a pagination class.

Up until now I’ve used a function that I wrote way back when for paging. It was clunky, kludgy, and limited. I looked around at what was available online and what I found was, for the most part, clunky, kludgy, and limited.

Starting from my existing code, I laid out some goals for how I wanted my new pagination object to work:

  • It had to be very simple to integrate. I wanted to be able to drop it into a file and have it just work.
  • The output had to be semantic, valid (X)HTML that would be easy to style with CSS.
  • I wanted options for how the links would display.
  • It needed to have options to output clean URLs (for when I’m using mod rewrite) or normal URLs with ugly query strings.
  • It needed the option of using sessions to store SQL queries since, much of the time, this would be necessary when using clean URLs.
  • It had to be drop-dead simple to configure options, such as how many pages to display per page, enabling mod rewrite functionality, enabling the use of session data, etc.

The idea for using sessions and clean URLs came from Ben Jamieson / Thyme Online. I’m also going to credit him with the idea for highly compartmentalizing the code used in the class (he has a highly compartmentalized pagination class of his own with sessions and clean URLs…) even though I remember what his code looked like when I first met him and I think this may be a case of the student becoming the master!

If you’re wondering why I wrote my own class instead of just using his, well, there were a couple of reasons:

  • I wanted the practice (I re-read the chapter on OOP in my PHP book before starting).
  • I’m an idiot: I was concerned about security and I didn’t realize the session data was only storing a session ID in the client side cookie and not the actual SQL queries. I initially wrote this class to include Alexander Valyalkin’s most excellent md5_ encryption and decryption functions.
  • There were some things I wanted to do differently.
  • And because I already had my own paging code that I wanted to adapt.

If you already have something in place to handle pagination, a lot of this code will probably look familiar — there aren’t that many ways to skin this particular cat — but hopefully this code is clean enough and reusable enough that some people will find it useful.

A Simple Example

<?php
   include_once('class.pagination.php');
   $sql = "SELECT * FROM table_name";
   $paging = new pagination();
   $result = mysql_query($paging->paginate($sql));
   while ($record = mysql_fetch_assoc())
   {
      // Output records here
   }
   print($paging->getLinks());
   print("<p>".$paging->getCount()."</p>");
?>

The above example is the simplest usage. The class is included, the object is initialized, the SQL code is passed and returned with the LIMIT clause appended (note: it will replace any existing limit clause) and the links are output.

Sample Output

For large sets of data, ten or more pages, first and last links are added to let users quickly jump to the beginning or end of the data set. Otherwise, just the pages and previous/next links are displayed. You can change that by passing an optional variable to the getLinks() function or, if you’re going to output multiple sets of paging links on a page, you can override the default format via the setDisplayOptions() function (see description of this function below for more details).

Available Functions

paginate($sql) – This function initializes several variables and returns a modified SQL statement with a LIMIT clause appended to it.

setDisplayOptions($x) – This function changes how pagination links are output for a given page. It takes a numeric value between 1 and 4:

  1. Only show the first and last links for large data sets (ten or more pages). Only show previous link when not on the first page. Only show next link when not on the last page. This is the default setting.
  2. Always show first and last links. Always show previous and next links.
  3. Never show first and last links but always show previous and next links (the Flickr option).
  4. Never show first and last links. Only show previous link when not on the first page. Only show next link when not on the last page.

You can achieve the exact same functionality by passing this variable in the getLinks() function. Both of the following examples output the same thing:

<?php
   // Example one
   $paging->setDisplayOptions(3);
   print($paging->getLinks());

   // Example two
   print($paging->getLinks(3));
?>

setPageSize($x) – Override the default number of items to display per page. The default is 25.

setModRewrite(TRUE) – The default value is FALSE. Override this if you plan to use mod_rewrite to create clean URLs. If you don’t know what this is, leave it alone.

setUseSessions(TRUE) – The default value is FALSE. Override this if you have complex SQL statements that you don’t want to pass via query strings. You’ll probably need to enable this if you’re using clean URLs.

setSessionName($name) – This just exists to prevent any possible conflicts with existing code. The default session name is ‘searchdata‘. If, by any chance, you already use a session variable with that name, you can override the name used by the pagination class.

This function can also be used if you plan to store multiple SQL queries by assigning a unique session name for each query.

getSQL() – What goes up, must come down — or better put: what is input, must be output. You pass a SQL statement to the pagination object; this function returns that SQL statement to you with the LIMIT clause appended to it.

getCount() – This returns the “Displaying from x to y of z” string. It gets its own function so that it is easy to omit if don’t want to display it.

getLinks($x) – This is the meat and potatoes. This function returns the list of links for output. It accepts the same numeric option that setDisplayOptions($x) uses.

Miscellaneous Notes

Regardless of whether you use clean URLs or not, the the current page is determined by the $_GET['page'] variable. The page variable always needs to be the last part of the query string or path. Examples:

  • domain.com/articles/title/5/
  • domain.com/article.php?name=title&page=5
  • domain.com/search.php?keywords=xyz&sort=desc&page=2

The first example above is using mod_rewrite.


To use sessions, you first have to initialize the session data with:

<?php
session_start();
?>

If you are using cookie-based sessions, you must call session_start() before anything is output to the browser. For more information on how to use session_start(), see the php.net website.


You can view the source code of this page and the associated stylesheet to see how the links are output and how I’ve styled them.

If you have suggestions regarding this class, please leave a comment. Also, this isn’t heavily tested, so if you find a bug (I’m sure there will be some) please let me know about it.

Download this file

Tags: ,

The need for project planning

I’ve been working on a largish website project and I’ve been falling steadily behind schedule. The reasons for the delays fall into two categories: data conversion and code conversion. Both turned out to be more complicated than I expected.

Data Conversion (Filemaker to MySQL)

Filemaker is a weird sort of database. Instead of tables you have “layouts” that show certain fields but all fields exist in the same bucket. The database is the table. In this case the Filemaker database had hundreds of fields in it that were spread across 16 layouts and all of it needed to be converted to MySQL. Unfortunately this was not an a => b scenario for several reasons:

- A lot of calculations and data manipulation are taking place in Filemaker
- The LDML code made extensive use of lists built into Filemaker
- A lot of data had to be translated
- Certain restrictions were placed on the MySQL databases (see below)

The data conversion is part of the larger conversion from Filemaker/LDML to MySQL/PHP. On the PHP side the client already has a database structure and code built out for several of the portions of the site being converted. In those cases some data has to be split across multiple tables, so data has to be converted to new formats, and various other tweaks had to be performed.

This is a longer term project (four months). Because the data conversion will have to be done several times, I chose to write a script to handle it. Again, because it will have to be run over and over again, it first starts by emptying the existing tables and resetting all of the auto_increment counters to 1. When the site has been fully converted and is ready to relaunch, we’ll be able to run the script again and at the push of a button grab the most recent data from the previous site. Whenever data turns out to need more “massaging” during the code translation process (i.e. something turns out to be wrong) I can make the changes and re-run the script without having to perform a lot of manual labor.

I’ll outline the conversion script another day — it’s about 800 lines of code. It took about a week to write and get right and since this project is ongoing it will almost certainly require more tweaks as the project moves forward. That’s a lot more than the one day I had estimated for the conversion.

Code Conversion

Once I had the data poured into 19 MySQL tables I could start setting up the website. First thing was converting the new layout into XHTML and CSS. No problemo. The second step was to setup the new navigation structure. A little bit more work and planning here but again, no problemo. The third step was to create pages for all of the static content. This was the easiest step in the process. The fourth step was, and is, where I get my hands dirty and start mucking around with the site code.

Now, it seemed easiest to start with the pre-existing PHP modules from the client and get those up and running. Unfortunately, this is where I ran headfirst into one of my own great shortcomings. I have a hard enough time reading my own well-formatted and well-documented code. In this case I’m reading someone else’s code with functions and classes that are spread across 25 different files. Everything is being generated or manipulated by something else. Coming into this from the outside it’s very hard to figure out what is going on. For me this has led to a lot of confusion, a lot of delays, and a lot of sleepless nights.

Finally, this weekend I decided that something had to give. I was trying to take the short route and fumble through things. Define a task, tackle it, and when it doesn’t work try to trace the code back through the various files to find out why. Fix, try again, run into another problem, trace it back through, etc.

For most people this would actually work. They can just learn from doing something hands on. For me that doesn’t work. I have to first read a manual, then get hands on and refer back to the manual as I’m going along. It’s not enough for me to know how something works, I have to understand why it works.

I determined that I needed to write a manual. In doing so I would develop a deep understanding of how everything in the various files worked.

Yesterday I spent the day printing out most of a ream (500 pages) of code. I got a binder and a bunch of tabbed inserts. I created tabs for each document, hole punched everything and assembled my book. Then I started the two day process of reading the book. For each file I created an outline of each class and function. I also outlined the structure for each include. This is my table of contents and is in the front of the book.

Now I have a much greater understanding of what is going on because I’ve read through everything once. I also now have a quick reference to any section of code without having to open five different files to track function calls. At a glance I can see what is going on and if I’m passing data to a function in the correct format or using a function in the correct way. This took two days and it could have saved me weeks of sleepless nights.

Planning and organization are incredibly important when working on projects. It may seem like wasted time but in the end it saves more time than it consumes.

Tags: , ,