Proposal: {% doctype %} and {% field %} tag for outputting form widgets as HTML or XHTML

15 views
Skip to first unread message

Simon Willison

unread,
Sep 9, 2008, 7:28:56 PM9/9/08
to Django developers
Back in March there was a discussion about providing a way to output
django.forms widgets as HTML (at the moment they always use XHTML,
which leads to nastyness on sites using an HTML doctype):

http://groups.google.com/group/django-developers/browse_thread/thread/5f3694b8a19fb9a1/

On the plane back from DjangoCon I implemented the {% doctype %} and
{% field %} tags I proposed in that thread as custom template tags in
an application called "django_html". You can grab the code from here
and try it out:

http://code.google.com/p/django-html/

svn checkout http://django-html.googlecode.com/svn/trunk/django_html
django_html

(put django_html somewhere on your python path and add it to
INSTALLED_APPS)

I'm pretty confident this is the right approach. What do people think?

Rob Hudson

unread,
Sep 9, 2008, 7:56:43 PM9/9/08
to django-d...@googlegroups.com
On 9/9/08, Simon Willison <si...@simonwillison.net> wrote:
>
> Back in March there was a discussion about providing a way to output
> django.forms widgets as HTML (at the moment they always use XHTML,
> which leads to nastyness on sites using an HTML doctype):

After I read that I created the doctype part in a patch on this ticket
but didn't have the genius idea of the {% field %} tag to take it the
rest of the way...
http://code.djangoproject.com/ticket/7281

So awesome and simple. I love it.

I'll get rid of my weird form hack on my latest project and test this out soon.

Thanks,
Rob

Ville Säävuori

unread,
Sep 9, 2008, 10:32:48 PM9/9/08
to Django developers
> On the plane back from DjangoCon I implemented the {% doctype %} and
> {% field %} tags I proposed in that thread as custom template tags in
> an application called "django_html". You can grab the code from here
> and try it out:

> I'm pretty confident this is the right approach. What do people think?

I *love* the idea behind this.

I hate the fact that Django only outputs XHTML out of the box, even
though it should be the Web framework for perfectionists (with
deadlines and no time to write custom renderers only to get valid
HTML :)

About the {% doctype %} tag, should we then maintain a (potentially
long?) list of different doctypes and/or should there be a way to
define your own?

- VS

Simon Willison

unread,
Sep 10, 2008, 4:49:08 AM9/10/08
to Django developers
On Sep 10, 3:32 am, Ville Säävuori <vi...@syneus.fi> wrote:
> About the {% doctype %} tag, should we then maintain a (potentially
> long?) list of different doctypes and/or should there be a way to
> define your own?

I think we should maintain a list of doctypes - there really aren't
that many: xhtml1, xhtml1trans, xhtml1frameset, html4, html4trans,
html4frameset, xhtml11 and html5 should cover everything.

The current design of the {% doctype %} tag supports setting your own
custom doctype using the "silent" argument. You need to pick a
supported doctype that is closest to your own, then supress output
with "silent" and add your own instead:

{% doctype "xhtml1" silent %}<!DOCTYPE my-custom-xhtml-doctype>

Cheers,

Simon

Ivan Sagalaev

unread,
Sep 10, 2008, 5:19:01 AM9/10/08
to django-d...@googlegroups.com
Simon Willison wrote:
> {% doctype "xhtml1" silent %}<!DOCTYPE my-custom-xhtml-doctype>

To me it looks a bit weird but I'm afraid my English is not apt to dare
to describe it :-). May be this will look cleaner:

{% doctype "xhtml1" "<!DOCTYPE my-custom-xhtml-doctype>" %}

E.g. instead of "doctype(mode, silent=False)" it's "doctype(mode,
override='')"

Sean Legassick

unread,
Sep 10, 2008, 6:13:04 AM9/10/08
to django-d...@googlegroups.com

