Edgewall Software

Changes between Version 32 and Version 33 of GenshiTutorial


Ignore:
Timestamp:
Aug 30, 2007, 3:20:18 PM (17 years ago)
Author:
cmlenz
Comment:

Renamed Submission->Link

Legend:

Unmodified
Added
Removed
Modified
  • GenshiTutorial

    v32 v33  
    187187
    188188
    189 class Submission(object):
     189class Link(object):
    190190
    191191    def __init__(self, username, url, title):
     
    194194        self.title = title
    195195        self.time = datetime.utcnow()
    196         self.code = hex(hash(tuple([username, url, title, self.time])))[2:]
     196        self.id = hex(hash(tuple([username, url, title, self.time])))[2:]
    197197        self.comments = []
    198198
     
    219219{{{
    220220#!python
    221 from geddit.model import Submission, Comment
     221from geddit.model import Link, Comment
    222222}}}
    223223
     
    257257#!pycon
    258258>>> from geddit.model import *
    259 >>> submission1 = Submission(username='joe', url='http://example.org/', title='An example')
    260 >>> submission1.add_comment(username='jack', content='Bla bla bla')
    261 >>> submission1.add_comment(username='joe', content='Bla bla bla, bla bla.')
    262 >>> submission2 = Submission(username='annie', url='http://reddit.com/', title='The real thing')
    263 
     259>>> link1 = Link(username='joe', url='http://example.org/', title='An example')
     260>>> link1.add_comment(username='jack', content='Bla bla bla')
     261>>> link1.add_comment(username='joe', content='Bla bla bla, bla bla.')
     262>>> link2 = Link(username='annie', url='http://reddit.com/', title='The real thing')
    264263>>> import pickle
    265 >>> pickle.dump({
    266 ...     submission1.code: submission1, submission2.code: submission2
    267 ... }, open('geddit.db', 'wb'))
    268 }}}
    269 
    270 You should now have two submissions in the pickle file, with the first submission having a comment, as well as a reply to that comment. Restart the CherryPy server by running:
     264>>> pickle.dump({link1.id: link1, link2.id: link2}, open('geddit.db', 'wb'))
     265}}}
     266
     267You should now have two links in the pickle file, with the first link having a comment, as well as a reply to that comment. Restart the CherryPy server by running:
    271268
    272269{{{
     
    276273== Extending the Template ==
    277274
    278 Now let's change the `Root.index()` method in `geddit/controller.py` to pass the submissions list to the template:
     275Now let's change the `Root.index()` method in `geddit/controller.py` to pass the links list to the template:
    279276
    280277{{{
     
    282279    @cherrypy.expose
    283280    def index(self):
    284         submissions = sorted(self.data.values(),
    285                              key=operator.attrgetter('time'))
     281        links = sorted(self.data.values(), key=operator.attrgetter('time'))
    286282
    287283        tmpl = loader.load('index.html')
    288         stream = tmpl.generate(submissions=submissions)
     284        stream = tmpl.generate(links=links)
    289285        return stream.render('html', doctype='html')
    290286}}}
    291287
    292 And finally, we'll modify the `index.html` template so that it displays the submissions in a simple ordered list. While we're at it, let's add a link to submit new items:
     288And finally, we'll modify the `index.html` template so that it displays the links in a simple ordered list. While we're at it, let's add a link to submit new items:
    293289
    294290{{{
     
    306302    <p><a href="/submit/">Submit new link</a></p>
    307303
    308     <ol py:if="submissions">
    309       <li py:for="submission in reversed(submissions)">
    310         <a href="${submission.url}">${submission.title}</a>
    311         posted by ${submission.username}
    312         at ${submission.time.strftime('%M/%d/%Y %H:%m')}
     304    <ol py:if="links">
     305      <li py:for="link in reversed(links)">
     306        <a href="${link.url}">${link.title}</a>
     307        posted by ${link.username}
     308        at ${link.time.strftime('%M/%d/%Y %H:%m')}
    313309      </li>
    314310    </ol>
     
    324320This template demontrates some aspects of Genshi that we've not seen so far:
    325321 * We declare the `py:` namespace prefix on the `<html>` element, which is required to be able to add [wiki:Documentation/xml-templates.html#template-directives directives] to the template.
    326  * There's a `py:if` [wiki:Documentation/xml-templates.html#conditional-sections condition] on the `<ol>` element. That means that the `<ol>` and all nested content will only be included in the output stream if the expression `submissions` evaluates to a truth value. In this case we know that `submissions` is a list (assembled by the `Root.index()` method), so if the list is empty, the `<ol>` will be skipped.
    327  * Next up, we've attached a `py:for` [wiki:Documentation/xml-templates.html#looping loop] to the `<li>` element. `py:for="submission in reversed(submissions)"`. What this does is that the `<li>` element will be repeated for every item in the `submissions` list. The `submission` variable is bound to the current item in the list on every step.
     322 * There's a `py:if` [wiki:Documentation/xml-templates.html#conditional-sections condition] on the `<ol>` element. That means that the `<ol>` and all nested content will only be included in the output stream if the expression `links` evaluates to a truth value. In this case we know that `links` is a list (assembled by the `Root.index()` method), so if the list is empty, the `<ol>` will be skipped.
     323 * Next up, we've attached a `py:for` [wiki:Documentation/xml-templates.html#looping loop] to the `<li>` element. `py:for="link in reversed(links)"`. What this does is that the `<li>` element will be repeated for every item in the `links` list. The `link` variable is bound to the current item in the list on every step.
    328324 * You can tell that we can also use more complex expressions than just simple variable substitutions: the directives such as `py:if` and `py:for` take Python expressions of any complexity, while you can include complex expressions in other places by putting them inside curly braces prefixed with a dollar sign (`${...}`).
    329325
     
    346342                raise cherrypy.HTTPRedirect('/')
    347343            # TODO: validate the input data!
    348             submission = Submission(**data)
    349             self.data[submission.code] = submission
     344            link = Link(**data)
     345            self.data[link.id] = link
    350346            raise cherrypy.HTTPRedirect('/')
    351347
     
    409405
    410406
    411 class SubmissionForm(Schema):
     407class LinkForm(Schema):
    412408    username = validators.UnicodeString(not_empty=True)
    413409    url = validators.URL(not_empty=True, add_http=True, check_exists=False)
     
    420416#!python
    421417from formencode import Invalid
    422 from geddit.form import SubmissionForm
     418from geddit.form import LinkForm
    423419}}}
    424420
     
    432428            if cancel:
    433429                raise cherrypy.HTTPRedirect('/')
    434             form = SubmissionForm()
     430            form = LinkForm()
    435431            try:
    436432                data = form.to_python(data)
    437                 submission = Submission(**data)
    438                 self.data[submission.code] = submission
     433                link = Link(**data)
     434                self.data[link.id] = link
    439435                raise cherrypy.HTTPRedirect('/')
    440436            except Invalid, e:
     
    590586    @template.output('index.html')
    591587    def index(self):
    592         return template.render(submissions=self.data)
     588        links = sorted(self.data.values(), key=operator.attrgetter('time'))
     589        return template.render(links=links)
    593590
    594591    @cherrypy.expose
     
    598595            if cancel:
    599596                raise cherrypy.HTTPRedirect('/')
    600             form = SubmissionForm()
     597            form = LinkForm()
    601598            try:
    602599                data = form.to_python(data)
    603                 submission = Submission(**data)
    604                 self.data.append(submission)
     600                link = Link(**data)
     601                self.data[link.id] = link
    605602                raise cherrypy.HTTPRedirect('/')
    606603            except Invalid, e:
     
    723720    <p><a href="/submit/">Submit new link</a></p>
    724721
    725     <ol py:if="submissions">
    726       <li py:for="submission in submissions">
    727         <a href="${submission.url}">${submission.title}</a>
    728         posted by ${submission.username}
    729         at ${submission.time.strftime('%M/%d/%Y %H:%m')}
     722    <ol py:if="links">
     723      <li py:for="link in links">
     724        <a href="${link.url}">${link.title}</a>
     725        posted by ${link.username}
     726        at ${link.time.strftime('%M/%d/%Y %H:%m')}
    730727      </li>
    731728    </ol>