Skip to content. | Skip to navigation

Sections
Personal tools
What is this?
Hi, my name is Tom Lazar and I'm a Plone and Zope developer based in Berlin, Germany and this is my personal and professional (no big difference, really...) website.
 

Customizing base_edit using widgets

Filed Under:

From the Show-and-Tell-Department

Update: As Derek points out, there is now an updated How-To on plone.org that specifically also works with Plone 3.x. You should check that out, instead of this here.

I probably needn’t tell any member of this audience how cool Archetypes are (either you already know or you couldn’t care less…) One of Archetype’s many promises to developers (besides becoming more attractive to the opposite sex) is rapid development – especially in conjunction with (drink the kool-aid! drink the kool-aid!) ArchgenXML: whip up a simple UML class diagramm of your content, generate, fire up plone and presto! You’ve got yourself sane view- and edit-templates “out-of-the-box” for all your content. Your users can start entering content from day one of your project (if they insist…) while you march on with the rest of the magic.

The fun stops, however, if you need to customize those auto-generated templates, because Archetypes doesn’t actually generate any specific templates for your particular content type but rather provides two generic templates (base_edit.cpt and base_view.pt) that niftily adapt to whatever contenttype they’re being applied to.

While it’s usually fairly trivial to generate additional view templates, that is sadly not the case for edit forms. Of course, one could always manually create all the necessary fields and i18n-ified labels and descriptions and what-not, but for anything but the most simple content types that’s a no-go: afterall, what did you create all those labels and message_ids for in the first place, if you end up hard-coding them into your templates in the end? Changes to your content model would then no longer necessarily be reflected in your form templates.

One hard-core approach would be to simply copy the entire base_edit.cpt and edit_macros.pt, renaming the former to <name-of-your-contenttype>_edit.pt and the latter to <name-of-your-contenttype>_edit_macros_.pt. That would work™, but, man! That’s some serious amount of boilerplate you’ve gotten yourself into just now!

Macros and slots to the rescue! Because, of the two templates involved, edit_macros.pt is by far the larger and more complex one – here’s where all the ‘magic’ happens. This is the template you definitely want to leave alone and let smarter people than yourself (i.e. its authors) deal with. Turns out, this can be achieved fairly easily, because the part where the actual edit fields are generated (by looping over the schema) comes with its own slot (widgets). This means, that you can simply copy base_edit.cpt to your skin folder, renaming it to <name-of-your-contenttype>_edit.pt and then replacing its call of the widgets-macro with your own fill-slot="widgets" statement.

For example, here’s a snippet from the <body> element from a current project of mine:


<metal:fill fill-slot="main">
  <metal:main define-macro="main">
    <metal:use_header use-macro="header_macro" />
    <metal:use_typedescription use-macro="typedescription_macro" />
    <metal:use_body use-macro="body_macro">
        <metal:widgets metal:fill-slot="widgets">
            [...]
            <metal:fieldMacro use-macro="python:here.widget('id', mode='edit')" />
            <metal:fieldMacro use-macro="python:here.widget('title', mode='edit')" />                          
            [...]
        </metal:widgets>
    </metal:use_body>
    <metal:use_footer use-macro="footer_macro" />
  </metal:main>
</metal:fill>

Once ‘inside’ the fill-slot="widgets" area you can go honkwild with creating a layout for your input form and then simply call the appropriate widget wherever you want one by using the <metal:fieldMacro use-macro="python:here.widget('title', mode='edit')"/> calls.

Thanks to Alec Mitchell and Rob Miller from #plone-IRC for the pointers and hand-holding!

Update: This approach has only been tested with Plone versions 2.x at the time. Unfortunately, it has proven not to work with 3.x YMMV etc. pp.

Documentation area how-to, please! :)

Posted by Alexander Limi at Mar 02, 2006 02:00 AM

Can you add this as a how-to at plone.org? We need to document the insanity. ;)

Archetypes has a dedicated area with how-tos etc now, this would fit very well there.

an addition

Posted by Anonymous User at Feb 27, 2008 10:37 AM

The trick is that base_edit "load" your macros from your_content_type_edit.pt template, if it exists. So your content type uses base_edit, until a macro in your_content_type_edit.pt has the same name of a macro in base_edit. In that case, the base_edit uses your macro.

ZPT is very powerful (but can be slow because of this) :)

So you can replace header of the edit form and what ever you want. Example:

Put in your_content_type_edit.pt in portal_skin -> custom:

My custom header, I can put whatever I want :P

You've changed the header :)

formatting sucks :(

Posted by Anonymous User at Feb 27, 2008 10:39 AM

sorry... if tom can edit my post and "format" it...

How-To on plone.org

Posted by Anonymous User at Mar 16, 2008 02:46 PM

This material is also now covered by a how-to on plone.org:

http://plone.org/documentation/how-to/how-to-customise-view-or-edit-on-archetypes-content-items/?searchterm=base_view

Evidently, archetypes/plone will automagically use a page template with the name [name-of-content-type]_edit.pt . Thus, supposedly, there is no need to copy all of base_edit. Using the how-to approach instead of the total-copy approach will help future-proof your edit form. Plus, it reduces boilerplate even further!

Derek Richardson

Thanks, Derek.

Posted by Tom Lazar at Mar 16, 2008 04:27 PM
I updated the entry with a link.

personalize_form

Posted by Anonymous User at Apr 03, 2008 07:26 AM

Hi, can I use the widgets also in the personalize_form, for textfields like description, to wrtie html instead of plain text?