Personal tools
You are here: Home Documentation Tutorials Customizing AT View Templates Customizing Widgets
Support

Get Help

Join our chat rooms or support forums if you have more specific questions.

Plone Training
Learn how to design, build, and deploy a website in Plone through one of the numerous Plone training sessions around the world.
Find Plone training…
 
Document Actions

Customizing Widgets

This page shows you how to customize widgets, and gives some examples of what kinds of neat tricks can be done with widget customization.

Floyd May

This tutorial describes the steps to produce a fully-customized view of an Archetypes object. This is applicable to tweaking little details of the default AT behavior as well as gutting and re-building the view from scratch.
Page 3 of 6.

As we've already said, widgets are what Archetypes uses to display individual fields. Archetypes' built-in templates, base_view,base, and widgets/field use each field and the field's associated widget (specified in the schema) to determine which widget template to use. However, you can override a widget's template, as we will show below. Furthermore, you can create a whole new widget class, which will have data and operations specific to the display of your custom data type. Read the next section to determine how much widget hacking you need to do.

How to Determine If You Need to Create A Custom Widget Class

If you cannot find a widget in Archetypes or in a readily-available third-party product that does what you need, use the following set of questions to determine if you can just customize the template versus creating a new widget class. If you answer "no" to the following questions, a custom template is all you need:

  • Does the display of your field require helper functions to do conversions or formatting that would be difficult or cumbersome in TALES?
  • Do you have multiple AT-based classes where some fields in those classes share all of the the following characteristics?
    • The same data type
    • Similar, needs for display
    • One or more attributes that are class-specific that apply to the display (i.e. the most appropriate place to set these attributes is in the schema definition)
  • Does your custom data type need some super-specific marshalling when edited or searched that you can't get from any standard AT widget class?
  • Do you need to override or change the way that Archetypes handles the processing of the edit form for a particular field?

If you answered yes to most of the questions, then you might need to create a Widget class. If the questions aren't clear, take a look at the RichDocument tutorial . If you've got a specific enough use-case (like RichDocument) that you need custom widget classes, you're probably able to make it happen just by the sheer fact that you know you need them. [1]

Customizing Widget Templates

Creating custom widget templates is not hard, so don't be afraid. I assume if you're reading this far, you've already determined that you don't need a custom widget class, and just need to tinker a little bit with how things are done by default.

First, you should understand what you have control over by customizing a widget template itself. You're controlling the display of the widget's data, but not its label. For a StringField called myfield, the default display is something like:

myfield: some value

The only thing we can control is the display of what comes after "myfield:", which is just the data contained within the field itself (we'll talk about how to customize the display of labels later). However, if we customize the template, we can insert all kinds of nifty HTML into there! So, let's look at StringWidget's template, widget/string :

    <html xmlns="http://www.w3.org/1999/xhtml"
          xmlns:tal="http://xml.zope.org/namespaces/tal"
          xmlns:metal="http://xml.zope.org/namespaces/metal"
          xmlns:i18n="http://xml.zope.org/namespaces/i18n"
          i18n:domain="plone">
      <head><title></title></head>
      <body>

        <!-- String Widgets -->
        <metal:view_macro define-macro="view"
                          tal:replace="structure accessor" />

        <metal:define define-macro="edit">
          <metal:use use-macro="field_macro | here/widgets/field/macros/edit">
            <input metal:fill-slot="widget_body"
                   type="text"
                   name=""
                   value=""
                   size="30"
                   tabindex="#"
                   tal:attributes="name fieldName;
                                   value value;
                                   size widget/size;
                                   maxlength widget/maxlength;
                                   tabindex tabindex/next;"
                   />
          </metal:use>
        </metal:define>

        <div metal:define-macro="search">
          <div metal:use-macro="here/widgets/string/macros/edit">
          </div>
        </div>

      </body>

    </html>

It's pretty straight-forward. As you can see, there are three important macros in a widget template:

  • view
  • edit
  • search

Don't concern yourself with the edit and search macros; remember, we're customizing the view. Let's start by creating a new template called my_string_widget [2]. Start like this:

    <html xmlns="http://www.w3.org/1999/xhtml"
          xmlns:tal="http://xml.zope.org/namespaces/tal"
          xmlns:metal="http://xml.zope.org/namespaces/metal"
          xmlns:i18n="http://xml.zope.org/namespaces/i18n"
          i18n:domain="plone">
      <head><title></title></head>
      <body>

        <!-- String Widgets -->
        <metal:view_macro define-macro="view"
                      tal:replace="structure accessor" />

        <metal:define define-macro="edit">
          <div metal:use-macro="here/widgets/string/macros/edit">
          </div>
        </metal:define>

        <div metal:define-macro="search">
          <div metal:use-macro="here/widgets/string/macros/edit">
          </div>
        </div>

      </body>

    </html>

Notice how we use the same pass-through macro call in the edit macro that the string template originally uses in the search macro. It's important to remember the following concept: Widget templates must define all three macros: view, edit, and search. Also, notice how there is no display code for the label; that's handled elsewhere. If you're wondering where the accessor variable comes from, that's part of the widget display code. The widget class defines the following local variables that are accessible inside widget templates:

accessor
The accessor method for the field. Call it to retrieve the value of the field.
fieldName
The name of the field.
widget
The widget object for the field.
field
The instance of the field class itself.
mode
Will be view or edit, based on the action being taken. For our purposes, it should always be view.

Now, let's modify the way that our StringField displays. For brevity, I'll just show the view macro:

    <metal:view_macro define-macro="view"
                      tal:replace="structure python:str('&quot;' + accessor()) + '&quot;' +
                                                    'is the coolest field data ever!'" />

Then, we should tell our type's schema to point at the new template:

    StringField('myfield',
        widget=StringWidget(
            label='Myfield',
            label_msgid='ATViewTutorial_label_myfield',
            description_msgid='ATViewTutorial_help_myfield',
            i18n_domain='ATViewTutorial',
            macro='my_string_widget',
        )
    ),

Be sure to restart Zope and reinstall using portal_quickinstaller. Now, our StringField, when rendered, looks like this:

How the custom widget looks

Yes, folks, it's just that easy.

[1] Again, this probably only applies to wiggy.

[2] Notice I'm breaking AT's convention here. You don't have to do that, but I find it more convenient and understandable to add a _widget to the names of my widget templates.

 
by Floyd May last modified April 27, 2006 - 19:30 All content is copyright Plone Foundation and the individual contributors.

For any issues with the web site functionality, please file a ticket.

Please consult the policy on plone.org content if you want your content published on this site.

Servers and hosting by