Re: RFC: Templatetag API for form rendering

2011-06-14 Thread Benoît Bryon

Hi,

Le 22/05/2011 22:21, Gregor Müllegger a écrit :

 {% renderform my_form hidden "honeypot" %}

Render all fields but outputs the my_form.honeypot field as a hidden 
field.
If one wants to force a field to be hidden, wouldn't it be better to use 
a "hidden" widget?

Why provide a "hidden" argument when you could do it with a widget?
::

  {% widget widgets.HiddenInput for "honeypot" %}

It would keep the renderform tag simple.


Benoît

--
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.



Re: RFC: Templatetag API for form rendering

2011-06-14 Thread Benoît Bryon

I'm not sure yet, if it's worth the extra {% formdefaults %} tag. Ofcourse it
>  prevents template authors from excidentally overriding defaults, but I think
>  who will use these utilities must know about these implications anyway. It's
>  somehow just reflecting the behaviour of a python module scope.
>  But maybe I'm a bit too much programmer here and reflecting too much
>  of my habits
>  onto the template authors mind.
There are some key differences between this and Python module scope,
besides the usual "template authors aren't necessarily Python
programmers." The main one is that Python module scope is contained
within a single file; here we're talking about a global scope that
potentially extends across many template files, what with inheritance
and includes, and even into Python code files too. I think because of
this action-at-a-distance factor, there's a much greater need to make
the modification of global scope explicit, clear, and hard to do by
accident or overlook.

Maybe it could be useful to provide a test utility to make sure a layout can handle all 
"standard cases".
I mean, if one wants to create a new layout and set it as the global default, 
the layout should be tested. So a layout testing tool (or documented procedure) 
would be great.
But I guess that is a bonus, not a required feature in the Gsoc.

Benoīt


--
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.



Re: RFC: Templatetag API for form rendering - Second Edition

2011-06-14 Thread Benoît Bryon

Le 03/06/2011 16:58, Gregor Müllegger a écrit :

{% formerrors  %}

Will it use duck typing? rather than testing Form or Field or ErrorList or 
ErrorDict subclasses.
Drawback:
  more work needed since some refactoring of Form, BoundField, ErrorList and 
ErrorDict may be required.
Advantage:
  duck-typing (I mean kind of interfaces) would be more flexible: we will be 
able to pass custom objects to {% formerrors %}.

Benoit



--
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.



Re: RFC: Templatetag API for form rendering

2011-06-14 Thread Benoît Bryon

Le 22/05/2011 22:21, Gregor Müllegger a écrit :

{% renderform my_form %}

Another suggest from formrenderingtools...

Can we consider that "form" is the naming convention for form context variables?
* generic views use "form"
* there is usually only one form in a view

If "form" can be considered as a convention, could we apply "convention over 
configuration" here?
::

  {% renderform %}

Convention: use the "form" variable
Configuration: pass my_form as an argument

In formrendering tools, there are 2 kinds of context:

* form context: where a "form" variable is required in the context =>  form, 
field list, form errors...
* field context: where a "form" variable is useful, and a "field" variable is 
required =>  label, field errors, field, widget...

Benoît

--
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.



Re: RFC: Templatetag API for form rendering

2011-06-14 Thread Benoît Bryon

Le 23/05/2011 00:21, Carl Meyer a écrit :

Just had a quick conversation with Gregor and Chris Beaven on IRC;
based on a comment of Chris', we discussed the possibility of ditching
the {% formlayout %} tag in favor of specifying the layout as an
argument to the {% form %} block tag. E.g. instead of


 {% form %}
 {% formlayout "table" %}
 {% renderform my_form %} {# will use table layout #}
 {% endform %}

You'd say:

{% form "table" %}
 {% renderform my_form %}
{% endform %}

And perhaps if the layout can be specified that way, with minimal
boilerplate, we don't need the global-context-modifying version of
formlayout either.

From my experience, the most common use case would be to render one form using 
one layout.
So passing the layout at the toplevel form tag would be nice.

However, what could be interesting with the {% formlayout %} modifier is that 
you could use several layouts to render one form.
As an example:
::

  {% form %}
{% formlayout "p" %}
{% renderform form.field1 form.field2 %}

{% formlayout "table" %}

  {% renderform form.checkbox1 form.checkbox2 form.checkbox3 %}

  {% endform %}

So I would say:
* add the layout as an argument of the toplevel {% form %} tag
* and keep {% formlayout %} as an option for specific use cases

I just realized that I adviced the opposite approach for hidden fields: not in 
the {% form %} tag, but in modifier.
That is because I think that hiding fields is not the most common use case, 
whereas using a specific layout is.

Benoît

--
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.



Re: RFC: Templatetag API for form rendering

2011-06-14 Thread Benoît Bryon

Le 24/05/2011 16:35, Gregor Müllegger a écrit :

This is not yet defined in detail. I would suggest a schema like:

 forms/layouts//.html

Resulting in templates for the layout "table" like:

 forms/layouts/table/row.html
 forms/layouts/table/label.html
 forms/layouts/table/field.html
 forms/layouts/table/errors.html
 forms/layouts/table/help_text.html


In django-formrenderingtools, I first tried a schema similar to the one you are 
suggesting.
But I eventually chose a different schema:

forms/layouts/{{ LAYOUT_NAME }}/{{ ELEMENT_NAME }}/{{ TEMPLATE_NAME }}
where :
* {{ LAYOUT_NAME }} is "table" in your examples,
* {{ ELEMENT_NAME }} stands for row, label, field, errors...
* {{ TEMPLATE_NAME }} is "default.html by default, but can be overriden by passing a 
"template" argument to the template tag.

I chose this schema because it allows layout variations and thus limits the 
need to create new layouts.
What if one wants a specific layout for one field in one form?
* with your schema, he creates a new layout (involving several templates?).
* with the formrenderingtools schema, he overrides the layout (involving one 
template).

If there can be plenty of templates for several fields or forms in a layout, the layout 
directory could become a mess. Which ones are templates for fields? Which ones are 
templates for labels? We could use a filename prefix like "field_", but a 
folder may be more pertinent.

In addition, in formrenderingtools, field's name is used to search for a 
template like firstname.html before default.html.
If the template is well-named (i.e. {{ field.html_name }}.html), then there is 
no need to specify the new template.
I find it really useful, but it can lead to namespace errors (what if a field is named 
"default"?). So maybe it is not a so great idea.

For details about the template names in formrenderingtools: 
http://packages.python.org/django-formrenderingtools/reference/template_names.html
(it misses the "field.html_name" tip)


Layouts have to be easy to use, but also easy to create.
For the creation purpose, think about layout inheritance.

As a template designer, I do not want to rewrite or copy all the base layout 
when I just want to customize a few items.
As an example, Django's default behavior is to display a ":" beside the.
If I want to remove or replace it, I do not want to create a brand new layout with 
all templates! I just want to override the  item.
Note: for french, we'd better use a " :". I mean the ":" element is not standard, so 
I don't like it and I used to remove it or sometimes use some {% trans ":" %}.

There are at least 2 ways for inheritance.

1. inheritance using {% block %} tags.
Roald de Vries showed some ways to use it in his mail on 10/06/2011.
Right now, I not convinced it is a good idea. From my point of view, the syntax 
is not light enough to write.

2. template fallback mecanism.
It is somehow implemented in formrenderingtools. For a given layout, you use 
select_template() to get a specific template and fallback to the default if 
necessary.
Formrenderingtools allows only 2 levels for field list elements: specific and default. As 
a consequence, you cannot override a layout which is not the default one. If 
"as_ul" layout is not the default, you cannot override just a part of it. You 
have to copy all the templates in a new layout and then modify a part. That is bad.
But what if we could say: "use foo layout, or fallback to, in order, bar, baz or 
default"?

A suggest about the n°2 implementation:
::

  {% renderform %}
  {% form using baz %}
{% form using foo bar %}
{% endform %}
  {% endform %}


Another idea: what if we got "layout loaders"?
FORM_LAYOUT_LOADERS = (
'my.custom.app.SelectLayoutMatchingUserPreferences',
'another.custom.app.SelectLayoutMatchingUrl',
'another.custom.app.SelectTemplateMatchingFieldHtmlName',
'django.forms.layouts.loaders.FallbackLayoutLoader',
)


Benoît



--
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.



Re: RFC: Templatetag API for form rendering - Second Edition

2011-06-14 Thread Benoît Bryon

Le 03/06/2011 16:58, Gregor Müllegger a écrit :

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  %}


