[Zope-CVS] CVS: Packages/JobBoardEx - Tutorial.html:1.10

Guido van Rossum guido@python.org
Fri, 14 Jun 2002 17:23:11 -0400


Update of /cvs-repository/Packages/JobBoardEx
In directory cvs.zope.org:/tmp/cvs-serv25584

Modified Files:
	Tutorial.html 
Log Message:
Checkpoint checkin of changes.  I plan to change much more, but I've
got to go now.  Please don't make more changes in CVS -- just mail me
your suggestions if you have any.


=== Packages/JobBoardEx/Tutorial.html 1.9 => 1.10 ===
 
 <body>
+
 <h1>The Job List Example in Zope3</h1>
 
+
 <h2>Overview</h2>
 
-<p>This application will provide you with a simple but useful example
-in Zope3, which can be modified and adapted for your own purposes. It
+<p>This application provides you with a simple but useful example in
+Zope3, which can be modified and adapted for your own purposes.  It
 also demonstrates a pattern for you to follow when creating your own
 applications.
 
 <p>The Job List allows users to post job information on a site, and to
-view a simple list of jobs. A particular job can be selected and
-viewed in detail. When a job is submitted for posting, the
-administrator of the job list can accept or reject the job. The
+view a simple list of jobs.  A particular job can be selected and
+viewed in detail.  When a job is submitted for posting, the
+administrator of the job list can accept or reject the job.  The
 administrator may also delete existing jobs from the list.
 
 <p>This example was created at the March 19-21, 2002 Sprint at the
-PythonLabs offices in Washington DC, lead by Jim Fulton and including
+PythonLabs offices in McLean, VA, lead by Jim Fulton and including
 Guido van Rossum, Jeremy Hylton, Tim Peters, Fred Drake, Barry Warsaw,
-Stephan Richter, and Bruce Eckel. The initial draft of this document
+Stephan Richter, and Bruce Eckel.  The initial draft of this document
 was written by Bruce Eckel with help from Jim Fulton, on a train to
-New York City.  This document is placed in the public domain so that
-others may freely improve upon it, but if you do so please submit the
-result back to Zope Labs.
+New York City.  Most of the example code was recreated nearly from
+scratch, to match significant improvements in the Zope3 API, by Jim
+Fulton and Guido van Rossum in the afternoon of June 12, 2002.  Jim,
+Guido and Steve Alexander made subsequent changes.  This tutorial was
+improved by Ken Manheimer and Guido van Rossum around the same time.
+This document is placed in the public domain so that others may freely
+improve upon it, but if you do so please submit the result back to
+Zope Labs.
+
 
 <h2>Building applications with Zope3</h2>
 
 <p>One way to look at Zope in this case is as the controller of a
 state machine.  Your system will move through various states based on
-input (typically from the user through the web). In a particular
+input (typically from the user through the web).  In a particular
 state, the system will display a page and wait for the user to provide
-input and request a response. Based on the input and the request, the
+input and request a response.  Based on the input and the request, the
 system will perform an operation and move to a new state.  So your
-primary job is to tell Zope what to do and what to display for each
-state, and how to move from state to state.
+primary job as a programmer is to tell Zope what to do and what to
+display for each state, and how to move from state to state.
 
 <p>In addition, this application will make use of the fact that Zope
-is built on an object-oriented database. Anything that we want to be
+is built on an object-oriented database.  Anything that we want to be
 persistent in this application (for example, the jobs in the list)
-will be stored automatically in the Zope database. To do this, all we
+will be stored automatically in the Zope database.  To do this, all we
 have to do is inherit a class from the <b>Persistent</b> base class,
 as you shall see.
 
+
 <h2>Entities/Business Objects</h2>
 
 <p>We'll start by defining what can be thought of as the "business
-objects," or simply the "entities": those classes that correspond directly 
-to elements of the system's conceptual model. In this case, the model has a
-<b>Job</b> object which contains all the information about a single
-job, and a <b>JobList</b> object which holds the collection of
-<b>Job</b> objects, and also controls the addition and removal of
-<b>Job</b> objects to itself.
+objects", or simply the "entities": those classes that correspond
+directly to elements of the system's conceptual model.  In this case,
+the model has a <b>Job</b> object which contains all the information
+about a single job, and a <b>JobList</b> object which holds the
+collection of <b>Job</b> objects, and also controls the addition and
+removal of <b>Job</b> objects to itself.
 
 <p>We want to tell Zope how the Job and JobList should be created,
 edited, viewed, etc. so that Zope can perform these operations on its
-own. We do this by:
+own.  We do this by:
 
 <ol>
 
