On Webmasters and jQuery plugin Monkeys

If one is remotely interested in Web sites, JavaScript and coding, then I strongly recommend YUI Theater’s Douglas Crockford on JavaScript series—all of it. “Scene 6 – Loopage” I found especially interesting, not only because Crocker’s unique blending of history and passionate way of putting things in context makes the subject matter come alive—he does that all the time—but he also goes to great lengths to acclaim, to a still too typically nearly-all-male audience, the early contributions of a woman, Grace Murray Hopper, saying in no uncertain terms she “created the discipline of software engineering” (ibid. 50:36).

But it’s at the YUIConf 2010 Panel Discussion: The Future of Frontend Engineering, that the contributions of “webmasters” were discussed with rather less acclaim, and the term “jQuery plugin monkeys” was floated.

52:45, response to question beginning 51:55

Douglas Crockford: Yeah, we have to make them. Historically we had people call themselves ‘webmasters’. This is going way, way back. Generally they weren’t very smart.


Douglas Crockford: But they figured out how to bring up Apache, and they could do a little bit of Perl, and that was enough to build a website. There were a lot of hobbyists who kind of got into the web that way. The thing we found is that that’s not a good way to do this stuff…

…The world is still full of webmasters though…


Ouch! My professional designation for over 7 years was “Webmaster.” But did I just sit around bringing up Apache? Hmm…

Elaine Wherry: I look back in 2005 when we were starting to hire our initial team, and… I think it’s actually better now than it was then… Now at least there’s a lot of enthusiasm and people are playing around with all the open source initiatives. I initially got into JavaScript by looking at Rico many, many years ago. So I think there’s just a lot more to play with, and it’s a lot easier to pick up than it was back then.

Dion Almaer: So today’s webmasters are JQuery plugin monkeys?

Elaine Wherry: They are, and it makes reviewing resumes a little bit more difficult, because there’s a higher signal to noise ratio. But at least most people who are interested in JavaScript have a website, you can go to it, and you can kind of get an initial read of the person, so that’s helpful.

Elaine Wherry will never hire me from my blog or web site, but—having been at one time a webmaster (York University Faculty of Education, 1998-2005) and having witnessed first-hand the entire progression from a time when web site duties were about 30% of my job (email administration and BBS-style collaboration accounting for the rest—and at that time & place far more engaging) to the cloud-hosted mashup stuff they’re doing there today—I refuse to be laughed and not talk back!😉

When it comes to coding I have no illusions about my abilities. I approach the matter somewhat the way my father approaches his morning crossword puzzle.

Image as callout... I advocate this because it's fun and educational.

...because it's fun and educational!

I suggest classroom teachers learn more about coding, databases, application servers, other hardware and software—and do it in their classrooms with their students—because 1) it’s fun and 2) I’ve found that knowing something about it, getting a foothold in the common language of programmers, may make for more powerful collaborations with more realistic expectations. And occasionally amateurs or hobbyists can have an outside-the-box moment knowing the “right way” to do something sometimes prevents  from happening at all. If I do simple things, simplistically, then I hope my enthusiasm at least is worthwhile, and I hope that somewhere, to someone, it is contagious—perhaps a young person gets interested, then engaged, and goes on to do things she wouldn’t otherwise have done.

As Tantek Çelik says…

Tantek Çelik: …Anyone can slop together a website that works for one person, or works for 100 hits a day… But you want to build something that scales economically? You’re going to need a [computer science] person to do that.

…and he’s absolutely right. Elsewhere in the discussion they talk about such things as music majors (as I was) who are also talented programmers. I’ve already repeated a few times that I learned HTML and JavaScript in exactly the same way I learned guitar, “stealing other people’s licks.” Tantek’s also right when he says,

Tantek Çelik: “You mentioned music, and I think something that’s interesting there is that a lot of musicians learn how to do …what? They learn how to improvise. And that’s, frankly, what being a frontend developer is a lot about.”

This former webmaster can take the ribbing. I trust I won’t be dismissed out of hand. Please tell me when I’m wrong, when I can do things much better—I’ll learn. I’m not after anyone’s job… in fact I think educators and programmers are destined to make beautiful music together.

A useful discovery about Audacity files, and how I used ColdFusion to exploit it

Summary: In which I describe a “mail merge-like” application to generate Audacity projects with all the meta-data filled in advance.

I’ve been known to open files with a text editor for a number of reasons. Usually all you see is gibberish, but sometimes you find something useful in the gibberish, for example what software created it or the plain text the file contained, which you can then retrieve without access to the original software (anybody remember PK Works?)