What about sharing primitives (templates) to display form errors and 
messages from the message framework?

In a way, form errors are a kind of error messages, aren't they?

To go further, I am wondering if, in future, forms could generate other 
types of messages, like warnings: they don't block the validation 
process but the user may pay attention to them.
Maybe there could be a relationship between form validation and 
generation of a messages.SUCCESS too.


Benoit

--
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.



Re: RFC: Templatetag API for form rendering - Second Edition

2011-06-10 Thread Roald de Vries

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 %}

  {% block label %}...{# label rendered #}{% endblock  
%}

  
{% block fielderrors %}...{# fielderrors rendered #} 
{% endblock %}
{% block widget %}...{# widged rendered #}{% endblock  
%}

  

  {% 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   
%}


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 controver

RFC: Templatetag API for form rendering - Second Edition

2011-06-03 Thread Gregor Müllegger
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  %}

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.



Re: RFC: Templatetag API for form rendering

2011-05-24 Thread Benoît Bryon

Hi,

I am the author of the django-formrenderingtools package, which focuses 
on a template tag library to render forms.

Currently widgets and formsets are not supported, but they could be.
I guess it matches the subject of the GSoC.

So I would be glad if you had a look at my work. It is certainly not 
perfect, but I did my best.
Although the code is available since some time now (2009 as I remember) 
I really miss feedback from other users. I do not know if others are 
using the application, and if not, I do not know why.

I recently worked on the following items so that you can review it quickly :
* documentation
* packaging
* a demo project to discover the application and try it in a sandbox
The version 0.2.1, released on last sunday, is tagged as "beta", but I 
am using it in production. I mainly miss feedback to be sure.


I am open to any suggestions if I can help:
* I can switch to Github if it helps
* I can adapt the license
* I will try to follow this GSoC and contribute to discussions

I would be glad to share my work and contribute to this topic...

Some links :
http://pypi.python.org/pypi/django-formrenderingtools/
http://packages.python.org/django-formrenderingtools/
https://bitbucket.org/benoitbryon/django-formrenderingtools/src

About the particular topic of your original post :
http://packages.python.org/django-formrenderingtools/reference/template_tags.html
http://packages.python.org/django-formrenderingtools/reference/template_names.html

--
Benoît Bryon
Makina Corpus

--
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.



Re: RFC: Templatetag API for form rendering

2011-05-24 Thread Carl Meyer


On 05/24/2011 09:35 AM, Gregor Müllegger wrote:
>> Which templates are involved in a form layout?
> 
> This is not yet defined in detail. I would suggest a schema like:
> 
> forms/layouts//.html
> 
> Resulting in templates for the layout "table" like:
> 
> forms/layouts/table/row.html
> forms/layouts/table/label.html
> forms/layouts/table/field.html
> forms/layouts/table/errors.html
> forms/layouts/table/help_text.html

This looks like a pretty good starting point to me.

Since we're building on top of Bruno's templated widgets, I think it
would also be quite useful if you could override the default widget
templates in your layout, just by placing the properly named file at the
right location. So if a widget uses the template
forms/widgets/textarea.html, and you're using "mycustom" layout, it
would first look for a template at
"forms/layouts/mycustom/widgets/textarea.html".

> A note on something different: We haven't specified yet how it will look like
> to render just parts of a single field like errors. If we keep the
> {{ field.errors }} syntax (which is unlikely since the template variable has
> no access to the layout set by {% formlayout %}) or if we use an extra
> templatetag for that. A proposal for these details will follow after we have
> agreed on the higherlevel things like described in the RFC.

Yeah. I guess it would be possible to squeeze this into the {% form %}
(nee {% renderform %}) tag with some syntactical modifiers, e.g.:

{% form "myfield:errors" %}

Or even with a filter?

{% form "myfield"|fielderrors %}

But it may be cleaner just to do it as a separate tag.

Carl

-- 
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.



Re: RFC: Templatetag API for form rendering

2011-05-24 Thread Carl Meyer
Hi Gregor,

On 05/24/2011 09:25 AM, Gregor Müllegger wrote:
>
> Yes, defining a global default is really useful, we shouldn't skip that.

Yep, I'm definitely converted to that position ;-)

>> For the case-by-case override, though, I'd still much rather write
>>
>> {% form "table" %}
>>  {% renderform myform %}
>> {% endform %}
>>
>> than
>>
>> {% form %}
>>  {% formlayout "table" %}
>>  {% renderform myform %}
>> {% endform %}
>>
>>
>> What if instead of allowing form modifier tags to appear unenclosed, and
>> making them then implicitly global, we had a {% formdefaults %} tag that
>> paralleled the {% form %} tag, except it defined your defaults for form
>> rendering:
>>
>> {% formdefaults "table" %}
>>  {% widget ... %}
>> {% endformdefaults %}
>>
>> This is much more explicit, which means that a) a random new designer
>> reading your templates is more likely to notice that global defaults are
>> being defined, and b) you're less likely to accidentally define global
>> defaults because you omitted an enclosing block tag.
> 
> A question for my own understanding: The difference between your
> {% formdefaults %} variant and my "modify a global scope" is just a
> syntactical difference i.e. the following examples are equal?

