Proposal: label tag attributes

172 views
Skip to first unread message

oggy

unread,
Sep 14, 2008, 8:16:52 AM9/14/08
to Django developers
Currently, Django's form library doesn't facilitate a way to add
attributes to the fields' labels. So, while it's dead simple to add,
say, 'class="required"' to your widgets, you have to go out of your
way to do the same for your <label> tags.

The patch to add the functionality is very simple. I'm opening a new
ticket and attaching it, but I didn't make any tests or docs yet.

oggy

unread,
Sep 14, 2008, 8:53:03 AM9/14/08
to Django developers
Here's a link to the ticket: http://code.djangoproject.com/ticket/9079

Simon Willison

unread,
Sep 14, 2008, 6:36:52 PM9/14/08
to Django developers
I think this is indicative of a bigger problem: people
use .as_p, .as_table and .as_li far more than they should, because
there isn't an enormously convenient alternative. If you want to use
custom markup for a form at the moment you really have to define the
HTML for every one of your fields, which is dull, repetitive and means
that when you change your fields you have to update both your form
definition and your template.

What's needed is a way to loop over the fields in a form within your
template, thus making it easy to roll your own custom form markup
without being repetitive.

I had a play around with this today and I think I've come up with a
really nice general solution. I've posted it to Django Snippets
http://www.djangosnippets.org/snippets/1057/ , but here's the code:

from django import forms
from django.forms.forms import BoundField
class Form(forms.Form):
def bound_fields(self):
"""
Returns this form's fields, bound against the form. Useful for
looping
through the fields in a form from a template.
"""
return [
BoundField(self, field, name)
for name, field in self.fields.items()
]

# Now define your form as a subclass of Form, instead of forms.Form

class MyForm(Form):
name = forms.CharField()
age = forms.IntegerField()
email = forms.EmailField()

Once you have a bound_fields method on the Form class, you can write
templates that look like this:

{{ form.non_field_errors }}
{% for field in form.bound_fields %}
<div class="row">
{{ field.errors }}
<label for="{{ field.auto_id }}"
{% if field.field.required %} class="required"{% endif
%}>{{ field.label }}</label>:
{{ field }}
</div>
{% endfor %}

This gives you almost complete control over your form's HTML, and in
my opinion is a much more powerful technique than continuing to add
options to customise the output of form.as_p and friends. Assuming no
one can think of a major drawback, I plan to check it in to trunk as
soon as we've spun off the 1.0.x release branch.

If you want even more control, try out http://code.google.com/p/django-html/
- I'd love to hear some feedback on both approaches.

alex....@gmail.com

unread,
Sep 14, 2008, 6:54:50 PM9/14/08
to Django developers
What? You can iterate over a form as it is and render each field.

On Sep 14, 6:36 pm, Simon Willison <si...@simonwillison.net> wrote:
> On Sep 14, 1:16 pm, oggy <ognjen.ma...@gmail.com> wrote:
>
> > Currently, Django's form library doesn't facilitate a way to add
> > attributes to the fields' labels. So, while it's dead simple to add,
> > say, 'class="required"' to your widgets, you have to go out of your
> > way to do the same for your <label> tags.
>
> > The patch to add the functionality is very simple. I'm opening a new
> > ticket and attaching it, but I didn't make any tests or docs yet.
>
> I think this is indicative of a bigger problem: people
> use .as_p, .as_table and .as_li far more than they should, because
> there isn't an enormously convenient alternative. If you want to use
> custom markup for a form at the moment you really have to define the
> HTML for every one of your fields, which is dull, repetitive and means
> that when you change your fields you have to update both your form
> definition and your template.
>
> What's needed is a way to loop over the fields in a form within your
> template, thus making it easy to roll your own custom form markup
> without being repetitive.
>
> I had a play around with this today and I think I've come up with a
> really nice general solution. I've posted it to Django Snippetshttp://www.djangosnippets.org/snippets/1057/, but here's the code:
> If you want even more control, try outhttp://code.google.com/p/django-html/

Simon Willison

unread,
Sep 14, 2008, 7:08:25 PM9/14/08
to Django developers
On Sep 14, 11:54 pm, "alex.gay...@gmail.com" <alex.gay...@gmail.com>
wrote:
> What?  You can iterate over a form as it is and render each field.

Really? How? I'm going to be kicking myself for months.

alex....@gmail.com

unread,
Sep 14, 2008, 7:14:36 PM9/14/08
to Django developers
the __iter__ method on a form yields BoundFields for each field on the
form, which you can then render as you please.

