[Zope-dev] ZPatterns design questions

Steve Spicklemire steve@spvi.com
Thu, 5 Oct 2000 22:46:34 -0500 (EST)


Again.. this is an embarrassingly trivial example.. but here it goes:

First of all there is a ZClass.... 'ToDoClass'. 

It needs to have a base class of ZPatterns:DataSkin.

You don't need constructor methods, but I don't think they hurt anything
if you leave them in.

The ToDo needs methods:

index_html to render itself like any ZClass:
----------------------------------------------------------------------
<dtml-var standard_html_header>
<center>
<table>
<tr><th>Name</th><td>&dtml-id;</td></tr>
<tr><th>Description</th><td>&dtml-description;</td></tr>
<tr><th>Doer</th><td>&dtml-doer;&nbsp;</td></tr>
<tr><th>Done?</th><td><dtml-if done>Done!</dtml-if>&dtml-done;&nbsp;</td></tr>
<tr><th>Last Modified</th><td>&dtml-bobobase_modification_time;</td></tr>
</table>
<a href="editInstanceForm">Edit this instance</a>
<a href="&dtml-URL2;">Back to list</a>
<center>
<dtml-var standard_html_footer>
----------------------------------------------------------------------

editInstanceForm so folks can edit its contents... (just like any ZClass)
----------------------------------------------------------------------
<dtml-var standard_html_header>
<center>
<h2>Edit ToDo Item</h2>
<form action="editInstance" method="post">
<table cellspacing=3 cellpadding=3>
<tr><th>Name</th><td>&dtml-id;</td></tr>
<tr><th>Description</th><td><textarea name="description" wrap=soft cols=60 rows=15>&dtml-description;</textarea></td></tr>
<tr><th>Doer</th><td><select name="doer"><option value="">Nobody
<dtml-in doers sort>
<option value="&dtml-sequence-item;" <dtml-if "doer==_['sequence-item']">selected</dtml-if>>&dtml-sequence-item;
</dtml-in>
</select>
</td></tr>
<tr><th>Done?</th><td><input type=checkbox name="done" <dtml-if done>checked</dtml-if>></td></tr>
<tr><td colspan=2 align=center><input type=submit value="Edit ToDo"></td></tr>
</table>
</form>
</center>
<dtml-var standard_html_footer>
----------------------------------------------------------------------

a method that actually does the changing of the properties... (just like...)

editInstance
----------------------------------------------------------------------
<dtml-var standard_html_header>
<center>
<dtml-if "REQUEST.form.has_key('done')"> <!-- booleans can be tricky.. -->
<dtml-call "REQUEST.set('done',1)">
<dtml-else>
<dtml-call "REQUEST.set('done',0)">
</dtml-if>

<dtml-call "propertysheets.Basic.manage_changeProperties(REQUEST=REQUEST)">
ToDo Changed.<br>
<form action="&dtml-URL2;">
<input type=submit value="OK">
</form> 
</center>
<dtml-var standard_html_footer>
----------------------------------------------------------------------

That's it for the methods of the ZClass...we can view/edit instances TTW.

Now.. we need propertysheets:

