I’ll assume you know raw JavaScript and a little raw Node. Enough JavaScript to be familiar with the DOM, anonymous functions, and callbacks. You dont have to know React or anything of the sort.
First up, Learn enough to recognise the new syntaxes in ES2016, along with promises, arrow functions, generators and async await. You don’t have to be good at them; just be able to know how to read them.
Now learn enough Node and NPM to start a vanilla Express server and realise how much work it would be to write a whole fully featured web application in it.
Now quit jQuery, cold turkey.
If you come from using a Rails-like framework such as Rails, Django or Laravel, the though of scouring NPM for all the packages you’ll need, you’ll be wanting someone to make opinionated decisions about the right packages for the job for you. May I suggest Adonis.js. It comes with all the MVC, Authentication and ActiveRecord stuff you’re used to, along with loads of other good stuff too. You’ll have a good reason to learn about Generators, Promises and async await here.
Resist the urge to jQuery.
If you want to write your front end as a single page application (SPA), to run in front of your API, you could use what you’re familiar with, or you can start afresh with Vue.js because it has the gentlest learning curve of any of the mainline frameworks, all the best stuff from the other frameworks, and you don’t even have to learn a bundled/compiler if you don’t need it.
Vue is easy to learn, easy to adopt, and you’re never forced into complicating things too early. Go at your own pace, and eventually you’ll learn about components, which will change everything. Get started with Vue’s single file components and never look back.
With Vue, you don’t need a router out of the box, until you know you do. You also don’t need state storage until you know you do.
You want to write a universal app, or use Material design you can do that when you want. Heck, you can even bring in JSX if you’re feeling that. And you dont have to add any of these packages to your project, until you need it, and in any order.
tl;dr: Learn enough JS and Node to spot new JS language constructs, starting with Adonis will give you a reason to learn the new stuff while giving you an easier path to success.
Disagree? Got a easier, faster path to productivity and learning all this crazy JS? Chime in below, or hit me up: @Glutnix on Twitter.
]]>Sure, I did spend some time ‘upskilling’ at work doing the design and html template, but I got the whole WordPress skin done in about 4 hours.
I based it off of the Classic theme (y’know, the ugly default theme) and tweaked the living daylights out of it, adding extra template files.
I’m quite happy with how it came out. What say you?
]]>Want more details on this? Check out Brett’s Arduino Reaction Game in the projects section.
]]>I’ve been volunteering at Catalyst IT working with Brenda Wallace to work on projects of her choice. She assigned me to work on Laconica (an open-source version of Twitter that works in a distributed fashion). In order to do so I’ve had to learn a little about many different technologies, like PostgreSQL, the weirdness of Apache+PHP on MacOS X 10.5, and overall, how to checkout and contribute code to an open source software project with Git.
I’ve now had three code merges into Laconica, albeit very minor ones, mostly fixing bugs.
I don’t even use Laconica. (Twitter is working just fine for me, thanks.)
But I feel great.
Computer programming is something some have described as the most complex thing humans have invented — it’s all abstract, there are few corollaries to it in nature. Probably the only thing more complicated is quantum mechanics (but that is, in fact, nature).
My job is to explain, demonstrate, and encourage people who have never programmed a computer in their life (let alone their VCR) to create rather complicated things we call websites.
Why have I enjoyed contributing patches so much to an project I don’t use or much care about? A couple of reasons:
The elusive Zone has many names; Wikipedia refers to it as “flow“. It’s that state of being you get when they’re so intensely focussed in the task at hand that time and reality become irrelevant because you’re so energised and focussed and involved at what you’re working on, and having good success at doing it. You come away feeling elated and energised that you’ve completed something of value.
I haven’t been in The Zone for nearly four years. I’ve been teaching people how to program for nearly four years now, and nary the mind to knuckle down and flex my coding muscles. I’m too worked up with office politics, helping my workmates with the technology, and thinking that I wasn’t good enough to be in the industry.
It’s good to know that I can do it, though to do it professionally, I’d just need to learn more about the processes involved.
I’ve had to learn how to use Git, how to create PostgreSQL users and databases, and submit my finished code to the project administrators for merging with the mainline version of the program’s code.
I don’t normally get to be a learner. I’m a full-time teacher, and what I have to learn is usually because I need to teach it.
It’s nice to learn things for me and me alone. I may never get to teach what I’m learning here, but what I’ve learned is helping fulfill me (more on that later)
That old adage “Those who can, do. Those who can’t, teach”. It’s lies.
Actually I’m a tutor, but that’s just a particular kind of teacher. Not meaning to blow my own horn, but according to my student evaluations I am actually a really good tutor. Sure, I have my weaknesses, but overall, apparently I rock at it.
And I really enjoy teaching. It’s rewarding when the metaphorical light-bulbs turn on above the student’s heads. Some of them slowly brighten, some just pop on, and some of them shine more powerfully than others, but the lights do turn on. To know that a learner now understands one of the most complicated things there is to know,
I was at Wordcamp New Zealand here in Wellington over the weekend, and Nicki Gemmell was talking about using blogs at primary schools around New Zealand. She related how uploading an image to a blog was something a principal got excited about: “I uploaded a photo to our school blog today; how cool is that?!”.
As a programmer who has written photo upload functionality, I forget how far I have come and how valuable the skills I have really are. The challenge of teaching people to do things is fun and rewarding. Teaching students to do this even more complicated stuff is the same but even more challenging.
Teaching programming, from my own experience, is the ability to communicate the concepts and foster the understanding and use of them. I was told by a trainer there were four levels of competency:
1. Unconscious Incompetence – you are unaware that you don’t know how to do X.
… awareness brings:
2. Conscious Incompetence – you are aware that you don’t know how to X.
… learning brings:
3. Conscious Competence – you can do X, and you are thinking about it when doing it.
… practice brings:
4. Unconscious Competence – you can do X, but you do not have to think about it when doing it.
I say that there’s a fifth level: where you have become once again conscious of what it is you are competent at. And that’s the level where you’re ready to teach it.
To be able to teach, you must be able to learn, and then go further so you can show others the way.
Those who can teach, do teach.
Okay, I’ll be honest: being around Brenda and the other like-minded geeks at Catalyst IT has been a really energising experience. Being able to vent frustration at code and technology, bounce ideas off each other and have fun while doing it has been great.
But working on Laconica and spending some time reading other peoples code and improving it, and learning the technical, and social aspects of doing so has been fun and very enlightening.
My motivation for staying a teacher has been pretty simple: Hell is other people’s work. Most of the employment in the industry has been creating websites for companies; wish fulfilment for others. I could change the world one organisational website at a time, or I could change the world 20 web students at a time.
But working on an open source project has let me use my programming skills to directly improve, ever-so-slightly at this stage, the lives of people around the globe. By making the software they use better.
Having that sense of purpose in what I are doing is really important to me. I don’t want to just be working to collect a pay check: working to live. And I don’t want to be living to work either. I just want to do what is worthwhile while I’m alive: live life to the fullest. Use the abilities I have to do things worth doing.
I am a teacher. I am a programmer. I’ve been neglecting the programmer side of me.
]]>“Computer programming is tremendous fun. Like music, it is a skill that derives from an unknown blend of innate talent and constant practice. Like drawing, it can be shaped to a variety of ends – commercial, artistic, and pure entertainment. Programmers have a well-deserved reputation for working long hours but are rarely credited with being driven by creative fevers. Programmers talk about software development on weekends, vacations, and over meals not because they lack imagination, but because their imagination reveals worlds that others cannot see. Larry O’Brien and Bruce Eckel
Jakob Nielsen’s Alertbox, June 23, 2009: Stop Password Masking
Usability suffers when users type in passwords and the only feedback they get is a row of bullets. Typically, masking passwords doesn’t even increase security, but it does cost you business due to login failures.
This sounds like Nielson kicking up publicity. This is shorter than his normal articles and he hasn’t backed this one up by mentioning his latest rounds of usability tests. He’s often got really good points, but this is one that I have issue with.
Nielson has forgotten that the reason password masking exists is if you type it out but don’t submit the form right away, then it won’t be on the screen for a long length of time for passers-by to ‘shoulder-surf’. The form could be really really long and/or you might be a really slow typist.
Padlocks and deadbolts keep honest people honest. The same goes for password masking.
Not to mention that password masking is visual shorthand reminder for the personal habits of “you should remember what you right in this box, cos even you won’t see it” and “no-one else should see this but you”. If we removed this ‘tell’, what would become of the culture of ‘protect your password’?
Think of where, other than web sites, that password masks get used. ATMs, EFTPOS machines, computer software, the Operating System uses it. Western culture is conditioned to this design pattern, and I speculate that the only people who have trouble remembering passwords are the ones who were born before 1980.
I guess a compromise would be to have the field in plain text when it has focus, switching to a password mask on blur…? Not a difficult solution.
]]>Just curious as to what your IDE of choice is for PHP development and why?
You’ll see that I replied with the following.
Being nearly Mac-exclusive, I do most of my coding in TextMate, and any text manip in TextWrangler (it has superb grep/regex capabilities).
I don’t use an IDE, but if I was to use one, it’d be something like Coda or Espresso.
If I wanted to use a cross-platform, free IDE that isn’t half bad, but is based on Eclipse, I’d use Aptana for HTML+CSS+JS+PHP support. It’s nice because it has built in support for Firefox and Safari, (and IE when you’re on Windows).
Once enabled, you get access to a staggering amount of icons! To be exact, 469 symbols, ranging from smiley faces to weather icons, flags, animal faces, (clean) hand gestures, and much more. Here’s what they all look like, screen-grabbed right on my iPhone after I put them all in an email. FYI, scaling has occurred, these are not perfect.
The trick here is that while these icons look fantastic on the iPhone, when sent in SMS text messages and emails, the beautiful pictures you see above are sent as Unicode characters, as they came through to me via my Gmail:
…
These characters are part of the Private Use Area of Unicode. Which is why, if you’re viewing this page on a browser not running on an iDevice, you will see a whole slew of question marks or boxes with little letters in them, followed by the copyright, registered trademark and trademark symbols.
Doing some more research, it turns out a bug has been filed on OpenRadar outlining how Apple’s implementation isn’t even that compatible with NTT DoCoMo’s de-facto standard on ‘Pictographs’, even though it would seem they’ve implemented every single icon in that standard.
I’m not expert, but it seems that pre-Unicode, Japan standardised on Shift-JIS, a modification to ASCII that would allow the storage and display of the Japanese Hiragana and Katakana characters that make up Japanese written language. This was pressed forward into the design and manufacture of the Japanese handsets, and even into the operator’s networks, and for the time being, this means both NTT DoCoMo, the biggest telco in Japan, and Softbank, the telco serving iPhones in Japan.
NTT DoCoMo created the defacto standard on emoji on Japanese mobile phones, and have outlined the character encodings for both Shift-JIS and Unicode. Every handset in Japan supports this standard.
When the iPhone was first released, it apparently was criticised in Japan for not supporting the sending and receiving of emoji glyphs. Eventually Apple got around to it, but according to rdar://6402446, iPhone Firmware 2.2 currently implements the encoding of emoji using Unicode characters in the private use area, but not the same private use characters as the NTT DoCoMo Pictographs standard.
So it would seem that, to cut a long story short, Apple’s emoji are directly incompatible with every other handset in the world.
According to Apple, Softbank doesn’t even do translation for iPhone SMS to other Japanese handsets. It will however, translate emoji in emails, but only if you have a Softbank email address and SIM.
And because the rest of the world doesn’t have handsets that work with emoji, that’s why Apple only enables the emoji keyboard for phones with Softbank SIMs.
Still, it wouldn’t be too difficult to write a script to support emoji characters in your web app, supporting both NTT DoCoMo Unicode and Apple Emoji Unicode. Apple have done a nice job with their icons. Interesting times.
Sources:
Done using simple CSS and a nice bit of JavaScript, but nothing too advanced, and without any libraries!
Enjoy it!
]]>urlTea
A Web 2.0 look at the Short URL services. Light, simple interactivity. Intuitive design. And even an API! I’ll probably GPL it soon too…
Your thoughts?
The extension for Firefox just went 1.0 final (heh, a Web 2.0 tool coming out of beta), and that’s a big deal. Joe has been working on Firebug for just over a year, and it has become a tool more indispensible than even Chris Pederick’s Web Developer extension!
What? You don’t have either of these?! You call yourself a web developer? Let me guess, you still think IE is the only browser worth developing for, and heck, you probably believe that developing to Web Standards is just elitist acadamia… get with the program. Why leave the interpretation of your code to tag-souped chance?
… Eh-erm. Sorry about that monkey I had to get off my back. I heard a rumor yesterday and my anger has found its vent.
But seriously, all those IE die-hards that are still out there today should be amazed at what tools our industry-standard (as opposed to the de-facto-standard) web browser we call Firefox makes available, let alone makes possible.
Since Mozilla 0.7, I’ve found it’s more time-efficient to develop in a Gecko-based browser, then bug-fix for everything else — because it’s much harder and stressy to start in IE and bugfix to Gecko. I’ve found this true for all the technologies: CSS, JavaScript, XSL, AJAX, and now SVG
Viva la revolución! Viva la web standards!
]]>You can now update from your Mac OS X Dashboard, with my first ever Dashboard Widget Twitterlex. It displays the latest status messages from your friends, and provides a quick access way for you to update your own status easily!
]]>import JSON; // http://www.theorganization.net/work/jos/JSON.as
var jsonFetcher:LoadVars = new LoadVars();
jsonFetcher.onLoad = function(success:Boolean) {
if (!success) {
trace("Error connecting to server.");
}
};
jsonFetcher.onData = function(thedata) {
// ...
// if writing a desktop app or widget, string manip or regexp
// the JSON data packet out of the JS source provided by many
// web services at this point..
// ...
try {
var o:Object = JSON.parse(thedata);
//mytrace(print_r(o));
trace(print_a(o));
} catch (ex) {
trace(ex.name+":"+ex.message+":"+ex.at+":"+ex.text);
}
};
// get the feed
jsonFetcher.load("url-to-json-feed.php");
// from: http://textsnippets.com/posts/show/633
// recursive function to print out the contents of an array similar to the PHP print_r() function
//
function print_a(obj, indent) {
if (indent == null) {
indent = "";
}
var out = "";
for (item in obj) {
if (typeof (obj[item]) == "object") {
out += indent+"["+item+"] => Objectn";
} else {
out += indent+"["+item+"] => "+obj[item]+"n";
}
out += print_a(obj[item], indent+" ");
}
return out;
}
BTW, what’s up with these JSON feeds that serve up JS that’s JSON plus some more code? That’s annoying — you gotta strip it out before you run the JSON converter :P.
Update: here’s the actionscript 2.0 JSON.as file people were looking for.
]]>So we did. And let me tell you, I’m really happy with how it turned out. It’s nothing revolutionary or taxing, but it was heaps of fun to redesign and make the templates as we went, with Michelle right there working with me.
This comment from The Abandonware Blog about Bunny Abandonware 4.0 really made me feel good:
Finally some nice scene news! Bunny from Bunny Abandonware has been mentioning is for quiet some time now but finally managed to get the new version of her website online and I must say (again) that it kicks ass! The unique colors used by only one abandonware site, the wonderfull [sic] navigation, the nice kinda web 2.0 style with all the gradients and big buttons ‘n stuff… damned pretty.
LOL, I did some Web 2.0 :rolleyes: But I’m taking it all as a compliment. I believe that what Michelle does with her abandonware hobby is crucial for the survival, not just of the games, but of the memories. Abandonware, while legally dubious, is less a case of stealing and more the case of paying tribute. I keep telling Michelle she’s not just another retro gamer; she’s an archivist — the curator of her own museum. A museum where the exhibits remind her visitors of the way video games used to be, and where not only games, but ourselves as people have come since then, for better or for worse.
I think the best Christmas present I gave myself was when for Christmas I gave my brother a huge pack of water balloons . I had moved out of home to Wellington and I had come to realise that I missed him. We had fun in that back yard that one day, running around with the sole purpose of cooling off and having a blast. But I did it with the motive of having that memory to look back on — a careless, happier day in my history. It worked, and it’s one of the most cherished memories I have. It didn’t cost a lot.
Memories are worth gold, but the most valuable memories are the ones that cost the least.
]]>Gosh, there’s a bit there. Does that count as only one?
Yet recently I’ve bought so many DS and GBA games for my Nintendo DS Lite, and haven’t clocked any others
Bob Brown (Confessions of a Guru), Hamish MacEwan (self titled), Hillary (Kiwirose in Canada), Dan Milward (Mind of Mufasa) (fix your feeds, they’re broken), and Unbounded (self-titled), even though Unbounded is the kind of guy who would abhor this kinda meme; TAG – You’re it!
]]>Tomek, Nahum, and I are organising a Rails session for newbies this month. We aim to make it the best Rails session yet. We’ve organised some books to give away, a discount for O’Rielly, and will be putting on Pizza (and hopefully beer if we find a sponser. The session will be about building a basic blog app, but the overriding theme will be to get the uninitiated but curious, and the beginners along, and give them a taste of the good stuff. We aim to nuture their curiousity into a love of Rails – which will benefit the entire Wgtn software development scene.
What: Getting started with Ruby on Rails – a community based approach
When: 6:30pm, Tuesday, 31st October 2006
Where: CreativeHQ, 25a Marion Street, Te Aro, Wellington (behind Resene Paint)
Presented by: Nahum Wild
Intended audience: Anyone interested in Ruby on Rails.
Prerequisites: Interest in Ruby on Rails. Knowledge of programming in any language will be useful during the live demo.
Refreshments: Hell pizza
Cost: Free. It’s a community event. It is our turn to give back.
The format will be as follows:
Interested? Only 12 places left… Find out more about this event! I’m looking forward to this one…
]]>Quinn is an implementation of a popular falling-blocks game which, according to the Tetris Company, must not be named here.
ROFL. You got served, Tetris Co.
Seriously, Quinn is a really good implementation of that unnameable game for Mac OSX.
]]>So I’ve been mucking around with Quartz Composer for Mac OS X recently, and a few nights ago, inspiration struck. So I spent my evening making up this: ESV Daily Verse Screensaver. I am learning a lot about Quartz just making these kinds of things, and the fact that this one goes online to get stuff from the ESV’s RSS feeds is even neater. Maybe someone out there will enjoy this one
I’m working on a ‘star wars’ type screensaver with the same content right now, but am having issues with pixelisation of the text when I get it at the right angle and perspective, i.e., freakishly close up.
As Quartz Compositions tend to be user-editable, I’ve decided to release all of mine under a Creative Commons Attribution licence.
]]>Clark doesn’t just criticise the content of the new guidelines, but the manner in which they have been delivered to the world and how valuable stakeholders haven’t been listened to or even consulted.
What does this mean? A lot of the work of WCAG1 — the things that actually work — seems to be being undone and losing a lot of it’s punch. And instead, most of what WCAG2 is proposing Joe claims to be unachievable — and he’d know.
I could start explaining, but you’re better off reading what Joe Clark had to say his A List Apart article.
The WAI committee didn’t give much time for interested parties to provide comments — only until 31st May 2006. You better read this now and provide your feedback to the group while you still can.
UPDATE: Corrected some mistakes — thanks Joe Clark for dropping by and correcting me
]]>SubEthaEdit is basically multiplayer notepad – it allows you to collaborate with others across a network, all editing the same file in different places.
I don’t know if I’d use it personally, but hey, commercial software for free is not something I’d balk at
]]>?gonaked=1
on the end of any inner.geek.nz url, or view this page naked.
]]>Try it at the bottom of the sidebar on this site, or in the Meta section of the sidebar on Webfroot!
]]>The site is valid XHTML, they provide various RSS interfaces, including Bible in One Year feeds and various other daily devotionals, a Web service (SOAP and REST/HTTP-GET) interface for doing verse fetches), favelets, A Firefox search plugin, integration with OpenSearch initiatives such as A9.com, Javascript syndication, and even search-by-email! Talk about spreading the Word of God!
I also really enjoyed reading the Technical Introduction to the ESV Online Edition, which included a report of a usability study of their own and other bible search engines, expected behaviour and implemented behaviour, caveats of search ambiguity, how their whole bible is in XML and is transformed into XHTML, what they did for older browsers, popular bible book query patterns, and strangely enough, MySQL database definitions and PHP source code for viewing (not borrowing) of how their search works. I learnt a lot.
Wow… It’s so geeky, it almost makes me proud to be a Christian
Oh, and the translation itself is good too They even have the entire audio version available to listen to, and if you search on something, you can listen to the results too
]]>So I did it.
Get your Gizoogleate It! Bookmarklet after the jump…
]]>I’m loving the 1.5 action. I love how plugins just add themselves to the menu bar in the admin panel. I love the dashboard. I love Pages. I love the Presentation tab.
One cool thing I discovered about Kubrick is it has a few CSS classes for adding images to posts, namely .aligncenter
, .alignleft
and .alignright
… I’ve been meaning to add these kinds of classes to Webfroot for a while, but then again, we don’t post nearly as many images as we could…
Hey Adam,
I heard on the show you were looking to learn how to type better. I used to be just like you, always looking at the keyboard, somewhere between hunt and peck and touchtyping.
A few years ago I had a whole lot of spare time on my hand, and I looked into the Dvorak keyboard layout. It’s a completely different keyboard layout, but it’s got some advantages over the standard QWERTY layout. All the vowels and most common constants are on the ‘home keys’, and more common letters are nearer the home row.
` 1 2 3 4 5 6 7 8 9 0 [ ] BACKSPACE ' , . p y f g c r l / = a o e u i d h t n s - ENTER ; q j k x b m w v z
You don’t need a new keyboard to learn Dvorak, because Windows, Linux and MacOSX have the ability to switch to Dvorak in software (instructions later).
Learning Dvorak appealed to me because I could learn keyboarding afresh — my bad habits that I had learned using the QWERTY layout would be useless.
It took me about 6 weeks of typing before I was able to ditch the Qwerty layout. But during that time, if I had something important to do, I would switch back to Qwerty, and when I was done switched back to Dvorak.
However, it has been said that you can learn the Dvorak layout in about a month…
About 2 months after starting the learning process, my friend started learning Dvorak too. We’re both computer programmers working in the Web industry, so typing is an integral part of our day. I now no longer look at the keys, and am touch typing. I average about 45wpm when typing from copy.
Biggest con with the Dvorak layout:
Ctrl-Z : Undo
Ctrl-X : Cut
Ctrl-C : Copy
Ctrl-V : Paste
Those editing key shortcuts are grouped together on the Qwerty keyboard, and are close to the Ctrl key — On Dvorak keyboards they are all over the place. And the worst one is when editing a blog post in a web browser, and on Dvorak you go to press Ctrl-V but by accident you press Ctrl-W, which is the shortcut for Close Window… that’s something that really got me angry when learning.
But four years on, I’m still a Dvorak advocate.
If you do want to learn keyboarding (Q or D) here’s a tip:
Don’t EVER look at the keyboard while learning.
If you’re learning Dvorak for one, your keyboard will have the wrong key labels on them. Instead of buying a new keyboard or putting labels on your keys, print out a copy of the layout and attach it to your monitor somehow. Typing tutor programs display the keyboard on the screen for a reason
A veritable treasure trove of Dvorak information is available at http://www.mwbrooks.com/dvorak/ including a picture of the layout and how get your OS to remap your standard QWERTY keyboard to a Dvorak layout
A really good typing tutor program is Ten Thumbs Typing Tutor, and is available for Windows, Linux and Mac!
Anyway, love the show, keep it real!
]]>Current Version: 1.1
How It Works:
If you are logged into your WordPress admin panel, and you make a comment, the plugin will see that you are an official WP user of your blog and mark the comment with your WP User ID.
When the page is rendered, that User ID is called up by the plugin functions, which you can use to change text, change CSS class, add images, whatever your imagination desires.
Installation
Either:
official-comments.php
to your wp-content/plugins
directory. Log-in to your WP admin panel, go to the Plugins tab and activate the Official Comments plugin.How to implement:
Simply add this somewhere within the Comments loop in wp-comments.php and/or wp-comments-popup.php:
<?php if(is_wpuser_comment() != 0) {echo "Official ";} ?>
Or get tricky and add a CSS Class to the LI:
<li class="comment <?php echo (is_wpuser_comment() ? ' commentOfficialUser' : ''); ?>" id="comment-<?php comment_ID() ?>">
and this very basic css example:
.commentOfficialUser { border: 1px solid black; background-color: #999999 }
Documentation
View Official Comments Readme.txt
Examples
There is a very basic example on this post, but more exciting examples available at Webfroot.
Known Issues
It only works with official comments made after the point of installation, as WordPress doesn’t automatically add the WP user ids to the comments field it already has.
Bugs and Suggestions
Any bugs or suggestions, please email me — email link in the sidebar (RSS readers: drop by the site ).
I’m especially proud of the CSS work on “The Code” on the index page — it looks like a table, but it’s not! — it’s a <dl>
with nested <ul>
s! Mmm… semantic goodness
I used Fireworks, Dreamweaver, TopStyle and the content editors all used Contribute.
]]>