-<li>Creating an interface for each entity. The interface is used by
-Zope to hook the various views to the entity.</li>
-
-<p><li>Creating one or more classes that implement that
-interface. These classes perform the actual "business logic" for your
-application, but they don't control the views (they don't have
-anything to do with views -- if you asked them about thier views, they
-wouldn't know what you're talking about).</li>
-
-<p><li>Creating one or more Zope Page Template files (.pt files), used
-to create the views on an interface.</li>
-
-<p><li>Creating a view class that contains both the logic for the
-presentation layer and the presentation itself. The presentation is
-described in the separate ZPT files mentioned above. The logic for the
-presentation layer consists primarily of the actions that occur when
-the buttons on your web forms are pressed. In more sophisticated
-examples than this one, the view class might also do things like
-convert data into an appropriate format for display.</li>
+    <li>Creating an interface for each entity.  The interface is used
+    by Zope to hook the various views to the entity.</li>
 
-<p><li>Modifying the configuration (.zcml) file to give Zope the
-recipe of how all these things fit together.</li>
+    <p><li>Creating one or more classes that implement that interface.
+    These classes perform the actual "business logic" for your
+    application, but they don't control the views (they don't have
+    anything to do with views - if you asked them about thier views,
+    they wouldn't know what you were talking about).</li>
+
+    <p><li>Creating one or more Zope Page Template files (.pt files),
+    used to create the views on an interface.</li>
+
+    <p><li>Creating a view class that contains both the logic for the
+    presentation layer and the presentation itself.  The presentation
+    is described in the separate ZPT files mentioned above.  The logic
+    for the presentation layer consists primarily of the actions that
+    occur when the buttons on your web forms are pressed.  In more
+    sophisticated examples than this one, the view class might also do
+    things like convert data into an appropriate format for
+    display.</li>
+
+    <p><li>Providing a configuration (.zcml) file to give Zope the
+    recipe of how all these things fit together, and modifying Zope's
+    master product configuration file (prodicts.zcml) to let it
+    include our configuration file.</li>
 
 </ol>
 
+
 <h2>Job Objects</h2>
 
 <p>We'll start by creating the Job Object and its views.
 
-<h3>The IJob Interface</h3>
+<h4>The IJob Interface</h4>
 
 <p>The primary task of the Job object is to hold information about a
-job. In IJob.py, you can see that most of the elements in the
+job.  In IJob.py, you can see that most of the elements in the
 interface are Zope attributes, defined by the Attribute() function in
 Zope's Interface module.  Attribute() is a way to define attributes in
 an interface.  Following all the attributes is a method, approve(),
 which is used to take the job from the PendingApproval to the Approved
-state. These states are defined in the class JobState.
+state.  These states are defined in the class JobState.
 
 <p>Note that there is no awareness of display in either the IJob
 interface or the Job class.
 
-<h3>The Job class</h3>
+<h4>The Job class</h4>
 
 <p>Because we want it to be automatically stored in the Zope database,
-the Job class is inherited from Persistent. In addition, it is marked
-as implementing the IJob interface with the __implements__
-assignment. The initialization code simply creates and initializes the
-fields from the arguments, and puts the object in the PendingApproval
-state. The approve() method changes the state to Approved.
+the Job class is inherited from Persistent.  In addition, it is marked
+as implementing the IJob interface with the __implements__ assignment.
+The initialization code simply creates and initializes the fields from
+the arguments, and puts the object in the PendingApproval state.  The
+approve() method changes the state to Approved.
 
-<h3>The JobView class</h3>
+<h4>The JobView class</h4>
 
-<p>JobView tells Zope how to display a Job. JobView inherits
+<p><b>XXX this class no longer exists!  From here on the tutorial is
+fiction.  I'm planning to fix it though, but I've got to go first.</b>
+
+<p>JobView tells Zope how to display a Job.  JobView inherits
 AttributePublisher, which is the big clue that this is a view class,
-since that base class is only associated with view classes. The
+since that base class is only associated with view classes.  The
 AttributePublisher class includes an
 
 <pre> __implements__ = IBrowserPublisher </pre>
@@ -134,81 +150,80 @@
 to report an error if it is used incorrectly.
 
 <p>An instance of a view class is only ever associated with a single
-object to be viewed. In this case, it's a Job object, so the __init__()
+object to be viewed.  In this case, it's a Job object, so the __init__()
 stores the associated Job object and getContext() produces
-it. (getContext() is called when ...).
+it.  (getContext() is called when ...).
 
 <p>Although the <b>index</b> assignment initially appears to be
 creating a simple attribute in the JobView class, it's actually
