OLD | NEW |
| (Empty) |
1 | |
2 """ | |
3 Woven object collections. | |
4 | |
5 THIS MODULE IS HIGHLY EXPERIMENTAL AND MAY BE DEPRECATED SOON. | |
6 """ | |
7 | |
8 from __future__ import nested_scopes | |
9 | |
10 __version__ = "$Revision: 1.13 $"[11:-2] | |
11 | |
12 | |
13 import warnings | |
14 warnings.warn("The tapestry module is deprecated. Use page instead.", Deprecatio
nWarning, 1) | |
15 | |
16 # System Imports | |
17 import sys | |
18 import os | |
19 | |
20 # Twisted Imports | |
21 | |
22 from twisted.internet.defer import Deferred | |
23 | |
24 from twisted.web.resource import Resource, IResource | |
25 from twisted.web.static import redirectTo, addSlash, File, Data | |
26 from twisted.web.server import NOT_DONE_YET | |
27 from twisted.web import util | |
28 | |
29 from twisted.python.reflect import qual | |
30 | |
31 # Sibling Imports | |
32 from twisted.web.woven.view import View | |
33 | |
34 _ChildJuggler = util.DeferredResource | |
35 | |
36 class ModelLoader(Resource): | |
37 """Resource for loading models. (see loadModel) | |
38 """ | |
39 def __init__(self, parent, templateFile=None): | |
40 Resource.__init__(self) | |
41 self.parent = parent | |
42 self.templateFile = templateFile | |
43 | |
44 def modelClass(self, other): | |
45 return other | |
46 | |
47 def getChild(self, path, request): | |
48 d = self.loadModel(path, request) | |
49 templateFile = (self.templateFile or self.__class__.__name__+'.html') | |
50 d.addCallback( | |
51 lambda result: self.parent.makeView(self.modelClass(result), | |
52 templateFile, 1)) | |
53 return util.DeferredResource(d) | |
54 | |
55 def loadModelNow(self, path, request): | |
56 """Override this rather than loadModel if your model-loading is | |
57 synchronous. | |
58 """ | |
59 raise NotImplementedError("%s.loadModelNow" % (reflect.qual(self.__class
__))) | |
60 | |
61 def loadModel(self, path, request): | |
62 """Load a model, for the given path and request. | |
63 | |
64 @rtype: L{Deferred} | |
65 """ | |
66 from twisted.internet.defer import execute | |
67 return execute(self.loadModelNow, path, request) | |
68 | |
69 | |
70 from twisted.web import microdom | |
71 from twisted.web import domhelpers | |
72 | |
73 class TapestryView(View): | |
74 tapestry = None | |
75 parentCount = 0 | |
76 def lookupTemplate(self, request): | |
77 fullFile = os.path.join(self.templateDirectory, self.templateFile) | |
78 document = microdom.parse(open(fullFile)) | |
79 if self.tapestry: | |
80 return self.tapestry.templateMutate(document, self.parentCount) | |
81 return document | |
82 | |
83 class Tapestry(Resource): | |
84 """ | |
85 I am a top-level aggregation of Woven objects: a full `site' or | |
86 `application'. | |
87 """ | |
88 viewFactory = TapestryView | |
89 def __init__(self, templateDirectory, viewFactory=None, metaTemplate=None): | |
90 """ | |
91 Create a tapestry with a specified template directory. | |
92 """ | |
93 Resource.__init__(self) | |
94 self.templateDirectory = templateDirectory | |
95 if viewFactory is not None: | |
96 self.viewFactory = viewFactory | |
97 if metaTemplate: | |
98 self.metaTemplate = microdom.parse(open( | |
99 os.path.join(templateDirectory, metaTemplate))) | |
100 else: | |
101 self.metaTemplate = None | |
102 | |
103 def templateMutate(self, document, parentCount=0): | |
104 if self.metaTemplate: | |
105 newDoc = self.metaTemplate.cloneNode(1) | |
106 if parentCount: | |
107 dotdot = parentCount * '../' | |
108 for ddname in 'href', 'src', 'action': | |
109 for node in domhelpers.findElementsWithAttribute(newDoc, ddn
ame): | |
110 node.setAttribute(ddname, dotdot + node.getAttribute(ddn
ame)) | |
111 ttl = domhelpers.findNodesNamed(newDoc, "title")[0] | |
112 ttl2 = domhelpers.findNodesNamed(document, "title")[0] | |
113 ttl.childNodes[:] = [] | |
114 for n in ttl2.childNodes: | |
115 ttl.appendChild(n) | |
116 body = domhelpers.findElementsWithAttribute(newDoc, "class", "__BODY
__")[0] | |
117 body2 = domhelpers.findNodesNamed(document, "body")[0] | |
118 ndx = body.parentNode.childNodes.index(body) | |
119 body.parentNode.childNodes[ndx:ndx+1] = body2.childNodes | |
120 for n in body2.childNodes: | |
121 n.parentNode = body.parentNode | |
122 f = open("garbage.html", "wb") | |
123 f.write(newDoc.toprettyxml()) | |
124 return newDoc | |
125 return document | |
126 | |
127 def makeView(self, model, name, parentCount=0): | |
128 v = self.viewFactory(model, name) | |
129 v.parentCount = parentCount | |
130 v.templateDirectory = self.templateDirectory | |
131 v.tapestry = self | |
132 v.importViewLibrary(self) | |
133 return v | |
134 | |
135 def getSubview(self, request, node, model, viewName): | |
136 mod = sys.modules[self.__class__.__module__] | |
137 # print "I'm getting a subview", mod, viewName | |
138 | |
139 # try just the name | |
140 vm = getattr(mod, viewName, None) | |
141 if vm: | |
142 return vm(model) | |
143 | |
144 # try the name + a V | |
145 vn2 = "V"+viewName.capitalize() | |
146 vm = getattr(mod, vn2, None) | |
147 if vm: | |
148 return vm(model) | |
149 | |
150 vm = getattr(self, 'wvfactory_'+viewName, None) | |
151 if vm: | |
152 return vm(request, node, model) | |
153 | |
154 def render(self, request): | |
155 return redirectTo(addSlash(request), request) | |
156 | |
157 def getChild(self, path, request): | |
158 if path == '': path = 'index' | |
159 path = path.replace(".","_") | |
160 cm = getattr(self, "wchild_"+path, None) | |
161 if cm: | |
162 p = cm(request) | |
163 if isinstance(p, Deferred): | |
164 return util.DeferredResource(p) | |
165 adapter = IResource(p, None) | |
166 if adapter is not None: | |
167 return adapter | |
168 # maybe we want direct support for ModelLoader? | |
169 # cl = getattr(self, "wload_"+path, None) #??? | |
170 return Resource.getChild(self, path, request) | |
OLD | NEW |