1
from time import time as now
3
import twisted.python.components as tpc
5
from nevow import rend, inevow, url, util, loaders, tags as t
6
from nevow.rend import _CARRYOVER
7
from formless import iformless
10
# This example is meant to be of some inspiration to those people
11
# who need to have some inspiration to handle forms without using
12
# formless. It _WILL_ raise an exception when you submit a form
13
# without filling all values. This example should NOT be used as-is
14
# but should be modified and enhanced to fit one's need.
16
# To sum up: it's just a starting point.
22
class WebException(Exception): pass
24
class ManualFormMixin(rend.Page):
25
def locateChild(self, ctx, segments):
26
# Handle the form post
27
if segments[0].startswith(SUBMIT):
28
# Get a method name from the action in the form plus
29
# the firt word in the button name (or simply the form action if
30
# no button name is specified
32
args = inevow.IRequest(ctx).args
37
kwargs[key] = (args[key][0], args[key])[len(args[key])>1]
39
bindingName = args[key][0]
40
name_prefix = segments[0].split('!!')[1]
41
if bindingName == '': name = name_prefix
42
else: name = name_prefix + '_' + bindingName.split()[0].lower()
43
method = getattr(self, 'form_'+name, None)
44
if method is not None:
45
return self.onManualPost(ctx, method, bindingName, kwargs)
47
raise WebException("You should define a form_action_button method")
48
return super(ManualFormMixin, self).locateChild(ctx, segments)
50
def onManualPost(self, ctx, method, bindingName, kwargs):
51
# This is copied from rend.Page.onWebFormPost
52
def redirectAfterPost(aspects):
53
redirectAfterPost = request.getComponent(iformless.IRedirectAfterPost, None)
54
if redirectAfterPost is None:
55
ref = request.getHeader('referer') or ''
57
## Use the redirectAfterPost url
58
ref = str(redirectAfterPost)
60
refpath = url.URL.fromString(ref)
61
magicCookie = str(now())
62
refpath = refpath.replace('_nevow_carryover_', magicCookie)
63
_CARRYOVER[magicCookie] = C = tpc.Componentized()
64
for k, v in aspects.iteritems():
66
request.redirect(str(refpath))
67
from nevow import static
68
return static.Data('You posted a form to %s' % bindingName, 'text/plain'), ()
69
request = inevow.IRequest(ctx)
70
return util.maybeDeferred(method, **kwargs
71
).addCallback(self.onPostSuccess, request, ctx, bindingName,redirectAfterPost
72
).addErrback(self.onPostFailure, request, ctx, bindingName,redirectAfterPost)
75
class Page(ManualFormMixin, rend.Page):
78
docFactory = loaders.stan(
81
t.title['Advanced Manualform']
84
t.p['Use the form to find out how to easily and manually handle them'],
85
t.form(action=url.here.child('_submit!!post'),
86
enctype="multipart/form-data",
89
t.input(type='text', name='what'),
90
# the name attribute must be present and must be
91
# post_btn for all the buttons in the form
92
t.input(type='submit', value='btn1', name=BUTTON),
93
t.input(type='submit', value='btn2', name=BUTTON)
99
def form_post_btn1(self, what=None):
100
# 'what' is a keyword argument, and must be the same name that you
101
# give to the widget.
104
def form_post_btn2(self, what=None):
105
# see above for 'what'.