That's right.

> (using your syntax)
> {% formdefaults %}
> {% widget ... %}
> {% endformdefaults %}
> 
> {% form %}
> {% renderform my_form %}
> {% endform %}
> 
> (using the RFC syntax)
> {% widget ... %}
> 
> {% form %}
> {% renderform my_form %}
> {% endform %}
> 
> And you propably want to raise a TemplateSyntaxError if the {% widget ... %}
> tag is used outside a {% formdefaults %} or {% form %} enclosed block?

Also correct.

The other difference is that if we have {% formdefaults %} we can
specify the layout as an argument to {% formdefaults %} as well as an
argument to {% formconfig %} or whatever we name it (presuming we listen
to Russ on that naming, and I think he's right), and that means we
really wouldn't need {% formlayout %} as a separate tag anymore. Which I
think is a plus.

> I'm not sure yet, if it's worth the extra {% formdefaults %} tag. Ofcourse it
> prevents template authors from excidentally overriding defaults, but I think
> who will use these utilities must know about these implications anyway. It's
> somehow just reflecting the behaviour of a python module scope.
> But maybe I'm a bit too much programmer here and reflecting too much
> of my habits
> onto the template authors mind.

There are some key differences between this and Python module scope,
besides the usual "template authors aren't necessarily Python
programmers." The main one is that Python module scope is contained
within a single file; here we're talking about a global scope that
potentially extends across many template files, what with inheritance
and includes, and even into Python code files too. I think because of
this action-at-a-distance factor, there's a much greater need to make
the modification of global scope explicit, clear, and hard to do by
accident or overlook.

It also makes it easy to "grep" for places where the global defaults are
being set. Otherwise, there'd be no easy way to find them and separate
them out from scoped uses of the modifier tags.

Given that this is something you'd likely only do once in your project,
not over and over again, I think the downside of typing the extra tag is
minimal.

> After all I have no objections against the {% formdefaults %} proposal and
> would be happy implementing it if thats your prefered way.

I do think it's clearly better, though if you disagree of course you
should argue, not just do it my way ;-)

Carl

-- 
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.



Re: RFC: Templatetag API for form rendering

2011-05-24 Thread Gregor Müllegger
Hi Preston,

2011/5/23 Preston Timmons :
> This looks interesting so far.
>
> How does setting the form layout affect rendering individual fields in
> a form?
>
> Is the output of {% renderform my_form "first_name" %} equivalent to
> {{ form.first_name }}, or is it more like the output of "as_p" or
> "as_table"?

It's not really equivalent to {{ form.first_name }} because the template
variable would only render the widget. The {% renderform %} is meant to
render complete rows, including field errors, help text, the label etc.

This means you could list all the fields of a form by hand and it would
result in the same output, i.e. the following examples would result in the
same output:

(assuming my_form only has two fields)

{% rendeform my_form "first_name" %}
{% rendeform my_form "last_name" %}

-- or --

{% rendeform my_form %}

> Which templates are involved in a form layout?

This is not yet defined in detail. I would suggest a schema like:

forms/layouts//.html

Resulting in templates for the layout "table" like:

forms/layouts/table/row.html
forms/layouts/table/label.html
forms/layouts/table/field.html
forms/layouts/table/errors.html
forms/layouts/table/help_text.html

But this might change if we see it fit while using it in sample projects
during the summer.


A note on something different: We haven't specified yet how it will look like
to render just parts of a single field like errors. If we keep the
{{ field.errors }} syntax (which is unlikely since the template variable has
no access to the layout set by {% formlayout %}) or if we use an extra
templatetag for that. A proposal for these details will follow after we have
agreed on the higherlevel things like described in the RFC.

-- 
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.



Re: RFC: Templatetag API for form rendering

2011-05-24 Thread Gregor Müllegger
2011/5/23 Carl Meyer :
> I guess I was comparing
>
> {% form %}
>  {% renderform myform %}
> {% endform %}
>
> to
>
> {% form "table %}
>  {% renderform myform %}
> {% endform %}
>
> and thinking the latter didn't seem too comparatively onerous, even if
> you were doing it for every form render. But I'd forgotten that for
> simple cases you could otherwise just do {% renderform myform %} with no
> block tag; it is unfortunate to require the block tag every time in case 3.
>

Yes, defining a global default is really useful, we shouldn't skip that.

> For the case-by-case override, though, I'd still much rather write
>
> {% form "table" %}
>  {% renderform myform %}
> {% endform %}
>
> than
>
> {% form %}
>  {% formlayout "table" %}
>  {% renderform myform %}
> {% endform %}
>
>
> What if instead of allowing form modifier tags to appear unenclosed, and
> making them then implicitly global, we had a {% formdefaults %} tag that
> paralleled the {% form %} tag, except it defined your defaults for form
> rendering:
>
> {% formdefaults "table" %}
>  {% widget ... %}
> {% endformdefaults %}
>
> This is much more explicit, which means that a) a random new designer
> reading your templates is more likely to notice that global defaults are
> being defined, and b) you're less likely to accidentally define global
> defaults because you omitted an enclosing block tag.

A question for my own understanding: The difference between your
{% formdefaults %} variant and my "modify a global scope" is just a
syntactical difference i.e. the following examples are equal?

(using your syntax)
{% formdefaults %}
{% widget ... %}
{% endformdefaults %}

{% form %}
{% renderform my_form %}
{% endform %}

(using the RFC syntax)
{% widget ... %}

{% form %}
{% renderform my_form %}
{% endform %}

And you propably want to raise a TemplateSyntaxError if the {% widget ... %}
tag is used outside a {% formdefaults %} or {% form %} enclosed block?

I'm not sure yet, if it's worth the extra {% formdefaults %} tag. Ofcourse it
prevents template authors from excidentally overriding defaults, but I think
who will use these utilities must know about these implications anyway. It's
somehow just reflecting the behaviour of a python module scope.
But maybe I'm a bit too much programmer here and reflecting too much
of my habits
onto the template authors mind.

After all I have no objections against the {% formdefaults %} proposal and
would be happy implementing it if thats your prefered way.

-- 
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.



Re: RFC: Templatetag API for form rendering

2011-05-23 Thread Preston Timmons
This looks interesting so far.

How does setting the form layout affect rendering individual fields in
a form?

Is the output of {% renderform my_form "first_name" %} equivalent to
{{ form.first_name }}, or is it more like the output of "as_p" or
"as_table"? Which templates are involved in a form layout?

Preston

-- 
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.



Re: RFC: Templatetag API for form rendering

2011-05-23 Thread Bruno Renié
Hi,

I like the API and I'm looking forward to this. Just a small comment
on the {% widget %} tag:

