Thursday, September 28, 2006

XPath Trick: Count() Function

For those who use XML to mark up their data, you're probably used to seeing statements such as the one below, that returns a set of nodes that each have a specified child node as per the criteria:
"/root/record[lastname]"
This would return all record nodes that are children of the root node, but only if they have a lastname child node. If there are any record nodes that don't have lastname children, they won't be returned in the resulting nodeset.


But what if rather than search for nodes that have a certain child node, you want to search for all nodes that don't have that child node? For instance, recently I worked on a project where a last-minute change was applied to the specs, where a certain record only applied to one set of data, but not the others.

The thing was, they wanted a side-by-side comparison between these data sets, and the design called for showing the record in the relevant set and showing blank data cells for the other sets. Also, each data set could be viewed individually, and they wanted it to not show in the other data sets.

So I had an interesting problem. I needed a way to extensibly tag that particular record to indicate that it only applied to the one data set. I knew that I could set up a node named something like "includethis" in every other record, but that seemed like overkill. It would be much simpler to do an XPath query similar to:
"/root/record[!excludethis]"
i.e. Return all nodes that don't have the excludethis child node. But that particular syntax doesn't exist in XPath, so I had to find another way. Luckily the answer turned out to be pretty simple.

The standard XPath functions include a Count(node-set) function, that returns an integer. So for instance, if you used something like:
"Count(/root)"
you should always get a result of 1, because you can only have one root node in your XML tree. So the answer to my exclusion problem is as such:
"/root/record[Count(excludethis)=0]"
Which does exactly what I want: only return record nodes where the number of excludethis children is 0, i.e. there aren't any. This way, I only need to tag the one record, and I can leave all of the others alone.

If you know any other snazzy XPath tricks, feel free to leave them in the Comments!

Monday, September 25, 2006

Measuring Time

Mantra: If you expect to improve a process, you must first be able to measure its efficiency. Otherwise, you don't know (other than intuitively, ie just having a hunch) whether or not you're making progress.

As developers, one of the ways we can improve our work efficiency is by measuring the time we spend on a task. This gives us a number of benefits:
  • We can measure and compare times from one execution to the next, make observations about the methods we used, and determine what works better by comparing the methods used against the time spent.
  • We can use the statistical data to create better estimations of the time it will take to complete a task. This can be a huge benefit when preparing project bids.
To make it easier to keep track of time, you can use a tool like Rachota to automatically keep track of how long you spend on a task. You tell it what you're working on, do your work, click the Relax button if you take a break, and click Done when you're done. You can switch tasks in the middle, too. Once you've done your work, it gives you graphs of time spent so that you can easily compare the figures.

Remember the mantra: Measure, Improve.

Monday, September 18, 2006

How to Not Frame the Issue

Remember when it was cool to have a frameset on your site? Me neither. Granted, I've been guilty of placing the things on my old free-hosted site back in the day, but I since learned the error of my ways. And now you can, too!

Why You Might Want To Use Framesets


Many developers want a consistent layout that's also easy to manage. When learning HTML and getting into greater numbers of files on your site, you reach a point where creating a new primary link from your navigation bar becomes a huge chore, because you have to edit each file on the site and plug the link into the proper place. Using Framesets lets you create one navigation file, and divide the rest of the site into content frame pages. That way, you only have to edit the one navigation file when a new link comes along.

There's also the keep-em-0n-site effect. If your site has outbound links to other sites, you'd normally want to use the target="_top" attribute on your link tag so that when a visitor clicks the link, their browser opens the linked page at the main browsing level, rather than opening it inside your content frame. But, what if you want to allow users to keep seeing your navigation frame even when they've clicked a link to another site? That way they can always click back into pages on your site, because it's in sight and in mind. And maybe you have some kind of advertising banner that you want to optimize by keeping it in view as much as possible.

Stop the Insanity! (Please)

Now, here's why those reasons to use framesets don't hold up, plus a few extra for good measure.

First, the issue of what to do when your site is so big (how big is it?) that you need to spend all day pasting links to new pages. Whatever into-to-HTML page or book you've been reading might not have mentioned it, or maybe your skills haven't gotten to that point, but there have been a few add-ons to HTML that will be a big help to you.

