Skip to content

collective/dexterity.draftspreviewbehavior

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

WARNING
=======
June 18, 2010

Last Updated: July 29, 2010
---------------------------

This package is currently in experimental status and will be changing.  I suggest
not using it in any production environemnt until it has had further testing and
all the features are implemented properly.

This is work in progress and the trunk may not even work at times.  I do encourage
feedback so this can be released.  I hope to have something stable enough to use
and test with within a month.  Comments can be made on the dexterity mailing list
located at http://groups.google.com/group/dexterity-development.

The package naming will change and implementation could also change based on testing

Currently I have only tested in plone 3.5 using dexterity 1.0a3 and 1.0b1. and in
plone 4.0b4 using dexterity 1.0b1.

Jason Mehring (nrgaway@yahoo.com)

END OF WARNING :)


Introduction
============
experimental.dexterityz3cformdrafts implements services for managing auto-saved dexterity 
content drafts in Plone specificly using z3cform. This addresses two problems:

* If the browser is accidentally closed or crashes whilst a page is being
  edited, all changes are lost.
* Some data may need to be managed asynchronously via ajax, This data should not be 
  saved until the form is saved (and in the case of an add form, it is impossible 
  to do so). I will be releasing shortly a widget that allows image previews without
  loading a page.
* The ability to preview drafts before making a choice to save them.
* Images and other fields do not 'disappear' when a form is submitted and there were
  errors in the form


Installation
============
The source for this package only resides on the collective repo at the moment
so you will either need to check it out manually, or use mr.developer:

    [auto-checkout] 
    experimental.dexterityz3cformdrafts
    plone.app.drafts

    [eggs]
    experimental.dexterityz3cformdrafts
    plone.app.drafts

    [develop]
    src/experimental.dexterityz3cformdrafts
    src/plone.app.drafts

    [sources]
    experimental.dexterityz3cformdrafts = svn http://svn.plone.org/svn/collective/experimental.dexterityz3cformdrafts/trunk
    plone.app.drafts = svn https://svn.plone.org/svn/plone/plone.app.drafts/trunk

You can install experimental.dexterityz3cformdrafts as normal, by depending on it in your
``setup.py`` or adding it to the ``eggs`` list in your buildout. The package
will self-configure for Plone; there is no need to add a ZCML slug.

IMPORTANT:
----------
You will also need to install the 'Drafts Support'  from the portal_quickinstaller tool
or Plone's Add-ons control panel.

How it Works
============
When a user chooses to add or edit content, the traverser in intercepted and and
if the IDexterityDraftable behavior is enabled for a draft content object replaces
the origninal context.  The draft context is then marked with IDexterityDraft
which allows other adapters such as view adapters and the z3cform datamanager
adapters to hopefully work seamlessly with the object, just as it was a real
object.  The draft object is not catalogued.

The draft object id becomes ++add_draft++your.custom.content.type which allows
z3cform to call the object directly from a URL (usefull for image @@download
for instance). (For editing, it becomes ++edit_draft++your.custom.content.type)

All the add / edit buttons and handlers that appear in the add/edit forms are
overwritten with Custom button handlers to allow the draft to be saved properly.
The original 'save' and 'cancel' handlers will be executed though, after a few
things are set up so any original code can still complete.  

All the new buttons can be overridden if needed, since they are just adapters.
See button.py, add.py and edit.py for examples.  These button action adapters
could also be used for any other project to override handlers I suppose.

Two new buttons will appear in the add / edit forms (if the behaviors are 
enabled) being 'Save' and 'Preview'.

Save, just saves the draft.  No error checking or validation takes place at
this point.  The page will be reloaded.  User can navigate away or access
the draft from another browser simply by choose to add or edit the existing
content object again.

Preview mode actually will attempt to use the current view that would be used
to display the content type once it is saved, to allow the user to make a decision
to save, edit or discard the form (either a custom view or generated by autoform). 

Cancel will discard the draft.  If editing, the original content is not modified.