On Sun, May 22, 2011 at 10:21 PM, Gregor Müllegger  wrote:
> (You can read this RFC online if you prefer:
> https://github.com/gregmuellegger/gsoc2011-stuff/blob/master/rfc_syntax.rst )

>    {% widget [] [using ] for
>  [with = ...] %}
>
> In this syntax description  means that you can specify one of
> three things as argument:

We just had a chat about the {% widget %} tag on IRC, it would be
useful to let template authors add attributes to the widget without
having to alter the template *and* add a context variable. Something
like:

{% widget field width foo="bar" attrs placeholder="john.sm...@example.com" %}

Instead of {% widget field with boo="bar" placehodler="..." using
"some_template.html" %} and having to copy the default template to add
the placeholder next to the attrs.

The 'with' keyword would be used to add template variables, the
'attrs' keyword to add new attributes. The content of the context and
the attrs also needs to be checked: switching the input type or the
placeholder from the template is safe, I think but people shouldn't be
able to overwrite the input name for instance. There needs to be a
clear separation between what can be touched and what can't.

For the record, in my work on template widgets, the input's "name",
"value" and "type" are passed directly in the template context, not in
the attrs dict (which contains only the id by default). We chose to be
explicit but people may expect a different behaviour :)

Cheers,
Bruno

-- 
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.



Re: RFC: Templatetag API for form rendering

2011-05-23 Thread Carl Meyer
Hi Jonathan,

On 05/23/2011 04:30 AM, Jonathan Slenders wrote:
> 1. Like Carl said, I always prefer template tags which alter the
> context to create a scope. (I hate {% url ... as varname %})
> 
> {% form "table" %}
> {% renderform my_form %}
> {% endform %}

Well, in any case, not all context-altering tags will create their own
scope; even if we do ditch {% formlayout %}, {% widget %} still alters
context without creating a new scope. However, if my {% formdefaults %}
proposal is used, we'd at least maintain that the context-altering tags
can only be used within a scoped tag, either {% formconfig %} or {%
formdefaults %} (though in the latter case, although there's a scope
within which the modifications must be made, they have global impact).

> 2. Also totally agreed with Russell that we need consistency about
> when template tag parameters need to be quoted.
> That is, quoted in case of constants, and unquoted when they need to
> be resolved.

Yes. I'm still not entirely understanding which part of the RFC made it
appear that it didn't follow this rule. It already does.

> And even if this seems to cover all the use cases, ensure
> extensibility.

Definitely.

Carl

-- 
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.



Re: RFC: Templatetag API for form rendering

2011-05-23 Thread Jonathan Slenders
1. Like Carl said, I always prefer template tags which alter the
context to create a scope. (I hate {% url ... as varname %})

{% form "table" %}
{% renderform my_form %}
{% endform %}


2. Also totally agreed with Russell that we need consistency about
when template tag parameters need to be quoted.
That is, quoted in case of constants, and unquoted when they need to
be resolved.


And even if this seems to cover all the use cases, ensure
extensibility.

Other than that, nice proposal.

-- 
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.



Re: RFC: Templatetag API for form rendering

2011-05-22 Thread Carl Meyer
On 05/22/2011 08:54 PM, Russell Keith-Magee wrote:
> My argument: I'm trying to think of another example in Django's
> template language where the template tag is an "action" in this way.
> To my reading, outside of the tags used for logic (for, if, etc), and
> tags that define a contextual block (autoescape, comment, etc),
> template tags have the flavor of {% this block will be replaced with X
> %}, not {% do X here %}. For example, it's {% csrf_token %}, not {%
> render_csrf_token %}; {% cycle %}, not {% render_cycle_value %}; and
> so on.

Point taken. Yeah, renderform -> form does seem like the right thing. {%
formconfig %} doesn't quite sit right with me yet, but we can ponder
that name.

 Another tag to modify the rendering is the widget tag::

{% widget [] [using ] for
  [with = ...] %}

 In this syntax description  means that you can specify one of
 three things as argument:

 1. A bound field, means that the widget will be rendered only for this 
 field.
 2. A field class/type that will match for all fields that are using this
   formfield class. Example::

{% widget widgets.PasswordInput for formfields.CharField %}

   will render a  for all charfields.

 3. A field name (string). This will apply to all fields that have that
   particular field name. It's only useful if the option should apply to 
 more
   than one form or as convenience for short reference of a field.
>>>
>>> Broadly, I like what you've described here for the widget field. My
>>> only concern is a subtle one, regarding the way that quotes are
>>> interpreted.
>>>
>>> Over time, Django's template language has been slowly moving to a
>>> position where any user-specified argument can be interpreted as a
>>> variable or as a constant, with quotation used to differentiate
>>> between the two. For example, the {% url %} tag was modified in 1.3
>>> (using the future import syntax) so that the argument is interpreted
>>> literally if it is quoted, an as a variable if it isn't. This opens up
>>> all sorts of options for dynamic template programming, making the
>>> decision of where a link will land based on view logic, rather than
>>> template logic. Looking at your examples:
>>>
{% widget widgets.Textarea for my_form.comment %} (1. case)
{% widget widgets.DatePicker for formfields.DateField %} (2. case)
{% widget widgets.PasswordInput for "password" %} (3. case)
>>>
>>> In these examples, for X is being interpreted as a context variable in
>>> case 1, an interpreted class name in case 2, and a string that will
>>> match against a name in case 3.
>>>
>>>  * Case 1, but determining in the view which field will be a text area.
>>>  * Case 2, but determining the class that will be matched in the view.
>>>  * Case 3, but matching against a dynamic string (i.e., determine in
>>> the view the string that will be used for a match).
>>>
>>> Now, this isn't a case where I have an obvious use case I can point at
>>> -- these examples feel contrived, even to me. The third case is the
>>> only one that seems likely in practice. What I'm really arguing for
>>> here is consistency with the broad direction of the template language
>>> as a whole -- if you're specifying a constant, it should be quoted.
>>
>> Oh, I'm all about maintaining our newfound consistency in template tag
>> argument quoting. Which is why that was part of my feedback to the
>> original proposals, and Gregor and I spent quite a while working out the
>> solution which you apparently read a bit too quickly to notice ;-)
>>
>> If you read again, you'll note that "widgets" and "formfields" are not
>> some kind of magical syntactical marker, they are just template
>> variables (dictionaries of widgets and formfields, respectively) that
>> would be provided by a new context processor. So in every case above,
>> the argument is either a quoted string or a normal template variable;
>> there are no syntactic special cases.
> 
> I saw that explanation; I just wasn't sure how it would play out in
> practice. In particular, I wasn't sure how:
> 
>   {% widget widgets.PasswordInput for foo %}
> 
> would be interpreted, since foo could be a string, a field, or a
> widget class; 

