April 28, 2008
Weekend update to Newsbrew
A couple weeks ago, I blogged about a Google App Engine news aggregator I wrote called Newsbrew (original post). A few days later, Google announced the availability their RESTful feed API. Since the trickiest part of Newsbrew was the aggregation code, I decided to refactor the application to use Google's new service.
Newsbrew still stores feed and post data, but rather than retrieving and parsing the feeds myself (a surprisingly complex and error-prone process), Newsbrew now uses Google's REST feed API. All data, regardless of the underlying syndication format, is returned in a nice normalized JSON format.
With just a few hours of work, I was able to make Newsbrew much more robust, and because I no longer have code for parsing nine different formats of RSS and Atom, Newsbrew is much less error prone, and the code base is simpler.
I also added Ajaxian to the blogroll at the request of Dion Almaer. If you know of any other sites I should add, let me know.
Posted by cantrell at 11:32 AM. Link | Comments (1) | References
April 18, 2008
Newsbrew is now a Google Application
I wrote a news aggregator a couple of years ago called Newsbrew which I primarily used for my own news-reading needs. I think I took it down when I got tired of paying for the server, and worrying about keeping it up.
After Google launched the Google App Engine, I decided to take a little break from Flex and AIR and rewrite Newsbrew in Python to get a good feel for the GAE experience. You can see the current beta version here.
Overall, I was very pleased GAE. It took me about five days to write this version of Newsbrew, but that included learning Python, Django, and everything about GAE. The application is fairly comprehensive, consisting of a user interface, aggregation service, and a secure administrator section. Unfortunately, I didn't get to all the features and bug fixes that I wanted, but the app still seems to work reasonably well.
It's still going to be a little while before we're writing real-world production apps on GAE as it still has several rough patches, bugs, and missing functionality. But it's very clear where Google is going with this, and there's no doubt that GAE is a very powerful concept and platform. I'm certainly going to keep my eye on GAE, and use it as much as I can.
Posted by cantrell at 11:16 AM. Link | Comments (2) | References
November 07, 2006
Firefox 2 Live Titles
I'm sure most Firefox users are familiar with Live Bookmarks by now -- bookmarks that point to RSS feeds, and update themselves as the feed is updated. Firefox 2 has now introduced Live Titles -- page titles that also update themselves. If you're using Firefox 2 and you want to see an example, go to woot.com and bookmark it. Rather than the typical name text field, you'll see a combo box that lets you enter a static title, or choose one of woot's two Live Titles, which is a brief description of the item currently being sold. Makes perfect sense for both woot and woot fans.
Live Titles are actually "microsummaries" which are easily implemented using a link tag with a rel value of "microsummary". For more information, check out this page on the Mozilla wiki. You can also find a list of microsummary-enabled sites here. And finally, check out the Firefox 2 Release Notes for more information on what's new in Firefox 2.
Posted by cantrell at 10:28 AM. Link | Comments (2) | References
January 31, 2006
Programmatically Determining a Site's Language
I was having a conversation with a couple guys the other day about data aggregation, and the topic of language came up. They wanted to know how you can programmatically determine what language a site is written in (language as in spoken and written language, not computer language). Off the top of my head, I guessed one could uncover clues in the site's HTTP headers, character encoding, or by geocoding the site's IP address.
It turns out to be a harder problem to solve than I initially thought. HTTP headers are really no more help than a site's character encoding which really isn't much help at all since UTF-8 can pretty much encode any language there is. And geocoding an IP address is really nothing more than a hint for all the regular reasons geocoding IP address doesn't always work, and for the additional reason that a server being in a particular country doesn't really tell you anything about the language the sites on the server are written in (I used to live in Japan, but never posted a single thing in Japanese).
I did a little research, and it looks like folks like Google use very complex techniques for determining a site's language like comparing characters and words against known sets of characters and words in a database. This seems like a reasonable approach, but not one that I could implement in a reasonable amount of time (like a couple of hours), so I did what I always do when faced with a very complex problem: I looked for an obvious and simple solution.
What I eventually decided was that the sites out there with the most content, and content which is updated most frequently (and therefore are the most interesting sites to index) actually almost always tell you what language they are written in through their RSS or Atoms feeds. Of course, a research paper isn't likely to have an RSS feed, but most news sites and just about all blogs certainly do.
I tested the theory by writing a Ruby script that crawls sites and their feeds looking for things like xml:lang attributes and other language-related tags. I ran the finished product against a sample of 50 non-English blogs from MXNA and determined that the technique is about 60% accurate. Not great, but not too bad, either. I also rediscovered a lesson I'd already learned many times over when writing aggregators, which is that you should never trust data you don't control since all but one of the sites that my script got wrong actually lied and claimed to be a language it wasn't (in every case, they claimed to be English rather than the language they were actually written in). How do I explain the fact that about 40% of blogs seem to lie about their language? I'm sure it's an innocent mistake. Most people don't really know much about how RSS and Atom work, and just trust their blogging software to do the right thing. Even if they write the software themselves, they probably don't really know what all the RSS/Atom tags actually mean. RSS is sort of the new HTML: as long as it mostly works, it's good enough for most people.
Like I said, the script works by crawling sites and their RSS or Atom feeds. If you're interested in the source, you can grab it here. I also threw together a CGI wrapper for it, so you can test it out online yourself here. If you're new to Ruby and don't feel like decoding all the regular expressions, here is a brief description of how it actually works.
- You give it the URL of a blog or other news site which you assume has an RSS or Atom feed, and it grabs the source.
- It checks to see if the site's source itself gives any clues about the language it's written it through meta tags.
- If it doesn't find any clues in the site itself, it looks for link tags referencing RSS or Atom feeds. If it doesn't find any, it searches for any links in the page that seems like they might references an RSS or Atom feed.
- Assuming it has found one more links to probable feeds, it resolves the URLs, grabs the source, and looks for language-related attributes and tags in the feeds.
- Finally, once it finds what it thinks is a language code, it simple converts it into an actual language name.
Some lessons learned:
- Never trust data that you don't own unless absolutely necessary. This is an important lesson in data aggregation. Don't trust dates, languages, or even things like character encodings and categories. Determine as much as you can yourself, and be skeptical of the rest. As C3PO says in The Empire Strikes Back, "R2D2, you know better than to trust a strange computer."
- If you have a non-English blog, check your feed and make sure you're not masquerading as English. I knew my script wouldn't be 100% accurate, but I was really surprised to discover that almost %40 of non-Enligh blogs claim to be written in English.
- Use link tags to point to your site's feeds to allow people to "auto-discover" them. You can add a link tag to the head section of your site which references your feeds which allows things like Firefox, Safari, future versions of IE, aggregators, and rogue Ruby scripts to find your feeds more easily.
- Flash tags are complicated. They have a lot of different options. The FlashTag class supports 17 different properties. You can set the ones you need (only four are required), and defaults are used for the rest. Also, the FlashTag JavaScript class validates the information you set on it to make sure all the values are supported (if not, it throws exceptions).
- Flash vars can be a pain. Flash vars are passed into Flash movies at load-time, and have to be formatted as a URL encoded string. The FlashTag makes setting Flash vars much easier (see code below).
- Encapsulation is good. What if you wanted to change something across all your Flash tags? Wouldn't it be better to change it one place?
Posted by cantrell at 10:24 AM. Link | Comments (1) | References
December 02, 2005
Firefox + Exposé = foXposé
I can't remember where I came across this yesterday, but I somehow stumbled upon the foXposé Firefox extension. It basically tiles all your tabs inside of a single window, and lets you click on one to select it. Very cool. I've never been a big fan of Exposé on OS X, but I'm testing this extension to see if I find it useful as it is impressive.
I've also started pulling all the essential Firefox hacks and extensions together under a Firefox del.icio.us tag. Expect it to continue to grow.
Posted by cantrell at 11:22 AM. Link | Comments (2) | References
November 29, 2005
Firefox 1.5 possibly (hopefully) available today
The rumor is that Firefox 1.5 will be released today. Keep an eye on GetFirefox.com. My favorite new feature: drag and drop reordering of tabs. I've been waiting for this for as long as I've been doing tabbed browsing, and have always found the plugins that provide this functionality to be sketchy, especially on OS X. I'm glad to see Ansers.com is being added to the search engine list, as well. And of course performance improvements are always welcomed.
Mozilla.org has a full list of new features (for RC 3, not the final release). Let's hope it's today. I could use something to brighten up this dreary San Francisco morning.
Update: As mentioned in the comments, it's available now. Also, when I installed 1.5, I was told that the SpellBound and Live HTTP Headers extensions would not work, and were being disabled. I uninstalled them both (along with the dictionaries), then reinstalled, and they both work fine.
Posted by cantrell at 09:50 AM. Link | Comments (5) | References
November 01, 2005
How do you parse your log files?
I've been playing around with different ways to parse log files and generate server reports. I currently have Webalizer, Analog, Omniture, and mod_log_sql in place. Unfortunately, I can't find one package that provides everything I want. Anyone have any suggestions?
Posted by cantrell at 03:03 PM. Link | Comments (9) | References
August 18, 2005
JavaScript Flash Tag Update
If you use the JavaScript Flash Tag object for rendering Flash tags client-side, I just checked in an update you might want to grab. I added a missing parameter (which is useful for Flash Player 8) and fixed a bug that was cropping up on older versions of Internet Explorer. You can grab the new source and read the revision notes here.
The API hasn't changed at all, so you can drop it right in to your existing code with no problems.
Posted by cantrell at 10:10 AM. Link | Comments (0) | References
August 05, 2005
Search + Ajax = MXNA Suggest
I'm experimenting with making the MXNA search more useful, so I decided to borrow some ideas from Google and build MXNA Suggest. MXNA Suggest lets you search interactively by suggesting terms that other people have searched for in the past as you type. The terms MXNA Suggest returns are ordered by relevance, which is determined by the number of times people have searched for them. In addition to being a potentially useful search interface, it's also an interesting research tool. It's sort of a quick and even fun way to see what terms are most popular in the Macromedia community.
MXNA Suggest is still very much in an "alpha" stage which means I've just been hacking away at it in my free time, and therefore it has not been thoroughly tested. That said, it does seem to work pretty well, although it took a lot of work to get it that way. I'm a big Ajax/JavaScript fan, but it can get very frustrating when developing across browsers and platforms (even with all the most modern browsers). If you view the source code, you'll see areas where I had to branch based on browser, and if you use it enough, you might even find a bug or two I haven't fixed yet (for instance, in Safari, hitting the up and down arrow will make the selection jump two items at a time instead of one because Safari throws two key down events for the arrow keys for some reason I couldn't possibly begin to explain).
The other difficult part of this project was basically building my own component in JavaScript. I'm using a standard HTML text input for the search term, but everything below that is custom built. Getting things like the auto-complete and the selection behavior to work like you'd expect, and getting it to work across browsers and platforms, was not easy.
But of course I love these types of challenges, so I'm not complaining. I've been dealing with cross browser issues since I first got into web development (many years ago), and at least in the realm of JavaScript and DHTML, it looks like they aren't going away any time soon.
Anyway, feel free to view the source and swipe some code if you can use it. It isn't documented, but it's pretty clearly written, so it should be easy enough to follow. And if you find any bugs, post them here, and I'll try to get them fixed. If this proves a useful feature, maybe eventually I'll move it out of the "experimental" directory and integrate it with the main application.
Posted by cantrell at 08:58 AM. Link | Comments (2) | References
August 02, 2005
JavaScript Support for Eclipse
I'm looking for a good JavaScript plugin for Eclipse. I see there are several out there. Can anyone recommend one in particular?
Posted by cantrell at 01:42 PM. Link | Comments (6) | References
July 20, 2005
History Management in RIAs
I've been doing a lot of experimentation with RIAs recently. First, Mike Chambers and I experimented with integrating Flash and Ajax. Then, I did some work to support deep linking in both Flash and Ajax applications. The next challenge was history management.
History management refers to the ability for users to navigate backward and forward using their browsers' integrated history buttons. We've all been doing this for as long as we've been browsing the web. In fact, it's something most of us take for granted, and even depend on (I know I do).
The problem with history management is that it is not always compatible with Rich Internet Applications. One of the distinguishing features of RIAs is that they eliminate the need for total page refreshes by loading data in the background and updating only portions of page. In most cases, this is done without creating a new entry in the browser's history table, which means you can't use your browsers' forward and back buttons to navigate an RIA. Typically, clicking the back button will take you back to the page you were on before visiting the RIA, regardless of how much you had been interacting with the RIA in the meantime.
Flex automatically addresses this issue using a hidden frame which invisibly creates entries in the browsers' history table as users navigate a Flex application. It's a very seamless and elegant approach which seems to work quite well, so I decided to borrow some of the same concepts and apply them to MXNA's Category Click Feed Report.
The Category Click Feed Report has become our sandbox for RIA experimentation. In the latest build, I added some initial support for history management. To see it in action, go to the report, click around on the categories and feeds, then use your browsers' back and forward buttons to navigate through your history. If all goes according to plan, you should get the best of both the RIA and standard web interface worlds.
The technique I'm using is slightly different than the one Flex uses. Since Flex only needs to worry about history mangement in Flash, it loads a piece of Flash content in a hidden frame which is able to communicate with the main SWF. MXNA, on the other hand, is a combination of both Flash and JavaScript/HTML, so I needed a more generic approach. The technique I settled on (at least for this first, very experimental version) is basically an Ajax history manager which I've extended with the Flash / JavaScript Integration Kit so that it talks to Flash, as well. It seems to work fine on all the browsers I have sitting around me (Firefox, Safari, and IE), but it hasn't gone through a thorough QA cycle. If you find any issues, please let me know. And if you want the code, it's all availble by viewing the source of the page (and the Flash chart). None of it is obfuscated, so you're welcome to it.
Posted by cantrell at 01:30 PM. Link | Comments (7) | References
June 24, 2005
Using JavaScript to Render Flash Tags
The first time I embedded a piece of Flash into a ColdFusion application, I wrote a ColdFusion custom tag to render the Flash tag for me. Yesterday, I wrote a JavaScript class that essentially does the same thing, but renders the Flash tag client-side rather than generating it on the server. Why encapsulate the process of writing out a Flash tag?
Here's some sample code. First, load the required classes like this:
<script type="text/javascript" src="/path/to/Exception.js"></script>
<script type="text/javascript" src="/path/to/FlashTag.js"></script>
The Exception class is required so that the FlashTag class can throw exceptions if something goes wrong. Now, create an instance of the FlashTag and write it out:
<script type="text/javascript">
// The arguments below are path, width, height, and Flash Player version number.
var tag = new FlashTag('/path/to/flashContent.swf', 300, 300, '7,0,14,0');
tag.write(document);
// or
document.write(tag.toString());
</script>
You can set properties like this:
tag.setBgcolor('ff0000');
tag.setMenu(false);
You can add Flash vars like this...
tag.addFlashVar('someName', 'some value');
... or like this...
tag.addFlashVars('a=b&b=c&a=c');
Why use JavaScript rather than rending Flash tags server-side? JavaScript runs everywhere whereas ColdFusion only runs on a ColdFusion server which makes the JavaScript solution more versatile. Also, using JavaScript allows you to render Flash dynamically and on demand, after the page has loaded, which is becoming more relevant as internet applications become richer and more interactive.
I wrote the FlashTag JavaScript class as part of the Flash / JavaScript Integration Kit. You can grab the source from Subversion here:
I tested it fairly well, but if you find a bug, let me know and I'll get it fixed right away.
Update: As "sang" points out in the comments, this is also a good way to keep your pages W3C/XHTML compliant.
Posted by cantrell at 09:02 AM. Link | Comments (9) | References
June 20, 2005
Deep Linking in Flash and AJAX Applications
A couple of weeks ago, Jon Udell made a post entitled "Web-friendly rich Internet apps, continued" in which he asks the questions "can rich Internet apps be web-friendly?" He mentions MXNA, and specifically, the experimental MXNA Category Click Feed Report which combines Flash and JavaScript/AJAX techniques to make the page more dynamic, interactive, and responsive.
But Jon wanted more out of the experience. From his post:
If I link to the aggregator, it defaults to the Macromedia category and to Kevin Lynch's blog. You can navigate to the Technology category, and thence to my blog, but there are no URLs exposed for these, so I can't link from here to there. In this case it's not a Flash issue, it's a DHTML issue. But the principle is exactly the same. Toolkits and frameworks for building rich Internet apps ought to make support for deep linking a no-brainer for developers. It should be the rule, not the exception.
That sounded like a good idea to us, so we did it. Although the Category Click Feed Report initially defaults to one weblog (currently set to mine), you can navigate to other feeds, and bookmark or link directly to that feed's report. For example, check out John Udell's report. Or Kevin's. Or Mike Chambers'. Notice how the state of both the Flash and the JavaScript portion of the application are captured.
The Category Click Feed Report uses two techniques for deep linking. The first technique is based on Kevin's RIA deep linking example in which he dynamically appends anchor names to the URL in the location bar which describe the sate of the application. Click on some different feeds in the right-hand column, and you'll notice the URL getting updated with information the application needs to recreate the current state. This technique works well, primarily because it allows users to copy the URL right out of the location bar in order to preserve the state of the application, which is what we are generally used to doing. However, there are two disadvantages:
- Anchors don't work like query string parameters. If you change the IDs in the URL in the location bar and press return, the app won't update which means if you are already looking at one person's report, and you try to paste in the URL for someone else's report, nothing will happen. The reason is that the browser is simply trying to jump to a named anchor on the page, which it does not find, so it does nothing. There may be a way to capture this event in JavaScript so you can tell your application to react accordingly, however, which is something I need to look into.
- There are cross-browser issues. The dynamic anchor technique works pretty well across all browsers except Safari. When you have multiple tabs open in Safari, a little loading animation will play on the right side of the tab when a page is loading. Safari starts playing that animation in response to the href property of the location JavaScript object being changed, even if you are just appending anchor names and not loading anything from the server (which I would consider a bug). The result is that although the page is being updated without reloading the entire document, it looks to the user like the entire page is being refreshed. What's worse is that the code in Safari that stops that animation from playing seems to run in response to a page fully loading, which in this case never happens, so the animation never stops. That makes the page feel like it's "hung" or broken in some way which I personally find pretty annoying.
The second technique I used for deep linking has to do with the "Link to this report" link below the chart. This uses a technique similar to what Google Maps uses to let you link to a specific map state (they may have opted for this approach due to the issues mentioned above). Notice how the URL in the location bar never changes as you use Google Maps since the entire page is not refreshing, which means that it doesn't give you any query string parameters to capture the state of the app. Instead, the "Link to this page" link in the upper right-hand corner changes, capturing the information needed to redraw the map in its current state.
Mouse over the "Link to this report" link below the chart in the Category Click Feed Report and note the query string parameters. Then click on another feed, mouse over the link again, and you will see that it seamlessly updated with the information necessary to link directly to that report. This technique uses query string parameters rather than anchors and is therefore technically more reliable, however the disadvantage is that it requires users to learn a new paradigm for capturing the state of an application. Rather than just copying the URL out of the location bar and sending it to a friend, thunately, it is not possible to combine these techniques by dynamically updating query string parameters in the location bar because the only portion of a URL in the browser's location bar that you can dynamically change using JavaScript without causing the entire page to refresh is the anchor portion.
Ultimately, I think the dynamic link technique is the better way to go even though it is currently less intuitive to users. My pediction is that this will change (partially thanks to Google), and users will soon know to look for special links to use to capture the state of an application rather than relying on the location bar. Using dynamic links is actually safer since you can be sure that the links you are sending around or posting on your site for the world to click on don't contain session informtion that can either compromise your account on the site you are linking to, or cause the link to be invalid after the session has timed out.
I'd like to get some feedback on how I've incorporated deep linking into the Category Click Feed Report, and eventually, I'll release all the code along with a tutorial. In the meantime, check out Kevin's tutorial on the dynamic anchor technique, and feel free to view (and steal) my ource code. It is all easily accessible and readable.
Posted by cantrell at 08:16 AM. Link | Comments (5) | References
June 15, 2005
Flash / JS Integration Kit Released Under an Open License
Mike blogged the news yesterday, but just in case you avoid his blog in favor of mine, I'll blog the news, too. As you might have noticed from Kevin Lynch's Flash Platform white paper, we recently released the Flash / JavaScript Integration Kit (beta). The kit allows you to call JavaScript functions from Flash, and to call ActionScript functions from JavaScript. Not only can you invoke functions seamlessly across environments, but you can also pass most data types back and forth, as well, such as:
- Objects
- Arrays
- Strings
- Numbers
- Booleans
- Dates
- nulls
- undefined
The Flash / JavaScript Integration Kit works across all major platforms and browsers, and is available over at osflash.org for free under an open license based on the Apache 1.1 software license. Here are all the important links:
- Flash / JavaScript Integration Kit home page (get info and download the latest release).
- The project site (wiki and docs).
- The development site (hosted on Source Secure).
- The mailing list.
- The source tree (using Subversion -- very nice!).
- The Flash / JavaScript Integration Kit license.
Submit any bugs or feature requests at the development site. Check out the integration kit in action over at MXNA. And finally, if you build something cool with the kit, let me know.
Posted by cantrell at 11:16 PM. Link | Comments (11) | References
June 01, 2005
What Have We Learned From the Google Web Accelerator?
At the beginning of May, Google launched their Web Accelerator beta. A couple of weeks later, the beta was suspended with the message "Thank you for your interest in Google Web Accelerator. We have currently reached our maximum capacity of users and are actively working to increase the number of users we can support." The Web Accelerator had been receiving a lot of criticism around the web because of some of the techniques it was using to speed up browsing, like pre-fetching. In theory, pre-fetching URLs is not a bad thing, and according to the RFCs, Google was doing the right thing. In practice, however, it caused all kinds of problems since browsers were pre-fetching links in admin applications that would do things like cause records to be automatically deleted or otherwise altered.
The problem is that, technically, we (meaning web developers) should not be using GET requests to alter data in any way. GETs should be used only to request documents and other resources, and should be entirely safe for pre-fetching. We should be using POSTs for requests that affect data, which Google's web accelerator knows to stay away from. I've known this for some time, but I have generally disregarded this rule whenever it was convenient to do so. In fact, a couple weeks ago, I made a post entitled Why Distinguish Between GETs and POSTs? in which I provide a technique to combine FORM and URL ColdFusion variables into a single scope so that other ColdFusion code doesn't have to distinguish between the two types of requests. The post got a lot of good comments about why that may not be such a good idea in a post Web Accelerator world, and I now believe this technique should only be used by people who really know what they are doing, and even then, sparingly.
Sometimes it takes events like the launch of the Web Accelerator to nudge the web forward. I'm not sure Google or anybody else is going to be able to get away with extensive pre-fetching anytime in the near future, but now that they have raised our awareness, hopefully we will work toward creating an environment where pre-fetching is safe. I've always known that using GETs when I should be using POSTs wasn't kosher, but there were never any ramifications until now. Apparently, even Google is guilty of taking a shortcut here and there. I logged into Google Alerts this morning and found that I can delete and edit search terms by clicking on a simple link that performs a GET request. Good thing I didn't have the Google Web Accelerator installed.
Posted by cantrell at 11:14 AM. Link | Comments (7) | References
May 27, 2005
Which Firefox Extensions Do You Use?
One of the primary reasons I love Firefox so much is the all the extensions that are available. Here's a list of all the extensions I have installed, and that I use on a regular basis:
- Feed Your Reader: Lets external applications and web based aggregators use RSS autodscovery (extremely useful).
- HTML Validator: Adds HTML validation to the View Page Source of the browser.
- MeasureIt: Draw out a ruler to get the pixel width and height of any elements on a webpage.
- Scribe: Ads Word Processor like functionality to web forms, including opening and saving for entries as files. (Good for weblog posting.)
- Aardvark: Allows cleaning up a page prior to printing it. Also has page analysis tools for web developers (which is mainly what I use it for -- I hate printers).
- Web Developer: Adds a menu and a toolbar with various web developer tools.
- Live HTTP Headers: View HTTP headers of a page and while browsing.
- SpellBound: Adds spell checker support to web forms and extensions.
What extensions am I missing that you can't live without?
Posted by cantrell at 10:03 AM. Link | Comments (21) | References
May 10, 2005
I'm Looking for AJAX Applications
As you are probably aware, I've been working with AJAX techniques recently, and I've been very impressed, especially with the Flash integration we've been able to accomplish. And now I need your help. What are the coolest AJAX sites you've seen out there? I'm looking for sites that inspire and amaze!
Posted by cantrell at 03:20 PM. Link | Comments (13) | References
May 09, 2005
Flash and AJAX Integration Example
Kevin Lynch is at the O'Reilly AJAX Summit in San Francisco today and tomorrow. He gave a presentation to the group earlier today about integrating Flash and AJAX, and he demoed a cool new proof of concept Mike Chambers and I put together for him. We've integrated Flash and AJAX before for the MXNA reports, but the new MXNA Category Feed Report takes it to a new level by using two-way data exchange between Flash and JavaScript. First of all, click on the category names, and notice how the feed names reload below without reloading the page. Pretty standard "AJAX" stuff, really, but now click on a feed name and notice how both the Flash chart and the posts below the chart update without the page refreshing. When you click on a feed name, we're using JavaScript to pass data into the Flash movie which then updates itself using the MXNA web services. When you click on a bar in the chart, we pass data from the Flash chart into JavaScript to load the selected post at the top of the list. Overall, I think it's a very good experience.
Ajaxian is reporting on the summit, and wrote a good summary of Kevin's presentation. There will be lot more information available on how we did this with lots of code and documentation (along with a more generic, reusable framework), but for now, feel free to view source and steal. You can even right-click on the Flex chart and view its source, as well.
Posted by cantrell at 07:21 PM. Link | Comments (14) | References
May 03, 2005
Creating Custom JavaScript Alerts
Slayeroffice has a nice tutorial on creating custom JavaScript alert boxes. Custom alert boxes, in and of themselves, are nothing to write home about, but the slayeroffice tutorial suggests an interesting twist. Rather than calling your own alert function, like this...
if (foo) {
myCustomAlert("Hey, you can't do that!");
}
... they suggest actually replacing the default window.alert() function with your own. There's plenty of code in the tutorial, but here's the code that actually performs the magic:
window.alert = function(txt) {
createCustomAlert(txt);
}
What's the advantage of overriding the default window.alert() function rather than calling your own? First, it's way cooler. But second, it allows you to easily retrofit existing applications with new and improved alert boxes. For instance, most web applications include a common header, so in order to change all the alert boxes for an entire application, you can simply drop some new code in your application's header, and magically, all those ugly gray default alert boxes are transformed. Pretty cool stuff.
Posted by cantrell at 03:14 PM. Link | Comments (2) | References
April 21, 2005
I've Been Experimenting with AJAX
I did a new installation of MXNA 2.0 last night. In addition to adding "Most Popular" views (check out the new menu at the top on the right), I've also been experimenting with AJAX. Each post has an "Email to a Friend" option under it. Click it and give it a try. It exposes an email form and sends your email without ever refreshing the page. I think it makes for an improved user experience, and works great with ColdFusion and, after some tweaks, the MXNA 2.0 framework. Expect to see more AJAX features rolled into MXNA 2.0 in the future.
Posted by cantrell at 01:55 PM. Link | Comments (7) | References
April 11, 2005
IE Only Allows Two Simultaneous Connections
I didn't know this, but according to IEBlog, Internet Explorer only allows two simultaneous connections to any single domain. I knew there was a limit, but I thought it was higher. Anyway, IEBlog tells why, and what you can do as a developer to get around it.
Posted by cantrell at 02:58 PM. Link | Comments (2) | References
March 31, 2005
Rounded Corners Using CSS
My pal Ben Simon sent me this URL a while ago that describes a technique for creating rounded corners using just CSS and no images. Check out Nifty Corners for the full scoop. Hopefully you are
looking at an example right now, unless it doesn't work in your
browser for some reason (I haven't done extensive testing). If it
doesn't work, leave a comment here so people will know the compatibility
limitations.
Update: I have no idea why this wouldn't work in IE. An isolated version of the code works fine as do the examples. I suspect it's just buggy IE rendering, but if anyone can figure out why it's not working, and can suggest a fix, I will publicly shower him or her with praise.
Posted by cantrell at 02:54 PM. Link | Comments (10) | References
March 22, 2005
CSS XML Buttons
It's not rocket science, but here's an easy way to make XML buttons(or any kind of button you want) using CSS. In other words, this button (XML) is not an image, but is done all with CSS. I like using CSS buttons when I can because it gives me a lot of control over the look, and I can change the label easily without opening an image editing application. See? Christian Cantrell
Anyway, here's the CSS class:
.xml-icon {
padding: 0px 3px 1px 3px;
margin: 0;
text-align: center;
font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
font-weight: bold;
color: #fff;
background-color: #ff6600;
border: 1px solid;
border-color: #ffc8a4 #3f1a01 #3f1a01 #ffc8a4;
cursor: pointer;
}
Posted by cantrell at 11:15 AM. Link | Comments (3) | References
March 15, 2005
Advanced JavaScript Settings in Firefox
There are few things I hate more than websites that resize and/or move your browser. I don't visit a lot of sites that would tend to use such techniques, but every now and then, I'll come across one. I found one the other day (a watch-related site which I will allow to remain anonymous) at which point I decided I would not quit until I found a way to configure Firefox to not allow such poor JavaScript behavior. Fortunately, the solution was simple. Open up Firefox preferences, go to Web Features, and click on the "Advanced..." button next to JavaScript. You can allow or disallow the following:
- Move or resize existing window
- Raise or lower windows
- Disable or replace context menus
- Hide the status bar
- Change the status bar
- Change status bar text
- Change images
If your website relies on any of the functionality listed above, you might want to consider a redesign. I'm not saying that Firefox is about to take over the world (though I certainly wouldn't mind if it did), but I think it's safe to say that the trend is toward giving end users more control over their experience. And in the end, users will simply appreciate your site more if it behaves the way they want it to rather than the way you want it to.
Posted by cantrell at 02:14 PM. Link | Comments (1) | References
February 22, 2005
Extending Google Maps With JavaScript
If you're into Google Maps, check out Jon Udell's screencast demonstrating the Google Maps Route Animation Bookmarklet. Remarkable stuff. This project (consisting of a single line of JavaScript code contained in a single bookmarklet) shows some real creativity, innovation, and just plain smarts. But it also raises some other interesting possibilities.
Right now, there's a trend toward application extensibility, usually through web services, driven by companies like Amazon, eBay, Google, Flickr, etc. But that's all "server-side extensibility". Why not client-side extensibility? Are we witnessing the beginning of a new trend? I've experimented with bookmarkelts before, but it's fascinating how this one jacks into the existing JavaScript on the page to add very cool new functionality to the application practically as though it were native functionality. It's admittedly sketchy since Google's code will likely change someday, swiftly breaking the bookmarklet. But what if it were based on public, published API rather than some very clever reverse engineering? As applications become richer, will they start providing JavaScript and ActionScript APIs to allow third-parties to build simple client-side extensions? Will we start extending RIAs in the same way we extend Firefox? Man, I hope so!
Posted by cantrell at 10:39 AM. Link | Comments (2) | References
February 17, 2005
IE 7 Announcement: A Retrospective
I think it's been about three days since Microsoft announced that they will release a new version of IE. The announcement was so thoroughly blogged and discussed that I didn't bother blogging it myself (I was too busy reading what others had written), but now that the dust has settled, I want to offer my two cents.
First, if you haven't done so already, you might want to check out the official Microsoft press release. If you're in a hurry, I'll save you the trouble. Here's the most relevant excerpt:
Gates announced Internet Explorer 7.0, designed to add new levels of security to Windows XP SP2 while maintaining the level of extensibility and compatibility that customers have come to expect.
Next, read the post on the IEBlog. Again, I'll save you the trouble:
...we listened to customers, analysts, and business partners. We heard a clear message: "Yes, XP SP2 makes the situation better. We want more, sooner. We want security on top of the compatibility and extensibility IE gives us, and we want it on XP. Microsoft, show us your commitment."
What I'm hearing loud and clear here is that Microsoft wants to release a new version of IE for XP, and they want to focus on security. Now read the comments left in response to the post on IEBlog. They are far too numerous to even paraphrase here, and it would probably take you all day to read through them all, but just read a few at random and the message will be clear, which is that security updates are fine, but what Microsoft really needs to focus on is standards compliance and rendering. In other words, "maintaining the level of extensibility and compatibility that customers have come to expect" is not what customers are expecting.
Microsoft has put itself in an interesting position. They have publicly announced that they are listening to their customers, and are committed to giving them what they want, however they have also indicated that their agenda is not consistent with what it appears their customers want. I will reserve judgment, but one thing I will say is that it's not yet clear to me whether Microsoft has created an opportunity for themselves with this announcement, or for Firefox.
Posted by cantrell at 11:47 AM. Link | Comments (7) | References
February 15, 2005
If You're Having Trouble Starting and Stopping MySQL...
The first thing you want to do, I learned today, is look for a left-over MySQL configuration file from a previous installation. I installed MySQL 4.1 on a brand new server today, and two hours later, I still was not able to get it to run. I kept getting error messages indicating that the mysql.sock and .pid files couldn't be found. I was just about to give up computers forever and pursue a career as a farmer when I found a mention of /etc/my.cnf which can be used to configure things like the location of your .pid and mysql.sock files. "That can't be my problem," thought I, "since I didn't even create one of those files." Then it hit me. I checked /etc, and there was the my.cnf file from the default RedHat Enterprise installation of MySQL. Renaming the configuration file and restarted fixed the problem, and made me realize how needlessly I wasted the last two hours of my life.
I really don't like default installations of things like Apache and MySQL where files are spread all over the file system. When I get my hands on a brand new box, I like to install brand new versions of software, and I like to install them where I like to install them. Anyway, hopefully this post will rescue someone out there from the same fate.
Posted by cantrell at 06:33 PM. Link | Comments (4) | References
January 25, 2005
JavaScript Function to Automatically Focus Your Curser
Here's a simple JavaScript function that iterates through all the forms on a page and drops the cursor in the first text or textarea input it finds. Not rocket science, but useful. If you're building an application, you probably include a header from each page, so the way to use this function is to put it in your header (or better yet, source or include it from your header), and call it onLoad. That way, it will automatically work on any page in the application with a form on it. If a page doesn't have any forms, or you have a form with no text or textarea inputs, the function does nothing.
function focusCursor()
{
for (var i = 0; i < document.forms.length; ++i)
{
var f = document.forms[i];
for (var j = 0; j < f.elements.length; ++j)
{
if (f.elements[j].type == 'text' ||
f.elements[j].type == 'textarea')
{
f.elements[j].focus();
return;
}
}
}
}
Posted by cantrell at 11:18 AM. Link | Comments (3) | References
January 24, 2005
JavaScript References
Now that Netscape's JavaScript reference material appears to be gone, what are people using for online resources? Once I discovered DevEdge was no more, I resorted to some old-fashioned paper-based O'Reilly books. Today I started using Google to find some new online resources, and I'm surprised by how hard good ones are to come by. Any favorites?
Posted by cantrell at 01:57 PM. Link | Comments (8) | References
December 09, 2004
Time For a New Browser Survey
With the release of Mike Chambers' Macromedia News Firefox Extension, I figured it was about time for another browser poll. A year ago, I created a browser poll and found that IE was in the lead (among people who read my weblog, at least) with 49.55%. Firebird was in second place with 17.68%, Safari in third with 15.73%, and Mozilla was in forth place with 10.14%. The total number of responses were 1,233. If you have a second, take the new poll to the right and let's see where we are a year later.
Why is this information important? If you're a web developer, which I'm guessing you are if you're reading this, you already know the answer. Although we all try to make our work accessible to as many people as possible (which often means on as many different browsers and platforms as possible), it's almost always necessary to draw a line somewhere, especially now that many of us have made the transition from tables and fonts to CSS and styles, or even Flash or DHTML. Which browsers do you spend time testing on? Which browsers get highest priority? Is it ok if your app is broken or maimed in certain browsers? In order to answer any of these questions, you have to know the numbers.
I know that this poll is not necessarily representative of the demographic who uses our applications, but it's been my experience that the trends we see with technologists are often the trends which eventually make it into the mainstream.
Posted by cantrell at 12:03 PM. Link | Comments (8) | References
October 26, 2004
Are You Using a robots.txt File?
If you have a lot of 404s in your access logs from search engines looking for robots.txt, then this post is for you.
A robots.txt file in your web root can help search engines index your site's pages more efficiently by telling either all search engines, or just specific ones, which areas of your site to index and which areas to stay away from. Why is that important?
- Spiders can really throw off your metrics. I found that an aggregator I recently release was getting massive amounts of clicks in a particular category. A little investigation revealed that it was an MSN bot following links to my click handler, completely ruining any chance of gathering any type of meaningful data.
- Although you probably want most of your site indexed, there is no sense in drawing people to your site through search engine results that aren't really relevant. robots.txt files can help improve the quality of all search results which makes the web a better experience for everyone.
robots.txt files are quick and simple to write and put in place. Find out more at robotstxt.org.
(Note that robots.txt files are not a replacement for security. If you really don't want anyone to see a particular portion of your site, protect it with a password!)
Posted by cantrell at 11:37 AM. Link | Comments (0) | References
August 03, 2004
Using Images as Inputs
Just in case any of you have not seen this technique before, you can use images as submit buttons in your forms with code like this:
<input name="submitButton" type="image" src="myButton.png"/>
The client will send the X and Y coordinates of where the button was clicked as the parameters "submitButton.x" and "submitButton.y". The coordinates are seldom useful, however it is nice to be able to use images as buttons and have them work exactly as submit buttons do (without having to write any JavaScript).
These are all the basic ways of creating buttons to submit forms.
- Input of type "submit".
- Input of type "button" with JavaScript to submit the form.
- Input of type "image".
- Image with JavaScript to submit the form.
- Link with JavaScript to submit the form.
- CSS button with JavaScript.
- Flash button with JavaScript to submit the form.
Personally, I try to use standard submit inputs as much as possible since they tend to give users a familiar and consistent experience. Some might see the fact that various browsers render buttons completely differently as a disadvantage to using submit inputs since they feel it gives them less control over the look and feel of their applications, however I like the fact that users are presented with consistent and familiar buttons. I also like the flexibility of being able to use variable as buttons' values, and even being able to change their values client-side using JavaScript.
How do you like your buttons, and why?
Posted by cantrell at 11:27 AM. Link | Comments (3) | References
June 24, 2004
How to Create Navigation Like Macromedia's
One of the most consistent and frequently asked questions I see on the Macromedia forums is "how can I create a top navigation bar like Macromedia's?" Answers range from explanations and advice to URLs pointing to various DHTML and Flash projects.
I want to create the "Macromedia Top Navigation Bar Definitive Resource" right here on my weblog, so I'm posing this question to you:
What's the best way to create navigation like Macromedia's?
Here is your opportunity to promote your own projects, components, templates, or extensions. Promote a friend's work. Promote the work of someone you don't even know. Offer advice, tips, tricks, gotchas, etc. Post anything and everything you have to say about creating these types of navigation widgets. Then when I see this question out in the wild, I can point people to this post, or better yet, hopefully Google will uncover this post before the question ever gets posted.
Posted by cantrell at 10:44 AM. Link | Comments (15) | References
June 14, 2004
How to Implement an Image Upload Preview
Let's say you have an application that allows users to upload images, but you want them to be able to preview the image they are about to upload to make sure it's the right file before they actually upload it since uploading the wrong file costs time, bandwidth and disk space. Try browsing to a file on your local machine in the file input below and see if this trick works:
I put this very simple (but very useful) code together over the weekend, but I haven't tested it widely. Did it work for you? If not, what browser/platform are you using? Here's the code in case you want to use/modify it yourself:
<script language="javascript">
var imgRe = /^.+\.(jpg|jpeg|gif|png)$/i;
function previewImage(pathField, previewName)
{
var path = pathField.value;
if (path.search(imgRe) != -1)
{
document[previewName].src = 'file://'+path;
}
else
{
alert("JPG, PNG, and GIFs only!");
}
}
</script>
<div align="center">
<form name="imageTest">
<input type="file"
name="myImage"
size="30"/>
<input type="button"
value="Preview!"
onClick="previewImage(document.imageTest.myImage,
'replaceMe')"/><br>
<img src="images/clear.gif" name="replaceMe"/>
</form>
</div>
It should also be possible to use this code to do client-side image dimension validation, but I haven't written that part yet. I want to see how well this works first before going any further.
Posted by cantrell at 03:08 PM. Link | Comments (23) | References
May 11, 2004
Keeping Content From Caching
The tags below are what I use to keep dynamic data from being cached:
<cfheader name="Cache-Control" value="no-store" />
<cfheader name="Pragma" value="no-cache" />
<cfheader name="Expires" value="Tue, 16 Oct 1973 00:00:00 GMT" />
(The value of the "Expires" header is not some magical date -- it can be any date in the past. I usually use my birthday, just for fun.)
These headers address client-side caching (caching by the browser), and server-side caching (proxy servers that do caching, like those used by AOL). The "Pragma" tag is a little obsolete and has been replaced by the "Cache-Control" tag in HTTP 1.1, but I keep it in there just to be safe. These tags go at the top of my Application.cfm file, just below the CFAPPLICATION tag. So far, I have had pretty good luck with them, and they go in just about every application I write.
For more information on how AOL handles proxy server caching (something all web developers need to be aware of), check out this document published by AOL.
Posted by cantrell at 10:17 AM. Link | Comments (5) | References
March 25, 2004
ERD Tools
What are Macromedia developers out there using for ER diagraming? For small projects (meaning a few tables), I just use text files and write the SQL by hand. For larger projects, I have actually used UML tools with some success, and more generic tools like OmniGraffle. Last night, I decided I wanted something more sophisticated, however, that could generate SQL for me, so I downloaded a tool called XERD for OS X. So far, I'm pretty impressed with it, though I haven't generated any SQL with it yet, which I believe will be the true test. I like the fact that it's simple and streamlined, serving just this one specific purpose, and that it supports multiple databases (MySQL, Oracle, PostgreSQL, Sybase, and OpenBase).
What other tools are people using, for Windows, OS X, Linux and Solaris?
Posted by cantrell at 11:14 PM. Link | Comments (13) | References
December 08, 2003
ColdFusion vs Flash (the conclusion)
I finally finished both the Flash version and the ColdFusion version of the Community Resource Directory, and both are running and in use internally. I learned a lot, especially about Flash MX 2004, and I had a lot of fun building both interfaces.
I thought I would come out of this feeling like one approach was better than the other, however I really don't have a sense of one being superior in any way. Neither was faster or easier to build (well, maybe the ColdFusion version was a little faster because I had to update my knowledge of Flash and ActionScript, but that was one-time "cost"). And I also don't feel like either one provides a hugely superior experience over the other. Both clearly have their advantages and disadvantages, which I try to summarize below:
- I definitely like the immediacy and interactivity of the Flash interface. Different pieces of the application update themselves in realtime based on events fired from other parts of the application. For instance, the Flash interface consists of a data grid containing community resources. You can select one, then open up a details and/or an edit window which corresponds to the selected record. If you select a new row underneath the details and edit windows, both windows will immediately update themselves with data from the newly selected row. If you edit the record in the edit window, both the details window and the data grid will immediately update themselves. This makes the Flash version slightly more efficient to use since you're constantly loading very small sets of data so that you always have exactly what you need when you need it as opposed to having to refresh large amounts of data at less frequent intervals.
- I love not worrying about browser compatibility. When I was writing the CF/HTML version, I did some cool CSS effects which relied on the static positioning of elements. It worked fine on Safari and Mozilla, but fell apart on the Windows version of IE simple because the developers of IE chose to ignore the static attribute. We've all been dealing with these kinds of issue for many years now, and I don't feel like it's getting any better. The issues change over time as browsers evolve, but they never go away. Developing in Flash was great because all I had to worry about was whether people had the plugin or not.
- Although Flex is amazing technology, there is something to be said for being able to design your interface by dragging and dropping UI elements, which is an advantage Flash has over the HTML world. Yes, you can use WYSIWYG HTML tools, but with Flash, what you see is really what you get in any browser on any platform. This is by no means a limitation of WYSIWYG tools like Dreamweaver -- it's just the nature of HTML web development.
- Although Flash makes it very easy to display record sets in many different components -- allowing you to map data as opposed to having to loop through record sets -- I also really like how large amounts of data sets end up being rendered in HTML. It's fast, and you can display thousands of records before size really becomes an issue (especially with internal applications), and your tables can easily span the width of the browser, giving your user plenty of room to work with. Using CSS for all your styles and layout, and tables for your actual tables (as opposed to using tables for your layout) allows your pages to be small, well organized and functional.
- Although I like how well designed HTML tables are rendered in browsers, it's a pain to implement sorting manually. One of the biggest advantages of using Flash and the data grid is that sorting (and column resizing -- almost impossible in HTML) is built right in. Although if you are accustomed to building reporting type applications in CF, sorting usually doesn't take much time to implement, you still can't beat having it built right in.
- I also really enjoyed having all the different UI widgets that come with Flash. I can't believe that I'm still using the exact same form elements to build HTML applications now that I used five years ago. There hasn't been a single form element added to the HTML specification since I started doing web development many years ago! All you have are text fields, text areas, password fields, check boxes, radio buttons, select lists, buttons and file fields. Although you can obviously do quite a lot with these, I love having things like numeric steppers, calendars, editable combo boxes, menus, etc.
- Customizing a specific column in a Flash data grid is not overly easy. You have to use a custom cell renderer, which seemed like a lot of work just to get a movie clip to display in a cell rather than a piece of data. On the other hand, it just seems like a lot of work compared to the almost no work that goes into rendering just plain data. It seems easier to customize table cells in HTML/CF (for instance, to drop a little icon in a cell rather than just a number or a string), however that's probably only because you are already going to all the trouble of iterating through your record set manually anyway. It all probably comes out even in the end.
- As limited as HTML inputs are, they do provide a way to upload files which is conspicuously missing from Flash. It's not something I need often, but when you do need it, it's hard to get around.
- I found the development process itself (the process of changing code and viewing the results) slightly more streamlined with ColdFusion since with CFMX 6.1, changes are compiled and visible almost immediately whereas with Flash, you have a somewhat lengthy compile process. On the other hand, there is generally less guesswork and experimentation with Flash in terms of layout, etc., so in the end, it probably all balances out.
- Both make great use of web services, however I discovered that you cannot send an array as a property of a complex type from Flash which was a problem. I had to re-factor some code to use lists rather than arrays, which felt a bit like a hack, but wasn't the end of the world. Anyway, I believe it's a bug in Flash, but that is still being determined.
- Since I'm not a designer, I found that it was easier to get the Flash interface to look decent than it was the HTML version. Although since I used all CSS for the HTML version, a designer could probably just make a few tweaks to my CSS file and make the whole app look much better, the Flash version looks great right from the start without having to do any design at all. Thank god for Halo.
So I guess what it comes down to is analyzing your requirements and making an informed decision from there. Both Flash and ColdFusion are great for building web applications, so let your requirements and resources determine which one you pick. In the meantime, I'm going to check out Central and see what advantages it offers!
Posted by cantrell at 12:49 PM. Link | Comments (5) | References
November 26, 2003
target = _blank = annoying (Part II)
I got a lot of good comments on yesterday's post. So many, in fact, I feel compelled to post a follow-up.
First of all, I should make it clear that I don't view anyone's opinions as "wrong." It's just a healthy debate which I believe ultimately comes down to preference. Anyway, enough disclaimer. Here it goes:
A few people commented that most users don't know they can shift/command/right-click on links to have more control over how pages are opened. If someone is not savvy enough to shift-click, are they savvy enough to understand that when they click on a link with a _blank target, a new browser instance is opened which they must close rather than clicking on its disabled back button? That's not really an issue on Macs because it's pretty evident that a new window has opened, but on Windows, if the browser is maximized to fill the entire screen (which I'm guessing is the norm), it's much more difficult to tell that a link opened a new window. Windows users out there, is that correct?
It is in fact true that opening a link in a new tab will do the right thing whether the target of the link is _blank or _self, so when intentionally opening links in new tabs, I'm happy regardless of the target. What is frustrating, however, is when I click on a link with the intention of replacing the content I'm looking at, and it opens an entirely a new window. For some reason (probably because I'm addicted to tabbed browsing), I have come to believe that people should not be opening new windows and cluttering up my desktop without my permission. (More on tabbed browsing below.)
It is also very true that sometimes you don't want to completely take someone away from what they are doing just to follow a link. I completely understand and agree with that. For instance, if someone is filling out a payment form, then decides they want to read your privacy policy, you don't want to replace the page with the payment form with your privacy policy. No matter now you look at it, you have just decreased the chances that the user will complete the transaction. My approach, therefore, would be to open a small pop-up window containing the information they need so that it is clear they can close it and get back to what they are doing. I would not open a new full-sized window out of fear that my users would not realize it was a new window, and feel lost. I think scaled down pop-ups (used sparingly) can help users keep their bearings better than using blank targets.
Finally, I agree with Modius that this is probably a complaint more likely to come from people who use browsers with tabs. If you are used to using tabs (or the "snap back" feature of Safari -- very cool concept, but I haven't gotten used to it yet), you probably want to make the decision yourself as to how links open. You are used to having more control, and have probably come to loath having more than one one browser window open at a time (which is the case with me). If you don't use tabs, you may appreciate sites who try to help you navigate more efficiently by using the occasional blank target.
Ok, back to tabs. Personally, I can't imagine using a browser without tabs. I started using them with Mozilla, and couldn't use Safari until the second beta when tabs were introduced (probably the #1 requested feature since so many of us were coming from Mozilla). I had to install Firebird on my wife's computer because I couldn't stand to use IE when surfing the web upstairs. Even something as simple as reading the news is much more efficient with tabs, in my opinion. I recommend that those who have not tried using tabs do so immediately. Today. Right now. (Can IE be made to use tabs?) My guess is that most of you will never go back.
I think it all comes down to being a matter of consistency. There's a time and place for inconsistency, creativity and spontaneity, but that place is not user interfaces. I really like the suggestions of using different link styles for different effects (solid lines for target=_self, broken lines for target=_blank and mailtos, etc.), but I also agree that it's a hopeless crusade. As more and more people discover the power and convenience of CSS, I predict we will actually see less consistency and more "creativity."
(PS: Take the new poll, and let's get some idea of how many people are using tabs out there.)
Posted by cantrell at 12:55 PM. Link | Comments (12) | References
November 25, 2003
target = _blank = annoying
How many people use target=_blank to open links in new browser windows? I used to occasionally do so whenever I felt it made more sense to preserve the content of the window containing the link. Now, however, I feel quite differently. I have come to believe that it should be up to the user to decide where the link should open up: in the same window, in a new window, or in a new tab. I think shift-clicking, command-clicking and right-clicking are well enough understood by the general public at this point that we can all stop assuming we know what the user wants and start letting them choose for themselves.
What really annoys me is when people use target=_blank when linking to other sites because they don't want the user to leave their website. If you don't want users to leave your site, don't put links to other websites on it. And what really annoys me is when people use JavaScript to either resize or reposition your browser for you, as if they know more about how your desktop should be arranged than you do.
Ok, I'll stop griping now. Just had to blow off some steam. Back to work.
Posted by cantrell at 05:18 PM. Link | Comments (29) | References
October 23, 2003
Customizing Unordered Lists
I occasionally see people on lists and forums asking how they can customize bulleted lists. This is about all you need to know:
.disc {list-style:disc}
- this is
- a disc
.square{list-style:square}
- this is
- a square
.circle {list-style:circle}
- this is
- a circle
.image {list-style-image:url(http://www.markme.com/cantrell/images/mm_bullet.gif)}
- these are
- custom bullets
Posted by cantrell at 03:12 PM. Link | Comments (5) | References
September 23, 2003
Mad Scientists at Google
If you haven't done so already, check out labs.google.com. As Google describes it, labs.google.com is Google's "technology playground" and has some very cool functionality including Search by Location, News Alerts, Google Glossary, Voice Search (can anyone get this to work?), Keyboard Shortcuts and a few others. It's great to see a company play around with technology like this for no other reason than to have some fun and learn.
Posted by cantrell at 02:23 PM. Link | Comments (1) | References
August 28, 2003
Which Editors Do You Use, and Why?
With the announcement of Dreamweaver MX 2004, there has been a lot of talk about editors out there. Which editor(s) do you use, and why?
Me? Well, I use a few different editors. I use Dreamweaver sometimes as it's the most feature rich editor I have at my disposal. I like the simplicity and speed of TextPad for some things when I'm using my Windows machine, which isn't very often. And although I know it sounds strange, I probably use vim (VI Improved) more than anything. I'm the kind of person who likes to use one editor for everything, which makes vim perfect. Not only can I use it for all types of code, but I can use it everywhere, on any platform, even over an SSH connection, which is very important for me.
I'm guessing that vim is actually one of the least popular editors out there for ColdFusion and Java development, so what else are people using? Dreamweaver? TextPad? EditPlus? ColdFusion Studio? Homesite? jEdit? Eclipse? Emacs? Something I've never heard of? Make sure you mention what it is about your editor that you like.
Posted by cantrell at 12:03 PM. Link | Comments (37) | References
July 22, 2003
Using JS to Close a Window You Didn't Open
We all know it's impossible to use JavaScript to close arbitrary windows, right? One of the first things you learn when playing with opening and closing windows with JavaScript is that, for security reasons, you can't close a window that you didn't open.
Well, as it turns out, you can, as I recently learned from this post on ASP Alliance. I won't reveal the secret here, but if you want proof that it works, here it is:
This is a traditional attempt to close the main browser window. It shouldn't work in most browsers -- at least not without prompting. This, on the other hand, is an attempt that should work. Goodbye.
Posted by cantrell at 11:42 AM. Link | Comments (11) | References
June 11, 2003
Site Statistics - An Informal Poll
What tools do people use to gather site usage statistics? WebTrends? SiteCatalyst? Home-grown Perl or shell scripts parsing Apache access logs? What are people willing to pay for these types of solutions, and how important is it to your business? If you don't mind, when commenting, please indicate how much traffic your site gets.
Posted by cantrell at 03:08 AM. Link | Comments (10) | References
May 27, 2003
DevEdge: Netscape's Web Development Resource
If you don't use devedge.netscape.com already, you might want to check it out. I mostly use it as a JavaScript reference, but it's a good resource for things like CSS, XML and HTML, as well. It's laid out well, easy to navigate, and, best of all, you can check out the Amazing DHTML Fish Tank (best viewed on Netscape 7, naturally).
How many of you out there already use DevEdge? What other web development resources do you use?
Posted by cantrell at 02:00 AM. Link | Comments (2) | References
May 23, 2003
Using "rdate" to Keep Your Server's Time Accurate
I don't know why servers' clocks tend to drift (if someone knows, please explain), but the fact is, they do. Having the wrong time on your server can be a problem for various reasons since time stamps are used in several decisions that the server has to make as well as for debugging and logging. Plus it's just really annoying. In fact, it's so important to me to know the right time that I wear a watch which synchronizes with an atomic clock in Colorado over radio waves three times a day. Maybe that's going a little far, but it's certainly not too much to ask of an expensive, high-end server to maintain the correct time.
As I was setting up a new server last night (whose time was hopeless off), I decided to experiment with "rdate". rdate uses NTP, or Network Time Protocol, to get the time from a network, and either print it out or set it on the server. I have only used it on Linux and OS X, so I don't know if it is supported on Windows, but I would image there is either a Windows equivalent, or you can get the actual rdate program with Cygwin (if you don't use Cygwin, I highly recommend it).
The next step was to find an NTP server that kept accurate time. I found a list of servers here:
http://www.eecis.udel.edu/~mills/ntp/clock1a.html
Although the list was last updated on May 8th, I only found a few that actually worked. I'll save you the trouble and list them here:
Washington DC area:
- nist1-dc.glassey.com
- 205.188.185.33
Texas:
- tick.greyware.com
- tock.greyware.com
I found that the two servers in the DC area were exactly in synch with my watch (at least down to the second) while the two servers in Texas were about .5 seconds off. To get the time from an rdate server, type:
[wednesday:tmp]$ rdate -p tick.greyware.com
The last step was to set up a cron job (or on Windows, a scheduled task) to update the time on a regular schedule. To have rdate actually set the time on your server using the time from the network, use the "-s" flag:
[wednesday:tmp]$ rdate -s tick.greyware.com
(Note that you have to root to change the time on the server.)
Now I have the time automatically synchronized daily on my new server. I just hope the time on the NTP server doesn't start to wonder now, or the time on the atomic clock in Colorado, for that matter. Then I will really be lost.
Posted by cantrell at 10:38 AM. Link | Comments (2) | References
May 22, 2003
CVS Tip: Find Out Exactly Who Made That Change, and When
How many CVS users are there out there? Have you ever updated a file with a bug in it, and had everyone on your team deny having made the change? Use CVS annotate to find the culprit.
The command (from the command line) looks like this:
[wednesday: templates]$ cvs annotate someFile.cfm
The result will be a line-by-line account of who made the last change to the line, and when. And despite many developers' claims, CVS does not make mistakes!
Daemonite recently posted a cool CVS tip, as well:
http://blog.daemon.com.au/archives/000151.html
Posted by cantrell at 09:40 AM. Link | Comments (1) | References
May 20, 2003
Browser Detection with BrowserHawk
There is a new article on DevNet about using BrowserHawk to do some very advanced server-side browser detection. You can check out the article here:
http://www.macromedia.com/devnet/mx/flash/articles/browser_hawk.htmlBrowserHawk will let you detect Flash player presence and version along with just about anything else you could possibly need. For a quick sample, go to the page below and scroll down a bit:
http://www.cyscape.com/showbrow.aspFind out more about BrowserHawk here:
http://www.cyscape.com/products/And now for a quick survey:
- Are you currently using BrowserHawk?
- Have you ever tried BrowserHawk?
- What other packages do you know of that are like BrowserHawk?
Posted by cantrell at 11:35 AM. Link | Comments (8) | References
May 12, 2003
TheServerSide Features Talk By Macromedia Software Architect
TheServerSide.com is featuring a talk by Sean Neville, the JCP Executive Committee representative for Macromedia and Flash Remoting software architect. From TheServerSide's site:
Sean talks about Rich Internet Applications (RIAs), how they can be used to aggregate the business tier and enterprise applications using the client and looks at architectural approaches and technologies used for designing RIAs. He discusses how the J2EE Petstore was implemented in Flash, how the Flash Remoting product enables interoperability between J2EE and rich clients, and examines why vendors are trying to attract a new 'VB-style' group of developers. He also looks at changes that need to occur in the industry for RIAs to become mainstream.
Check it out here:
http://www.theserverside.com/events/index.jsp
Posted by cantrell at 01:48 PM. Link | Comments (0) | References
May 11, 2003
Git Rid Of Annoying Line Breaks From Form Tags
If you are very particular about your page layouts, the last thing you need are HTML elements like the <form> tag conspiring against you by adding arbitrary line breaks for no apparently reason (at least it seem arbitrary to me -- if anyone knows why the world the form tag behave like this, let me know). The old way to solve the problem was by putting your form tags between table rows or outside of table cells. It doesn't make for particularly well-formed or pretty HTML, but it made the problem go away. But what do you do if you are using cascading style sheet positioning, so you don't have any table tags to sweet extra line breaks under? All you have to do is drop the following line in your stylesheet, and you will never have to worry about it again:
form {margin: 0px 0px 0px 0px; }
Of course, you can also use this technique to add wanted and controlled spacing to your form, as well. The areas that the numbers represent are, in order, top, right, bottom and left.
Posted by cantrell at 11:33 PM. Link | Comments (12) | References