Audacity for Windows is the sound editor I normally use to record narrations. I export WAV files from Audacity, import those to Captivate for the fancy versions, and convert them to MP3 and OGG for Web-based delivery. Audacity’s simplicity and the fact I can run it from a USB key make it for me perhaps the most useful open source software I can think of.  It seems to have a very low memory footprint —  if I have Captivate, Dreamweaver, Photoshop and Bridge open at once and I try to use Soundbooth I’m just begging for crashes and other trouble… not so Audacity. Audacity  saves its files with a .AUP extension. And it has a so-called “Metadata Editor,” which opens from the File menu—and every time you export a file—and allows you to add title, copyright and other data about the file…

screen shot of Audacity metadata editor

File --> Open Metadata Editor...

…one tedious field at a time (to be fair, there are buttons that help, I would still be copy/pasting 50-60 titles and typing over as many track numbers per project).

The sheer elegance achieved by Audacity’s devotion to simplicity wasn’t fully known to me until I opened a .AUP file in Notepad. What I discovered was a plain old XML file. Not quite convinced, I copied it any old place, made some edits, and tried to open it with Audacity.  I got an error saying it couldn’t find the data directory associated with the project.  I changed the project tag’s  “projname” parameter to “blank_project_data” and created a directory of the same name, and presto, it opened as a new Audacity project!  Here’s what a new project file looks like before you record any sound (I’ve made only a few other changes I’ll explain below):

image of Audacity XML file

Audacity XML with minor modifications

If you guessed I added everything that’s all-caps and beginning with the word MY, you’re right. If it weren’t the case that every elearning module I create must be done in both French and English I could hard-code the genre as “Speech,” my organization’s name etc., but I think you’ll see in a minute where I’m going with this.

I love ColdFusion and while I completely understand why .NET and PHP have “disrupted” its influence, and that I benefit from knowing a bit about both of those platforms, let it be known here and for all time, I not only prefer ColdFusion, I believe it has very strong pedagogical value—I credit have started there with much of my success as a self-taught programmer (topic for a future post). I used it at a previous job, and for every app I developed that went live to the public I had 3 or 4 I considered “tools” meant mainly for my own use, which assisted me in repetitive tasks I encounter during development. After settling in at my new job I convinced the powers that be to let me install the free Developers’ Version on my laptop. It’s pretty much essential to the way I work.

I now keep all my modules in a MySQL database that stores everything I need to know about every slide in all the languages we now target, and ColdFusion allows me to do many different things with that information. Everything I’m about to describe regarding Audacity can be done using .NET, PHP, or any other Application Server platform you may know.  My goal is to create a folder of empty AUP files, organized by language, corresponding to each slide in my module. Each one needs a corresponding data folder of the same name. What I want to do is exactly like a mail merge, I just need to replace “MYPROJECTNAME” etc. with real values, create a corresponding directory, and write the file to my hard drive.

ColdFusion makes this ridiculously easy, using its very readable tag-based format anyone who ever clicked View–>Source would recognize, and the specific tags <cfquery>, <cfoutput>, <cfdirectory>, <cffile>, <cfsavecontent> and one built-in function, replaceList(stringToEdit,’replace,old,list’,’with,new,list’).  One thing ColdFusion allows that may or may nor have analogies in other languages is <cfsavecontent>:

I placed the entire XML document, with my modifications, between the tags and gave it the variable_name aupFile.

Next I query my database (*I’ve since added forms and extra functionality, error handling, moved some pieces to a CFC, so I’m only talking about the essentials and only showing enough code to get the point across. If you’d like more information, please just ask). image of coldfusion codeI need to count the “tracks” and replace MYTRACKNUMBER, so I initialize a variable myTrackNumber=0 before I start looping through results, and increment it within the loop.  I also get the translations for “Speech” etc., (another query from another table) and assign it to myGenre, likewise the organization’s name and the items that remain constant in every file. I also create variables the absolute paths to the files and directories I’ll create.

There are two ways to loop through query results in CF, for my needs here I used <cfoutput>. As it begins each loop I grab what I need for each slide

image of coldfusion code

Set variables, do "mail merge," write file, create data directory

The working ColdFusion script produces 60 pre-filled .AUP files and their data folders in under 2 seconds. I can double click one and press R to record. File–>Export still opens the Metadata Editor but I can just press enter to close it and save the WAV, MP3 or OGG file. That makes life much easier.

Since my last post I’ve learned…

I’ve been busy, and living means learning, so what have I been learning? Among other things, I attended a lecture on Planned Serendipity that got me thinking about all the ways information from various times and places suddenly clicks. Let’s see what happens if I throw it all down here and then look for the connections…