SSI allows you to grab the contents of one HTML file and embed it inside another file. This gives you the same effect of the navigation frameset, where you only have one file containing navigation links. The only differences are that each file on your site will explicitly include the navigation file, and there won't be a frameset. To do things the SSI way, you'll probably want to rename your file extensions from .htm(l) to .shtm(l), the S standing for SSI. That tells the web server, "Hey, this file is somewhat dynamic, and will require actual processing rather than just fetch/retrieve." Then, where you want to include another file, you use this comment code: or:
Most scripting languages also have some mechanism to do this, for instance in php, include("file.php");

You can also use a feature in Dreamweaver called Templates, where you create a template file, which has static and editable regions (parts of the file). Then you create your site files based on the template. Any time you edit the static parts of the template, Dreamweaver automatically rounds up all of the files based on that template and updates them to reflect the change. You can use this if your site doesn't support SSI or scripting.

Now for the other issue, regarding keeping users on your site: just don't! For one thing, it's annoying to your visitors. You may think you're doing them a kindness by allowing them to access other parts of your site even though they found a link to another site and followed it, and they can still instantly get back into your site. Well, think of it this way: if there was other content on your site that they were interested in, they would have bookmarked it. Or Digged it, or del.icio.used it, or just opened the link in a new tab/window, or viewed the other site and then hit the Back button or History to get back to your site. By leaving your frameset sitting there, you're cluttering their screen real estate, and forcing them to look at something they neither want nor expect to see. Not to mention, you could be violating the terms of use of the site to which you are linking: some of them have rules about not bringing their content into a frameset, and your site might end up on their list of banned referers. Your users probably don't want to click a link from your site, only to get a message that you are a naughty boy/girl.

Here's the best reason to drop the framesets: search engine optimization and accessibility. Think about it: in order to get at the actual content of your site, a user agent (user using a browser, or a search engine spider that is automatically following links and recording what it finds) has to make more connections to your site if you use a frameset. First, it requests the frameset file. (GET /index.html) When it reads that file, it finds your frameset tag, and the nested frame tags with their src attributes pointing to your navigation file and home page content file. So now, it has to make requests for both of those files. (GET /nav.html) (GET /home.html) This extra time spent getting the files reflects poorly on the value of your content, and thus, your search engine ranking will take a hit. Also, if a visitor is using a non-visual browser, then they're going to get a prompt asking them which frame they want to get information from. If they don't know which is navigation and which is content, they might make the wrong choice. And if your content pages don't link to the rest of the site, then they have to switch frames into the navigation frame in order to browse through your site. You want things to be simple for your visitors, to ensure that they refer you to others and keep coming back to your site. You don't want to turn them off by making things more difficult than they need to be.

If you've never worked with accessibility in mind, try downloading the Lynx browser, which is a text-only interface and does a pretty good job visualizing your accessible content. It's also a piece of history, and knowing how to use it will improve your geek-cred.

Wednesday, September 13, 2006

Making 1300 Sales Calls - 30 Day Trial

Personal Development blogger Steve Pavlina has a great insight into tackling insurmountable daily to-dos, by approaching the endeavor as a 30-day trial. The rationale:
  • 30 days is a short enough time to suffer through a new process. It's not like you have to do it every day forever, just for 30 days.
  • At the end of the trial, you'll know the costs and benefits of the process, so
  • You'll have a better idea of whether or not it's worth continuing for the long term
  • You'll have gained whatever benefits come from having executed the process
This can be a great way to evaluate a potentially big change in your life, because you're not making a permanent commitment to it. In particular, Steve points out this example of a daily habit that can help your web design business:
Make 25 sales calls every day to solicit new business. Professional speaker Mike Ferry did this five days a week for two years, even on days when he was giving seminars. He credits this habit with helping build his business to over $10 million in annual sales. If you make 1300 sales calls a year, youÂ’re going to get some decent business no matter how bad your sales skills are.
And making those 25 sales calls each day will be easier when you use the Web Site Cold Call Helper.

Monday, September 11, 2006

Label: Use the Right Tags