Simon Willison

unread,
Sep 14, 2008, 7:33:00 PM9/14/08
to Django developers


On Sep 15, 12:14 am, "alex.gay...@gmail.com" <alex.gay...@gmail.com>
wrote:
> the __iter__ method on a form yields BoundFields for each field on the
> form, which you can then render as you please.

I am now kicking myself. I honestly have no idea how I missed that,
and it's been bugging me for months. Thank you!

SmileyChris

unread,
Sep 14, 2008, 7:34:50 PM9/14/08
to Django developers
Start kicking... :P

Simon Willison

unread,
Sep 14, 2008, 7:56:29 PM9/14/08
to Django developers
As penance, I've added that idiom to the documentation:

http://code.djangoproject.com/changeset/9030

oggie rob

unread,
Sep 15, 2008, 12:12:03 AM9/15/08
to Django developers
On Sep 14, 4:56 pm, Simon Willison <si...@simonwillison.net> wrote:
> As penance, I've added that idiom to the documentation:
>
> http://code.djangoproject.com/changeset/9030

It might also be worth mentioning that at a project or app level, it
is helpful to re-use that code via the {% include %} tag, e.g.

"If you are using the similar HTML for each of your form fields, you
can reduce duplicate code by looping through each field in turn using
{% for field in form %} (and perhaps re-use that code with the
"include" tag):"

-rob

oggy

unread,
Sep 15, 2008, 5:17:03 AM9/15/08
to Django developers
On Sep 15, 1:08 am, Simon Willison <si...@simonwillison.net> wrote:
> Really? How? I'm going to be kicking myself for months.

Whilst I generally enjoy the sight of people kicking themselves, may I
break you out of it for a moment? :)

I was aware of the __iter__ method, but I generally find the .as_*
methods highly convenient and they work for me in 99% of the cases.
Why should I be forced to do:

<td><label for="{{ field.auto_id }}" {% if field.required
%}class="required_field"{% endif %}>...

Or say I have AJAX fields which are initially not displayed to the
user:

<td><label for="{{ field.auto_id }}" {% ifequal field.name
'my_ajaxy_field1' %}style="display: none;"{% endif %}>...

I don't even know how does that work if I have more such fields, can
you do an "or" with ifequal?

One might argue that this sort of thing is presentation-specific, and
thus belongs to templates. But newforms already gives me virtually
full control over the presentation of my form fields - I can not only
pick my Widget, but I can also pass attrs to it. The only part I have
no control of are labels, which is IMHO inconsistent - and that's one
adjective I use very rarely when it comes to Django.

Simon Willison

unread,
Sep 15, 2008, 5:30:36 AM9/15/08
to Django developers
On Sep 15, 5:12 am, oggie rob <oz.robhar...@gmail.com> wrote:
> > As penance, I've added that idiom to the documentation:
>
> >http://code.djangoproject.com/changeset/9030
>
> It might also be worth mentioning that at a project or app level, it
> is helpful to re-use that code via the {% include %} tag, e.g.

Good call; I've added that as well: http://code.djangoproject.com/changeset/9033

SmileyChris

unread,
Sep 15, 2008, 8:20:05 AM9/15/08
to Django developers
On Sep 15, 10:17 pm, oggy <ognjen.ma...@gmail.com> wrote:
> Why should I be forced to do:
>
> <td><label for="{{ field.auto_id }}" {% if field.required
> %}class="required_field"{% endif %}>...

Just a side note here related to this whole discussion. It's (usually)
much more useful to put this sort of class information in the row tag
rather than directly on the label (or field tag).

Regarding the common cases of required / error, I think that the form
should store the class names and the bound field should have a
row_class function which outputs the common classes for that row.

Eduardo O. Padoan

unread,
Sep 15, 2008, 8:23:05 AM9/15/08
to django-d...@googlegroups.com

I see that you mention wrapping the include tag on a "with" block. My
personal rule is to use an inclusion_tag everytime the snippet that I
want to include contains one or more variables -- you never know when
you'll want to use it with variables of different names.


--
Eduardo de Oliveira Padoan
http://djangopeople.net/edcrypt/

Julien Phalip

unread,
Sep 15, 2008, 8:39:40 AM9/15/08
to Django developers
[...]

> I see that you mention wrapping the include tag on a "with" block. My
> personal rule is to use an inclusion_tag everytime the snippet that I
> want to include contains one or more variables -- you never know when
> you'll want to use it with variables of different names.