-creating a method. The PageTemplateFile() function takes a Zope Page
+creating a method.  The PageTemplateFile() function takes a Zope Page
 Template description and compiles it to produce a callable (in this
-situation) object which thus behaves as a method. So you can treat
+situation) object which thus behaves as a method.  So you can treat
 that expression as creating a method for the class, just like
 <b>def</b> creates a method.
 
-<p>The <b>index</b> method is treated specially by Zope. When you ask
+<p>The <b>index</b> method is treated specially by Zope.  When you ask
 for a view (typically through a URL, by specifying the object and then
 the view you want on that object), if you don't otherwise say the
 particular view you are looking for then Zope will look for a method
-named <b>index</b> and use that. So in JobView we're saying that
+named <b>index</b> and use that.  So in JobView we're saying that
 PageTemplateFile('JobView.pt') is the default view for that object.
 
-<p><i>Note: the methods that wrap the attributes are necessary to
-allow access control for those attributes, until this issue is fixed
-in Zope3.</i>
-
-<h3>Editing a Job with JobEditView</h3>
+<h4>Editing a Job with JobEditView</h4>
 
 <p>The JobEditView class, in association with the JobEditView.pt and
 JobPreviewView.pt page templates, defines the process of editing a
-Job. This starts on the page produced by JobEditView.pt.
+Job.  This starts on the page produced by JobEditView.pt.
 
 <p>If you look
 at this code, you'll see relatively normal HTML with some extra "tal"
-information buried in the tag fields. Leaving that aside for the time
+information buried in the tag fields.  Leaving that aside for the time
 being, we're primarily interested in the form's "action" and the
-"submit" inputs (the buttons). The "action" is set to "", which means
+"submit" inputs (the buttons).  The "action" is set to "", which means
 (to the browser) "back to the object that created the page." In this case,
-that means the JobEditView object. When you combine this fact with the
+that means the JobEditView object.  When you combine this fact with the
 "submit" inputs, for "Preview" and "Cancel," we produce the desired
 results.
 
-<p>The name for the preview button is "preview:method". This
+<p>The name for the preview button is "preview:method".  This
 tells Zope that when that button is pressed it should call a method
 named "preview," and since "action" is "", that indicates that Zope
 should call the preview method on the page's current object, a
-JobEditView. So it calls JobEditView's preview() method, which you can
+JobEditView.  So it calls JobEditView's preview() method, which you can
 see will produce another page, created with the expression
-PageTemplateFile('JobPreviewView.pt'). If instead you press the
+PageTemplateFile('JobPreviewView.pt').  If instead you press the
 "cancel" button, the name associated with that button is
 "cancel:method" so the JobEditView cancel() method will be
-called. Note that this is a regular def method.
+called.  Note that this is a regular def method.
 
 <p>The submit() method is called from the JobPreviewView.pt in the
-same way. The same edit() and cancel() methods are also called from
+same way.  The same edit() and cancel() methods are also called from
 JobPreviewView.pt.
 
 <p>You can see that the view classes don't just display pages, but
 they also contain control logic that will respond to actions on those
-views. If you are thinking in terms of model-view-controller, what you
-see here is only a partial fullfillment of that idea. True, as much of
+views.  If you are thinking in terms of model-view-controller, what you
+see here is only a partial fullfillment of that idea.  True, as much of
 the "controller" aspect as possible is built into the standard Zope
 code (and is thus "under the covers" from the perspective of our
 application), and the goal is to just tell Zope how to do the
-controlling for you. But it's inevitable that you must put <i>some</i>
+controlling for you.  But it's inevitable that you must put <i>some</i>
 control code in your system, and it turns out that control code is
 typically highly coupled with view code - so it's cleaner to
 include the control code, such as the cancel() and submit() methods,
-in the view class. Thus we end up with more of a view/controller. The
+in the view class.  Thus we end up with more of a view/controller.  The
 trick is not to give into the temptation to put all your logic in the
 view class, because doing so leads you down the Visual Basic path,
 which inevitably produces applications that are problematic to
 maintain and that don't scale well.
 
+
 <h2>IJobList and Joblist</h2>
 
+
 <h2>Viewing a Joblist</h2>
 
+
 <h2>Page Templates</h2>
 
 <p>In the previous section there was a bit of introduction to page
@@ -218,9 +233,10 @@
 
 <p>...
 
+
 <h2>Tying it all together with the configuration file</h2>
 
-<p>Finally, we need to tell Zope what's what with all these classes --
+<p>Finally, we need to tell Zope what's what with all these classes -
 how they are supposed to interact with each other and what permissions
 to allow.