Sorry for the quite late response, everything is getting pretty close to the
deadline. I'm not happy with it but I need to tackle some personal issues at
once.

2011/4/5 Russell Keith-Magee <russ...@keith-magee.com>:
>
> ...
>
> In particular, I have two objections:
>  * it feels like it's trying to cram too much into a single template tag.
>  * it requires a lot of duplication of "form myform configure" or
> "formblock myform using"
>
> Consider a slight variation that uses more tags:
>
> {% form myform configure %}
>    {% layout "uni_form" %}
>    {% widget "calendar" for DateField %}
>    {% autocomplete "lastname" from "/users/lastnames" %}
> {% endform %}

Yes that looks clean and easy to follow. I just don't like the lone keyword
'configure' (or 'using') at the end of the tag. But I guess we need it to
determine if we search for a closing endform tag or if it's a standalone one
(or we use the 'trick' you described for the media handling).

> Then, when it comes time to render:
>
> {% form myform using %}
>    {% field "firstname" %}
>    <p>And some HTML decoration</p>
>    {% field "lastname" %}
> {% endform %}

Looks good. A problem would be with using multiple forms:

    {% form myform using %}
    {% form another_form using %}
        {% field "name" %}
    {% endform %}
    {% endform %}

Is "name" a field of "myform" or "another_form"? But thats easy to work around
by using {% field myform.name %} for example.

> or, using an iterative approach:
>
> {% form myform using %}
>    {% for field in myform %}
>        {% field field %}
>    {% endfor %}
> {% endform %}

I wonder how it would look like to change the layout and outputting the whole
form like {{ form.as_ul }}. Your example is for more than basic scenarios good
but very verbose for just changing the layout. Maybe using the form tag would
inherit the configuration from the wrapping form tag::

    {% form myform using %}
        {% layout "ul" %}
        {% form myform %}
    {% endform %}

Skipping the wrapping {% form myform using %} is also possible, layout would
configure the whole template by setting a context variable. However this might
have sideeffects on included templates etc. Explicit is usually better than
implicit. But we will find a way to deal with it.

> or, using default layout:
>
> {% form myform %}
>
> This approach:
>  * cuts down on the duplication, either in the form of indented form
> blocks, or in duplicated 'tag opening' content
>  * avoids the need for a DSL embedded in the tag definition
>  * avoids potential grammar ambiguities -- the less grammar there is
> in a tag, the less likely there will be edge cases in the parsing.
>
> ...
>
>>> Rendering modifiers
>>> ~~~~~~~~~~~~~~~~~~~~
>>>
>> But like I already wrote above: I see your concerns with adding yet another
>> registry that might not be used very often. I would agree on dropping that
>> feature if you think its better to skip this until users demand it 
>> afterwards.
>
> I think this might be the better approach. Your proposal is already
> fairly ambitious, especially if it's going to include a reworking of
> admin's rendering. And, to that end, reworking admin's rendering
> should prove a useful testbed for whether it is needed at all.
>
> Also -- some food for thought; the reason that a registry is needed
> here is because you're defining an extension api for a monolithic {%
> form %} tag. If the rendering strategy used multiple tags, modifiers
> could also be defined as template tags:
>
> {% form myform %}
>    {% mymodifier foo %}
> {% endform %}
>
> Then you don't need a separate registry; a "modifier" just becomes a
> template tag operating on the API exposed by the form rendering API
> (presumably a set of known objects in the local context of the form
> tag). If an end user wants a rendering modifier, they just define
> their own template tag and use it in a {% form configure %} block.

Ha! That makes me happy to have a possibility for custom behaviour in the form
rendering and you happy because we don't need another abstraction. I like this
approach and will go for it.

