"""Update quotient CVS for this to work """ from twisted.application import service, internet from nevow import iwoven from nevow import appserver from nevow import renderer from nevow import freeform from nevow import formless from nevow.url import here from nevow.tags import * whole = [(1, 'one'), (2, 'two'), (3, 'buckle'), (4, 'my'), (5, 'shoe')] def doQuery(q, *args): """Pretend like we have a database and we are accessing it through this hypothetical interface. Ignore this. Use dbapi or adbapi instead, and build a real sql table. I hope that's obvious. """ matchid = 'select * from foo where id =' setsql = 'update foo set subject = ' insertsql = 'insert into foo values' if q == 'select * from foo': return whole elif q.startswith(matchid): theId = args[0] for dbid, subj in whole: if dbid == theId: return [(dbid, subj)] raise KeyError, theId elif q.startswith(setsql): newsubj, theId = args for index, (dbid, subj) in enumerate(whole): if dbid == theId: whole[index] = (dbid, newsubj) elif q.startswith(insertsql): max = whole[-1][0] subject, = args whole.append((max + 1, subject)) class IAddItem(formless.TypedInterface): def addItem(self, newSubject=formless.String()): pass addItem = formless.autocallable(addItem) class DBBrowser(renderer.Renderer): __implements__ = IAddItem, renderer.Renderer.__implements__ def addItem(self, newSubject): doQuery('insert into foo values subject = "%s"', newSubject) def data_queryDatabase(self, context, data): return doQuery('select * from foo') def render_row(self, context, data): theId, theSubj = data return context.tag[ # put our anchor in the li provided by the template a(href=theId)[ theSubj ] ] document = html[ body[ h1["Welcome, user"], ul(data=directive("queryDatabase"), renderer=directive("sequence"))[ li(pattern="item", renderer=render_row) ], freeform.configure ] ] def getDynamicChild(self, name, request): """Since we created anchor tags linking to children of this resource directly by id, when the anchor is clicked, getDynamicChild will be called with the appropriate id as the name argument.""" try: ## Pass the id of the database item we want to be rendered on this page ## to the DBItem constructor. This integer will be used as the default data ## for this page. return DBItem(int(name)) except ValueError: pass ## returning None results in a 404 class IItemWithSubject(formless.TypedInterface): def setSubject(self, newSubject=formless.String(label="Change Subject")): pass setSubject = formless.autocallable(setSubject) class DBItem(renderer.Renderer): __implements__ = IItemWithSubject, renderer.Renderer.__implements__ def setSubject(self, newSubject): ## Self.original is the data that was passed to the DBItem constructor above; the id of this record doQuery('update foo set subject = "%s" where id = %s', newSubject, self.original) def render_viewSelector(self, context, data): args = context.locate(iwoven.IRequest).args view = args.get('view', ['view'])[0] if view == 'view': selector = "View | ", a(href=here(view="edit"))[ "Edit" ] editor = '' else: selector = a(href=here(view="view"))["View"], " | Edit" editor = context.patterns('edit')() # get one copy of the edit pattern viewer = context.patterns('view')() # get one copy of the view pattern return selector, viewer, editor def render_itemDetail(self, context, data): theId, theSubject = doQuery('select * from foo where id = %s', self.original)[0] return h2["Object ", theId], span["Subject: ", theSubject] document = html[ body[ p[ a(href=here.parent())["Up"] ], div(renderer=render_viewSelector)[ p(pattern="edit")[ freeform.configure ], p(pattern="view")[ render_itemDetail ] ] ] ] application = service.Application("db") internet.TCPServer(8080, appserver.NevowSite(DBBrowser())).setServiceParent(application)