[Zope-CVS] CVS: Packages/JobBoardEx - Tutorial.html:1.12
Guido van Rossum
Mon, 17 Jun 2002 10:52:36 -0400
Update of /cvs-repository/Packages/JobBoardEx
In directory cvs.zope.org:/tmp/cvs-serv28623
Some progress on [I]JobList.py and JobListView.pt.
=== Packages/JobBoardEx/Tutorial.html 1.11 => 1.12 ===
- <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>
+ <p><li>Providing a configuration file (<a
+ href="JobList.zcml">JobList.zcml</a>) to give Zope the recipe of
+ how all these things fit together, and modifying Zope's master
+ product configuration file (products.zcml) to let it include our
+ configuration file.</li>
@@ -105,35 +106,41 @@
<p>We'll start by creating the Job Object and its views.
<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
-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.
+job. In <a href="IJob.py">IJob.py</a>, 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.
<p>Note that there is no awareness of display in either the IJob
interface or the Job class.
<h4>The Job Class</h4>
-<p>Because we want it to be automatically stored in the Zope database,
+<p>The Job class is defined in the module <a href="Job.py">Job.py</a>.
+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.
<h4>The JobView Page Template</h4>
-<p>JobView tells Zope how to display a Job. Because this is a rather
-straightforward view, we don't have to write any Python code: instead,
-it is coded as a page template. This is an HTML-like file with
-embedded directives in the form of attributes that cause substitutions
-to happen. More about page templates later.
+<p><a href="JobView.pt">JobView.pt</a> tells Zope how to display a
+Job. Because this is a rather straightforward view, we don't have to
+write any Python code: instead, it is coded as a page template. This
+is an HTML-like file with embedded directives in the form of
+attributes that cause substitutions to happen. Page template files
+have the extension ".pt". More about page templates later.
<p>The view is attached to the Job class by means of a single
statement in the configuration file:
@@ -147,47 +154,88 @@
<p>This tells Zope that there is a view named index.html which applies
-to instances of the IJob interface, implemented by the page template
-JobView.pt, and requiring the permission Zope.Public (a fancy way to
-say that anyone can view the job; more about permissions later).
+to objects implementing the IJob interface (in our case, instances of
+the Job class). The view is implemented by the page template
+JobView.pt; we'll see other ways to implement view later. This view
+requires the permission Zope.Public, a fancy way to say that anyone
+can view the job; more about permissions later.
<p>Another statement in the configuration file tells Zope that this is
-the default view:
+the default view for such objects:
-<browser:defaultView for=".IJob." name="index.html" />
-<b>XXX The rest is not ready yet</b>
+<h2>The JobList Object</h2>
+<p>Next let's have a look at the JobList.
+<h4>The IJobList Interface</h4>
+<p>In <a href="IJobList.py">IJobList.py</a>, you can see that a job
+list manages a mapping from job ids to job objects. It supports
+__getitem__() and __delitem__() methods. It doesn't support
+__setitem__(), because the job list is in control of assigning the job
+id to a job when it is inserted into the list. This is done by the
+add() method, which returns the assigned id. There is also a
+generalized query() method which returns the ids of all jobs with a
+given state, and two shortcuts, getApprovedIds() and getPendingIds().
+(Recall that the allowable job states are defined by the class
+JobState in IJob.py.)
+<h4>The JobList Class</h4>
+<p>The JobList class is defined in the module <a
+href="JobList.py">JobList.py</a>. Like the Job class, the JobList
+class inherits from Persistent and indicates the interface it
+implements with an __implements__ assignment. There are two pieces of
+internal state: self._lastid records the last job id assigned, and
+self._jobs is a persistent mapping from integer job ids to Job
+objects. (A persistent mapping ensures that changes are recorded
+correctly. This is an implementation detail of the persistence
+machinery that you sometimes have to be aware of.)
+<p>For technical reasons, the job ids seen by Zope must be strings;
+internally, we like them to be integers so we can sort jobs by
+ascending job id, which corresponds to chronologic order of
+submission. (This is really a bug in Zope; once it is fixed, job ids
+will be represented as integers both internally and externally.)
+<p>The rest of the class is straightforward.
+<h4>The JobListView Page Template</h4>
-<pre> __used_for__ = IJob </pre>
+<p><a href="JobListView.pt">JobListView.pt</a> tells Zope how to
+display a JobList. Again, it is a rather straightforward view coded
+as a page template. The page template contains a loop over the job
+ids returned by the getApprovedIds() method of the JobList class,
+displaying the summary line with a link to the full job view for each
-statement allows Zope to check to make sure that the JobView class is
-only used for IJob objects during the configuration of the system, and
-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__()
-stores the associated Job object and getContext() produces
-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
-Template description and compiles it to produce a callable (in this
-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
-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
-PageTemplateFile('JobView.pt') is the default view for that object.
+<p>The view is attached to the JobList class and made the default view
+by the following statements in the configuration file:
+<hr><b>XXX The rest is historical fiction</b>
<h4>Editing a Job with JobEditView</h4>
@@ -236,12 +284,6 @@
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>