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: Filtering on Many2Many Related Objects

2011-05-22 Thread Chris Beaven
Isn't the first suggestion (__contains) achievable already by just chaining 
two filters: Group.objects.filter(persons=p1).filter(persons=p2) ?

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



[GSoC form-rendering] Weekly check-in -0.0

2011-05-22 Thread Gregor Müllegger
Hi,

Carl and me had a vital discussion about the syntax that we will
propose for a RFC.
There is already a mailing list thread to which I warmly invite you to join:

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

Read the templatetag syntax proposal there and give your feedback!


I also changed the planed timeline of my project slightly. I will push the
start of writing documentation right after DjangoCon.eu. Hopefully there will
be more comments on that topic that I can integrate then into the project.
Before DjangoCon I will totally focus on backwards compatibility, extending
the test suite, converting the current form rendering to use templates etc.

This Monday is the official start of the GSoC project phase.
So let's get the coding started :-)

Watch my progress on github:
https://github.com/gregmuellegger/django/tree/soc2011%2Fform-rendering

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



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