The longer you surf the web, the more common design elements you notice. One of things that clients (and bosses) asked me to do repeatedly, was to format forms in a two-column table, with the left column containing bold tags that labeled the input in the right column, with each column aligned in the opposite direction so that they lined up nicely in the center. There are three problems with this approach:
  1. Bold tags, while making it easier to tell that they are describing the input rather than just adding content to the page, don't translate well to non-visual presentation media. And...
  2. Non-visual browsers can't easily relate the inputs back to their label text, so you have to keep moving back and forth to figure out what input you're filling in.
  3. Bonus problem: A table is meant for holding tabular data, rather than for laying out text. In a two-column layout with only labels and text inputs, this isn't much of a problem, as we can just fill in the summary and caption with "for layout purposes." However, if you're trying to do things like placing tons of descriptive text into the label column and making it render as multi-line, then you run into problems with screen readers; they'll read the first line, then the input, then the rest of the label lines.
The issue of how to column-format forms is a whole other can of worms, so I'll address that another time. For now, lets focus on the benefits of label tags:
  1. Non-visual browsers gain a way to easily tell the intent of an input field.
  2. Users of visual browsers can click the label text and send focus to the input, making it easier to move to it by giving a larger clicking target.
  3. You can use the label to convey an access key through visual styling like underlining, and allow users to instantly jump to an input without having to tab through all of the preceeding inputs.
  4. When using scripts (server- and client-side) to inform the user of validation errors, you can apply distinctive styles to the label to catch the user's attention. For instance, make it red. Your script gains the same benefit as a non-visual browser in that you can more easily find the label text associated with the input.

Wednesday, September 06, 2006

The Evolution of Web Applications

Fred Gallagher's rant today on megatokyo (strip 902) made me feel a little old. On the topic of "the ebb and flow of obsolescence," he mentioned some bits of the moldy old days of PCs, before hard drives and directly-connected modems. Wow, talk about pre-historic. Anyway, if you'll allow me to ramble on a bit...

The year was 1997, and I was a freshman at RPI. The campus ACM club was giving a lecture on a relatively new feature of the web called CGI. It was horribly boring to hear about the importance of echoing a Content-Type header, newlines, and whatnot, (so boring that I won't bother linking to the specifications here), but I came out of it hungry to see what this stuff could do. I got back to my dorm room, fired up a telnet connection to the campus Unix network (we actually had Ethernet back in those days, but no DHCP, and it took a month for the help desk to assign you a static IP address), wrote my first CGI script using plain old shell echo commands, and then... nothing. It turned out that the network admins had disabled CGI on the main network, due to the potential insecurity. It would be another year or two until I had access to the Computer Science department's web server with its CGI capabilities.

We learned all about how Environmental Variables held the URL query string, and how POST data was sent through standard input. I don't remember if the CGI.pm module was available at that point. That module was a major help, since you could access individual variables through the param() method, and not have to parse them out of the input yourself.

With more modern, web-specific languages like ASP, PHP, and ColdFusion, we don't even need to include a library to do those things. They've become implicit to the whole web application concept, no longer just a convenience.

We also saw how, back in those old dark days, we could use output functions to send strings of HTML back to the client. And they were ugly HTML strings, to be sure. Since so much of the markup includes quotes, and quotes usually need to be escaped with backslashes, your CGI code tended to look a bit like this: print "<td colspan=\"2\">$stuff</td>"

So there was quite a disconnect between the code generating the HTML and the final output, which would then be rendered in the browser. As you can imagine, it was (and sometimes can still be) a major headache, especially for high-quality applications with layouts designed by professionals. I still deal with issues of code-generated HTML, and the fact that designers have a hard time making changes to it, particularly if they're used to working in a visual editor. Now that we have embedded processing directives in the aforementioned modern languages, we're much better off, and more able to divide-and-conquer the workload.

Tuesday, September 05, 2006

Privacy Policy

Just to be absolutely clear, to satisfy my affiliate requirements at the risk of sounding like a complete tool:

This particular blog does not gather any personal information from you. We do, however, use content-driven advertising, and our third-party advertisers may collect information that you provide, and may set cookies in your browser. For information about my advertising partners and their respective privacy policies, please visit their website through the link included in the presentation of the advertisements. Our host, Blogspot, may set cookies in your browser without my knowledge.

And there you have it.

Web Cold Call Helper Launched

Well folks, my first live web application is now loose in the wild. Web Site Cold Call Helper (localbiz404.com)

This app should be useful for freelancers and web design firms who are looking to pick up new clients. By searching within a business category and locality, users can work themselves into a local niche market and sell services based on their familiarity with that market. The app then filters out any results for businesses that already have their own web site, making the cold calling process go easier. You never need to hear that your prospect already has a web site and doesn't need your services.