That's a good point. Mixing {% include %} and {% with %} is both more
verbose and less flexible than if using a custom tag. In this case,
using a custom filter would also make sense since it's about
presentation:

{{ form|render_form:"thisway" }}

Eduardo O. Padoan

unread,
Sep 15, 2008, 8:50:45 AM9/15/08
to django-d...@googlegroups.com

I tend to see filters more as a way to format text, and inclusion_tags
looks more like function calls:

{% show_fields comment_form %}

And all it takes is:

@register.inclusion_tag('form_snippet.html')
def show_fields(form):
return {'form': form}

The difference is a matter of taste :)

David Larlet

unread,
Sep 15, 2008, 8:57:21 AM9/15/08
to django-d...@googlegroups.com

Le 15 sept. 08 à 14:39, Julien Phalip a écrit :

Yes, someone suggests to use as_* as filters like {{ form|as_p }}
months ago (I can't find the thread) and that was clearly an
improvement in terms of flexibility. Maybe it's time to discuss this
point?

David

TiNo

unread,
Sep 15, 2008, 9:17:40 AM9/15/08
to django-d...@googlegroups.com
To come back on the problem of the TS, why not give all labels containing a required field a 'required' class by default? As is done in the admin interface. (if 'required' is to common, it could also be 'required_label' or something like that)

Eduardo O. Padoan

unread,
Sep 15, 2008, 9:21:39 AM9/15/08
to django-d...@googlegroups.com
On Mon, Sep 15, 2008 at 10:17 AM, TiNo <tin...@gmail.com> wrote:
> To come back on the problem of the TS, why not give all labels containing a
> required field a 'required' class by default? As is done in the admin
> interface. (if 'required' is to common, it could also be 'required_label' or
> something like that)

I'm not sure it is good to the framework to force it to designers.
Some people prefer "*", other may have already a use for a "required"
class, and so on.


> On Mon, Sep 15, 2008 at 2:57 PM, David Larlet <lar...@gmail.com> wrote:
>>
>>
>> Le 15 sept. 08 à 14:39, Julien Phalip a écrit :
>>
>> >
>> > [...]
>> >
>> >> I see that you mention wrapping the include tag on a "with" block. My
>> >> personal rule is to use an inclusion_tag everytime the snippet that I
>> >> want to include contains one or more variables -- you never know when
>> >> you'll want to use it with variables of different names.
>> >
>> > That's a good point. Mixing {% include %} and {% with %} is both more
>> > verbose and less flexible than if using a custom tag. In this case,
>> > using a custom filter would also make sense since it's about
>> > presentation:
>> >
>> > {{ form|render_form:"thisway" }}
>>
>> Yes, someone suggests to use as_* as filters like {{ form|as_p }}
>> months ago (I can't find the thread) and that was clearly an
>> improvement in terms of flexibility. Maybe it's time to discuss this
>> point?
>>
>> David
>>
>>
>>
>
>
> >
>

--

Eduardo de Oliveira Padoan
http://djangopeople.net/edcrypt/

http://whoisi.com/p/514
http://pinax.hotcluboffrance.com/profiles/edcrypt/

Simon Willison

unread,
Sep 15, 2008, 11:29:51 AM9/15/08
to Django developers
On Sep 15, 1:23 pm, "Eduardo O. Padoan" <eduardo.pad...@gmail.com>
wrote:
> > Good call; I've added that as well:http://code.djangoproject.com/changeset/9033
>
> I see that you mention wrapping the include tag on a "with" block. My
> personal rule is to use an inclusion_tag everytime the snippet that I
> want to include contains one or more variables -- you never know when
> you'll want to use it with variables of different names.

I'll put in a pointer to the inclusion_tag documentation, but
personally I much prefer the with/include pattern as it lets you
abstract out your form logic without needing to write any Python code
at all. This is important if you are working with client-side
developers who don't touch your Python (the use-case for which the
Django template language was originally designed).

Cheers,

Simon

Simon Willison

unread,
Sep 15, 2008, 11:31:29 AM9/15/08
to Django developers
On Sep 15, 1:39 pm, Julien Phalip <jpha...@gmail.com> wrote:
> That's a good point. Mixing {% include %} and {% with %} is both more
> verbose and less flexible than if using a custom tag. In this case,
> using a custom filter would also make sense since it's about
> presentation:
>
> {{ form|render_form:"thisway" }}

I'm not at all keen on that approach, for the same reason that I don't
like the form.as_p shortcuts in general: it hides your HTML, making it
much less clear how you modify the generated markup. Using an {%
include %} tag makes the location of the actual HTML for the form
explicit.

Joseph Kocherhans

unread,
Sep 15, 2008, 11:52:40 AM9/15/08
to django-d...@googlegroups.com

I disagree with you here, but you're actually writing code so... :) (I
really need to change that soon.)