For adding, Once the user choose to saves the form, a new content object is 
created and the data from the draft object is synced to the new object, 
then discarded; for editing, the original content object is updated.


Usage
=====
Enable behaviors requires to enable draft on z3cform geterated content type:
(usually locted in .profiles/default/types directory.

<!-- enabled behaviors -->
 <property name="behaviors">
     <element value="plone.app.content.interfaces.INameFromTitle" />

     <!-- specicific related to draft behaviors below -->
     <element value="experimental.dexterityz3cformdrafts.interfaces.IDexterityDraftable" />

     <!-- To enable user to be able to manually save the draft -->
     <element value="experimental.dexterityz3cformdrafts.interfaces.IDexterityDraftSaveBehavior" />

     <!-- To enable previews on the draft content type -->
     <element value="experimental.dexterityz3cformdrafts.interfaces.IDexterityDraftPreviewBehavior" />
 </property>

If you have any custom Views, and do not want to to use it as the preview (so you
can be lazy and not need to create a custom preview View), you need to add the following
to your view.pt file so the Save / Edit / Cancel buttons will appear.

If you do not have any custom view, then plone.autoform will be used to generate the preview.

   <!-- Action buttons for prefiew mode -->
    <tal:block tal:condition="exists: view/actions">
         <form action="." method="post" tal:attributes="action view/request/getURL">
             <metal:actions metal:use-macro="context/@@ploneform-macros/actions"/>      
         </form>
    </tal:block>

If you choose to create a custom preview View, hook it in like follows in the zcml
file (not sure if grok can be used on a regualr View and changing name to preview,
instead od view).  Remember to add the Action section above to the preview.pt
    
   <browser:page
        for=".IYourDexterityContentType"
        name="preview"
        class=".preview.DefaultPreviewView"
        template="preview.pt"
        permission="zope2.View"
        />

NOTE:  I have not tested a custom preview yet; may not work as stated above.

NOTE:  I am looking into rendering the preview into a JQuery Tools overlay (using 
       plone.app.jquerytools), and have no buttons, just use the "close"  link to 
       return to the edit form and then save/cancel. 
       ** I don't think we can rely on this overlay completely though, since if
       the user does not have javascript enabled, then we will need to fall back
       to provideing the Save / Edit / Cancel buttons in the preview **

IMPORTANT: Don't forget to re-install (import via portal_setup) your content type 
           when you have added the new draft behaviors or they won't be enabled!!


In Progress
===========
* 


Todo
====
* hide tabs in getContent() to solve edit problem creating items in items if
  edit tab is pressed 
* provide an adapter to choose an IStatus message to show
* remove IDexterityDraftContainer/Item; just override plone.app.dexteity.browser
  adapters to adapt mine (that contain actions)
* Write tests once implementation seems solid
* Currently I don't think plone.app.drafts is set up to deal with anon users since it
  uses the userid to store draft.  Need to implement code to addow anon users to add 
  content maybe by using a session id or something since I dont want to require a user
  to have to be a member in my use case (I would use work flow to confirm add by
  email confirmation if not a registered member)
* create adapters in traverse routines and look them up instead of calling code 
  directly
* consider using subscribers to populate draft / preview buttons so they can be in
  seperate module and code wont rely on them


Possible Bugs
=============
* If the Save and Preview buttons do not appear on when adding or editing a draft, you
  are not editing the draft since the draft failed to load.  This is more than likely
  due to the code in .dexterity.py.setupupDraft() that failed to identify the userid
  of the loggged in user.  I wrote code to handle this case, but has not been tested
  very much yet, since I just finished it yesterday.  The reason this happens is the
  draft context is trying to be returned before user validation, so I need to grab
  the user from session or other cookie.


Identified Bugs
===============
* Edit tab does not get highlighted when editing (view tab remains highlighted).  Will
  need to figure out how to set it when entering edit view 
* edit submit or draft ended up creating a content type within a content type by
  a tester.  This happens when you press 'edit' tab on an existing draft.  Either I 
  need to disable tabs, or handle it on the submit. 

Releases

No releases published

Packages

No packages published

Languages