in the “careful what you wish for department: at work, a project we shelved in April because it will be superseded by another initiative this coming spring was resurrected. I was glad powers that be recognized the added value of getting the information to the public in spite of impending changes (mainly to layout and branding), yet at the same time it’s changing horses yet again, the stream unmistakably forming rapids just ahead!

Back in April I was about to add fully ARIA-compliant keyboard accessibility to my multilingual elearning interface. I had identified an excellent, fully object-oriented methods-based model for a template at the OpenAjax Alliance‘s examples page, but concluded that I’d either have to re-write their code or mine in order to integrate it. Picking up from there with only weeks until a public reveal I’ve opted for a devil I know… I’m writing my own behaviors on top of everything in a way I won’t have to tamper with anything that already works. Everything I’m learning about key clicks will need a post of its own, but a Google search led me to see something new in a place I’d been many times before, which led me — serendipitously — to solve a problem I wasn’t thinking about when I Googled.

From this department I learned: – Sometimes things really do come back off the shelf. Be prepared. –  There may be an analogy between the serendipity of human networks and the serendipity of connections within bodies of information. – I’m consistently able to get useful results in the first few results using Google, and I think many of the sites I already visit may rise to the top of Google results because they consistently give useful information. – How Focus and tab key navigation work, and also how long 2 years is in the tech world.

In the seemed like a good idea at the time department: The way I write code leaves plenty of room to ” Step back, look at your code, and DRY things up a bit!” as Ben Alman wrote in an article I found by Googling for examples of jQuery code related to keystrokes. (This is not the first I’ve heard of “Cowboy” Ben Alman. If you have even a faint interest in JavaScript you need to follow @cowboy, bookmark his web site, discover his plugins, …and help support his work when you use them!). “DRY” in this case means “Don’t Repeat Yourself.” One effort I made even before reading this particular article was to try to condense some debugging code. Programmers need to keep track of variables as they write code.  As many surely have done, I once relied very heavilyon the alert('myVariable currently = '+myVariable); method of debugging.  Using Firefox and Firebug you can write messages to a console, but if you then look at the code in a browser with no console you get an error. To prevent that I would write

if ( window.console && window.console.log ) {  window.console.log('myVariable currently = '+myVariable)  } /* if ( someConditionIsTrue ){ Do something. } */

That prevents popups and errors, but it’s not much of a time or space saver. I eventually began to make it a habit to add three variables to every script I work on, right at the top to make them globally available…

var DEBUG=true, LOGREADY = (window.console && window.console.log), myLog = LOGREADY ?  window.console.log : null ;

With those up top, what I had before becomes  if ( LOGREADY) {  myLog('myVariable currently = ' + myVariable)  }and you can turn it completely off by setting DEBUG = false in one place at the top of the script.

What wasn’t the best idea, as it turned out, was to try to assign the built-in alert function as a fallback. Instead of the above I tried myLog = LOGREADY ?  window.console.log : window.alert() ;  That means “if the log is ready use the window.console.log method to write to the console, but otherwise use the alert method to make a popup. It actually worked in Firefox and IE. But it crashed Chrome.  I temporarily wrapped it in a try{} catch(){}, which effectively turned it off in Chrome. In emergencies with deadlines I’ll ask for help, but as long as it wasn’t crashing it was no  emergency, and I always feel more in control when I figure it out for myself.  Today I took a look. My intuition said it was something about appropriating one global function to create another, and I vaguely recalled Douglas Crocker explaining that JavaScript’s loose declaration style could be a blessing and a curse [video]. I haven’t actually consulted with the gurus, but I made sure my function looks like a function and now it works in Chrome.


var DEBUG=true, LOGREADY = (window.console && window.console.log),
myLog = function(entry){ if (DEBUG && LOGREADY) { window.console.log(entry) } else if (DEBUG) { alert(entry) } } ;

myLog is now explicitly a function, you have to pass it an entry like so:

notVariables = ', but not variables,'; /* setting up a variable to make a point below*/
myLog("Wrap all text in quotes" + notVariables + " nor numbers like " + -5 + ", " + 0 + ", or "+ 13 + ".") ; /* plus signs are needed to string strings together.  Fancy word for it: concatenation   */

which prints out as: “Wrap all text in quotes, but not variables, nor numbers like -5, 0, or 13.”

…and, if you have DEBUG set to true and the condition tested and stored in LOGREADY was true when it tested for the presence of those features, it will print the entry you sent it to the console—otherwise it will pop up an alert.