>>> Form rows
>>> ~~~~~~~~~
>>>
>>> If you look at the existing as_* form layout tools, there is a
>>> distinction between gross form layout, and the layout of an individual
>>> form row.
>>>
>>> {{ form_header }}
>>> {% for field in form %}
>>>    {{ pre_field }}}
>>>    {{ field }}
>>>    {{ post_field }}
>>> {% endfor %}
>>> {{ form_footer }}
>>>
>>> Conceptually, the rendering for pre/post field could vary depending on
>>> the field. How is this handled in your proposal? Is it part of the
>>> form renderer? Or part of the widget rendering? This overlaps with
>>> your discussion about error templates -- since errors (and their
>>> rendering) is one of the major pre/post rendering activities for both
>>> forms and fields.
>>
>> I'm not sure if I get your example right. Is it representing the output of a
>> "as_*" method? I looked into the django/forms/forms.py code again and I'm
>> quite sure that there is no header or footer of a form rendered. I also don't
>> see many usecases of including a header and a footer into the layout (like a
>> wrapping <table> or <ul> element) since this is very different from form to
>> form. One might want the wrapping <table> the other wants to put two forms
>> into one <table> element etc.
>
> I wasn't thinking so much about the <table> rendering, as some of the
> other non-row rendering details.
>
> For example, non-form errors currently have a rendering style that is
> defined in code (although they are programmatically exposed in a way
> that makes them compatible with templates). This is something that
> isn't definable on a per-row basis, but it is tied to a form.
>
> A second example -- handling of hidden fields. Again, these aren't
> strictly row-based, but they do impact on the rendering of the form as
> a whole.

Ok I see. It would be very easy to implement support for all this. We just
choose different templates depending on if we want to output the whole form.

For a single row (using {% field ... %}) we will use
forms/layouts/.../row.html when using {% form myform %} we will use
forms/layouts/.../form.html which makes use again of row.html internally.

>
> ...
>
> Two more thoughts that have occurred to me:
>
> Firstly, from the point of view of proving the viability of your API,
> it might be worth collecting a selection of pathological use cases
> that can be used as a testbed. For example:
>
>  * A form with 30 widgets
>  * A form with only hidden widgets
>  * A form with multiple date widgets, all using a calendar widget
> except for the last one
>  * A page that contains two forms
>
> In effect, this is a set of conceptual test cases for your API -- in
> fact, it might even form the basis for your programatic test suite.

Good idea. I did some of this "testing" already with my first proposed syntax.
Looking how it would behave in certain conditions. I will start collecting
more of these test cases and will play with them to see how the different
syntaxes feel in complex situations.

This is something good I can do until the coding starts (if I get accepted),
providing evidence that the finally choosen syntax is the best one.

> Secondly: formsets. Are you intending to tackle formsets in this
> proposal? It's ok if you don't -- omitting formsets would be a good
> way to limit scope for the purposes of GSoC. However, I suspect the
> formset use case will ultimately be important for trunk inclusion.
> Even if you're not intending to tackle formsets, it's probably worth
> mentioning them in your proposal.

I have not thought about formsets yet. But in my understanding there is no
real difference between a formset and using multiple forms manually. In a
formset you would just iterate over them instead of using them explicitly. The
only difference is the management form. We will find a way to nicely integrate
this. For example outputting it in the {% endform %} block or something
similiar. I could also imagine a "rendering modifier" that outputs a "add
another form" handler like we have it in the admin.

I will give formsets a thought but would like to keep them out of the actual
proposal just because of the time constraints. I will have them in mind so
that we can integrate them nicely later on.

> In summary: I think you've got a strong proposal here. I've also taken
> a look at your new proposal timeline, and it looks good to me. There
> are certainly details to work out, and although they may appear
> significant on first impression, I think they're mostly cosmetic. A
> decision about using nested multiple tags or a single tag will
> certainly affect your implementation, but doesn't fundamentally alter
> the idea that you're driving at here: customizing the form rendering
> using templates. As long as your submission acknowledges the fact that
> there are some API issues still need to be resolved, I think your
> proposal is in reasonably good shape.
>
> Good luck with your final submission!
>
> Yours
> Russ Magee %-)

Thanks a lot Russ. I'm very concerned that I had nearly no time in the last
days to refine my proposal but the deadline is pretty close now. I will invest
all the time I have to make the last changes, but all in all I hope this
doesn't affect my chances, since this thread is a good reference on where we
will finally go.

Gregor

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

Reply via email to