It could be a string, a BoundField instance, or a Field subclass.

> or how
> 
>   {% widget widgets.PasswordInput for "foo" %}
> 
> would be interpreted as anything other than a string (i.e., is there a
> "constant" interpretation for the first two use cases).

No, if its a quoted string, then it's always a fieldname. That's why we
provide the "formfields" dictionary in the template context (via context
processor), so you have an easy way to pass in actual Field subclasses
and don't need any special "constant form" for that. (Same for the
"widgets" dictionary and the first argument; for that argument using a
quoted string would always be wrong).

> 
> Is the intention to run make the interpretation of {

Re: RFC: Templatetag API for form rendering

2011-05-22 Thread Russell Keith-Magee
On Mon, May 23, 2011 at 9:00 AM, Carl Meyer  wrote:
>
>
> On 05/22/2011 07:22 PM, Russell Keith-Magee wrote:
>> On Mon, May 23, 2011 at 6:21 AM, Carl Meyer  wrote:
>>> Just had a quick conversation with Gregor and Chris Beaven on IRC;
>>> based on a comment of Chris', we discussed the possibility of ditching
>>> the {% formlayout %} tag in favor of specifying the layout as an
>>> argument to the {% form %} block tag. E.g. instead of
>>>
     {% form %}
         {% formlayout "table" %}
         {% renderform my_form %} {# will use table layout #}
     {% endform %}
>>>
>>> You'd say:
>>>
>>> {% form "table" %}
>>>    {% renderform my_form %}
>>> {% endform %}
>>>
 The description of the form tag implies that the modifier tags are able to
 set/modify the global state in the current template. That is something 
 that is
 explicitly wanted. This way you can set a "formlayout" in the head of your
 base template and any other extending template will have this default for 
 the
 form rendering.
>>>
>>> And perhaps if the layout can be specified that way, with minimal
>>> boilerplate, we don't need the global-context-modifying version of
>>> formlayout either.
>>>
>>> Not sure if Gregor was entirely convinced, but I think I'd probably
>>> lean towards doing it this way.
>>
>> I'm not sure I am convinced. It seems to me that there would be three
>> common use cases for form rendering:
>>
>>  1) Render this form using defaults
>>  2) Render most forms using the defaults, but render for XXX using layout YYY
>>  3) Render all forms on this form using YYY
>>
>> It seems weird to me that in order to hit use case 3, you need to wrap
>> your entire template in a {% form %} block. Having a global form
>> layout context so that {% formlayout %} will work without an
>> encompassing {% form %} block makes more sense to me.
>
> I guess I was comparing
>
> {% form %}
>  {% renderform myform %}
> {% endform %}
>
> to
>
> {% form "table %}
>  {% renderform myform %}
> {% endform %}
>
> and thinking the latter didn't seem too comparatively onerous, even if
> you were doing it for every form render. But I'd forgotten that for
> simple cases you could otherwise just do {% renderform myform %} with no
> block tag; it is unfortunate to require the block tag every time in case 3.
>
> For the case-by-case override, though, I'd still much rather write
>
> {% form "table" %}
>  {% renderform myform %}
> {% endform %}
>
> than
>
> {% form %}
>  {% formlayout "table" %}
>  {% renderform myform %}
> {% endform %}

My counterargument would be to ask what other configuration items
there are -- or might there be in the future. Keeping the {%
formlayout %} tag doesn't seem especially onerous to me; it's explicit
about what is being configured; and it allows for future expansion in
the case that we think of some other configuration item that could be
handled at a form level.

> What if instead of allowing form modifier tags to appear unenclosed, and
> making them then implicitly global, we had a {% formdefaults %} tag that
> paralleled the {% form %} tag, except it defined your defaults for form
> rendering:
>
> {% formdefaults "table" %}
>  {% widget ... %}
> {% endformdefaults %}
>
> This is much more explicit, which means that a) a random new designer
> reading your templates is more likely to notice that global defaults are
> being defined, and b) you're less likely to accidentally define global
> defaults because you omitted an enclosing block tag.
>
> Global state is serious business - it means action-at-a-distance. It
> should be obvious when it's happening, and hard to do accidentally.

Agreed, and a 'formdefaults' block seems like an elegant solution.

Yours,
Russ Magee %-)

-- 
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.



Re: RFC: Templatetag API for form rendering

2011-05-22 Thread Russell Keith-Magee
On Mon, May 23, 2011 at 8:44 AM, Carl Meyer  wrote:
>
>
> On 05/22/2011 07:18 PM, Russell Keith-Magee wrote:
>> I like this. Simple, covers all the common use cases that I can see.
>> My only feedback here would be mostly bikeshedding -- the fact that {%
>> form %} is a configuration action, and {% renderform %} is the
>> rendering action. It feels to me like {% form %} should be the
>> rendering action, and {% formconfig %} (or something similar) should
>> be the configuration action.
>
> Hmm. In the current proposal, {% form %} isn't really an action at all,
> it's just a scope. Which is why a generic name seemed sensible for it.
> Whereas {% renderform %} is an action - it renders the form - and it
> seemed good for its name to be explicit about that action.
>
> I don't care too much about that naming, though. If the "common case" is
> just {% renderform my_form %} with no enclosing configuration scope at
> all, it would be nice to keep that common case as short as possible.

Preface: This is 100% bikeshed, you/Gregor get to paint it, and I
won't be put out at all if it goes a different way.

My argument: I'm trying to think of another example in Django's
template language where the template tag is an "action" in this way.
To my reading, outside of the tags used for logic (for, if, etc), and
tags that define a contextual block (autoescape, comment, etc),
template tags have the flavor of {% this block will be replaced with X
%}, not {% do X here %}. For example, it's {% csrf_token %}, not {%
render_csrf_token %}; {% cycle %}, not {% render_cycle_value %}; and
so on.

