Hi Gregor,
On the way home from DjangoCon I realized there is a (IMHO) elegant
solution to this problem that is closer to the nature of django's
template language.
What you want with form-rendering is having defaults, but being able
to override them; which is something you can do with django's
templates. I think something like the following would be conceptually
nice:
# in some template
{% with my_form as form %}
{% include 'my_app/my_form.html' %}
{% endwith %}
# in templates/my_app/my_form.html
{% extends 'form_as_table.html' %}
{% block fieldblock %}
{% ifequal field.name 'unnecessary_field' %}
{# don't use this field #}
{% else %}
{{ block.super }}
{% endifequal %}
{% endblock %}
# in templates/form_as_table.html
{% block form %}
{% block formerrors %}
...{# formerrors rendered #}
{% endblock %}
{% block fields %}
{% for field in form.fields %}
{% block field %}
<tr>
<th>{% block label %}...{# label rendered #}{% endblock
%}</th>
<td>
{% block fielderrors %}...{# fielderrors rendered #}
{% endblock %}
{% block widget %}...{# widged rendered #}{% endblock
%}
</td>
</tr>
{% endblock %}
{% endfor %}
{% endblock %}
{% endblock %}
Now this is not ideal in a few ways; as far as I can see:
1) the form rendering has to be done in a separate file, because
inheritance is needed
2) it would be more elegant if every field-block would have its own name
Django's template language could be extended a little bit (?) to
improve this:
1) block inheritance -- like a template can extend another template, a
block could be able to extend another block or template:
{% block form %}
{% extends 'partial.html' %}{# or extendsblock block.super #}
{% endblock form %}
2) dynamic block names -- like a template name in an {% extends %} tag
can be either a string or a variable, the same could hold for the
block name in a {% block %} tag (backward compatibility would have to
be solved somehow; different tag name/extra argument/...).
This would result in something like (for removing a field):
{% with my_form as form %}
{% block form %}
{% extends 'form_as_table.html' %}
{% dynamically_named_block 'unnecessary_field' %}
{# overrides the field with nothing #}
{% enddynamically_named_block %}
{% endblock %}
{% endwith %}
Note that also the unnecessary_field-block can extend its base block.
Choosing exactly which fields to render could be done like this:
{% with my_form as form %}
{% block form %}
{% extends 'form_as_table.html' %}
{% block fields %}
{% for field_name in 'field1 field2 field3'|split %}
{% dynamically_named_block field_name %}
{{ block.super }}{# refers to the
dynamically_named_block #}
{% enddynamically_named_block %}
{% endfor %}
{% endblock fields %}
{% endblock %}
{% endwith %}
Just brainstorming... let me know what you think.
Cheers, Roald
On Jun 3, 2011, at 4:58 PM, Gregor Müllegger wrote:
Hi,
this is the second RFC regarding template form rendering API/syntax.
The first
one defined how a complete form or a subset of fields will be
rendered. I'm
now proposing more tags to render more details like only the label
of a form
field.
Currently we haven't discussed how we will substitute what we
currently do
with using::
{{ form.non_field_errors }}
{{ form.errors }}
{{ form.field.errors }}
{{ form.field.help_text }}
{{ form.field.label_tag }}
We will implement these with template tags that are aware of the
currently
used layout:
Substituting {{ \*.errors }}::
{% formerrors <form instance|field instance|any ErrorList/ErrorDict>
%}
Some examples:
Display *all* errors of a form::
{% formerrors my_form %} (equals current {{ my_form.errors }})
Non-field errors::
{% formerrors my_form.non_field_errors %} equals
{{ my_form.non_field_errors }}
Single-field errors::
{% formerrors my_form.firstname %} equals
{{ my_form.firstname.errors }}
Basically it will render the error list/dict that is available in
the *errors*
attribute of the passed in object. As an alternative (e.g. the
non_field_errors) you can pass in directly a error list that gets
rendered::
{% formerrors my_custom_error_list %}
{% formerrors my_form.field.errors %}
Substituting ``{{ form.field.label_tag }}``
This one might be pretty obvious::
{% formlabel my_form.field %}
Substituting {{ form.field.help_text }}
Also pretty obvious::
{% formhelp my_form.field %}
But the naming is IMO not ideal. {% helptext %} as alternative is
reasonable,
but Carl and I agreed on that we wanted the tag to start with form*
but
{% formhelptext %} is to long. So we settled on {% formhelp %}
Better suggestions are welcome.
That's it basically. I don't see any controversies in here, but as
usual
with a RFC: comments are requested and will be integrated. :-)
--
Servus,
Gregor Müllegger
--
You received this message because you are subscribed to the Google
Groups "Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
.
To unsubscribe from this group, send email to django-developers+unsubscr...@googlegroups.com
.
For more options, visit this group at http://groups.google.com/group/django-developers?hl=en
.
--
You received this message because you are subscribed to the Google Groups "Django
developers" group.
To post to this group, send email to django-developers@googlegroups.com.
To unsubscribe from this group, send email to
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at
http://groups.google.com/group/django-developers?hl=en.