This makes it important to set DEBUG to false again before uploading the code to a live server, but at the right stage in development it could be useful to open another browser or computer and quickly check a variable.  If the alerts are just too  much remove ” else { alert(entry) } “. You’ll want to leave the other side wrapped in the if (){ ... }. That way if DEBUG is false or the browser lacks the console logging feature the implicit ” else ” is to do nothing.

From this department I learned – not to assume Safari, Chrome, Firefox, and IE all handle the newer features in compatible ways… in some ways just a lesson re-learned, but I think I’m now able to discern between “it crashed” and “it crashed because the browsers use different error handling (and apparently Firefox’s and IE’s are better than Chrome’s in this case!))” and if I’m right I’ve connected it to the “loose” nature of the JavaScript language itself, a piece of information that has been floating about in my mind for some years..

*   ———    *

* Published early. Was that a happy accident? I’m going to leave it and keep working on it.

My idea is to link the learning from each “department” to 1 or more level according to the SOLO taxonomy

1 Pre-structural: here students are simply acquiring bits of unconnected information, which have no organisation and make no sense.
2 Unistructural: simple and obvious connections are made, but their significance is not grasped.
3 Multistructural: a number of connections may be made, but the meta-connections between them are missed, as is their significance for the whole.
4 Relational level: the student is now able to appreciate the significance of the parts in relation to the whole.
5 At the extended abstract level, the student is making connections not only within the given subject area, but also beyond it, able to generalise and transfer the principles and ideas underlying the specific instance.

Read more: SOLO taxonomy http://www.learningandteaching.info/learning/solo.htm#ixzz1eHiFt3ei (Under Creative Commons License: Attribution Non-Commercial No Derivatives)

“Why do I need to learn this?”

In one of the many short chats with fellow participants at EdCampTO that happened Saturday we talked about engaging young people by teaching some programming. There was a mention of the age-old question that is the title of this post and, as is often the case, it was framed in connection with learning math. I mentioned how in my first grad course our professor had us write, as an exercise in self-discipline, abstracts of scholarly articles, some of perhaps 70 pages or more, in no more than 50 words. I was even more novice at JavaScript than I am today but I wrote back then about how I made a little textarea to type in, that warned when I was approaching 50 words.

Today I’m using another such self-designed tool, running from the EasyPHP web server on my USB key, powered by jQuery. I have an Adobe Captivate module that has been translated into Arabic, and as the text is written right to left everything in the module must be mirror-imaged.

Rather than eyeball it I see there’s some simple arithmetic involved using the Left and Top positions, and Width dimension that Captivate displays in editable text fields. The module’s “Stage” is 580 pixels wide. If you subtract the starting Left position from the module width, then (because Adobe doesn’t tell you the Right position) subtract the object’s width, you get the New Left position, or W - l - w = L, where W is the width of the module, l is the initial left position of the object to move, w is the width of the object to move, and L is the new left position to be pasted back into Captivate.

Here’s the function I wrote. The double bar ( || ) means “or,” and in this case provides a value of 0 whenever a field is blank (null or undefined, either of which causes an error).  CalcNewPosForm is the id of the form. I “bind” the function so that it fires (recalculates) every time any input field on the form is changed. (Unfortunately I can’t provide a working demo on my free WordPress blog):

        /* CALC form; requires jQuery */
        $('#CalcNewPosForm input').bind('change', function()
            var left = parseInt( $('#L').val() ) || 0, 
                width = parseInt( $('#W').val() ) || 0, 
                newLeft = 580 - left - width || left;
            if ( left !== 0 && width !== 0)
            { // nothing happens unless both left and width contain a value
        }); // parseInt() assures the value is treated as a number

This is the simple form. Notice how the id field of the inputs are referenced in the script above:

 <form id="CalcNewPosForm" name="CalcNewPosForm" method="post">
     <legend title="This is for use with RTL languages, in order to mirror object locations.">Calculate new item position</legend>
     <label for="L">L: <input size="1" id="L" name="L" type="text" value=""></label>&nbsp;&nbsp;
     <label for="W">W: <input size="1" id="W" name="W" type="text" value=""></label>&nbsp;&nbsp;
     <label for="newL">New L: <input size="1" id="newL" name="newL" type="text" value=""></label>

Would hands-on web app development engage students of say, middle school age?

UPDATED: link to work in progress is here.

That was the question I asked at EdCampTO today, and enough people expressed an interest that I got a slot to present in the second session of the morning. The first session was very engaging indeed but I had to pull myself away to set up, and as has happened way too many times, things weren’t ideal for my tech needs. In this case I needed an Admin account to unblock XAMPP, and York’s A/V/ITC staff had left the building. Having been there done that before I also had my examples on a remote server, but the extra time  caused me to lose most of the audience. I set up anyway and managed to recover a small but very interested few.