>>> Another tag to modify the rendering is the widget tag::
>>>
>>>    {% widget [] [using ] for
>>>  [with = ...] %}
>>>
>>> In this syntax description  means that you can specify one of
>>> three things as argument:
>>>
>>> 1. A bound field, means that the widget will be rendered only for this 
>>> field.
>>> 2. A field class/type that will match for all fields that are using this
>>>   formfield class. Example::
>>>
>>>    {% widget widgets.PasswordInput for formfields.CharField %}
>>>
>>>   will render a  for all charfields.
>>>
>>> 3. A field name (string). This will apply to all fields that have that
>>>   particular field name. It's only useful if the option should apply to more
>>>   than one form or as convenience for short reference of a field.
>>
>> Broadly, I like what you've described here for the widget field. My
>> only concern is a subtle one, regarding the way that quotes are
>> interpreted.
>>
>> Over time, Django's template language has been slowly moving to a
>> position where any user-specified argument can be interpreted as a
>> variable or as a constant, with quotation used to differentiate
>> between the two. For example, the {% url %} tag was modified in 1.3
>> (using the future import syntax) so that the argument is interpreted
>> literally if it is quoted, an as a variable if it isn't. This opens up
>> all sorts of options for dynamic template programming, making the
>> decision of where a link will land based on view logic, rather than
>> template logic. Looking at your examples:
>>
>>>    {% widget widgets.Textarea for my_form.comment %} (1. case)
>>>    {% widget widgets.DatePicker for formfields.DateField %} (2. case)
>>>    {% widget widgets.PasswordInput for "password" %} (3. case)
>>
>> In these examples, for X is being interpreted as a context variable in
>> case 1, an interpreted class name in case 2, and a string that will
>> match against a name in case 3.
>>
>>  * Case 1, but determining in the view which field will be a text area.
>>  * Case 2, but determining the class that will be matched in the view.
>>  * Case 3, but matching against a dynamic string (i.e., determine in
>> the view the string that will be used for a match).
>>
>> Now, this isn't a case where I have an obvious use case I can point at
>> -- these examples feel contrived, even to me. The third case is the
>> only one that seems likely in practice. What I'm really arguing for
>> here is consistency with the broad direction of the template language
>> as a whole -- if you're specifying a constant, it should be quoted.
>
> Oh, I'm all about maintaining our newfound consistency in template tag
> argument quoting. Which is why that was part of my feedback to the
> original proposals, and Gregor and I spent quite a while working out the
> solution which you apparently read a bit too quickly to notice ;-)
>
> If you read again, you'll note that "widgets" and "formfields" are not
> some kind of magical syntactical marker, they are just template
> variables (dictionaries of widgets and formfields, respectively) that
> would be provided by a new context processor. So in every case above,
> the argument is either a quoted string or a normal template variable;
> there are no syntactic special cases.

I saw that explanation; I just wasn't sure how it would play out in
practice. In particular, I wasn't sure how:

  {% widget widgets.PasswordInput f

Re: RFC: Templatetag API for form rendering

2011-05-22 Thread Carl Meyer


On 05/22/2011 07:22 PM, Russell Keith-Magee wrote:
> On Mon, May 23, 2011 at 6:21 AM, Carl Meyer  wrote:
>> Just had a quick conversation with Gregor and Chris Beaven on IRC;
>> based on a comment of Chris', we discussed the possibility of ditching
>> the {% formlayout %} tag in favor of specifying the layout as an
>> argument to the {% form %} block tag. E.g. instead of
>>
>>> {% form %}
>>> {% formlayout "table" %}
>>> {% renderform my_form %} {# will use table layout #}
>>> {% endform %}
>>
>> You'd say:
>>
>> {% form "table" %}
>>{% renderform my_form %}
>> {% endform %}
>>
>>> The description of the form tag implies that the modifier tags are able to
>>> set/modify the global state in the current template. That is something that 
>>> is
>>> explicitly wanted. This way you can set a "formlayout" in the head of your
>>> base template and any other extending template will have this default for 
>>> the
>>> form rendering.
>>
>> And perhaps if the layout can be specified that way, with minimal
>> boilerplate, we don't need the global-context-modifying version of
>> formlayout either.
>>
>> Not sure if Gregor was entirely convinced, but I think I'd probably
>> lean towards doing it this way.
> 
> I'm not sure I am convinced. It seems to me that there would be three
> common use cases for form rendering:
> 
>  1) Render this form using defaults
>  2) Render most forms using the defaults, but render for XXX using layout YYY
>  3) Render all forms on this form using YYY
> 
> It seems weird to me that in order to hit use case 3, you need to wrap
> your entire template in a {% form %} block. Having a global form
> layout context so that {% formlayout %} will work without an
> encompassing {% form %} block makes more sense to me.

I guess I was comparing

{% form %}
  {% renderform myform %}
{% endform %}

to

{% form "table %}
  {% renderform myform %}
{% endform %}

and thinking the latter didn't seem too comparatively onerous, even if
you were doing it for every form render. But I'd forgotten that for
simple cases you could otherwise just do {% renderform myform %} with no
block tag; it is unfortunate to require the block tag every time in case 3.

For the case-by-case override, though, I'd still much rather write

{% form "table" %}
  {% renderform myform %}
{% endform %}

than

{% form %}
  {% formlayout "table" %}
  {% renderform myform %}
{% endform %}


What if instead of allowing form modifier tags to appear unenclosed, and
making them then implicitly global, we had a {% formdefaults %} tag that
paralleled the {% form %} tag, except it defined your defaults for form
rendering:

{% formdefaults "table" %}
  {% widget ... %}
{% endformdefaults %}

This is much more explicit, which means that a) a random new designer
reading your templates is more likely to notice that global defaults are
being defined, and b) you're less likely to accidentally define global
defaults because you omitted an enclosing block tag.

Global state is serious business - it means action-at-a-distance. It
should be obvious when it's happening, and hard to do accidentally.

Carl

-- 
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.



Re: RFC: Templatetag API for form rendering

2011-05-22 Thread Carl Meyer


On 05/22/2011 07:18 PM, Russell Keith-Magee wrote:
> I like this. Simple, covers all the common use cases that I can see.
> My only feedback here would be mostly bikeshedding -- the fact that {%
> form %} is a configuration action, and {% renderform %} is the
> rendering action. It feels to me like {% form %} should be the
> rendering action, and {% formconfig %} (or something similar) should
> be the configuration action.

Hmm. In the current proposal, {% form %} isn't really an action at all,
it's just a scope. Which is why a generic name seemed sensible for it.
Whereas {% renderform %} is an action - it renders the form - and it
seemed good for its name to be explicit about that action.

I don't care too much about that naming, though. If the "common case" is
just {% renderform my_form %} with no enclosing configuration scope at
all, it would be nice to keep that common case as short as possible.