Regardless of whether we do rendering with tags or filters, both
approaches would benefit from some additional attributes in fields and
widgets. When I'm writing forms I want to do as little work as
possible, but be able to override things on a very granular level when
I need to. I think a good start here would be to expose the html
element name, attributes, and children as attributes of BoundField (or
possibly also a new BoundWidget class), the existing render methods
could then be changed to use those attributes and tags and filters
would have access to everything they needed to turn those structures
into (X)HTML (N). I haven't quite figured out the details of how to
handle multi widgets, radio inputs, or other widgets with multiple
child inputs, but it shouldn't be that difficult to work out, and all
in a backwards compatible way.

Joseph

oggy

unread,
Sep 15, 2008, 1:24:54 PM9/15/08
to Django developers
On Sep 15, 2:20 pm, SmileyChris <smileych...@gmail.com> wrote:
> Just a side note here related to this whole discussion. It's (usually)
> much more useful to put this sort of class information in the row tag
> rather than directly on the label (or field tag).
>
> Regarding the common cases of required / error, I think that the form
> should store the class names and the bound field should have a
> row_class function which outputs the common classes for that row.

I don't see a huge difference between assigning the "required" class
to the label/field tag vs. assigning it to a <tr> (or a <li> for that
matter), except that you have to define the class only once vs.
defining it twice, once for label and once for the widget.

OTOH, this is a very common idiom:

{% for field in form %}
<tr class="{% cycle row_1,row2 %}">

I guess you could get away with:
<tr class="{% cycle row_1,row2 %}{% if field.row_class %}
{{ field.row_class }}{% endif %}">

But how would you go about adding a style="display: none;" from my
previous example to that? I can't come up with anything particulary
elegant.

oggy

unread,
Sep 15, 2008, 1:36:00 PM9/15/08
to Django developers
On Sep 15, 3:17 pm, TiNo <tin...@gmail.com> wrote:
> To come back on the problem of the TS, why not give all labels containing a
> required field a 'required' class by default? As is done in the admin
> interface. (if 'required' is to common, it could also be 'required_label' or
> something like that)

I wouldn't really be in favour of this approach, not only would you
force the choice as Eduardo pointed out, but it would also make it
impossible to turn the attributes off if you didn't want them.
Besides, occassionally you'd need (at least I need) to control
attributes other than just "class".

Waylan Limberg

unread,
Sep 15, 2008, 2:15:35 PM9/15/08
to django-d...@googlegroups.com
On Mon, Sep 15, 2008 at 1:24 PM, oggy <ognjen...@gmail.com> wrote:
>
> On Sep 15, 2:20 pm, SmileyChris <smileych...@gmail.com> wrote:
>> Just a side note here related to this whole discussion. It's (usually)
>> much more useful to put this sort of class information in the row tag
>> rather than directly on the label (or field tag).
>>
>> Regarding the common cases of required / error, I think that the form
>> should store the class names and the bound field should have a
>> row_class function which outputs the common classes for that row.
>
> I don't see a huge difference between assigning the "required" class
> to the label/field tag vs. assigning it to a <tr> (or a <li> for that
> matter), except that you have to define the class only once vs.
> defining it twice, once for label and once for the widget.
>

For those who weren't around or don't remember, this was a much
debated issue some time ago. Currently, there are at least two open
tickets (#3512 & #3515) vying for inclusion with different solutions
for adding classes to fields. Unfortunately, neither has been updated
in some time and both are now out-of-date with trunk.

See this comment for how to do it in your template now:
http://code.djangoproject.com/ticket/3512#comment:15

For the record, I'm still of the opinion that #3512 is the right way
to go and anything else should be left for template others to do
manually as I argued in various comments in that ticket.

--
----
Waylan Limberg
way...@gmail.com

Justin Fagnani

unread,
Sep 15, 2008, 4:49:59 PM9/15/08
to django-d...@googlegroups.com
I haven't been able to read the whole thread yet, but I want mention
two thoughts I've had that might be relevant.

1) For a while I've thought that Forms should support "widget sets"
where you can replace the default widgets on every form field with one
setting in Meta (this would require Meta on non-model forms). This
would open things up so you could easily use Widget subclasses with
customized output. This would let people have template based widgets
if they wished, or easily specific JS libraries for complex widgets
like auto-complete, etc.

