<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Passing Curiosity: Posts tagged html</title>
    <link href="https://passingcuriosity.com/tags/html/html.xml" rel="self" />
    <link href="https://passingcuriosity.com" />
    <id>https://passingcuriosity.com/tags/html/html.xml</id>
    <author>
        <name>Thomas Sutton</name>
        
        <email>me@thomas-sutton.id.au</email>
        
    </author>
    <updated>2009-06-22T00:00:00Z</updated>
    <entry>
    <title>Django form fields and templates</title>
    <link href="https://passingcuriosity.com/2009/django-form-fields-and-templates/" />
    <id>https://passingcuriosity.com/2009/django-form-fields-and-templates/</id>
    <published>2009-06-22T00:00:00Z</published>
    <updated>2009-06-22T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>I’ve been working with <a href="http://djangoproject.org/">Django</a> for the last little while (or long
while) and something that stumped me for a while was a useful, generic
approach to marking-up forms in HTML. In particular, making it possible to use
CSS to style classes of fields (all checkboxes, for instance, or all
date-pickers) effectively. Doing so requires being able to write a selector to
pick such elements out, but I found it very difficult to do so.</p>
<p>The only way, as far as I (and <a href="http://groups.google.com/group/django-users/browse_thread/thread/16493dd43303efd3">the replies on django-users@</a>), is to write a template filter to extract a such a value for you. Thankfully, this it pretty easy:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a>    <span class="at">@register.filter</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">def</span> field_type(field):</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>        <span class="co">&quot;&quot;&quot;</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a><span class="co">        Get the name of the field class.</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a><span class="co">        &quot;&quot;&quot;</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="bu">hasattr</span>(field, <span class="st">'field'</span>):</span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>            field <span class="op">=</span> field.field</span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a>        s <span class="op">=</span> <span class="bu">str</span>(<span class="bu">type</span>(field.widget).<span class="va">__name__</span>)</span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a>        s <span class="op">=</span> s.rpartition(<span class="st">'Input'</span>)[<span class="dv">0</span>]</span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a>        s <span class="op">=</span> s.lower()</span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> s</span></code></pre></div>
<p>I can use the above filter to add a class to my form markup:</p>
<pre class="django"><code>            &lt;div class=&quot;form-field form-{{ field|field_type }}&quot;&gt;
                {{ field.label_tag}}
                {{ field.errors }}
                {{ field }}
            &lt;/div&gt;</code></pre>
<p>Which I can then use in my CSS to style particular widgets without having to do them one-by-one using ID’s:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode css"><code class="sourceCode css"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="fu">.form-field</span> label {</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">display</span><span class="ch">:</span> <span class="dv">block</span><span class="op">;</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">width</span><span class="ch">:</span> <span class="dv">15</span><span class="dt">%</span><span class="op">;</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">float</span><span class="ch">:</span> <span class="dv">left</span><span class="op">;</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a>div<span class="fu">.form-checkbox</span> label {</span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">width</span><span class="ch">:</span> <span class="dv">85</span><span class="dt">%</span><span class="op">;</span></span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a>    <span class="kw">float</span><span class="ch">:</span> <span class="dv">right</span><span class="op">;</span></span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true" tabindex="-1"></a>    <span class="kw">clear</span><span class="ch">:</span> <span class="dv">right</span><span class="op">;</span></span>
<span id="cb3-11"><a href="#cb3-11" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb3-12"><a href="#cb3-12" aria-hidden="true" tabindex="-1"></a>div<span class="fu">.form-checkbox</span> input {</span>
<span id="cb3-13"><a href="#cb3-13" aria-hidden="true" tabindex="-1"></a>    <span class="kw">float</span><span class="ch">:</span> <span class="dv">left</span><span class="op">;</span></span>
<span id="cb3-14"><a href="#cb3-14" aria-hidden="true" tabindex="-1"></a>    <span class="kw">margin-left</span><span class="ch">:</span> <span class="dv">12</span><span class="dt">%</span><span class="op">;</span></span>
<span id="cb3-15"><a href="#cb3-15" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>]]></summary>
</entry>
<entry>
    <title>A better way to control attributes in SPIP templates</title>
    <link href="https://passingcuriosity.com/2008/better-control-attributes-spip-templates/" />
    <id>https://passingcuriosity.com/2008/better-control-attributes-spip-templates/</id>
    <published>2008-11-25T00:00:00Z</published>
    <updated>2008-11-25T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p><em>Edit:</em> En español:
