Monthly Archives: February 2010

htmlspecialchars() for JavaScript

Creating markup with JavaScript for fun and profit is easy due to innerHTML. However, it would be nice to be able to escape output that is not trusted or known. Most references online point to encodeURI or encodeURIComponent, which will kind-of work; however those functions are intended for URI escaping, which has different rules.

So, here’s a quick solution that works pretty much like the similarly-named PHP function, htmlspecialchars:

function htmlspecialchars(str) {

    if (str === undefined) return "";
 
    return str.replace(/[<>"&]/g, function(match){
        return (match == "<") ? "&lt;" :
               (match == ">") ? "&gt;" :
               (match == '"') ? "&quot;" :
               (match == "&") ? "&amp;" : "";
    });
}

What’s missing? The “quote_style” parameter which allows deciding what will happen with single quotes (‘). If your markup is sane and under control, there should be no need for it — if it isn’t, it’s not hard to change the above function.

Making YUI ButtonGroups behave

I like YUI Buttons. Amongst other niceties they allow you to have reliable cross-browser, cross platform custom-rendered form widgets like checkboxes and radio buttons — while keeping all the accessibility concerns in check. One of the functionalities it has is to create “ButtonGroups”, i.e. a bunch of button controls that behave as a traditional radio-button group. All nice and good, except that it has one obnoxious behaviour: it forces all your radio buttons inside a common container — which might not be what you had in mind. I like my radio buttons where I put them, thank you…

So, quick fix coming up:

var radioGroup = new YAHOO.widget.ButtonGroup({ container: aDivSomewhereItDoesntMatterWhere });
var radioButtons = anArrayOfPlainNormalRadioButtons;

for (var i = 0, len = radioButtons.length; i < len; ++i) {

    var nodeIndex = getNodeIndex(radioButtons[i]),
        parentNode = radioButtons[i].parentNode,
        radioButton = new YAHOO.widget.Button(radioButtons[i]);

    // This will put the button somewhere silly
    radioGroup.addButton(radioButton);

    // Move the button back where it was
    parentNode.insertBefore(radioButton.get("element"), parentNode.childNodes[nodeIndex]);
}

So, it’s more verbose than just using the simple “new YAHOO.widget.ButtonGroup(radioButtonContainer)” syntax that does everything for you — if you are willing to have the radio buttons where YUI put them. Also… what’s that “getNodeIndex()” function?, I hear you ask. Just a simple utility off my toolbox; it gets the index of a node within all the nodes with the same parent:

var nodeIndex = function(element) {
    for (var index = 0, el = element; el = el.previousSibling; ++index);
    return index;
}

Hope that’s helpful…

Getting the category ID in WordPress

There is quite a bit of documentation in the WordPress site about categories, specifically how to retrieve data about them. Unfortunately all the available methods seem to focus on getting category data from a post, but it’s nearly impossible to figure out the category you are looking at when viewing the category page itself (i.e. the special “archive page” that lists all posts in a category).

The function is_category() falls short, since it only indicates whether or not the current page is a category page, but not which one. And get_cat_id(), get_category(), get_the_category(), and the half-dozen other “obviously”-named functions either require that you already know something about the category or provide information about a post.

So, the solution?

if (is_category()) {
   $categoryId = $GLOBALS["cat"];
}

Yes, it’s a global variable…