0

While building a small Flask based web app, I came across the need to pass arbitrary data from a Form Field object to the template where it's being rendered. However, I can't seem to find a way to do this.

The only place I think I could add such data was to the kwargs property of WTForms Field objects, but then I seem to have no way to access those properties from the template.

In case you're wondering what I'm trying to accomplish, I'm writing a template macro to ease form rendering, and I need to pass some extra data from the Form fields objects - mostly layout related, but which will not be HTML attributes for the fields themselves (which is what kwargs is designed for).

kyle
  • 691
  • 1
  • 7
  • 17
boliva
  • 5,604
  • 6
  • 37
  • 39
  • post a minimalist example of what you are trying to do, will help someone modify it to give a solution – Attack68 Mar 03 '19 at 18:33
  • thanks for your interest and sorry for the late response. I'm basically trying to achieve the same that was asked in this question https://stackoverflow.com/questions/39544715/custom-parameter-in-flask-wtfoms-field but, by the answer given, seems I'm out of luck. I thought that maybe I could use the `render_kw` dict of each Field object to pass some data back to the template but I can't find a way to access it from there. – boliva Mar 08 '19 at 06:35
  • I found an answer here: https://stackoverflow.com/questions/9749742/python-wtforms-can-i-add-a-placeholder-attribute-when-i-init-a-field#comment26131673_9783777 – boliva Mar 08 '19 at 07:25

1 Answers1

1

I found an answer here but it's not an answer per se but I comment.

Quoting Crast:

The description keyword argument of WTForms fields is allowed to be set at field construction, and is not inspected, just copied directly onto the field, and thus can be any value, not just a string, even a custom attribute. If you want to carry over your own metadata, you can simply use this to carry over any data you may want: TextField(..., description={'placeholder': foo', 'class': bar} (or even a custom class) then use this attribute in your template for any special metadata you want.

Yes, I know about separating content and presentation and the purpose of the description property isn't really intended for this kind of use, but it's the only way I found to pass data back to the template where I use a macro to render forms.

To access the passed data inside description from the template I did something like this:

{% macro render_create_form(form, form_title, enctype=None) %}
  <h2>{{ form_title }}</h2>
  <form action="" method="post"{% if enctype %} enctype="{{ enctype }}"{% endif %}>
  {{ form.hidden_tag() }}
    {% for field in form if not field.name == 'csrf_token' %}
      {% set class_name = field.description.class %}
      {% if field.type == "StringField" or field.type == "PasswordField" or field.type == "BooleanField" or field.type == "SelectField" %}
        <div class="{{ class_name }}">{{ field.label }} {{ field }}</div>
      {% elif field.type == "NumberField" %}
        <div class="{{ class_name }}">{{ field.label }} {{ field(type='number', min=field.description.min, max=field.description.max, placeholder=field.description.placeholder) }}</div>
      {% elif field.type == "HiddenField" %}
        {{ field }}
      {% elif field.type == "SubmitField" %}
        <div class="{{ class_name }}">{{ field }}</div>
      {% endif %}
  {% endfor %}
  </form>
{% endmacro %}
boliva
  • 5,604
  • 6
  • 37
  • 39