>> Another tag to modify the rendering is the widget tag::
>>
>>{% widget [] [using ] for
>>  [with = ...] %}
>>
>> In this syntax description  means that you can specify one of
>> three things as argument:
>>
>> 1. A bound field, means that the widget will be rendered only for this field.
>> 2. A field class/type that will match for all fields that are using this
>>   formfield class. Example::
>>
>>{% widget widgets.PasswordInput for formfields.CharField %}
>>
>>   will render a  for all charfields.
>>
>> 3. A field name (string). This will apply to all fields that have that
>>   particular field name. It's only useful if the option should apply to more
>>   than one form or as convenience for short reference of a field.
> 
> Broadly, I like what you've described here for the widget field. My
> only concern is a subtle one, regarding the way that quotes are
> interpreted.
> 
> Over time, Django's template language has been slowly moving to a
> position where any user-specified argument can be interpreted as a
> variable or as a constant, with quotation used to differentiate
> between the two. For example, the {% url %} tag was modified in 1.3
> (using the future import syntax) so that the argument is interpreted
> literally if it is quoted, an as a variable if it isn't. This opens up
> all sorts of options for dynamic template programming, making the
> decision of where a link will land based on view logic, rather than
> template logic. Looking at your examples:
> 
>>{% widget widgets.Textarea for my_form.comment %} (1. case)
>>{% widget widgets.DatePicker for formfields.DateField %} (2. case)
>>{% widget widgets.PasswordInput for "password" %} (3. case)
> 
> In these examples, for X is being interpreted as a context variable in
> case 1, an interpreted class name in case 2, and a string that will
> match against a name in case 3.
> 
>  * Case 1, but determining in the view which field will be a text area.
>  * Case 2, but determining the class that will be matched in the view.
>  * Case 3, but matching against a dynamic string (i.e., determine in
> the view the string that will be used for a match).
> 
> Now, this isn't a case where I have an obvious use case I can point at
> -- these examples feel contrived, even to me. The third case is the
> only one that seems likely in practice. What I'm really arguing for
> here is consistency with the broad direction of the template language
> as a whole -- if you're specifying a constant, it should be quoted.

Oh, I'm all about maintaining our newfound consistency in template tag
argument quoting. Which is why that was part of my feedback to the
original proposals, and Gregor and I spent quite a while working out the
solution which you apparently read a bit too quickly to notice ;-)

If you read again, you'll note that "widgets" and "formfields" are not
some kind of magical syntactical marker, they are just template
variables (dictionaries of widgets and formfields, respectively) that
would be provided by a new context processor. So in every case above,
the argument is either a quoted string or a normal template variable;
there are no syntactic special cases.

Our idea was that there would be public API for adding custom widgets
and formfields into these dictionaries, so that a third-party app can
make its own custom widgets and fields available for use in your
templates without requiring you to add yet another context processor.
I'm realizing now that we need to think carefully about the implications
of introducing a global flat namespace for widgets and formfields like
this; it could cause some nasty bugs if apps are stomping on each
others' names, or even built-in field/widget names. Maybe requiring an
additional context processor for any third-party app that wants to
provide custom fields and widgets into the template context isn't such a
bad idea after all.

Carl

-- 
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.

Re: RFC: Templatetag API for form rendering

2011-05-22 Thread Russell Keith-Magee
On Mon, May 23, 2011 at 6:21 AM, Carl Meyer  wrote:
> Just had a quick conversation with Gregor and Chris Beaven on IRC;
> based on a comment of Chris', we discussed the possibility of ditching
> the {% formlayout %} tag in favor of specifying the layout as an
> argument to the {% form %} block tag. E.g. instead of
>
>>     {% form %}
>>         {% formlayout "table" %}
>>         {% renderform my_form %} {# will use table layout #}
>>     {% endform %}
>
> You'd say:
>
> {% form "table" %}
>    {% renderform my_form %}
> {% endform %}
>
>> The description of the form tag implies that the modifier tags are able to
>> set/modify the global state in the current template. That is something that 
>> is
>> explicitly wanted. This way you can set a "formlayout" in the head of your
>> base template and any other extending template will have this default for the
>> form rendering.
>
> And perhaps if the layout can be specified that way, with minimal
> boilerplate, we don't need the global-context-modifying version of
> formlayout either.
>
> Not sure if Gregor was entirely convinced, but I think I'd probably
> lean towards doing it this way.

I'm not sure I am convinced. It seems to me that there would be three
common use cases for form rendering:

 1) Render this form using defaults
 2) Render most forms using the defaults, but render for XXX using layout YYY
 3) Render all forms on this form using YYY

It seems weird to me that in order to hit use case 3, you need to wrap
your entire template in a {% form %} block. Having a global form
layout context so that {% formlayout %} will work without an
encompassing {% form %} block makes more sense to me.

Yours,
Russ Magee %-)

-- 
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.



Re: RFC: Templatetag API for form rendering

