Wed Development - Dynamically Generated News Index
Jean-Paul Calderone
exarkun at divmod.com
Mon Dec 19 00:05:59 EST 2005
On 18 Dec 2005 12:27:55 -0800, infidel02 at lycos.com wrote:
>Hi Jean-Paul,
>
>I am a bit lost in you code. Is it possible for you to step through
>it?
For in depth-assistance, it would probably be best to continue on twisted-web at twistedmatrix.com. You might also want to check out some of the links on <http://divmod.org/trac/wiki/DivmodNevow>. There is also a friendly, helpful IRC channel on freenode: #twisted.web.
I'll give a brief overview of what's going on, though:
from nevow import rend, loaders, tags
# Subclass rend.Page - this is the base class for pretty
# much anything that represents an entire HTTP Resource
class NewsIndex(rend.Page):
# Set the template for this page. Since it's just a
# throw-away example, use some really cheesy stan (the
# stuff with the square brackets). The below template
# turns into something like
# <html><body>[whatever render_index returns]</body></html>
docFactory = loaders.stan(tags.html[
tags.body(render=tags.directive('index'))])
# Boring initializer that takes a database connection
# pool to issue queries against.
def __init__(self, connpool):
super(NewsIndex, self).__init__()
self.connpool = connpool
# "model" function - doesn't know about web, just
# knows the db schema; returns a Deferred that fires
# with information about all the articles in the database.
def _retrieveIndex(self):
return self.connpool.runQuery(
"SELECT articleId, articleTitle, articleImage FROM articles")
# Another model function. This one gets the body text for
# one particular article.
def _retrieveArticle(self, articleId):
return self.connpool.runQuery(
"SELECT articleBody FROM articles WHERE articleId = ?",
(articleId,))
# The render function for the guts of the index page. This
# uses one of the model functions to get all the articles in
# the database. Since _retrieveIndex returns a Deferred, it
# doesn't use the results right away - instead of defines a
# lambda that will get invoked with the article information
# when it is received.
# There's some display logic here, too. Some more stan, which
# renders to something like:
# <div>
# <a href="<articleID>">
# <img src="<article image>" />
# article title
# </a>
# </div>
# for each article in the index
def render_index(self, ctx, data):
return self._retrieveIndex().addCallback(lambda index: ctx.tag[[
tags.div[
tags.a(href=articleID)[
tags.img(src=articleImage),
articleTitle]]
for (articleID, articleTitle, articleImage)
in index]])
# Allow this Resource to have children. Above, we generated links
# to "articleID" for each article in the index. This function
# handles those links by using the other model function to retrieve
# the body of the requested article and return another Page subclass
# instance for it.
def childFactory(self, ctx, name):
return self._retrieveArticle(name).addCallback(lambda articleBody:
ArticlePage(articleBody))
# The other display class. This one is pretty boring. It just
# displays the body of an article.
class ArticlePage(rend.Page):
docFactory = loaders.stan(tags.html[
tags.body(render=tags.directive('article'))])
def __init__(self, articleBody):
super(ArticlePage, self).__init__()
self.articleBody = articleBody
# Just spit out the article body. Note I changed one thing here.
# In the original version, I left out the "ctx.tag[...]" around
# the article body. This would have removed the <body> tag from
# the resulting document! Ooops. I also left this out of
# render_index above (so I've added it there as well).
def render_article(self, ctx, data):
return ctx.tag[self.articleBody]
from twisted.enterprise import adbapi
# Whatever DB-API 2.0 stuff you want
cp = adbapi.ConnectionPool('pypgsql', ...)
from twisted.application import service, internet
from nevow import appserver
application = service.Application("News Site")
webserver = appserver.NevowSite(NewsIndex(cp))
internet.TCPServer(80, webserver).setServiceParent(application)
# Run with twistd -noy <whatever you name this file>
Hope this helps,
Jean-Paul
More information about the Python-list
mailing list