This document contains instructions how to manipulate
Archetypes schema (data model for content items) and
fields and widgets it consists of.
Schema is list of fields associated with a
content type. Each field can belong to one
schemata which corresponds to one Edit tab
sub-tab in Plone user interface.
Field schemata is chosen by setting field's
Archetypes based data model is defined as Schema object,
which is a list of fields.
When your class is being constructed you can refer the
schema simply in Python:
# Assume you have YourContentSchema object
You can access context schema object by using Schema()
Run-time schema patching is possible, so Schema()
output might differ what you put in to your content
type during the construction.
schema = context.Schema()
Each field has accessor method. Accessor method is
- In your content type class
Automatically generated if you don't give it
+ schema field name with first letter uppercase.
has accessor method
There are a few exceptions to this rule, for
fields that correspond to Dublin Core metadata. To
conform to the Dublin Core specification, the
accessor method for the
Archetypes has two kinds of access methods:
getSomething(), which filters output;
raw, the so-called edit accessor,
which does not filter output.
If you use direct attribute access, i.e.
you can get a
is an encapsulation of raw data for long text or file.
It contains information about mimetype, filename,
encoding. To get the raw value of a
object you can use the
method, or more simply
(but take care that you don't mess up the encoding).
You can use field.get(context) to read values of fields
indirectly, without knowing the accessor method.
This example shows how to read and duplicate all values
of lc object to nc:
from Products.Archetypes import public as atapi
nc = createObjectSomehow()
# List of field names which we cannot copy
do_not_copy = ["id"]
# Duplicate field data from one object to another
for field in lc.Schema().fields():
name = field.getName()
# ComputedFields are handled specially,
# and UID also
if not isinstance(field, atapi.ComputedField) and name not in do_not_copy:
value = field.getRaw(lc)
newfield = nc.Schema()[name]
# Mark creation flag to be set
field.writable() provides a short-cut whether the
currently logged in user can change the field value.
field = context.Schema()["phone_number"]
assert field.writable(), "Cannot set phone number"
There is also a verbose debugging version which will print
the reason to log if the writable condition is not
field = context.Schema()["phone_number"]
assert field.writable(debug=True), "Cannot set phone number"
Below is a sample through-the-web Python Script which you
can drop to any Plone through Zope Management Interface.
Use case: People are lazy to write descriptions (as in
Dublin Core metadata). You can generate some kind of
description by taking the few first sentences of the text.
This is not perfect, but this is way better than empty
This script will provide one-time operation to
automatically generate content item descriptions based on
their body text by taking the first three sentences.
The script will provide logging output to standard Plone
log (var/log and stdout if Plone is run in the debug
def create_automatic_description(content, text_field_name="text"):
""" Creates an automatic description from HTML body by taking three first sentences.
Takes the body text
@param content: Any Plone contentish item (they all have description)
@param text_field_name: Which schema field is used to supply the body text (may very depending on the content type)
# Body is Archetype "text" field in schema by default.
# Accessor can take the desired format as a mimetype parameter.
# The line below should trigger conversion from text/html -> text/plain automatically using portal_transforms
field = content.Schema()[text_field_name]
# Returns a Python method which you can call to get field's
# for a certain content type. This is also security aware
# and does not breach field-level security provided by Archetypes
accessor = field.getAccessor(content)
# body is UTF-8
body = accessor(mimetype="text/plain")
# Now let's take three first sentences or the whole content of body
sentences = body.split(".")
if len(sentences) > 3:
intro = ".".join(sentences[0:3])
intro += "." # Don't forget closing the last sentence
# Body text is shorter than 3 sentences
intro = body
# context is the reference of the folder where this script is run
for id, item in context.contentItems():
# Iterate through all content items (this ignores Zope objects like this script itself)
# Use RestrictedPython safe logging.
# plone_log() method is permission aware and available on any contentish object
# so we can safely use it from through-the-web scripts
context.plone_log("Fixing:" + id)
# Check that the description has never been saved (None)
# or it is empty, so we do not override a description someone has
# set before automatically or manually
desc = context.Description() # All Archetypes accessor method, returns UTF-8 encoded string
if desc is None or desc.strip() == "":
# We use the HTML of field called "text" to generate the description
# This will be printed in the browser when the script completes successfully