“<a href="http://nqnwebs.com/blog/article/una-mejor-manera-de-controlar-los">Una mejor manera de controlar los atributos en SPIP</a>”.</p>
<p>Lots of SPIP tags and filters generate HTML mark-up as output (the <code>#LOGO_*</code>
tags and <code>|image_*</code> 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
(<a href="http://www.spip.net/en_article2465.html#inserer_attribut"><code>inserer_attribut</code></a>
to insert an attribute and
<a href="http://www.spip.net/en_article2465.html#extraire_attribut"><code>extraire_attribut</code></a>
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.</p>
<p>When it comes to accessing and modifying the values of attributes nothing, in
my opinion, comes any where near to <a href="http://docs.jquery.com/Attributes">jQuery’s attributes
API</a>. The single <a href="http://docs.jquery.com/Attributes/attr">jQuery <code>attr</code>
method</a> 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 <code>attr</code> simply extracts and returns the value of the attribute. If both a
name and a value are specified, then <code>attr</code> 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 <code>attr</code> filter was
born.</p>
<p>Like the jQuery <code>attr</code> method, the SPIP <code>attr</code> 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 <code>extraire_attribut</code> to get and return the
value. If called with two parameters, it calls <code>inserer_attribut</code> instead to
modify the tag. Like the idea, the code is reasonably straightforward; the
only even slightly unusual but is the use of
<a href="http://php.net/func_get_args" title="PHP manual for func_get_args"><code>func_get_args</code></a>
to get an array of the arguments passed into the function call. With such an
array, we can use <a href="http://php.net/count" title="PHP manual for count"><code>count</code></a> 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 (<code>FALSE</code> or <code>NULL</code>, for example) because some user may genuinely want to
use that value (perhaps <code>NULL</code> will mean delete the attribute in a future
version?) and silently ignoring user input is never good.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode php"><code class="sourceCode php"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">&lt;?php</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>include_spip(<span class="st">&quot;inc/filtres&quot;</span>)<span class="ot">;</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a><span class="co">/**</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a><span class="co"> * The `attr` function allows the user to get and set the attributes of an</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a><span class="co"> * HTML tag. It is intended to be used as a SPIP filter and depends on </span></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a><span class="co"> * existing SPIP functionality.</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a><span class="co"> *</span></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a><span class="co"> * </span><span class="an">@param</span><span class="co"> </span><span class="cv">$tag</span></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a><span class="co"> *     The HTML code.</span></span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a><span class="co"> * </span><span class="an">@param</span><span class="co"> </span><span class="cv">$name</span></span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a><span class="co"> *     The name of the attribute.</span></span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a><span class="co"> * </span><span class="an">@param</span><span class="co"> </span><span class="cv">$val..</span><span class="co">.</span></span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a><span class="co"> *     The new value for the attribute $nom. Optional.</span></span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a><span class="co"> * </span><span class="an">@return</span></span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a><span class="co"> *     If $val was given, the code for tag with $name=$val</span></span>
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true" tabindex="-1"></a><span class="co"> *     Otherwise, the value for the $name attribute in $tag.</span></span>
<span id="cb1-18"><a href="#cb1-18" aria-hidden="true" tabindex="-1"></a><span class="co"> */</span></span>
<span id="cb1-19"><a href="#cb1-19" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span> attr(<span class="va">$tag</span><span class="ot">,</span> <span class="va">$name</span>){</span>
<span id="cb1-20"><a href="#cb1-20" aria-hidden="true" tabindex="-1"></a>        <span class="va">$args</span> <span class="op">=</span> <span class="fu">func_get_args</span>()<span class="ot">;</span></span>
<span id="cb1-21"><a href="#cb1-21" aria-hidden="true" tabindex="-1"></a> </span>
<span id="cb1-22"><a href="#cb1-22" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> (<span class="fu">count</span>(<span class="va">$args</span>) <span class="op">&gt;</span> <span class="dv">2</span>) {</span>
<span id="cb1-23"><a href="#cb1-23" aria-hidden="true" tabindex="-1"></a>                <span class="co">// SET</span></span>
<span id="cb1-24"><a href="#cb1-24" aria-hidden="true" tabindex="-1"></a>                <span class="cf">return</span>  inserer_attribut(<span class="va">$tag</span><span class="ot">,</span> <span class="va">$name</span><span class="ot">,</span> <span class="va">$args</span>[<span class="dv">2</span>])<span class="ot">;</span></span>
<span id="cb1-25"><a href="#cb1-25" aria-hidden="true" tabindex="-1"></a>        } <span class="cf">else</span> {</span>
<span id="cb1-26"><a href="#cb1-26" aria-hidden="true" tabindex="-1"></a>                <span class="co">// GET</span></span>
<span id="cb1-27"><a href="#cb1-27" aria-hidden="true" tabindex="-1"></a>                <span class="cf">return</span> extraire_attribut(<span class="va">$tag</span><span class="ot">,</span> <span class="va">$name</span>)<span class="ot">;</span></span>
<span id="cb1-28"><a href="#cb1-28" aria-hidden="true" tabindex="-1"></a>        }</span>
<span id="cb1-29"><a href="#cb1-29" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>Simply copy the code into the <code>mes_fonctions.php</code> file for your site (see
“Adding your own filters” in <a href="http://www.spip.net/en_article2465.html">SPIP’s
Filters</a>) and use <code>attr</code> in your SPIP
templates:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode html"><code class="sourceCode html"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="dt">&lt;</span><span class="kw">a</span><span class="ot"> href</span><span class="op">=</span><span class="st">&quot;[(#FICHIER|attr{src})]&quot;</span><span class="ot"> class</span><span class="op">=</span><span class="st">&quot;lightbox&quot;</span><span class="ot"> title</span><span class="op">=</span><span class="st">&quot;#TITRE&quot;</span><span class="dt">&gt;</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>    [(#FICHIER|image_reduire{100,100}|attr{alt,#TITRE})]</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a><span class="dt">&lt;/</span><span class="kw">a</span><span class="dt">&gt;</span></span></code></pre></div>
<p>There are a few changes that could be made to this function: passing <code>$args</code>
directly to <code>inserer_attribut</code> and <code>extraire_attribut</code> rather than the
individual variables, adding a <code>$value=FALSE</code> 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. <code>NULL</code> as a
value, etc. For the time being, however, it does the job.</p>
<p>A final note: you’ll probably need to be running PHP 5 for this to work – the
<code>func_get_args</code> documentation (linked above) mentions version 5.3.0 – and the
code above was modified after I last tested it, but should work anyway.</p>]]></summary>
</entry>

</feed>