I need to mention that in the engaging discussion prior to this I asked @HeidiSiwak, a teacher in Dundas, Ontario, if and how J/I (“junior/intermediate” division in Ontario system, nominally grades 4-10 but in practice more like 4-8) had so far engaged in web app development. It turns out they have an app project on the go, and the project management model they use has perhaps some Agile-like qualities: students and teachers drive the list of features and programmers code to their needs. I asked if giving the kids hands-on access to actual code a) might be even more engaging for them and b) might even lead one or two to go further into programming? I got the “Yes, quite likely” I was after in both cases. (Anyone think I might have a future writing questions for Rasmussen polls?)

This is take two for me on presenting this idea, and I’ve simplified it greatly. I will detour those whose answer to a question about Internet access suggests they need to install a Web server to a completely separate tutorial on XAMPP. Once every would-be user is certain they have access to a Web server and the ability to install and update files on it they can proceed with unpacking a small zip file I provide, containing a standard folder structure, three steps:

  1. Open a template file in a plain text editor, and save it as (File->Save As) index.html
  2. Open a form I’ve created, which as of this moment has a text field for the unique id of each page, another for its title, a text area for content input, and a another to receive output that appears when they click a submit button, which they then…
  3. copy/paste into a designated area of the file opened in Step 1, Save, and View in their Web browser.

I hope this process will provide instant gratification that will keep them engaged. I plan to add radio buttons and checkboxes to allow some header and footer variations, but the real Gate to Narnia is the button to the jQueryMobile Docs and Demos page. With nudges, guided tours and additional instructions I hope to inspire curiosity, creativity, exploration, and discovery.

I hope to prevent this from being framed entirely as a computer lesson. It can become another way to hand in assignments in almost any subject. A thorough correlating with Ontario K-12 Curriculum will be in order.

Thanks again for the feedback and discussion. It’s been a long but rewarding day (at the end of a long but rewarding vacation and a great visit with family in the States). I’ll post my code tomorrow.

At EdCampTO, an “un-conference”

I’ve registered at EdCamp (and I’m charging the phone!) You start by writing an idea and sticking on the wall. People vote to explore topics in a workshop/discussion a bit later.

In short: a very cool format. I’d like to show, tell and get feedback on an idea I think might engage teachers and learners, using jQueryMobile to wrap assignments and projects… or? Hope it’s a good start and others can extend on what I’m starting to envision.

Extending ADDIE with B&CCCP


At work we’re doing an “Online Renewal Project,” and we’re taking the opportunity to evaluate many related aspects of the way we do things. This week I took Aaron E. Silvers‘s idea of Borders and Conditions, Content, Context, Participation (B&CCCP or BCCCP … or?) to other members of our eLearning team. Regardless of willingness, not everyone is ready or able to move radically distant from our emerging instructional design workflow guided, predictably, by the ADDIE model—Analysis, Design, Develop, Implement, Evaluate (e.g., these meetings). We educate on human rights law and policy. My department’s role within our organization, by description, is not simply “education” but also “outreach.” We agreed that thinking in terms of experiential and situational learning will open paths to creating projects that go beyond list & drill mechanisms to foster partnerships, build relationships, while providing deeper learning—communities of praxis—around our subject matter.

This will be an evolving process. Our first step has been simply to think about points of entry for B&C, C, C, & P into our existing ADDIE workflow. We had a chart describing the steps we currently take to produce eLearning “modules.” We want to produce richer learning experiences that can be supported by our electronic materials.

Thus far we’ve overlayed our initial thoughts about where BCCCP fits in our process onto our chart. Some interesting things emerged. We realized the BCCCP lens could apply to our activity of rethinking and enriching our process, as well as within the products themselves (edited for clarity).

We know there’s much more to think about, but we’re convinced we’re onto something.

eLearning Project Flow Chart 2010 moving to the future


UPDATE August 12, 2011 at 5:02 pm: another meeting with additional minds, so here’s some more feedback. It was quickly recognized that boundary conditions (which people shorten to “boundaries”) needed to be paired with context and addressed straight off the top, an extension of the analysis phase. So we thought it naturally comes second: “Borders and Conditions, *Context*, Content, Participation” If we couple this approach with an idea of content in relation to communities of practice we end up looking at participation in the design, development and implementation stages in a different light. The experience of designing the experience seems important to the building of partnerships and relationships, which can impact our outreach in ways we wish to continue exploring.

We’re trying our hands at some new charts, much simpler we hope.