On 10 Sep 2008, at 09:49, Simon Willison wrote:
> I think we should maintain a list of doctypes - there really aren't
> that many: xhtml1, xhtml1trans, xhtml1frameset, html4, html4trans,
> html4frameset, xhtml11 and html5 should cover everything.

There's also xhtml-mp, wml and chtml for mobile apps...

> The current design of the {% doctype %} tag supports setting your own
> custom doctype using the "silent" argument. You need to pick a
> supported doctype that is closest to your own, then supress output
> with "silent" and add your own instead:

...which can always be handled by this mechanism if not directly
supported.

--
Sean L

Rob Hudson

unread,
Sep 10, 2008, 12:29:11 PM9/10/08
to django-d...@googlegroups.com
On 9/9/08, Simon Willison <si...@simonwillison.net> wrote:
> http://code.google.com/p/django-html/

As a 3rd party app this is awesome. It's simple and clean and doesn't
require much from the user.

But as part of Django itself, it seems like fixing django.forms (the
source) would be a better solution.

To avoid adding yet another setting (unless it's warranted here) can
the setting of a doctype in a template tag set a value in
django.conf.settings that django.forms can then check (with a
reasonable default)?

I recall seeing a patch that adds a new setting and updates (at the
time) django.newforms with some if/else logic based on the setting to
the various widgets' render methods. I can't seem to find it now.

I'm just trying to point out that for Django to output a string that
then later gets "fixed" smells funny to me (ask Malcolm likes to say).

-Rob

Ivan Sagalaev

unread,
Sep 10, 2008, 3:34:13 PM9/10/08
to django-d...@googlegroups.com
Rob Hudson wrote:
> To avoid adding yet another setting (unless it's warranted here) can
> the setting of a doctype in a template tag set a value in
> django.conf.settings that django.forms can then check (with a
> reasonable default)?

Why not just adopt {% field %} as a default way for rendering fields
instead of unicode()ing a them? As far as I recall Simon had already
proposed this some time ago.

Simon Willison

unread,
Sep 10, 2008, 3:43:17 PM9/10/08
to Django developers
On Sep 10, 5:29 pm, "Rob Hudson" <treborhud...@gmail.com> wrote:
> To avoid adding yet another setting (unless it's warranted here) can
> the setting of a doctype in a template tag set a value in
> django.conf.settings that django.forms can then check (with a
> reasonable default)?
>
> I recall seeing a patch that adds a new setting and updates (at the
> time) django.newforms with some if/else logic based on the setting to
> the various widgets' render methods.  I can't seem to find it now.
>
> I'm just trying to point out that for Django to output a string that
> then later gets "fixed" smells funny to me (ask Malcolm likes to say).

I completely agree, but I don't think the answer is to use a global
variable to influence django.forms. My plan for integration in to
Django proper was to modify Django's widget.render method to take an
optional as_xhtml=True/False argument. The {% form %} tag would then
set that argument based on context._doctype.

I would also modify Context to have an is_xhtml() method which does
the "self._doctype in xhtml_doctypes" check.

Justin Fagnani

unread,
Sep 10, 2008, 4:46:09 PM9/10/08
to django-d...@googlegroups.com
On Wed, Sep 10, 2008 at 12:43 PM, Simon Willison
<si...@simonwillison.net> wrote:
> Django proper was to modify Django's widget.render method to take an
> optional as_xhtml=True/False argument. The {% form %} tag would then
> set that argument based on context._doctype.
>
> I would also modify Context to have an is_xhtml() method which does
> the "self._doctype in xhtml_doctypes" check.

This isn't forms specific, but I have various classes that output HTML
into templates and one pattern I've used is to take the context in
their render() method, then display the variable with a tag that calls
render(), like:

{% render my_variable %}

I think it'd be interesting to apply this pattern to general variable
lookups, as it would solve this issue, plus be applicable to many more
problems. Variable lookups could check for render() and call it if
it's there, passing the context. Then you just call {{ my_variable }},
or {{ field }}.

Too big of a change?

-Justin

Reply all
Reply to author
Forward
0 new messages