I'd personally like to have a template-based widget set that let me
specify a directory to load my customized templates from:

class MyForm(forms.Form):
class Meta:
widget_set = TemplateWidgetSet('my_jquery_widgets')


2) I've also thought that'd it would be really nice to have some way
of dynamically transforming template output from within the template.
Basically doing jQuery-type manipulations in templates, possibly with
XPath or jQuery-style selectors. You could add a required class like
this:

{% transform %}
{% addclass "tr:has(*.required) label" "required" %}
{{ form }}
{% endtransform %}


Where I want to us that isn't with forms, but with menus:

{% transform %}
{% select %}#menu_{{ section }}{% endselect %}
{% addclass "selected" %}
<li id="menu_home"><a>Home</a></li>
<li id="menu_foo"><a>Foo</a></li>
...etc...
{% endtransform %}

That would add a "selected" class to the current sections menu item.
Right now I have to include a template that has an {% if %} inside
every <li> tag.

Just thought I'd throw this out there...

Cheers,
Justin

Simon Willison

unread,
Sep 15, 2008, 11:19:05 PM9/15/08
to Django developers
On Sep 15, 9:49 pm, "Justin Fagnani" <justin.fagn...@gmail.com> wrote:
> 2) I've also thought that'd it would be really nice to have some way
> of dynamically transforming template output from within the template.
> Basically doing jQuery-type manipulations in templates, possibly with
> XPath or jQuery-style selectors.

That's a really neat idea, but I don't think it could ever be accepted
in to Django's core set of template tags to the performance
implications. Actually implementing this requires Django to run an
HTML parser over a generated template, which has a significant
overhead and is a departure from our general philosophy of keeping the
core template system fast by avoiding expensive operations.

It would absolutely be a good idea to build as a third party
templatetags package, and it might even be something that could go in
django.contrib.webdesign once it had proved itself.

If you want to have a go at implementing it you may find my
http://code.google.com/p/soupselect CSS selector library for
BeautifulSoup useful. It doesn't support some of the advanced jQuery
selectors though (patches welcome!)

> Where I want to us that isn't with forms, but with menus:
>
> {% transform %}
>     {% select %}#menu_{{ section }}{% endselect %}
>     {% addclass "selected" %}
>     <li id="menu_home"><a>Home</a></li>
>     <li id="menu_foo"><a>Foo</a></li>
> ...etc...
> {% endtransform %}
>
> That would add a "selected" class to the current sections menu item.
> Right now I have to include a template that has an {% if %} inside
> every <li> tag.

There's a neat CSS trick you can use for this kind of thing:

<ul class="menu-for-{{ section }}">
<li id="menu_home">...</li>
<li id="menu_foo">...</li>
</ul>

Then in your CSS:

.menu-for-home #menu_home,
.menu-for-foo #menu_foo {
background-color: #fff;
}

Rather than setting a class of selected on the current menu item, you
add a class to a containing element then use CSS selectors to say
"when the menu_foo item is in the .menu-for-foo container, highlight
it".

You can even put the section class on the <body> element of the page
itself, which lets you use contextual CSS to customise all sorts of
other pieces in addition to which menu item is highlighted.

Cheers,

Simon


oggy

unread,
Sep 16, 2008, 5:41:17 AM9/16/08
to Django developers
On Sep 15, 10:49 pm, "Justin Fagnani" <justin.fagn...@gmail.com>
wrote:
> 1) For a while I've thought that Forms should support "widget sets"
> where you can replace the default widgets on every form field with one
> setting in Meta (this would require Meta on non-model forms). This
> would open things up so you could easily use Widget subclasses with
> customized output. This would let people have template based widgets
> if they wished, or easily specific JS libraries for complex widgets
> like auto-complete, etc.

I can clearly see the appeal of the idea. Django can stay Javascript-
agnostic, while the community could develop a PrototypeForms,
DojoForms, etc. and it would be a single settings for the user. One
problem I see is that for AJAX, you need to add view support. If I
were to switch from my regular form to an AJAX form with just a Meta
setting, how is my once-a-plain-CharFeild-but-now-auto-complete Widget
supposed to find its supporting view?

