I'm working on a package (plone.app.textfield) that's meant to solve the 
common use case in Plone whereby we have a rich text field that's got a 
"raw" value (a unicode string) with a MIME type (e.g. text/html or 
text/structured), which is transformed to HTML on output (even HTML 
input is transformed, because we do some markup tidying and stripping).

We're trying to implement this as efficiently as possible for the most 
common use case: the raw value is read infrequently (on the edit screen, 
basically); transformed value is read frequently (every time the content 
item is viewed).

The approach we've taken is to store the mime type, the raw input and 
the transformed output values in a RichTextValue object that's not 
IPersistent (it derives from 'object' only) but knows its parent, via a 
__parent__ pointer. This avoids a separate _p_jar so e.g. the object 
isn't loaded or cached separately. We use the _p_changed protocol to 
notify the parent when the value is changed.

Furthermore, we store the raw value in a blob, since it can be 
relatively big and is read/written infrequently. For performance, we 
store the transformed output HTML on the object in a regular string, on 
the assumption that it's almost always read when the object is used 
(i.e. on its view).

I have a couple of questions about the performance and behaviour of this:

  1) When a value is extracted from the request in the edit widget, it 
is used to construct a RichTextValue, which is passed back for 
validation etc. This means writing to a blob since setting the 'raw' 
attribute writes to a blob. It is possible that validation will fail and 
so the object will never be persisted (set onto its parent object). Is 
it bad for performance to do write a "temporary" blob like this?

  2) When a value is edited, we currently create a new RichTextValue 
object and replace the old one with it. Hence, we get a new blob. Would 
it be better to re-use the same blob and write a new value to it?

  3) If the parent object is copied (e.g. via manage_cut/manage_paste in 
Zope 2), will the blob be copied as well, or this something we need to 
implement e.g. with event handlers for IObjectCopiedEvent? Bear in mind 
that the blob is an attribute of a simple class (RichTextValue) which in 
turn is an attribute of a persistent content object. The RichTextValue 
has a __parent__ pointer to the content object.

  4) Speaking of that __parent__ pointer: if the content object is 
copied, is that going to point to the old instance? If so, we presumably 
have to fix the reference up in an event handler? Is there a better way 
to make an object that doesn't have its own _p_jar but doesn't need a 
reference to the parent? I suppose this isn't really any different from 
a folder structure in Zope 3 where each child has a __parent__ pointer 
to its parent. When the parent is copied, what happens to those 
__parent__ pointers?

The field class is here: 

The value class is here: 


Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

For more information about ZODB, see the ZODB Wiki:

ZODB-Dev mailing list  -  ZODB-Dev@zope.org

Reply via email to