2011-05-22 Thread Russell Keith-Magee
On Mon, May 23, 2011 at 4:21 AM, Gregor Müllegger  wrote:
> (You can read this RFC online if you prefer:
> https://github.com/gregmuellegger/gsoc2011-stuff/blob/master/rfc_syntax.rst )
>
>
> Hi,
>
> like you might know I've prepared as pre-work to my GSoC project a repository
> [1] with examples for two different approaches to my upcoming work on the form
> rendering. The first approach is called "single_tag" [2] the second one
> "modifier_tags" [3]. I agreed with my mentor Carl that we will follow a
> "hybrid" style of both proposals [4].
>
> I tried here to summarize a bit how the new tags will look like. I call now
> for comments and will really appreciate any feedback on them. Being it about
> their naming or if you have ideas for other tags. Be picky, this is something
> lots of people will use -- and though we want it to be as easy as possible to
> get started with.
>
> ::
>
>    {% renderform  [ ...] [hidden  name> ...] [exclude  ...] %}
>
> The renderform tag renders the complete form::
>
>    {% renderform my_form %}
>
> You can influence which fields will be used, sparing some fields out
> if you want that. Examples::
>
>    {% renderform my_form "username" "password" %}
>
> Renders only my_form.username and my_form.password and ignoring all other
> fields on the form. ::
>
>    {% renderform my_form exclude "first_name" "last_name" %}
>
> Render all fields but my_form.first_name and my_form.last_name. ::
>
>    {% renderform my_form hidden "honeypot" %}
>
> Render all fields but outputs the my_form.honeypot field as a hidden field.
>
> Thats it in what the renderform takes on arguments. You can influence it's
> rendering behaviour in more detail by using *form modifier tags*.
>
> One such modifier tag is the formlayout tag::
>
>    {% formlayout  %}
>
> Every {% renderform %} that is following in the templates will use the
> specified layout for rendering. We will provide layouts called "table", "ul"
> and "p". Users can specify new layouts just by putting some templates in the
> right template path.
>
> The {% form %} tag is limiting the scope of these modifier tags. If a modifier
> tag is wrapped in such a form-block, then it will lose its influence on form
> rendering outside of the form tag. ::
>
>    {% form %}
>        {% formlayout "table" %}
>        {% renderform my_form %} {# will use table layout #}
>    {% endform %}
>
>    {% renderform my_form %} {# will use default layout #}
>
> The description of the form tag implies that the modifier tags are able to
> set/modify the global state in the current template. That is something that is
> explicitly wanted. This way you can set a "formlayout" in the head of your
> base template and any other extending template will have this default for the
> form rendering.

I like this. Simple, covers all the common use cases that I can see.
My only feedback here would be mostly bikeshedding -- the fact that {%
form %} is a configuration action, and {% renderform %} is the
rendering action. It feels to me like {% form %} should be the
rendering action, and {% formconfig %} (or something similar) should
be the configuration action.

> Another tag to modify the rendering is the widget tag::
>
>    {% widget [] [using ] for
>  [with = ...] %}
>
> In this syntax description  means that you can specify one of
> three things as argument:
>
> 1. A bound field, means that the widget will be rendered only for this field.
> 2. A field class/type that will match for all fields that are using this
>   formfield class. Example::
>
>    {% widget widgets.PasswordInput for formfields.CharField %}
>
>   will render a  for all charfields.
>
> 3. A field name (string). This will apply to all fields that have that
>   particular field name. It's only useful if the option should apply to more
>   than one form or as convenience for short reference of a field.

Broadly, I like what you've described here for the widget field. My
only concern is a subtle one, regarding the way that quotes are
interpreted.

Over time, Django's template language has been slowly moving to a
position where any user-specified argument can be interpreted as a
variable or as a constant, with quotation used to differentiate
between the two. For example, the {% url %} tag was modified in 1.3
(using the future import syntax) so that the argument is interpreted
literally if it is quoted, an as a variable if it isn't. This opens up
all sorts of options for dynamic template programming, making the
decision of where a link will land based on view logic, rather than
template logic. Looking at your examples:

>    {% widget widgets.Textarea for my_form.comment %} (1. case)
>    {% widget widgets.DatePicker for formfields.DateField %} (2. case)
>    {% widget widgets.PasswordInput for "password" %} (3. case)

In these examples, for X is being interpreted as a context variable in
case 1, an interpreted class name in case 2, and a string that will
match against a name in case 3.

 * Case 1, but determining i

Re: RFC: Templatetag API for form rendering

2011-05-22 Thread Carl Meyer
Just had a quick conversation with Gregor and Chris Beaven on IRC;
based on a comment of Chris', we discussed the possibility of ditching
the {% formlayout %} tag in favor of specifying the layout as an
argument to the {% form %} block tag. E.g. instead of

>     {% form %}
>         {% formlayout "table" %}
>         {% renderform my_form %} {# will use table layout #}
>     {% endform %}

You'd say:

{% form "table" %}
{% renderform my_form %}
{% endform %}

> The description of the form tag implies that the modifier tags are able to
> set/modify the global state in the current template. That is something that is
> explicitly wanted. This way you can set a "formlayout" in the head of your
> base template and any other extending template will have this default for the
> form rendering.

And perhaps if the layout can be specified that way, with minimal
boilerplate, we don't need the global-context-modifying version of
formlayout either.

Not sure if Gregor was entirely convinced, but I think I'd probably
lean towards doing it this way.

Carl

-- 
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.



RFC: Templatetag API for form rendering

2011-05-22 Thread Gregor Müllegger
(You can read this RFC online if you prefer:
https://github.com/gregmuellegger/gsoc2011-stuff/blob/master/rfc_syntax.rst )


Hi,

like you might know I've prepared as pre-work to my GSoC project a repository
[1] with examples for two different approaches to my upcoming work on the form
rendering. The first approach is called "single_tag" [2] the second one
"modifier_tags" [3]. I agreed with my mentor Carl that we will follow a
"hybrid" style of both proposals [4].

I tried here to summarize a bit how the new tags will look like. I call now
for comments and will really appreciate any feedback on them. Being it about
their naming or if you have ideas for other tags. Be picky, this is something
lots of people will use -- and though we want it to be as easy as possible to
get started with.

::

{% renderform  [ ...] [hidden  ...] [exclude  ...] %}

The renderform tag renders the complete form::

{% renderform my_form %}

You can influence which fields will be used, sparing some fields out
if you want that. Examples::

{% renderform my_form "username" "password" %}

Renders only my_form.username and my_form.password and ignoring all other
fields on the form. ::

{% renderform my_form exclude "first_name" "last_name" %}

Render all fields but my_form.first_name and my_form.last_name. ::

{% renderform my_form hidden "honeypot" %}

Render all fields but outputs the my_form.honeypot field as a hidden field.

Thats it in what the renderform takes on arguments. You can influence it's
rendering behaviour in more detail by using *form modifier tags*.

One such modifier tag is the formlayout tag::

{% formlayout  %}

Every {% renderform %} that is following in the templates will use the
specified layout for rendering. We will provide layouts called "table", "ul"
and "p". Users can specify new layouts just by putting some templates in the
right template path.

The {% form %} tag is limiting the scope of these modifier tags. If a modifier
tag is wrapped in such a form-block, then it will lose its influence on form
rendering outside of the form tag. ::

{% form %}
{% formlayout "table" %}
{% renderform my_form %} {# will use table layout #}
{% endform %}

{% renderform my_form %} {# will use default layout #}

The description of the form tag implies that the modifier tags are able to
set/modify the global state in the current template. That is something that is
explicitly wanted. This way you can set a "formlayout" in the head of your
base template and any other extending template will have this default for the
form rendering.

Another tag to modify the rendering is the widget tag::

{% widget [] [using ] for
 [with = ...] %}

In this syntax description  means that you can specify one of
three things as argument:

1. A bound field, means that the widget will be rendered only for this field.
2. A field class/type that will match for all fields that are using this
   formfield class. Example::

{% widget widgets.PasswordInput for formfields.CharField %}

   will render a  for all charfields.

3. A field name (string). This will apply to all fields that have that
   particular field name. It's only useful if the option should apply to more
   than one form or as convenience for short reference of a field.

Some examples::

{% widget widgets.Textarea for my_form.comment %} (1. case)
{% widget widgets.DatePicker for formfields.DateField %} (2. case)
{% widget widgets.PasswordInput for "password" %} (3. case)

You can also change the template that will be used to render the widget with
the using keyword (we assume at this point that until this GSoC project is
finished we will likely have template based widget rendering like currently
developed by Bruno [5]), an example::

{% widget using "my_textarea_widget.html" for my_form.comment %}

It's actually possible to specify a special template for the widget *and* to
change the widget class itself with the tag::

{% widget widgets.DatePicker using
"widgets/alternative_datepicker.html" for my_form.birthday %}

The "with varname=varvalue" bit in the widget tag is meant as possibility to
pass extra arguments into the template that will be used to render the widget.
This will use the same syntax as django's ``include`` tag [6]::

{% widget for my_form.text with rows=10 cols=20 %}

{% widget using "widgets/tinymce.html" for my_form.comment with
theme="advanced" %}


At the end a short word to the meanings of widgets.Textarea etc. This
will basically be a template variable referencing the Textarea widget. So we
don't use special syntax for this in the tag, we just pull out the "widgets"
template variable that will be passed in via a context processor.

The "widgets" and "formfields" variables will be modifiable by users, so that
they can register their own widgets in their reusable apps, then usable in all
templates.


Thanks if you have read so far. Now please start commenting :-)

Gregor

| [1] https