Question

I'm trying to add dictionaries form_label and form_field to this macro call, and it's not going so well.

From the template. Only the macros line is really pertinent to the question. Let me repeat. Only the macros line is really pertinent to the question.

{% block content %}
<div id="edit_profile" class="well-lg">
  <fieldset>
    <form id="form_edit_profile" class="form-horizontal" action="{{ url|safe }}" method="post">
       <input type="hidden" name="_csrf_token" value="{{ csrf_token() }}">
       {{ macros.field(form.username, label=_("Username"), form_label={class:"col-xs-2"}, form_field={'placeholder':_("Enter your")+" "+_("Username"), class:"form-control focused required"}) }}
       ...

and the macro to support it. (has been updated because I didn't pass class as a string the first time.)

{% macro field(field, label='', form_label={},form_field={}) -%}
        <div class="form-group{% if field.errors %} error{% endif %}">
            {% set text = label or field.label.text %}

            {% if field.flags.required %}
                    {{ field.label(text=text + " *", class='control-label '+form_label['class'])}}
            {% else %}
                    {{ field.label(text=text + " ", class='control-label '+form_label['class']) }}
            {% endif %}
            <div class='col-xs-5'>
            {{ field(label, **form_field) }}
            {% if field.errors %}
                {% for error in field.errors %}
                   <label for="{{ field.id }}" class="error help-inline">{{ error }}</label>
                {% endfor %}
            {% endif %}
            </div>
        </div>
{%- endmacro %}

I'm wondering if I'm referencing the variables incorrectly or if the dictionary keys should be strings or something I'm not considering.

updated the traceback.

Traceback (most recent call last):
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 1535, in __call__
    rv = self.handle_exception(request, response, e)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 1529, in __call__
    rv = self.router.dispatch(request, response)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 1278, in default_dispatcher
    return route.handler_adapter(request, response)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 1102, in __call__
    return handler.dispatch()
  File "/Users/me/Documents/Aptana Studio 3 Workspace/project/bp_includes/lib/basehandler.py", line 89, in dispatch
    webapp2.RequestHandler.dispatch(self)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 572, in dispatch
    return self.handle_exception(e, self.app.debug)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 570, in dispatch
    return method(*args, **kwargs)
  File "/Users/me/Documents/Aptana Studio 3 Workspace/project/bp_includes/handlers.py", line 112, in get
    return self.render_template('login.html', **params)
  File "/Users/me/Documents/Aptana Studio 3 Workspace/project/bp_includes/lib/basehandler.py", line 325, in render_template
    self.response.write(self.jinja2.render_template(filename, **kwargs))
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.5.2/webapp2_extras/jinja2.py", line 158, in render_template
    return self.environment.get_template(_filename).render(**context)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/jinja2-2.6/jinja2/environment.py", line 894, in render
    return self.environment.handle_exception(exc_info, True)
  File "bp_content/themes/default/templates/login.html", line 1, in top-level template code
    {% extends base_layout %}
TypeError: macro 'field' takes no keyword argument 'placeholder'
Was it helpful?

Solution

It looks like you're trying to reference a variable from a dictionary without the enclosing string:

  form_label['class']

perhaps that is what is doing it? Also,

  form_label = {'class': ''}

Including Comments:

You have defined the macro as "field" but a variable within it is also labled "field." This could be confusing the parser.

OTHER TIPS

That is common issue when using dictionary literals in Python.

my_dict = {
  key: value
} 

Require you to have variables named key and value defined, so in fact

key = 1
value = 0

my_dict = {
 key: value
}

Will create your dictionary, the same as:

my_dict = {
  1 : 0
}

So if you wanted to have dictionary where entry key is 'key' you have to quote it

my_dict = {
 'key': 'value'
}

Jinja2 templates are no different:

 {% macro field(field, label='', form_label={class:""},form_field={class:""}) -%}

There are two issues here:

  • This requires class to be defined

  • identifier field is used twice

Replace it with:

{% macro field_macro(field, label='', form_label={'class':""},form_field={'class':""}) -%}

And of course:

 {{ field_macro(form.username, label=_("Username"), form_label={'class':"col-xs-2"}, 
        form_field={'placeholder':_("Enter your")+" "+_("Username"), 
            'class':"form-control focused required"}) }}

Another gotcha here, are default function parameters.

If by any chance you will change form_field within macro (you can do it in jinja) when default paramter was used ( ie nothing was passed for that parameter), all other calls with no parameter will use changed value.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top