Re: RFC: Templatetag API for form rendering
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
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
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
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
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
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
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
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
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
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
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
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
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/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
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
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
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
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
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
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
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
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
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
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
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
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
(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