pyramiddeformcolandercolanderalchemy

Custom templates and validation with Deform and mako


I am using deform in a project that uses pyramid with mako as a templating engine. I rewrote the templates for the widgets I need. I am using a modal for one of the forms so I wrote the mako template and the set the form widget with

form.widget = widget.FormWidget(template='modal')

The form works fine for the initial render, but when calling the validation block

 try:
   appstruct = self.my_form.validate(controls)
     
 except ValidationFailure as e:
   return dict(e.render())

e doesn't render the modal template, but rather the default form. How does make the validation form render using the same template as the form?


Right now I am using this to work around it...it shows the warning when there is an error, but does not display the particular errors on each field:

except ValidationFailure as e:
  form.error = e.error
  form.field = e.field
  return dict(form.render(e.cstruct)

The modal is the popup retail example from deform demo. The schema node just has a couple of text input fields.

Adding example:

facilities view:

@property
def form(self):
  schema = SQLAlchemySchemaNode(Facility)
  return Form(schema, buttons=('submit'))

@view_config(route_name="facilities", renderer="facilities.mako")
def index(self):
  form = self.form
  form.widget = widget.FormWidget(template="modal")

  if 'submit' in self.request.params:    
    try:
      controls = self.request.POST.items()
      appstruct = self.facility_form.validate(controls)

    except ValidationFailure as e:
      return dict(form=e.render())

  return dict(form=form.render())

The mako template then just injects the html:

{ form | n }

Solution

  • After playing with it for a while I came up with this solution (not sure if it is optimal). Before returning e.render(), set the form attributes on e.field

    @view_config(route_name="facilities", renderer="facilities.mako")
    def index(self):
      form = self.form
      form.widget = widget.FormWidget(template="modal")
    
      if 'submit' in self.request.params:    
        try:
          controls = self.request.POST.items()
          appstruct = self.facility_form.validate(controls)
    
        except ValidationFailure as e:
          e.field.widget = widget.FormWidget(template="modal")
          e.field.set_widgets({}) ## if using different from defaults
          e.field.formid = "my-popup" ## and any other non default attributes.
          return dict(form=e.render())
    
      return dict(form=form.render())