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.