A better way to control attributes in SPIP templates


This post describes a PHP function to replace SPIP's inserer_attribut and extraire_attribut filters with a single jQuery-inspired attr filter. Posted by Thomas Sutton on November 25, 2008

Edit: En español: “Una mejor manera de controlar los atributos en SPIP”.

Lots of SPIP tags and filters generate HTML mark-up as output (the #LOGO_* tags and |image_* filters are the most prominent) and we often need or want to modify this mark-up in our templates. There are several built-in filters to help with this (inserer_attribut to insert an attribute and extraire_attribut to extract the value of an attribute) but they are pretty long and tedious to type. Given that I uses these filters quite often when implementing such things as image galleries, and I still have to think quite hard to type the French words correctly the can be a bit annoying. Thankfully, a small wrapper (see below) can smooth these small annoyances away.

When it comes to accessing and modifying the values of attributes nothing, in my opinion, comes any where near to jQuery’s attributes API. The single jQuery attr method allows you to get and set the value for any attribute on any node: it takes one or two parameters, the name of the attribute and, optionally, the value. If only the name is specified, then attr simply extracts and returns the value of the attribute. If both a name and a value are specified, then attr modifies the object setting specified attribute to the specified value. This “polymorphic” style of interface – where a single method has two complementary behaviours which are distinguished by the number and/or types of the arguments – is everywhere in jQuery and is part of what makes it so concise and so productive. Seeing as it’s the best structure for such interfaces that I know (and also, one I use daily), I decided that my wrapper should mirror it. Thus the attr filter was born.

Like the jQuery attr method, the SPIP attr filter takes one or two parameters (and an implicit “object”, but we’ll ignore if for now). If only one, it passes the input on to extraire_attribut to get and return the value. If called with two parameters, it calls inserer_attribut instead to modify the tag. Like the idea, the code is reasonably straightforward; the only even slightly unusual but is the use of func_get_args to get an array of the arguments passed into the function call. With such an array, we can use count to check how many arguments the function was given and decide whether we should get or set the attribute. This is safer than specifying and checking a default value (FALSE or NULL, for example) because some user may genuinely want to use that value (perhaps NULL will mean delete the attribute in a future version?) and silently ignoring user input is never good.

<?php
include_spip("inc/filtres");

/**
 * The `attr` function allows the user to get and set the attributes of an
 * HTML tag. It is intended to be used as a SPIP filter and depends on 
 * existing SPIP functionality.
 *
 * @param $tag
 *     The HTML code.
 * @param $name
 *     The name of the attribute.
 * @param $val...
 *     The new value for the attribute $nom. Optional.
 * @return
 *     If $val was given, the code for tag with $name=$val
 *     Otherwise, the value for the $name attribute in $tag.
 */
function attr($tag, $name){
        $args = func_get_args();
 
        if (count($args) > 2) {
                // SET
                return  inserer_attribut($tag, $name, $args[2]);
        } else {
                // GET
                return extraire_attribut($tag, $name);
        }
}

Simply copy the code into the mes_fonctions.php file for your site (see “Adding your own filters” in SPIP’s Filters) and use attr in your SPIP templates:

<a href="[(#FICHIER|attr{src})]" class="lightbox" title="#TITRE">
    [(#FICHIER|image_reduire{100,100}|attr{alt,#TITRE})]
</a>

There are a few changes that could be made to this function: passing $args directly to inserer_attribut and extraire_attribut rather than the individual variables, adding a $value=FALSE parameter for the sake of documentation and then ignoring it (I’m not sure if this will work and don’t care enough to try it), deleting attributes when passed e.g. NULL as a value, etc. For the time being, however, it does the job.

A final note: you’ll probably need to be running PHP 5 for this to work – the func_get_args documentation (linked above) mentions version 5.3.0 – and the code above was modified after I last tested it, but should work anyway.

This post was published on November 25, 2008 and last modified on January 26, 2024. It is tagged with: spip, php, code, html, attributes.