> 2) I've also thought that'd it would be really nice to have some way
> of dynamically transforming template output from within the template.
> Basically doing jQuery-type manipulations in templates, possibly with
> XPath or jQuery-style selectors. You could add a required class like
> this:
>
> {% transform %}
>     {% addclass "tr:has(*.required) label" "required" %}
>     {{ form }}
> {% endtransform %}

That seems wicked cool, even if I don't understand it fully :D What
does "has(*.required)" select? A tr with a descendant with a
"required" class? It doesn't seem like XPath to me (but then again
it's been a couple of years since I last dealt with XPath), so I'm
guessing it's jQuery?

But, as Simon pointed out, it might be a pretty big performance hog.
And generally the template library mostly contains easy-to-undestand
functionality, while "transform" just screams XSLT :)

Brian Beck

unread,
Sep 21, 2008, 11:12:39 AM9/21/08
to Django developers
On Sep 15, 8:50 am, "Eduardo O. Padoan" <eduardo.pad...@gmail.com>
wrote:
> On Mon, Sep 15, 2008 at 9:39 AM, Julien Phalip <jpha...@gmail.com> wrote:
> > That's a good point. Mixing {% include %} and {% with %} is both more
> > verbose and less flexible than if using a custom tag. In this case,
> > using a custom filter would also make sense since it's about
> > presentation:
>
> > {{ form|render_form:"thisway" }}
>
> I tend to see filters more as a way to format text, and inclusion_tags
> looks more like function calls:
>
> {% show_fields comment_form %}

I've long been of the opinion that this is the way to go for form
rendering. The problem is that it's not easy to tell the inclusion
tag to use a different template, for those who want to customize. And
as Simon points out, it's not immediately obvious where the actually
HTML is pulled from. However:

- Any template can be globally overridden - all you need to know is
the name
- Ticket 9093[1] will greatly improve this situation

Since I was doing it this way for a large project, I already had the
code written, so I cleaned it up and released it as django-
renderform[2]. I think this approach has a much more appealing future
than as_p, as_ul, as_table and such, especially if #9093 makes it in.

[1]: http://code.djangoproject.com/ticket/9093
[2]: http://code.google.com/p/django-renderform/

Justin Fagnani

unread,
Sep 22, 2008, 8:01:41 PM9/22/08
to django-d...@googlegroups.com
On Tue, Sep 16, 2008 at 2:41 AM, oggy <ognjen...@gmail.com> wrote:
> On Sep 15, 10:49 pm, "Justin Fagnani" <justin.fagn...@gmail.com>
> I can clearly see the appeal of the idea. Django can stay Javascript-
> agnostic, while the community could develop a PrototypeForms,
> DojoForms, etc. and it would be a single settings for the user.

That would be the idea. You of course noticed some wrinkles, but I
think it'd be awesome if you could install a djQuery or djojo app and
get a bunch of form widgets and view base classes effectively give you
AJAX support of of the box.

> One problem I see is that for AJAX, you need to add view support. If I
> were to switch from my regular form to an AJAX form with just a Meta
> setting, how is my once-a-plain-CharFeild-but-now-auto-complete Widget
> supposed to find its supporting view?

I don't think that's too much of an issue. A CharField is never going
to magically going to convert to an AutoCompleteField without
specifying the data source to work from, but an AutoCompleteField
could provide a common interface that would allow the dev to switch
implementations. Maybe class based views could then be used to easily
provide the correct output format. A ChoiceField could be AJAXified
without additional configuration.

>> 2) I've also thought that'd it would be really nice to have some way
>> of dynamically transforming template output from within the template.
>> Basically doing jQuery-type manipulations in templates, possibly with
>> XPath or jQuery-style selectors. You could add a required class like
>> this:
>>
>> {% transform %}
>> {% addclass "tr:has(*.required) label" "required" %}
>> {{ form }}
>> {% endtransform %}
>
> That seems wicked cool, even if I don't understand it fully :D What
> does "has(*.required)" select? A tr with a descendant with a
> "required" class? It doesn't seem like XPath to me

Yeah, tha'ts jQuery, not XPath. "tr:has(*.required)" would be
approximately "tr[*[contains(@class, 'required')]]" in XPath, I think.
XPath is ugly when using predicates.

> But, as Simon pointed out, it might be a pretty big performance hog.
> And generally the template library mostly contains easy-to-undestand
> functionality, while "transform" just screams XSLT :)

This is true, but since templates are usually used to generate HTML,
it seems like a good idea to offer some HTML/XML specific features
when there's a benefit. Not sure if this counts since it's easily
contained in a third-party app.

-Justin

Reply all
Reply to author
Forward
0 new messages