I have been pretty unhappy about the way html has been generated from newforms for awhile now. I think we've come up with a good design that makes form rendering a lot easier, and a lot more modular. The basic idea is to render forms, formsets, errors, etc. with filters. Here are a few examples:
{% load forms %}
{{ formset|as_ul }} Render the entire formset as a ul {{ form|as_ul }} Render the entire form as a ul {{ field|as_li }} Render the given field and label as an li
{{ formset.non_form_errors|as_ul }} Render non_form_errors as a ul {{ formset.errors|as_ul }} Render errors as a ul {{ form.errors|as_ul }} Render errors as a ul {{ field.errors|as_ul }} Render field errors as as ul
The same idea would apply to widgets, and would let the html pedants *cough* ubernostrum *cough* ;-) have their non-xhtml ways without adding 2 methods to every single widget.
{{ field.widget|as_html }} Render the widget as html 4 {{ field.widget|as_xhtml }} Render the widget as xhtml
To accomplish this, each widget would get a new attrs() method that would return a dict that basically consisted of html attributes. (In practice it will be slightly more complicated than this, especially for select widgets, but you get the idea). The as_html and as_xhtml filters will be able to turn the dict into html code.
So how does this work from a backwards compatibility standpoint? For now, things can be completely backwards compatible. I would like the as_X methods to be deprecated, but the __unicode__ method would stick around for those poor souls who are working in our template language. Of course, they could import the filters and apply them manually (as tests might often do), but they won't have to. They just don't get to customize output.
> I have been pretty unhappy about the way html has been generated from > newforms for awhile now. I think we've come up with a good design that > makes form rendering a lot easier, and a lot more modular. The basic > idea is to render forms, formsets, errors, etc. with filters. Here are
This is a good idea. I do something similiar in my app also.
Joseph Kocherhans wrote: > I have been pretty unhappy about the way html has been generated from > newforms for awhile now. I think we've come up with a good design that > makes form rendering a lot easier, and a lot more modular. The basic > idea is to render forms, formsets, errors, etc. with filters.
On Tue, Mar 18, 2008 at 4:45 PM, Joseph Kocherhans
<jkocherh...@gmail.com> wrote: > I have been pretty unhappy about the way html has been generated from > newforms for awhile now. I think we've come up with a good design that > makes form rendering a lot easier, and a lot more modular. The basic > idea is to render forms, formsets, errors, etc. with filters.
Love it. For the record, I talked about this with Joseph here in person -- it's a good improvement.
Adrian
-- Adrian Holovaty holovaty.com | djangoproject.com | everyblock.com
> I have been pretty unhappy about the way html has been generated from > newforms for awhile now. I think we've come up with a good design that > makes form rendering a lot easier, and a lot more modular. The basic > idea is to render forms, formsets, errors, etc. with filters. Here are > a few examples:
> {% load forms %}
> {{ formset|as_ul }} Render the entire formset as a ul > {{ form|as_ul }} Render the entire form as a ul > {{ field|as_li }} Render the given field and label as an li
I seem to remember a similar suggestion being raised in the early days of newforms, but it got lost in the noise of the initial design discussions.
On Mar 18, 9:45 pm, "Joseph Kocherhans" <jkocherh...@gmail.com> wrote:
> I have been pretty unhappy about the way html has been generated from
> newforms for awhile now. I think we've come up with a good design that
> makes form rendering a lot easier, and a lot more modular. The basic
> idea is to render forms, formsets, errors, etc. with filters. Here are
> a few examples:
> {% load forms %}
> {{ formset|as_ul }} Render the entire formset as a ul
> {{ form|as_ul }} Render the entire form as a ul
> {{ field|as_li }} Render the given field and label as an li
I've been thinking along similar lines recently, but leaning towards
tags rather than filters. One problem with newforms that hasn't been
addressed yet is that it's hard to apply custom attributes to form
fields - in particular class="", but also attributes like tabindex and
accesskey.
Filters can't take extra arguments, but tags can. I was thinking along
these lines:
{% field email class="special" tabindex="3" %}
For the XHTML/HTML problem (which drives me batty, I have a custom {%
filter %} just to get rid of those nasty slashes) I've been thinking
about having a {% doctype %} tag. This would do two things: it would
save you from having to remember doctype strings - just drop {%
doctype html4strict %} or {% doctype xhtml1trans %} at the top of your
page and the tag will output the correct doctype for you. It would
also set a special variable in the template context (I was thinking
_doctype) which template tags that output HTML could use to decide if
they were going to use XHTML or HTML style output tags.
On Sat, Mar 22, 2008 at 5:32 AM, Simon Willison <si...@simonwillison.net> wrote:
> For the XHTML/HTML problem (which drives me batty, I have a custom {% > filter %} just to get rid of those nasty slashes) I've been thinking > about having a {% doctype %} tag. This would do two things: it would > save you from having to remember doctype strings - just drop {% > doctype html4strict %} or {% doctype xhtml1trans %} at the top of your > page and the tag will output the correct doctype for you. It would > also set a special variable in the template context (I was thinking > _doctype) which template tags that output HTML could use to decide if > they were going to use XHTML or HTML style output tags.
That's beautiful. I especially like the idea of the doctype "setting" telling what the tags to do.
I've always thought the idea of a post-processing filter to strip the slashes wasn't the best approach but the only other way I found was to make a set of HTML4 widgets, which I've done here: http://www.djangosnippets.org/snippets/618/
But it's always seemed a bit hackish, especially since I'm having to copy/paste all of the render() method just to remove the slash. My fear is that I won't notice if/when the base's render() method changes.
I'm happy to see this conversation and would be happy to help implement these ideas once they're hammered down.
> {{ formset|as_ul }} Render the entire formset as a ul > {{ form|as_ul }} Render the entire form as a ul > {{ field|as_li }} Render the given field and label as an li
+1 This is very cool
> {% field email class="special" tabindex="3" %}
-0
This would be convenient, but I think a filter is cleaner and more consistent, e.g.:
{{ field|class:"special"|as_li }}
This would keep it compatible with the original suggest, which I think is a logical approach. You could make the filter accept either a Field object or a string, i.e. if "field" is a Field object, then update the class attribute in the widget, so that it will be there when the widget is rendered later. If "field" is a HTML (basestring?), then update the class attribute in the top element. "tabindex" could be handled as a filter too... of course, a filter for each possible attribute is not a generic approach, but we don't use that many HTML attributes for forms and I think another tag would be clutter.
> I've been thinking about having a {% doctype %} tag.
> {% load forms %}
> {{ formset|as_ul }} Render the entire formset as a ul
> {{ form|as_ul }} Render the entire form as a ul
> {{ field|as_li }} Render the given field and label as an li
> I've been thinking about having a {% doctype %} tag.
On Mar 22, 11:21 am, "Will Hardy" <e.willha...@gmail.com> wrote:
> {{ field|class:"special"|as_li }}
> [...]
> > I've been thinking about having a {% doctype %} tag.
I could be uninformed, but as of now template filters cannot access
the context, and so you can't use filter while expecting doctype to do
the right thing. I think this was the main motivation behind Simon
suggesting tags.
That and
{{ email|class:"special"|tabindex:3|as_li }}
requires a lot of tricks to work properly (and isn't even that
readable) whereas
{% field email class="special" tabindex="3" list %}
can work with a lot of special object communication and can do a lot
of really nifty things with the context (like make list default, use
the doctype setting, etc).
On Mar 22, 10:09 pm, Mike Axiak <mcax...@gmail.com> wrote:
> On Mar 22, 11:21 am, "Will Hardy" <e.willha...@gmail.com> wrote:> {{ field|class:"special"|as_li }}
> > [...]
> > > I've been thinking about having a {% doctype %} tag.
> I could be uninformed, but as of now template filters cannot access
> the context, and so you can't use filter while expecting doctype to do
> the right thing. I think this was the main motivation behind Simon
> suggesting tags.
It was - but the ability to customise attributes turned out to be a
side effect that was potentially even more useful.
On Sun, Mar 23, 2008 at 6:01 AM, Simon Willison <si...@simonwillison.net> wrote:
> On Mar 22, 10:09 pm, Mike Axiak <mcax...@gmail.com> wrote: > > On Mar 22, 11:21 am, "Will Hardy" <e.willha...@gmail.com> wrote:> {{ field|class:"special"|as_li }} > > > [...] > > > > I've been thinking about having a {% doctype %} tag.
> > I could be uninformed, but as of now template filters cannot access > > the context, and so you can't use filter while expecting doctype to do > > the right thing. I think this was the main motivation behind Simon > > suggesting tags.
> It was - but the ability to customise attributes turned out to be a > side effect that was potentially even more useful.
Moreover, the use of filters means that the form can now provide a better interface for us to write our own fitlers, or tags, etc. Sort of like what they say about UNIX tools ... small tools combined to make bigger ones.
> On Sun, Mar 23, 2008 at 6:01 AM, Simon Willison <si...@simonwillison.net> wrote:
> > On Mar 22, 10:09 pm, Mike Axiak <mcax...@gmail.com> wrote:
> > > On Mar 22, 11:21 am, "Will Hardy" <e.willha...@gmail.com> wrote:> {{ field|class:"special"|as_li }}
> > > > [...]
> > > > > I've been thinking about having a {% doctype %} tag.
> > > I could be uninformed, but as of now template filters cannot access
> > > the context, and so you can't use filter while expecting doctype to do
> > > the right thing. I think this was the main motivation behind Simon
> > > suggesting tags.
> > It was - but the ability to customise attributes turned out to be a
> > side effect that was potentially even more useful.
> Moreover, the use of filters means that the form can now provide a
> better interface for us to write our own fitlers, or tags, etc. Sort
> of like what they say about UNIX tools ... small tools combined to
> make bigger ones.
On Mar 18, 5:45 pm, "Joseph Kocherhans" <jkocherh...@gmail.com> wrote:
> I have been pretty unhappy about the way html has been generated from
> newforms for awhile now. I think we've come up with a good design that
> makes form rendering a lot easier, and a lot more modular. The basic
> idea is to renderforms, formsets, errors, etc. with filters. Here are
> a few examples:
> {% load forms %}
> ...
Has anyone started working on this? I don't see a branch, but I'd
love to help out. I've also been writing similar tags and filters for
my form rendering (see [1]). I definitely agree with using tags
instead of filters due to their flexibility. Unlike the current
situation I hope these would render using the, *ahem*, templating
system? You know that thing for HTML generation and such? Then
people can really bust out the customization with their own widget/
label/form templates.
> Has anyone started working on this? I don't see a branch, but I'd
> love to help out. I've also been writing similar tags and filters for
> my form rendering (see [1]).
<snip>
> [1]:http://www.djangosnippets.org/snippets/693/
I'd like to know too. I especially liked both of Simon Willison's
ideas of 1) Template tags for form rendering, and 2) Outputting and
setting of a _doctype variable that the template tags use to decide
what kind of HTML to output.
If nobody has officially started anything, could we set up a Google
code project with the hopes of this being included in Django once it's
working and all the kinks are worked out?
-Rob
On May 21, 2:30 am, Aral Balkan <aralbal...@gmail.com> wrote:
On Wed, May 21, 2008 at 4:30 AM, Aral Balkan <aralbal...@gmail.com> wrote:
> Just a quick bump: has there been any progress on this?
Not really. I started the implementation on the plane ride back from PyCon, realized that it wouldn't work *quite* the way I'd proposed (widgets don't have access to form data, only BoundFields do), and haven't gotten back to it yet.