{#-
       Licensed to the Apache Software Foundation (ASF) under one
       or more contributor license agreements.  See the NOTICE file
       distributed with this work for additional information
       regarding copyright ownership.  The ASF licenses this file
       to you under the Apache License, Version 2.0 (the
       "License"); you may not use this file except in compliance
       with the License.  You may obtain a copy of the License at

         http://www.apache.org/licenses/LICENSE-2.0

       Unless required by applicable law or agreed to in writing,
       software distributed under the License is distributed on an
       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
       KIND, either express or implied.  See the License for the
       specific language governing permissions and limitations
       under the License.
-#}
<form method="{{method}}"
      {% if enctype %}enctype="{{enctype}}"{% endif %}
      action="{{action}}">
  {% set extra_width = 0 %}
  {% if style == 'wide' %}
    {% set extra_width = 4 %}
  {% endif %}
  {% if errors and not errors.iteritems and show_errors %}
  <div class="grid-{{19 + extra_width}}"><span {{widget.j2_attrs({'class':error_class})}}>{{errors}}</span></div>
  {% endif %}
  {% for field in widget.fields %}
    {% set ctx=widget.context_for(field) %}
    {% if field.field_type != 'hidden' %}
      {% if ctx.errors and field.show_errors -%}
      <div class="grid-{{19 + extra_width}}"><span {{widget.j2_attrs({'class':error_class})}}>{{ctx.errors}}</span></div>
      {%- endif %}
      {% if field.show_label and field.label %}
      <label for="{{ctx.id}}" class="grid-4">{{field.label}}:</label>
      <div class="grid-{{15 + extra_width}}">{{field.display(**ctx)}}</div>
      {% else %}
      <div class="grid-{{19 + extra_width}}">{{field.display(**ctx)}}</div>
      {% endif %}
    {% else %}
      {{field.display(**ctx)}}
    {% endif %}
  {% endfor %}
  {% if buttons %}
    <label class="grid-4">&nbsp;</label>
    <div class="grid-{{15 + extra_width}}">
      {% for b in buttons %}
        {{b.display()}}
      {% endfor %}
    </div>
  {% endif %}
  {% if widget.antispam %}{% for fld in g.antispam.extra_fields() %}
  {{fld}}{% endfor %}{% endif %}
</form>
