[Zope-book] CVS: Docs/ZopeComponentArchitecture/PythonProgrammerTutorial/Chapter1/Step7 - Contact.py:1.1 ContactAdd.py:1.1 ContactAddView.py:1.1 ContactCityState.py:1.1 ContactEditView.py:1.1 ContactInfoView.py:1.1 IContact.py:1.1 IPostal.py:1.1 __init__.py:1.1 add.pt:1.1 configure.zcml:1.1 contact.gif:1.1 contact_product_uml.txt:1.1 edit.pt:1.1 info.pt:1.1 products.zcml:1.1 stubpostal.py:1.1
Jim Fulton
jim at zope.com
Sun Dec 8 03:44:32 EST 2002
Update of /cvs-repository/Docs/ZopeComponentArchitecture/PythonProgrammerTutorial/Chapter1/Step7
In directory cvs.zope.org:/tmp/cvs-serv13804
Added Files:
Contact.py ContactAdd.py ContactAddView.py ContactCityState.py
ContactEditView.py ContactInfoView.py IContact.py IPostal.py
__init__.py add.pt configure.zcml contact.gif
contact_product_uml.txt edit.pt info.pt products.zcml
stubpostal.py
Log Message:
Added step 7 to include generation of object events
=== Added File Docs/ZopeComponentArchitecture/PythonProgrammerTutorial/Chapter1/Step7/Contact.py ===
import Persistence
from IContact import IContact
class Contact (Persistence.Persistent):
"""Personal contact information
Contacts keep track of personal data, such as name, email
and postal address. All methods are protected.
"""
__implements__ = IContact
def __init__(self, first='', last='', email='', address='', pc=''):
self.update(first, last, email, address, pc)
def name(self):
return "%s %s" % (self._first, self._last)
def first(self):
return self._first
def last(self):
return self._last
def email(self):
return self._email
def address(self):
return self._address
def postal_code(self):
return self._pc
def update(self, first=None, last=None, email=None, address=None, pc=None):
if first is not None:
self._first = first
if last is not None:
self._last = last
if email is not None:
self._email = email
if address is not None:
self._address = address
if pc is not None:
self._pc = pc
=== Added File Docs/ZopeComponentArchitecture/PythonProgrammerTutorial/Chapter1/Step7/ContactAdd.py ===
from Zope.App.OFS.Container.IAdding import IAdding
from Contact import Contact
from Zope.Event import publish
from Zope.Event.ObjectEvent import ObjectCreatedEvent
from Interface import Interface
class IContactAdd(Interface):
"""Add context using IAdding objects
"""
def add(first, last, email, address, pc):
"""Add a contact initialized from the given arguments
"""
class ContactAdd:
"Provide a user interface for adding a contact"
# Assert that we can only be applied to IAdding
__used_for__ = IAdding
__implements__ = IContactAdd
def __init__(self, context):
self.context = context
def add(self, first, last, email, address, pc):
contact = Contact()
publish(self.context.context, ObjectCreatedEvent(contact))
contact.update(first, last, email, address, pc)
self.context.add(contact)
=== Added File Docs/ZopeComponentArchitecture/PythonProgrammerTutorial/Chapter1/Step7/ContactAddView.py ===
from Zope.Publisher.Browser.BrowserView import BrowserView
from Zope.App.OFS.Container.IAdding import IAdding
from Zope.ComponentArchitecture import getAdapter
from ContactAdd import IContactAdd
class ContactAddView(BrowserView):
"Provide a user interface for adding a contact"
# Assert that we can only be applied to IAdding
__used_for__ = IAdding
# action method
def action(self, first, last, email, address, pc):
"Add a contact"
getAdapter(self.context, IContactAdd).add(
first, last, email, address, pc)
self.request.response.redirect(self.context.nextURL())
=== Added File Docs/ZopeComponentArchitecture/PythonProgrammerTutorial/Chapter1/Step7/ContactCityState.py ===
from IPostal import IPostalLookup, IPostalInfo
from IContact import IContactInfo
from Zope.ComponentArchitecture import getUtility
class ContactCityState:
"Provide access to city and state information for a contact"
__implements__ = IPostalInfo
__used_for__ = IContactInfo
def __init__(self, contact):
self._contact = contact
lookup = getUtility(contact, IPostalLookup)
info = lookup.lookup(contact.postal_code())
if info is None:
self._city, self._state = '', ''
else:
self._city, self._state = info.city(), info.state()
def city(self): return self._city
def state(self): return self._state
=== Added File Docs/ZopeComponentArchitecture/PythonProgrammerTutorial/Chapter1/Step7/ContactEditView.py ===
from Zope.Publisher.Browser.BrowserView import BrowserView
from IContact import IContact
from Zope.Event import publish
from Zope.Event.ObjectEvent import ObjectModifiedEvent
class ContactEditView(BrowserView):
"Provide a user interface for editing a contact"
# Assert that we can only be applied to IContact
__used_for__ = IContact
# action method
def action(self, first, last, email, address, pc):
"Edit a contact"
self.context.update(first, last, email, address, pc)
publish(self.context, ObjectModifiedEvent(self.context))
self.request.response.redirect('.')
=== Added File Docs/ZopeComponentArchitecture/PythonProgrammerTutorial/Chapter1/Step7/ContactInfoView.py ===
from Zope.ComponentArchitecture import getAdapter
from IContact import IContactInfo
from IPostal import IPostalInfo
class ContactInfoView:
"""Provide an interface for viewing a contact
"""
__used_for__ = IContactInfo
def __init__(self, context, request):
self.context = context
self.request = request
self.info = getAdapter(context, IPostalInfo)
def city(self):
return self.info.city()
def state(self):
return self.info.state()
=== Added File Docs/ZopeComponentArchitecture/PythonProgrammerTutorial/Chapter1/Step7/IContact.py ===
from Interface import Interface
class IContactInfo(Interface):
"Provides access to basic contact information."
def first(): "Get the first name"
def last(): "Get the last name"
def email(): "Get the electronic mail address"
def address(): "Get the postal address"
def postal_code(): "Get the postal code"
def name():
"""Gets the contact name.
The contact name is the first and last name"""
class IContact(IContactInfo):
"Provides the ability to change contact information."
def update(first, last, email, address, pc):
"""Modifies contact data
'None' values are ignored.
"""
=== Added File Docs/ZopeComponentArchitecture/PythonProgrammerTutorial/Chapter1/Step7/IPostal.py ===
from Interface import Interface
class IPostalInfo(Interface):
"Provide information for postal codes"
def city():
"""Return the city associated with the postal code.
An empty string is returned if the city is unknown.
"""
def state():
"""Return the state associated with the postal code.
An empty string is returned if the state is unknown.
"""
class IPostalLookup(Interface):
"Provide postal code lookup"
def lookup(postal_code):
"""Lookup information for a postal code.
An IPostalInfo is returned if the postal code is known. None is
returned otherwise.
"""
=== Added File Docs/ZopeComponentArchitecture/PythonProgrammerTutorial/Chapter1/Step7/__init__.py ===
=== Added File Docs/ZopeComponentArchitecture/PythonProgrammerTutorial/Chapter1/Step7/add.pt ===
<html metal:use-macro="views/standard_macros/page">
<head><title>Edit contact</title></head>
<body>
<div metal:fill-slot="body">
Enter the information about the contact.
<form action="action.html" method="post">
<table cellspacing="0" cellpadding="2" border="0">
<tr><td> First name</td>
<td><input type="text" name="first" size="40" value="" /> </td>
</tr>
<tr><td>Last name</td>
<td><input type="text" name="last" size="40" value="" /> </td>
</tr>
<tr><td>Email</td>
<td><input type="text" name="email" size="40" value="" /> </td>
</tr>
<tr><td>Address</td>
<td align="left" valign="top">
<textarea name="address" rows="3" cols="60"></textarea>
</td>
</tr>
<tr>
<td>Postal Code</td>
<td><input type="text" name="pc" size="40" value="" />
</td>
</tr>
</table>
<input type="submit" name="submit" value=" Save Changes " />
</form></div></body></html>
=== Added File Docs/ZopeComponentArchitecture/PythonProgrammerTutorial/Chapter1/Step7/configure.zcml ===
<zopeConfigure
xmlns='http://namespaces.zope.org/zope'
xmlns:browser='http://namespaces.zope.org/browser'>
<permission
id="ZopeProducts.Contact.ManageContacts"
title="Manage Contacts" />
<content class=".Contact.">
<implements interface="Zope.App.OFS.Annotation.IAttributeAnnotatable." />
<factory
id="ZopeProducts.Contact"
permission="ZopeProducts.Contact.ManageContacts" />
<require
permission="Zope.View"
interface=".IContact.IContactInfo." />
<require
permission="ZopeProducts.Contact.ManageContacts"
attributes="update" />
</content>
<browser:menuItem menu="add_content" for="Zope.App.OFS.Container.IAdding."
title="Personal Contact Information"
action="ZopeProducts.Contact"/>
<adapter
provides=".ContactAdd.IContactAdd"
for="Zope.App.OFS.Container.IAdding."
factory=".ContactAdd."
/>
<browser:view
name="ZopeProducts.Contact"
for="Zope.App.OFS.Container.IAdding."
factory=".ContactAddView."
permission="ZopeProducts.Contact.ManageContacts" >
<browser:page name="add.html" template="add.pt" />
<browser:page name="action.html" attribute="action" />
</browser:view>
<browser:defaultView for=".IContact.IContactInfo." name="info.html" />
<browser:view
for=".IContact.IContactInfo."
name="info.html"
template="info.pt"
class=".ContactInfoView."
permission="Zope.View" />
<browser:view
for=".IContact."
factory=".ContactEditView."
permission="ZopeProducts.Contact.ManageContacts" >
<browser:page name="edit.html" template="edit.pt" />
<browser:page name="editAction.html" attribute="action" />
</browser:view>
<browser:menuItems menu="zmi_views" for=".IContact.">
<browser:menuItem title="Edit" action="edit.html"/>
<browser:menuItem title="View" action="info.html"/>
</browser:menuItems>
<browser:icon name="zmi_icon" for=".IContact." file="contact.gif" />
<content class=".stubpostal.Info">
<allow interface=".IPostal.IPostalInfo" />
</content>
<utility
factory=".stubpostal.Lookup"
provides=".IPostal.IPostalLookup"
permission="Zope.Public" />
<adapter
factory=".ContactCityState."
provides=".IPostal.IPostalInfo"
for=".IContact.IContactInfo"
permission="Zope.Public" />
</zopeConfigure>
=== Added File Docs/ZopeComponentArchitecture/PythonProgrammerTutorial/Chapter1/Step7/contact.gif ===
<Binary-ish file>
=== Added File Docs/ZopeComponentArchitecture/PythonProgrammerTutorial/Chapter1/Step7/contact_product_uml.txt ===
<<utility>>
----------
| Lookup |
----------
|
o IPostalLookup
o IPostalInfo ^
| :
<<adapter>> :
-------------------- :
| ContactCityState |- - - - +
--------------------
:
:
:
: <<view>>
v IContactInfo -------------------
o<- - - - - - - - - - - - - - - - - - -| ContactInfoView |
^ --------^----------
: V
: |
: | <<page template>>
: <<page template>> -----------
: ----------- | info.pt |
: | edit.pt | -----------
: -----------
: |
: ^ <<view>>
: IContact --------V----------
o<- - - - - - -| ContactEditView |
| -------------------
|
-----------
| Contact |
-----------
Key:
o Interface (catalysis style)
^
V Aggregation
<- - - + Dependency
:
o<- - -o Interface B specializes interface A
A B
<<name>> Stereotype
--------
| name | Class
--------
=== Added File Docs/ZopeComponentArchitecture/PythonProgrammerTutorial/Chapter1/Step7/edit.pt ===
<html metal:use-macro="views/standard_macros/page">
<head><title>Edit contact</title></head>
<body>
<div metal:fill-slot="body">
Enter the information about the contact.
<form action="editAction.html" method="post">
<table cellspacing="0" cellpadding="2" border="0">
<tr><td> First name</td>
<td><input type="text" name="first" size="40" value=""
tal:attributes="value context/first" /> </td>
</tr>
<tr><td>Last name</td>
<td><input type="text" name="last" size="40" value=""
tal:attributes="value context/last" /> </td>
</tr>
<tr><td>Email</td>
<td><input type="text" name="email" size="40" value=""
tal:attributes="value context/email" /> </td>
</tr>
<tr><td>Address</td>
<td align="left" valign="top">
<textarea name="address" rows="3" cols="60"
tal:content="context/address"></textarea>
</td>
</tr>
<tr>
<td>Postal Code</td>
<td><input type="text" name="pc" size="40" value=""
tal:attributes="value context/postal_code" />
</td>
</tr>
</table>
<input type="submit" name="submit" value=" Save Changes " />
</form></div></body></html>
=== Added File Docs/ZopeComponentArchitecture/PythonProgrammerTutorial/Chapter1/Step7/info.pt ===
<html metal:use-macro="views/standard_macros/page">
<head><title>Contact Information</title></head>
<body>
<div metal:fill-slot="body">
<table border="0">
<caption>Contact information</caption>
<tbody>
<tr><td>Name:</td>
<td><span tal:replace="context/first">First</span>
<span tal:replace="context/last">Last</span></td>
</tr>
<tr><td>Address:</td>
<td tal:content="context/address">Mailing address here</td>
</tr>
<tr><td>Email:</td>
<td tal:content="context/email">foo at bar.com</td>
</tr>
<tr><td>City:</td>
<td tal:content="view/city | default">City</td>
</tr>
<tr><td>State:</td>
<td tal:content="view/state | default">State</td>
</tr>
</tbody>
</table>
</div></body></html>
=== Added File Docs/ZopeComponentArchitecture/PythonProgrammerTutorial/Chapter1/Step7/products.zcml ===
<zopeConfigure
xmlns='http://namespaces.zope.org/zope'
xmlns:security='http://namespaces.zope.org/security'
xmlns:zmi='http://namespaces.zope.org/zmi'
xmlns:browser='http://namespaces.zope.org/browser'
>
<!-- add include directives for products here -->
<include package="Zope.Contact" file="Contact.zcml"/>
</zopeConfigure>
=== Added File Docs/ZopeComponentArchitecture/PythonProgrammerTutorial/Chapter1/Step7/stubpostal.py ===
# Stub postal utility implemantation
from IPostal import IPostalLookup, IPostalInfo
class Info:
__implements__ = IPostalInfo
def __init__(self, city, state):
self._city, self._state = city, state
def city(self): return self._city
def state(self): return self._state
class Lookup:
__implements__ = IPostalLookup
_data = {
'22401': ('Fredericksburg', 'Virginia'),
'44870': ('Sandusky', 'Ohio'),
'90051': ('Los Angeles', 'California'),
}
def lookup(self, postal_code):
data = self._data.get(postal_code)
if data: return Info(*data)
More information about the Zope-book
mailing list