Future Developments.. For Discussion

Customising Templates

Although we can override a widgets html by including an identically named widget in a projects local template directory (for any templating language that provides template lookup facilites), we need a way of making template customisation able to be used in an ad-hoc way (i.e. not replacing ALL textarea elements).

At the moment the template for a widget is defined by a widgets _template attribute. The first way of overriding templates would be to provide a way of substituting this value. Simply adding an id keyword argument would allow this. Using this you would be able to do the following.

During form creation

>>> schema = schemaish.Structure()
>>> schema.add( 'firstName', schemaish.String())
>>> schema.add( 'surname', schemaish.String())

>>> form = formish.Form()
>>> form['firstName'].widget=TextArea()
>>> form['firstName'].widget.id = 'TextAreaCustom'

This first example would look inside the formish/widgets/TextAreaCustom for its template parts.

>>> schema = schemaish.Structure()
>>> schema.add( 'firstName', schemaish.String())
>>> schema.add( 'surname', schemaish.String())

>>> form = formish.Form()
>>> form['firstName'].widget=TextArea(id='TextAreaCustom')

Because both of these override the folder for the widget, any of the field parts can also be overriden. So if you include field_label.html in your folder then just this part will be override

Note

If a template is overridden but the directory only contains a field_label.html (for instance) should the widget default back to using the standard location?

At rendering time..

<%

temporary_template = """
<div id="${field.cssname}-field" class="${field.classes}">
% if field.widget._template != 'Hidden':
  <label for="${field.cssname}">${field.title}</label>
%endif
  <div class="inputs">
    <input id="${field.cssname}" type="text" name="${field.name}" value="${field.value[0]}" />
  </div>
% if field.error:
  <span class="error">${unicode(field.error)}</span>
% endif
% if str(field.description) != '':
  <span class="description">${field.description}</span>
% endif
</div>
"""

${form.header()|n}
${form.metadata()|n}

${form['firstName'](template=temporary_template)|n}

<div id="${form['surname'].cssname}-field" class="${form['surname'].classes}">
  <strong>${form['surname'].description}</strong>
  <em>${form['surname'].error}</em>
  ${form['surname'].widget()|n}
</div>

${form.actions()|n}
${form.footer()|n}

Obviously a big widget like this is silly inline so you could/should/may/might..

temporary_template.html

<div id="${field.cssname}-field" class="${field.classes}">
% if field.widget._template != 'Hidden':
  <label for="${field.cssname}">${field.title}</label>
%endif
  <div class="inputs">
    <input id="${field.cssname}" type="text" name="${field.name}" value="${field.value[0]}" />
  </div>
% if field.error:
  <span class="error">${unicode(field.error)}</span>
% endif
% if str(field.description) != '':
  <span class="description">${field.description}</span>
% endif
</div>
${form.header()|n}
${form.metadata()|n}

${form['firstName'](template=open('temporary_template.html').read())|n}

<div id="${form['surname'].cssname}-field" class="${form['surname'].classes}">
  <strong>${form['surname'].description}</strong>
  <em>${form['surname'].error}</em>
  ${form['surname'].widget()|n}
</div>

${form.actions()|n}
${form.footer()|n}

Depending on your templating language you may be able to get that string into the call in a better way.

Filtering Field Emission

It would be nice to be able to emit a bunch of fields by passing their ids to the fields() callable

${form.header()|n}
${form.metadata()|n}

${form.fields( ['title','firstname'] )|n}

<div id="${form['surname'].cssname}-field" class="${form['surname'].classes}">
  <strong>${form['surname'].description}</strong>
  <em>${form['surname'].error}</em>
  ${form['surname'].widget()|n}
</div>

${form.fields( ['surname','comments'] )

${form.actions()|n}
${form.footer()|n}

If we have a bunch of form fields we want to render with one custom one in the middle, we may want to spit out a slice of the fields.. e.g. fields[:4], then our custom one, then fields[5:]. If we can pass form.fields.keys to form.fields callable, we get lots of stuff for free.. We can apply filters, reductions, slices, etc, etc..

alternate syntaxes

personally I think using form.fields is OK.. Obviously the fields iterable is on one level though so we need a walk version of some sort.. Being as we are using dotted dicts omething like .dottedkeys which could then be reduced using different functions..

e.g.

form.fields( form.fields.dottedkeys[1:4] )
form.fields( form.fields.keys[-1] )

I think adding the simple ‘pass in a bunch of keys’ version is OK for most of what we’d like I’m sure..