[Checkins] SVN: Sandbox/luciano/kirbi/src/kirbi/ integrated all
forms with a new form template
Luciano Ramalho
luciano at ramalho.org
Thu Aug 16 21:49:40 EDT 2007
Log message for revision 78887:
integrated all forms with a new form template
Changed:
U Sandbox/luciano/kirbi/src/kirbi/app.py
U Sandbox/luciano/kirbi/src/kirbi/app_templates/index.pt
U Sandbox/luciano/kirbi/src/kirbi/app_templates/master.pt
U Sandbox/luciano/kirbi/src/kirbi/book.py
U Sandbox/luciano/kirbi/src/kirbi/book_templates/index.pt
A Sandbox/luciano/kirbi/src/kirbi/form.pt
U Sandbox/luciano/kirbi/src/kirbi/interfaces.py
U Sandbox/luciano/kirbi/src/kirbi/pac.py
U Sandbox/luciano/kirbi/src/kirbi/pac_templates/addbooks.pt
U Sandbox/luciano/kirbi/src/kirbi/pac_templates/index.pt
U Sandbox/luciano/kirbi/src/kirbi/static/master.css
U Sandbox/luciano/kirbi/src/kirbi/user.py
-=-
Modified: Sandbox/luciano/kirbi/src/kirbi/app.py
===================================================================
--- Sandbox/luciano/kirbi/src/kirbi/app.py 2007-08-17 00:49:04 UTC (rev 78886)
+++ Sandbox/luciano/kirbi/src/kirbi/app.py 2007-08-17 01:49:39 UTC (rev 78887)
@@ -10,6 +10,10 @@
PAC_NAME = u'pac'
USER_FOLDER_NAME = u'u'
+grok.define_permission('kirbi.Join')
+grok.define_permission('kirbi.EditBook')
+grok.define_permission('kirbi.DeleteBook')
+
class Kirbi(grok.Application, grok.Container):
"""Peer-to-peer library system."""
def __init__(self):
@@ -40,4 +44,5 @@
class Master(grok.View):
"""The master page template macro."""
+ # register this view for all objects
grok.context(Interface)
Modified: Sandbox/luciano/kirbi/src/kirbi/app_templates/index.pt
===================================================================
--- Sandbox/luciano/kirbi/src/kirbi/app_templates/index.pt 2007-08-17 00:49:04 UTC (rev 78886)
+++ Sandbox/luciano/kirbi/src/kirbi/app_templates/index.pt 2007-08-17 01:49:39 UTC (rev 78887)
@@ -4,12 +4,6 @@
</head>
<body>
<span metal:fill-slot="content_title">Collective catalog</span>
- <span metal:fill-slot="content_actions">
- <form class="search" tal:attributes="action view/pac_url">
- <input type="text" name="query">
- <input type="submit" name="submit" value="search">
- </form>
- </span>
<div metal:fill-slot="content">
Modified: Sandbox/luciano/kirbi/src/kirbi/app_templates/master.pt
===================================================================
--- Sandbox/luciano/kirbi/src/kirbi/app_templates/master.pt 2007-08-17 00:49:04 UTC (rev 78886)
+++ Sandbox/luciano/kirbi/src/kirbi/app_templates/master.pt 2007-08-17 01:49:39 UTC (rev 78887)
@@ -20,6 +20,7 @@
</head>
<body onload=setfocus()>
+
<div class="top">
<a tal:attributes="href python:view.application_url()">
<img tal:attributes="src static/circulante-logo-transp-212x51.png"
@@ -52,7 +53,14 @@
(not logged in)
</span>
</span>
- <span metal:define-slot="content_actions" />
+ <span metal:define-slot="content_actions">
+ <form class="search" tal:attributes="action python:view.application_url('pac')">
+ <input type="text" name="query">
+ <input type="submit" name="submit" value="search">
+ </form>
+ </span>
+
+
</span>
</div>
<div class="content">
Modified: Sandbox/luciano/kirbi/src/kirbi/book.py
===================================================================
--- Sandbox/luciano/kirbi/src/kirbi/book.py 2007-08-17 00:49:04 UTC (rev 78886)
+++ Sandbox/luciano/kirbi/src/kirbi/book.py 2007-08-17 01:49:39 UTC (rev 78887)
@@ -240,11 +240,13 @@
for key, value in kwargs.items():
setattr(self,key,value)
-
class Edit(grok.EditForm):
- # XXX: only the site manager should be able to edit a book
- pass
+ grok.require('kirbi.EditBook')
+ form_fields = grok.AutoFields(IBook)
+ template = grok.PageTemplateFile('form.pt')
+ form_title = u'Edit book record'
+
class Display(grok.DisplayForm):
pass
@@ -261,12 +263,14 @@
self.isbn13 = self.context.isbn13
self.creator_search_url = self.application_url('pac')+'?query=cr:'
self.subjects = ', '.join(self.context.subjects)
- if self.context.source and self.context.source_item_id:
+ if (self.context.source_url and self.context.source
+ and self.context.source_item_id):
self.source = '%s #%s' % (self.context.source,
self.context.source_item_id)
+ self.source_url = self.context.source_url
else:
self.source = self.context.source
- self.source_url = self.context.source_url
+ self.source_url = None
def coverUrl(self):
cover_name = 'covers/large/'+self.context.__name__+'.jpg'
Modified: Sandbox/luciano/kirbi/src/kirbi/book_templates/index.pt
===================================================================
--- Sandbox/luciano/kirbi/src/kirbi/book_templates/index.pt 2007-08-17 00:49:04 UTC (rev 78886)
+++ Sandbox/luciano/kirbi/src/kirbi/book_templates/index.pt 2007-08-17 01:49:39 UTC (rev 78887)
@@ -6,12 +6,6 @@
</head>
<body>
<span metal:fill-slot="content_title">Book details</span>
- <span metal:fill-slot="content_actions">
- <form class="search" action="../pac">
- <input type="text" name="query">
- <input type="submit" name="submit" value="search">
- </form>
- </span>
<div metal:fill-slot="content">
Added: Sandbox/luciano/kirbi/src/kirbi/form.pt
===================================================================
--- Sandbox/luciano/kirbi/src/kirbi/form.pt (rev 0)
+++ Sandbox/luciano/kirbi/src/kirbi/form.pt 2007-08-17 01:49:39 UTC (rev 78887)
@@ -0,0 +1,46 @@
+<html metal:use-macro="context/@@master/page">
+<body>
+
+ <span metal:fill-slot="content_title"
+ tal:content="view/form_title|string:Form"></span>
+
+ <div metal:fill-slot="content">
+
+ <form class="edit-form" enctype="multipart/form-data" method="post"
+ action="." tal:attributes="action request/URL">
+
+ <h1 tal:content="view/label" i18n:translate="">Edit something</h1>
+
+ <div class="summary" tal:condition="view/status"
+ tal:content="view/status" i18n:translate="">Status</div>
+
+ <div class="row" tal:repeat="widget view/widgets">
+ <div class="label">
+ <label for="field.name" title="The widget's hint"
+ tal:attributes="for widget/name; title widget/hint"
+ tal:content="widget/label" i18n:translate=""
+ i18n:attributes="title">Label</label>
+ </div>
+
+ <div tal:condition="widget/error"
+ tal:content="structure widget/error">Error</div>
+
+ <div class="field">
+ <input tal:replace="structure widget" />
+ </div>
+ </div>
+
+ <div class="row">
+ <div class="label"> </div>
+ <div class="field">
+ <span class="actionButtons" tal:condition="view/availableActions">
+ <input tal:repeat="action view/actions"
+ tal:replace="structure action/render"
+ />
+ </span>
+ </div>
+ </div>
+ </form>
+ </div>
+</body>
+</html>
Modified: Sandbox/luciano/kirbi/src/kirbi/interfaces.py
===================================================================
--- Sandbox/luciano/kirbi/src/kirbi/interfaces.py 2007-08-17 00:49:04 UTC (rev 78886)
+++ Sandbox/luciano/kirbi/src/kirbi/interfaces.py 2007-08-17 01:49:39 UTC (rev 78887)
@@ -10,7 +10,15 @@
required=False)
password = schema.Password(title=u"Password",
required=True)
+ password_confirmation = schema.Password(title=u"Confirm password",
+ required=True)
+ @invariant
+ def passwordConfirm(user):
+ if (user.password != user.password_confirmation):
+ raise Invalid(u'The password and confirmation do not match.')
+
+
class InvalidISBN(schema.ValidationError):
"""This is not a valid ISBN-10 or ISBN-13"""
@@ -47,7 +55,7 @@
value_type=schema.TextLine(),
default=())
- source = schema.TextLine(title=u"Record source",
+ source = schema.TextLine(title=u"Metadata source",
required=False,
description=u"Name of the source of this record.")
source_url = schema.URI(title=u"Source URL",
@@ -62,7 +70,7 @@
@invariant
def titleOrIsbnGiven(book):
if (not book.title or not book.title.strip()) and (not book.isbn):
- raise Invalid('Either the title or the ISBN must be given.')
+ raise Invalid(u'Either the title or the ISBN must be given.')
class ICopy(Interface):
"""An exemplar of a book."""
Modified: Sandbox/luciano/kirbi/src/kirbi/pac.py
===================================================================
--- Sandbox/luciano/kirbi/src/kirbi/pac.py 2007-08-17 00:49:04 UTC (rev 78886)
+++ Sandbox/luciano/kirbi/src/kirbi/pac.py 2007-08-17 01:49:39 UTC (rev 78887)
@@ -138,13 +138,18 @@
self.results = sorted(results, key=attrgetter('filing_title'))
-
class AddBook(grok.AddForm):
+ grok.require('kirbi.EditBook')
- form_fields = grok.AutoFields(Book)
+ form_fields = grok.AutoFields(IBook).omit(*['source','source_url',
+ 'source_item_id'])
+ template = grok.PageTemplateFile('form.pt')
+ form_title = u'Add book'
- @grok.action('Add book')
+ @grok.action('Save book')
def add(self, **data):
+ ### XXX: investigate why the source data is not being recorded
+ data['source'] = self.request.principal.getLogin()
book = Book()
self.applyData(book, **data)
self.context.addBook(book)
Modified: Sandbox/luciano/kirbi/src/kirbi/pac_templates/addbooks.pt
===================================================================
--- Sandbox/luciano/kirbi/src/kirbi/pac_templates/addbooks.pt 2007-08-17 00:49:04 UTC (rev 78886)
+++ Sandbox/luciano/kirbi/src/kirbi/pac_templates/addbooks.pt 2007-08-17 01:49:39 UTC (rev 78887)
@@ -7,12 +7,6 @@
</head>
<body>
<span metal:fill-slot="content_title">Collective catalog</span>
- <span metal:fill-slot="content_actions">
- <form class="search" action=".">
- <input type="text" name="query">
- <input type="submit" name="submit" value="search">
- </form>
- </span>
<div metal:fill-slot="content">
<table><tr>
<td valign="top">
Modified: Sandbox/luciano/kirbi/src/kirbi/pac_templates/index.pt
===================================================================
--- Sandbox/luciano/kirbi/src/kirbi/pac_templates/index.pt 2007-08-17 00:49:04 UTC (rev 78886)
+++ Sandbox/luciano/kirbi/src/kirbi/pac_templates/index.pt 2007-08-17 01:49:39 UTC (rev 78887)
@@ -7,12 +7,6 @@
</head>
<body>
<span metal:fill-slot="content_title">Collective catalog</span>
- <span metal:fill-slot="content_actions">
- <form class="search" action=".">
- <input type="text" name="query">
- <input type="submit" name="submit" value="search">
- </form>
- </span>
<div metal:fill-slot="content">
<h3 tal:content="view/results_title">999 items matched the query</h3>
Modified: Sandbox/luciano/kirbi/src/kirbi/static/master.css
===================================================================
--- Sandbox/luciano/kirbi/src/kirbi/static/master.css 2007-08-17 00:49:04 UTC (rev 78886)
+++ Sandbox/luciano/kirbi/src/kirbi/static/master.css 2007-08-17 01:49:39 UTC (rev 78887)
@@ -58,7 +58,6 @@
color: gray;
}
dt { font-size: 12pt; }
-th { font-size: 10pt; }
dd { font-size: 11pt; }
div.content_menu {
@@ -98,7 +97,7 @@
font-family: sans-serif;
font-weight: bold;
}
-th {
+th, .label {
font-family: sans-serif;
font-weight: bold;
font-size: 10pt;
@@ -124,3 +123,20 @@
.error {
color: red;
}
+
+form .row {
+ clear: both;
+ margin: 3px;
+}
+
+form .label {
+ float: left;
+ width: 10em;
+ padding: 7px;
+}
+
+form .field {
+ width: 40em;
+ float: left;
+ padding: 7px;
+}
\ No newline at end of file
Modified: Sandbox/luciano/kirbi/src/kirbi/user.py
===================================================================
--- Sandbox/luciano/kirbi/src/kirbi/user.py 2007-08-17 00:49:04 UTC (rev 78886)
+++ Sandbox/luciano/kirbi/src/kirbi/user.py 2007-08-17 01:49:39 UTC (rev 78887)
@@ -22,7 +22,7 @@
user = self.get(id)
if user is not None:
given_hash = sha.new(credentials['password']).hexdigest()
- if user.password == given_hash:
+ if user.password_hash == given_hash:
return IPrincipalInfo(self[id])
class User(grok.Container):
@@ -34,23 +34,34 @@
>>> alice = User('alice', u'Alice Cooper', u'headless-chicken')
>>> IUser.providedBy(alice)
True
- >>> alice.password
- 'f030ff587c602e0e9a68aba75f41c51a0dc22c62'
>>> alice.name_and_login()
u'Alice Cooper (alice)'
+
+ The password is not saved, only a SHA hash::
+
+ >>> alice.password is None
+ True
+ >>> alice.password_hash
+ 'f030ff587c602e0e9a68aba75f41c51a0dc22c62'
+
"""
implements(IUser)
login = u''
name = u''
- password = ''
+ password_hash = ''
- def __init__(self, login, name, password):
+ def __init__(self, login, name, password, password_confirmation=None):
super(User, self).__init__()
self.login = login
self.name = name
- self.password = sha.new(password).hexdigest()
+ if ((password_confirmation is not None)
+ and password != password_confirmation):
+ raise ValueError, u'Password and confirmation do not match'
+ self.password_hash = sha.new(password).hexdigest()
+ # we don't want to store the clear password
+ self.password = self.password_confirmation = None
def name_and_login(self):
if self.name:
@@ -106,12 +117,16 @@
return "This should log you out (but doesn't yet)."
class Join(grok.AddForm):
+ """User registration form"""
grok.context(UserFolder)
- """User registration form"""
form_fields = grok.AutoFields(IUser)
+ template = grok.PageTemplateFile('form.pt')
+ form_title = u'User registration'
- @grok.action('Add entry')
+ ### XXX: find out how to display message of the Invalid exception raised
+ ### by the password confirmation invariant (see interfaces.IUser)
+ @grok.action('Save')
def add(self, **data):
login = data['login']
self.context[login] = User(**data)
More information about the Checkins
mailing list