Basic: (Now it's a "Data Skin Attribute Property Sheet").

properties:
description (text)
doer (string)
done (boolean)

Shared: (This is a propertysheet that's meant to be shared 
        by all the instances. If you update this... update
	it in the ZClass, not an instance.....)

doers (lines)

Finally... we need methods for the ToDoManager (Specialist):

We'll set the defaultRack of the ToDoManager up to store its
objects persistently, using the ToDoClass we just created 
as the storage type. We can just leave the default data 
plugins installed since they work fine with persistent storage.
If later you want to experiment with other storage methods,
you can do it making almost no changes to any other code 
(with the possible exception of defaultRack.getPersistentItemIds()
which might not be appropriate if you're not using persistent
ZODB storage....)

Here is the default method of the ToDoManager... basically,
pull out the objects and view a brief list of ids, descriptions
doers, and doneness... :

----------------------------------------------------------------------
<dtml-var standard_html_header>
<center>
<br>
<h2><dtml-var title></h2>
<p>
<dtml-in "defaultRack.getPersistentItemIDs()" sort>

<dtml-if sequence-start>
<form action="." method="post">
<table cellspacing=3 cellpadding=3 border=1>
<tr><td>&nbsp;</td><th>Name</th><th>Description</th><th>Doer</th><th>Done?</th></tr>
</dtml-if>

<dtml-let currID="_['sequence-item']">
<dtml-with "getItem(currID)">
<tr>
<td><input type=checkbox name="ids:list" value="&dtml-currID;"></td>
<td><a href="<dtml-var currID url_quote>/editInstanceForm"><dtml-var currID></a></td>
<td><dtml-var description>&nbsp;</td>
<td><dtml-var doer>&nbsp;</td>
<td><dtml-if done>Done!<dtml-else>&nbsp;</dtml-if></td>
</dtml-with>
</dtml-let>

<dtml-if sequence-end>
<tr><td colspan=5 align=center><input type=submit name="newToDoForm:method" value="Add New ToDo"><input type=submit name="deleteInstances:method" value="Delete selected ToDos"></td></tr>
</table>
</dtml-if>

<dtml-else>
Sorry.. no "to do"s!
<br>
<form action=".">
<input type=submit name="newToDoForm:method" value="Add New ToDo">
</form>
</dtml-in>
</p>

</center>
<dtml-var standard_html_footer>

----------------------------------------------------------------------

We also need to be able to add and delete items from the rack:

newToDoForm:
----------------------------------------------------------------------
<dtml-var standard_html_header>
<center>
<form action="addNewToDo" method="post">
<table>
<tr><td align=center colspan=2><h2>Add New ToDo</h2></td></tr>
<tr><th>ToDo Name</th><td><input name="name" size=40></td></tr>
<tr><th>ToDo Description</th><td><textarea rows=10 cols=40 name="description"></textarea></td></tr>
<tr><td align=center colspan=2><input type=submit value="OK"></td></tr>
</table>
</form>
</center>
<p>
</p>
<dtml-var standard_html_footer>

----------------------------------------------------------------------

addNewToDo:
----------------------------------------------------------------------
<dtml-var standard_html_header>
<center>
<h2> Thanks for the new ToDo!</h2>
<dtml-let ni="newItem(name)">
<dtml-call "ni.propertysheets.Basic.manage_changeProperties(description=description)">
</dtml-let>
<form action=index_html>
<input type=submit value="OK">
</form>
</center>
<dtml-var standard_html_footer>

deleteInstances:
----------------------------------------------------------------------
<dtml-var standard_html_header>
<h2>Deleting Instances</h2>
<p>
<dtml-in ids>
<dtml-let ni="getItem(_['sequence-item'])">
<dtml-call "ni.manage_delete()">
</dtml-let>
</dtml-in>
<form action="&dtml-URL1;">
<input type=submit value="OK">
</form>
</p>
<dtml-var standard_html_footer>

----------------------------------------------------------------------

That's it.  I can't imagine anything simpler. ;-) Really!

-steve

>>>>> "Michael" == Michael Bernstein <webmaven@lvcm.com> writes:

    Michael> Steve Spicklemire wrote:
    >>  Ack.. of course I forgot to test creating new
    >> instances.... there was a snippet of code for editing and
    >> creating that didn't work with the new propertysheet stuff. I
    >> fixed it just now... so it really works. ;-)

    Michael> I didn't get a chance to play with this today, but I'll
    Michael> make time to do so tomorow. How easy would it be for you
    Michael> to write a step-by-step HowTo/WalkThrough of creating the
    Michael> example? I can edit it and flesh it out if you can write
    Michael> a bare-bones version.

    Michael> Thanks,

    Michael> Michael Bernstein.