[Zope3-checkins] CVS: Zope3/src/zope/app/demo/jobboard -
__init__.py:1.1 browser.py:1.1 browser_views.png:1.1
configure.zcml:1.1 edit.pt:1.1 interfaces.py:1.1 job.py:1.1
joblist.gif:1.1 joblist.png:1.1 joblistview.pt:1.1
jobview.pt:1.1 preview.pt:1.1 review.pt:1.1 tests.py:1.1
thanks.pt:1.1
Nathan Yergler
nathan at yergler.net
Thu Mar 11 08:07:12 EST 2004
Update of /cvs-repository/Zope3/src/zope/app/demo/jobboard
In directory cvs.zope.org:/tmp/cvs-serv8707/jobboard
Added Files:
__init__.py browser.py browser_views.png configure.zcml
edit.pt interfaces.py job.py joblist.gif joblist.png
joblistview.pt jobview.pt preview.pt review.pt tests.py
thanks.pt
Log Message:
Moving jobboard demo from Products3/demo/jobboard.
=== Added File Zope3/src/zope/app/demo/jobboard/__init__.py ===
=== Added File Zope3/src/zope/app/demo/jobboard/browser.py ===
from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile
from zope.publisher.browser import BrowserView
from zope.app.event import publish
from zope.app.event.objectevent import ObjectCreatedEvent, ObjectModifiedEvent
from job import Job
class JobCreateView(BrowserView):
""" class to create job entries
>>> from job import JobList
>>> from zope.publisher.browser import TestRequest
>>> from zope.app.tests.placelesssetup import setUp, tearDown
>>> setUp()
>>> class TestJobList:
... context = None
... def add(self, myObj):
... self.tempStorage = myObj
>>>
>>> request = TestRequest()
>>> joblist = TestJobList()
>>> view = JobCreateView(joblist, request)
>>> myThanksPage = view.create(submitter='sree', summary='my job summary',
... description='my desc', contact = 'sree')
>>> joblist.tempStorage.summary
'my job summary'
>>> tearDown()
"""
edit = ViewPageTemplateFile('edit.pt')
preview = ViewPageTemplateFile('preview.pt')
thanks = ViewPageTemplateFile('thanks.pt')
def create(self, submitter='', summary='', description='', contact=''):
# Validation code should go here
job = Job(submitter, summary, description, contact)
self.context.add(job)
publish(self.context,ObjectModifiedEvent(self.context))
return self.thanks()
################################
class ApproveJobsView(BrowserView):
""" class to Approve existing job entries
>>> from job import JobList
>>> from zope.publisher.browser import TestRequest
>>> from zope.app.tests.placelesssetup import setUp, tearDown
>>> setUp()
>>>
>>> request = TestRequest(form={'1':'approve','2':'discard'})
>>> class TestJobList:
... context = None
... tempStorage = []
... def add(self, myObj):
... self.tempStorage.append( myObj)
>>> joblist = JobList()
>>> view = JobCreateView(joblist, request)
>>> myThanksPage = view.create(submitter='sree', summary='my job summary',
... description='my desc', contact = 'sree')
>>> myThanksPage = view.create(submitter='sree2', summary='my summaryy2',
... description='my desc2', contact = 'sree2')
>>> approvedview = ApproveJobsView(joblist, request)
>>> approvedview.approve()
>>> request.response.getHeader('location')
'.'
>>> joblist['1'].state
'approved'
>>> joblist['2'].state
Traceback (most recent call last):
...
KeyError: 2
>>> tearDown()
"""
review = ViewPageTemplateFile('review.pt')
def approve(self):
form = self.request.form
for jobid in form:
try:
job = self.context[jobid]
except:
pass
action = form[jobid]
if action == 'approve':
job.approve()
elif action == 'discard':
del self.context[jobid]
response = self.request.response
if self.context.getPendingIds():
response.redirect('review.html')
else:
response.redirect('.')
publish(self.context,ObjectModifiedEvent(self.context))
=== Added File Zope3/src/zope/app/demo/jobboard/browser_views.png ===
<Binary-ish file>
=== Added File Zope3/src/zope/app/demo/jobboard/configure.zcml ===
<configure
xmlns="http://namespaces.zope.org/zope"
xmlns:browser="http://namespaces.zope.org/browser"
xmlns:i18n="http://namespaces.zope.org/i18n"
i18n_domain="jobboardi18n"
>
<content class="zopeproducts.demo.jobboard.job.JobList">
<implements interface="zope.app.interfaces.annotation.IAttributeAnnotatable"
/>
<factory
id="zopeproducts.demo.jobboard.job.JobList"
title="I18n Job List"
/>
<allow interface=".interfaces.IJobList" />
<implements interface="zope.app.container.interfaces.IItemContainer" />
</content>
<browser:addMenuItem
title="I18N Job Board"
description="Internationalized board for posting and searching jobs."
class="zopeproducts.demo.jobboard.job.JobList"
permission="zope.ManageContent"
/>
<content class=".job.Job">
<allow interface="zopeproducts.demo.jobboard.interfaces.IJob" />
</content>
<browser:page
name="index.html"
for="zopeproducts.demo.jobboard.interfaces.IJobList"
template="joblistview.pt"
permission="zope.View"
/>
<browser:pages
for="zopeproducts.demo.jobboard.interfaces.IJobList"
class=".browser.JobCreateView"
permission="zope.View"
>
<browser:page name="edit.html" attribute="edit" />
<browser:page name="preview.html" attribute="preview" />
<browser:page name="create.method" attribute="create" />
</browser:pages>
<browser:page
name="index.html"
for="zopeproducts.demo.jobboard.interfaces.IJob"
template="jobview.pt"
permission="zope.View"
/>
<browser:pages
for="zopeproducts.demo.jobboard.job.IJobList"
class=".browser.ApproveJobsView"
permission="zope.ManageContent"
>
<browser:page name="review.html" attribute="review" />
<browser:page name="approve.method" attribute="approve" />
</browser:pages>
<browser:icon
name="zmi_icon"
for="zopeproducts.demo.jobboard.interfaces.IJobList"
file="./joblist.gif"
/>
<i18n:registerTranslations directory="./locale" />
</configure>
=== Added File Zope3/src/zope/app/demo/jobboard/edit.pt ===
<html i18n:domain="jobboard">
<head>
<title i18n:translate="enter-new-job-data">Enter new job data</title>
</head>
<body>
<h1 i18n:translate="enter-new-job-data">Enter new job data</h1>
<p i18n:translate="when-done">When you are done, press the Preview
button below.</p>
<form action="preview.html" method="post">
<table border=0>
<tr><td i18n:translate="contributor-email">Contributor email:</td>
<td><input name="submitter" value="" size="60"
tal:attributes="value request/submitter|nothing" />
</td>
</tr>
<tr><td i18n:translate="one-line-summary">One-line summary:</td>
<td><input name="summary" value="" size="60"
tal:attributes="value request/summary|nothing" />
</td>
</tr>
<tr><td i18n:translate="full-description">Full description (no HTML):</td>
<td><textarea name="description" cols=60 rows=10 wrap="hard"
><span tal:replace="request/description|nothing">Description</span>
</textarea>
</td>
</tr>
<tr><td i18n:translate="contact">Contact (where to apply):</td>
<td><input name="contact" value="" size="60"
tal:attributes="value request/contact|nothing" />
</td>
</tr>
<tr><td i18n:translate="salary">Salary Range:</td>
<td><input name="salary" value="" size="60"
tal:attributes="value request/salary|nothing" />
</td>
</tr>
<tr>
<td><span i18n:translate="startdate">Start Date</span><br>
(<span tal:replace="python:request.locale.dates.getFormatter('date', 'short').getPattern()" />)</td>
<td><input name="startdate" value="" size="60"
tal:attributes="value request/startdate|nothing" />
</td>
</tr>
<tr><td colspan="2">
<input type="submit" value="Preview" i18n:attributes="value=Preview">
</td>
</tr>
</table>
</form>
</body>
</html>
=== Added File Zope3/src/zope/app/demo/jobboard/interfaces.py ===
from zope.interface import Interface
from zope.interface import Attribute
class IJob(Interface):
"""Interface for the basic Job"""
submitter = Attribute("submitter",
"Email address of the submitter")
summary = Attribute("summary",
"One-line summary of the job")
description = Attribute("description",
"Longer description of the job")
contact = Attribute("contact",
"Email address to contact about the job")
state = Attribute("state",
"Current state of the job listing.\n"
"The possible values are defined in JobState.")
salary = Attribute("salary",
"Salary range offered for the job.")
startdate = Attribute("startdate",
"Job start date")
def approve():
"Moves the job state to Approved"
class JobState:
"""Possible values of IJob.state."""
PendingApproval = "pending approval"
Approved = "approved"
##############################################################
#
#
#
#
##############################################################
class IJobList(Interface):
def __getitem__(jobid):
"""Returns the job with the given jobid"""
def query(state):
"""Returns a list of Job ids"""
def getApprovedIds():
"""Returns a sequence of ids for job that are in the approved state
"""
def getPendingIds():
"""Returns a sequence of ids for jobs that are in the pending state
"""
def add(job):
"""Add a Job object to the list.
Returns the id assigned to the job.
"""
def __delitem__(jobid):
"""Removes the Job object with the given id from the list.
Raises KeyError if the jobid is not in the list.
"""
=== Added File Zope3/src/zope/app/demo/jobboard/job.py ===
"""
Job.py
"""
from persistence import Persistent
from interfaces import IJob, JobState, IJobList
from zope.interface import implements
class Job(Persistent):
""" Job Class
>>> myJob = Job(submitter='my name', summary='my summary',
... description='my description',contact='my contact',
... salary='111', startdate='10/01/2003')
>>> myJob.summary
'my summary'
>>> myJob.state
'pending approval'
>>> myJob.approve()
>>> myJob.state
'approved'
"""
implements(IJob)
def __init__(self, submitter, summary, description,
contact, salary=None, startdate=None):
self.submitter = submitter
self.summary = summary
self.description = description
self.contact = contact
self.state = JobState.PendingApproval
self.salary = salary
self.startdate = startdate
def approve(self):
"""Moves the job state to approved"""
self.state = JobState.Approved
##########################################################################
from persistence.dict import PersistentDict
from zope.app.event import publish
from zope.app.event.objectevent import ObjectCreatedEvent
class JobList(Persistent):
""" the Joblist class manages the creation, deletion of job list and
can display the object ids which are in specific states
>>> from job import Job
>>> joblist = JobList()
>>> myJob1 = Job(submitter='my name', summary='my summary',
... description='my description',contact='my contact',
... salary='111', startdate='10/01/2003')
>>> myJob2 = Job(submitter='my name2', summary='my summary2',
... description='my description2',contact='my contact2',
... salary='222', startdate='20/12/2003')
>>> joblist.add(myJob1)
'1'
>>> joblist.add(myJob2)
'2'
>>> joblist.getPendingIds()
['1', '2']
>>> joblist.query('pending approval')
['1', '2']
>>> myJob1.approve()
>>> joblist.getPendingIds()
['2']
>>> joblist.getApprovedIds()
['1']
"""
implements(IJobList)
def __init__(self):
self._lastid = 0
self._jobs = PersistentDict()
def add(self, job):
self._lastid += 1
jobid = self._lastid
self._jobs[jobid] = job
# stringified for parity with query
# this can return an int when query can also return an int
return str(jobid)
def __delitem__(self, jobid):
# accept stringified job ids, see add()
try:
jobid = int(jobid)
except ValueError:
raise KeyError, jobid
del self._jobs[jobid]
def query(self, state):
ids = [jobid
for jobid, job in self._jobs.items()
if job.state == state]
ids.sort()
# this should work returning a list of ints,
# but it exposes a bug in PageTemplates
return map(str, ids)
def __getitem__(self, jobid):
# accept stringified job ids, see add()
try:
jobid = int(jobid)
except ValueError:
raise KeyError, jobid
return self._jobs[jobid]
def getPendingIds(self):
return self.query(JobState.PendingApproval)
def allIds(self):
return self._jobs.items()
#ids.sort()
# this should work returning a list of ints,
# but it exposes a bug in PageTemplates
#return map(str, ids)
def getApprovedIds(self):
return self.query(JobState.Approved)
=== Added File Zope3/src/zope/app/demo/jobboard/joblist.gif ===
<Binary-ish file>
=== Added File Zope3/src/zope/app/demo/jobboard/joblist.png ===
<Binary-ish file>
=== Added File Zope3/src/zope/app/demo/jobboard/joblistview.pt ===
<HTML i18n:domain="jobboard">
<HEAD>
<TITLE i18n:translate="job-board-title">Job Board</TITLE>
</HEAD>
<BODY>
<h1 i18n:translate="job-board-title">Job Board</h1>
<A href="edit.html" i18n:translate="submit-new-job">Submit a new job</A>
<H2 i18n:translate="job-listings">Job Listings</H2>
<table>
<tr tal:repeat="jobid context/getApprovedIds">
<td>
<a href="jobid" tal:attributes="href jobid">
<span tal:replace="context/?jobid/summary">A job summary</span></A>
</td>
</tr>
</table>
<!-- XXX this should only appear if the user has the proper permissions -->
<h2 i18n:translate="other-operations">Other operations</h2>
<a href="review.html"
i18n:translate="approve-submitted-jobs">Approve submitted jobs</a>
</BODY>
</HTML>
=== Added File Zope3/src/zope/app/demo/jobboard/jobview.pt ===
<html i18n:domain="jobboard">
<head>
<title tal:content="context/summary">Job summary goes here</title>
</head>
<body>
<h3 tal:content="context/summary">Job summary goes here</h3>
<table border=0>
<tr><td i18n:translate="full-description">Description:</td>
<td>
<pre tal:content="context/description">Full descripion goes here
(multiple lines)
</pre>
</td>
</tr>
<tr><td i18n:translate="contact">Contact:</td>
<td><a href="user at host.com"
tal:attributes="href string:mailto:${context/contact}"
tal:content="context/contact">user at host.com</a></td>
</tr>
<tr><td i18n:translate="salary">Salary Range:</td>
<td tal:content="context/salary"></td>
</tr>
<tr><td i18n:translate="startdate">Start date:</td>
<td><span tal:omit-tag="" tal:condition="exists: context/startdate"
tal:content="context/startdate"/></td>
</tr>
</table>
<table border=0>
<tr><td>
<a href=".." i18n:translate="back-to-jobs">Back to jobs</a>
</td></tr>
</table>
</body>
</html>
=== Added File Zope3/src/zope/app/demo/jobboard/preview.pt ===
<html i18n:domain="jobboard">
<head>
<title i18n:translate="preview-new-job-data">Preview new job data</title>
</head>
<body>
<h1 i18n:translate="preview-new-job-data">Preview New Job Data</h1>
<p i18n:translate="instructions">This is what your job will look like
once it is approved by the site manager. To change your submission
now, use your browser's Back button and resubmit the form. To submit
now, click on the Submit button below.
</p>
<p i18n:translate="verify">Your contact email address is recorded as
<span i18n:name="email">
<a href="user at host.com"
tal:attributes="href string:mailto:${request/submitter}"
tal:content="request/submitter">
user at host.com</a></span>.
This address will not be published on the website, but we will use it
to reach you if we have questions about your submission. Job seekers
will contact the address you provide in the Contact field.
</p>
<!-- p tal:condition="view/error"
tal:content="view/error">Error messages go here</p -->
<hr>
<h3 tal:content="request/summary">Job summary goes here</h3>
<table border="0">
<tr>
<td>
<pre tal:content="request/description">Full descripion goes here
(multiple lines)
</pre>
</td>
<tr><td i18n:translate="">Contact:</td>
<td><a href="user at host.com"
tal:attributes="href string:mailto:${request/contact}"
tal:content="request/contact">user at host.com</a></td>
</tr>
<tr><td i18n:translate="salary">Salary Range:</td>
<td tal:content="request/salary">
</td>
</tr>
<tr><td i18n:translate="startdate">Start Date:</td>
<td tal:content="request/startdate">
</td>
</tr>
</table>
<hr>
<form action="create.method" method="post">
<input name="submitter" type="hidden" value=""
tal:attributes="value request/submitter" />
<input name="summary" type="hidden" value=""
tal:attributes="value request/summary" />
<input name="description" type="hidden" value=""
tal:attributes="value request/description" />
<input name="contact" type="hidden" value=""
tal:attributes="value request/contact" />
<input name="salary" type="hidden" value=""
tal:attributes="value request/salary" />
<input name="startdate" type="hidden" value=""
tal:attributes="value request/startdate" />
<input type="submit" name="submit" value="Submit"
i18n:attributes="value Submit"/>
<input type="submit" name="edit" value="Edit"
i18n:attributes="value Edit" />
</form>
</body>
</html>
=== Added File Zope3/src/zope/app/demo/jobboard/review.pt ===
<html i18n:domain="jobboard">
<head>
<title i18n:translate="approve-title">Approve submitted jobs</title>
</head>
<body>
<h1 i18n:translate="approve-title">Approve Submitted Jobs</h1>
<form action="approve.method" method="post">
<table border=0>
<tr><th colspan=3 i18n:translate="">Action</th>
<th rowspan=2 i18n:translate="">Summary</th>
</tr>
<tr><th i18n:translate="">Defer</th>
<th i18n:translate="">Approve</th>
<th i18n:translate="">Discard</th>
</tr>
<tr tal:repeat="jobid context/getPendingIds"
style="text-align:center">
<div tal:define="job context/?jobid">
<td><input type="radio" checked
tal:attributes="name jobid"></td>
<td><input type="radio" value="approve"
tal:attributes="name jobid"></td>
<td><input type="radio" value="discard"
tal:attributes="name jobid"></td>
<td><a href="jobid" tal:attributes="href jobid"
tal:content="job/summary">A job summary </a>
(<a href="user at host.com"
tal:attributes="href string:mailto:${job/submitter}"
><span tal:replace="job/submitter">user at host.com</span></a>)
</td>
</div>
</tr>
<tr><td colspan="3">
<input type="submit" value="Submit" i18n:attributes="value=Submit">
<a href="." i18n:translate="back-to-summary">Back to summary</a>
</td></tr>
</table>
</form>
</body>
</html>
=== Added File Zope3/src/zope/app/demo/jobboard/tests.py ===
import unittest, doctest
def test_suite():
return unittest.TestSuite((
doctest.DocTestSuite('zopeproducts.demo.jobboard.job'),
doctest.DocTestSuite('zopeproducts.demo.jobboard.browser'),
))
if __name__ == '__main__': unittest.main()
=== Added File Zope3/src/zope/app/demo/jobboard/thanks.pt ===
<html i18n:domain="jobboard">
<head>
<title i18n:translate="thank-you-title">Thank you for your job
submission</title>
</head>
<body>
<h1 i18n:translate="thank-you-title">Thank you for your job submission</h1>
<p i18n:translate="thank-you-wherenext">Our site manager will review
and publish it shortly. Please use one of the following links to
continue to use our site:
</p>
<ul>
<li><a href="/" i18n:translate="back-to-site-home">Back to site home</a>
<p><li><a href="." i18n:translate="back-to-job-board">Back to job board</a>
<p><li><a href="edit.html" i18n:translate="submit-another">Submit
another job</a>
</ul>
</body>
</html>
More information about the Zope3-Checkins
mailing list