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

Guido van Rossum guido@python.org
Fri, 22 Mar 2002 20:27:14 -0500


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

Modified Files:
	Tutorial.html 
Log Message:
Convert to Unix line endings and reflow paragraphs (no effect on HTML
rendering, but easier on primitive editors like Emacs).


=== Packages/JobBoardEx/Tutorial.html 1.2 => 1.3 ===
-
-<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 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 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 Guido Van Rossum, 
-Jeremy Hylton, Tim Peters, Fred Drake, Barry Warsaw, 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.
-
-<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 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 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.
-
-<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 persistent in this 
-application (for example, the jobs in the list) 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 map directly from the conceptual model 
-of the system. 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:
-
-<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>
-
-<p><li>Modifying the configuration (.zcml) file to give Zope the recipe of how 
-all these things fit together.</li>
-
-</ol>
-
-<h2>Job Objects</h2>
-
-<p>We'll start by creating the Job Object and its views.
-
-<h3>The IJob Interface</h3>
-
-<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. After all the 
-attributes, there 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.
-
-<h3>The Job class</h3>
-
-<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.
-
-<h3>The JobView class</h3>
-
-<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 AttributePublisher class includes an 
-
-<pre> __implements__ = IBrowserPublisher </pre>
-
-Statement.
-
-<p>The
-
-<pre> __used_for__ = IJob </pre>
-
-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 to 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><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>
-
-<p>The JobEditView class in association with the JobEditView.pt and 
-JobPreviewView.pt page templates define the process of editing a Job. This 
-starts on the page produced by JobEditView.pt. 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 being, we're primarily interested in the 
-form's "action" and the "submit" inputs (the buttons). The "action" is set to 
-".", which means (to Zope) "back to the object that created the page." In this 
-case, that means the JobEditView object. When you combine this fact with the 
-"submit" inputs, for "Preview" and "Cancel," we produce the desired results. 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 see will produce another page, created with the expression
-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. 
-
-<p>The submit() method is called from the JobPreviewView.pt in the 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 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> control 
-code in your system, and it turns out that control code is typically highly 
-coupled with view code, and 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 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 templates. 
-Here we'll go into detail and explain how page templates are associated with 
-objects, and how they extract information from their objects.
-
-<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 -- how they 
-are supposed to interact with each other and what permissions to allow.
-
-<p>...
+<html><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
+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
+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
+Guido van Rossum, Jeremy Hylton, Tim Peters, Fred Drake, Barry Warsaw,
+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.
+
+<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
+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
+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.
+
+<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
+persistent in this application (for example, the jobs in the list)
+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 map directly
+from the conceptual model of the system. 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:
+
+<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>
+
+<p><li>Modifying the configuration (.zcml) file to give Zope the
+recipe of how all these things fit together.</li>
+
+</ol>
+
+<h2>Job Objects</h2>
+
+<p>We'll start by creating the Job Object and its views.
+
+<h3>The IJob Interface</h3>
+
+<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. After all the attributes, there 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.
+
+<h3>The Job class</h3>
+
+<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.
+
+<h3>The JobView class</h3>
+
+<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
+AttributePublisher class includes an
+
+<pre> __implements__ = IBrowserPublisher </pre>
+
+Statement.
+
+<p>The
+
+<pre> __used_for__ = IJob </pre>
+
+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 to 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><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>
+
+<p>The JobEditView class in association with the JobEditView.pt and
+JobPreviewView.pt page templates define the process of editing a
+Job. This starts on the page produced by JobEditView.pt. 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
+being, we're primarily interested in the form's "action" and the
+"submit" inputs (the buttons). The "action" is set to ".", which means
+(to Zope) "back to the object that created the page." In this case,
+that means the JobEditView object. When you combine this fact with the
+"submit" inputs, for "Preview" and "Cancel," we produce the desired
+results. 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
+see will produce another page, created with the expression
+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.
+
+<p>The submit() method is called from the JobPreviewView.pt in the
+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
+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>
+control code in your system, and it turns out that control code is
+typically highly coupled with view code, and 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
+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
+templates.  Here we'll go into detail and explain how page templates
+are associated with objects, and how they extract information from
+their objects.
+
+<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 --
+how they are supposed to interact with each other and what permissions
+to allow.
+
+<p>...