#15667: Implement template-based widget rendering ---------------------------------------+-------------------------- Reporter: brutasse | Owner: brutasse Type: New feature | Status: new Milestone: 1.4 | Component: Forms Version: | Severity: Normal Resolution: | Keywords: Triage Stage: Accepted | Has patch: 0 Needs documentation: 0 | Needs tests: 0 Patch needs improvement: 0 | Easy pickings: 0 ---------------------------------------+--------------------------
Comment (by brutasse): Replying to [comment:15 carljm]: > Replying to [comment:14 brutasse]: > > I have to agree the coupling between the template system and the forms library may be an issue. Maybe this should be discussed on django-dev but the GSoC proposal about form rendering is going to make this coupling even stronger if it gets merged. > > I don't think it's acceptable to have this enforced two-way coupling between forms and templates in the long run, but we do need to provide a deprecation-smoothed upgrade path. Here's my proposal: > > 1. Add the form-defaults template loader to TEMPLATE_LOADERS in the startproject template settings.py, but not to the global_settings TEMPLATE_LOADERS default. > 2. Document that you need to have the form-defaults template loader listed in TEMPLATE_LOADERS, if you want to have any of Django's default form/widget templates available (we should leave open the option that someone wants to provide all the form/widget templates they will use themselves, and not use any of the defaults built in to Django, though I think this is pretty unlikely in practice). > 3. Have temporary code that automatically adds the form template loader (last in priority order) if it is not listed in TEMPLATE_LOADERS, like you do now. > 4. If the form template loader is not explicitly listed in TEMPLATE_LOADERS and loads a template, have it issue PendingDeprecationWarning. This would result in lots of warnings, which is tricky. I don't want to make the warning module-wide, since, in the case I mentioned above, if people don't need the form-defaults loader because they provide all their own templates, they should be able to escape the warning. So it should only warn if the form loader actually loads a template. We might want to consider using some internal state on the loader to make it a first-time-only warning? I don't really like that, but it's better than hundreds of warnings or issuing the warning at module scope, IMO. > 5. When this deprecation cycle concludes in Django 1.6, remove the automatically-add-form-template-loader code. At this point, if people don't have the form template loader in TEMPLATE_LOADERS they'll just get a TemplateNotFound error for any form template they need but don't provide themselves. > > I think this solution would be able to adapt to the increased use of templates in Gregor's GSoC proposal without any trouble. > > Does this sound like a reasonable approach? Anything I'm missing? I like that, I agree it's much better than 2-way coupling. I'll have a look at the warnings and see how verbosity can be avoided. > > - the MultiWidget class has a format_output() method that joins the outputs from all of its widgets. The base MultiWidget just does "".join(outputs) but in the admin (see !AdminSplitDateTimeWidget) it inserts some markup between the outputs. I'm not sure of the best way to move this to the templates... Remove format_output and make MutiWidget use a higher-level template? Leave it as it is and let the users decide if they want format_output to use the template system or string interpolation? > > I think we should leave format_output() in place for backwards compatibility, and have its default implementation render a MultiWidget template. Moving forward, format_output can become an internal implementation detail, and overriding the template becomes the documented way to customize MultiWidget rendering. So a MultiWidget gets a template attribute? (it currently doesn't have any). By default it'd be {{{ {% for output in rendered_widget %}{{ output }}{% endfor %} }}}. If it gets implemented like this I'd say format_output() can be deprecated in favor of the API other widgets already have (get_context(), etc), unless there is a use case for format_output() that can't be implemented using a template. That'd be mostly for consistency if we want a MultiWidget to have the same customization hooks as every other widget. > > - Same for RelatedFieldWidgetWrapper. This basically wraps a widget, gets its output and adds the "Add Another" link next to it. I'd be tempted to make its render() method render the widget a separate template for the "Add Another" button, then join the outputs. Not sure if there are better options. > > I wouldn't implicitly join the outputs of two different templates; I'd have a related-field-widget-wrapper template that takes the wrapped widget's rendered HTML in its context and can wrap it however it wants. Ok, I'll do it this way. Thanks for your feedback :) -- Ticket URL: <http://code.djangoproject.com/ticket/15667#comment:16> Django <http://code.djangoproject.com/> The Web framework for perfectionists with deadlines. -- You received this message because you are subscribed to the Google Groups "Django updates" group. To post to this group, send email to django-updates@googlegroups.com. To unsubscribe from this group, send email to django-updates+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-updates?hl=en.