- 浏览: 333540 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
ProgrammingPower:
非常感谢您,搞定了,哈哈!
Debian下安装CodeBlocks -
hfa1s2:
是的。谢谢你哈! 我解决了这个问题
python模块之smtplib: 用python发送SSL/TLS安全邮件 -
huangro:
587端口的是很麻烦的,毕竟是需要ssl验证的。
python模块之smtplib: 用python发送SSL/TLS安全邮件 -
hfa1s2:
我想利用内网往公司邮箱里发,但接口是587 的 而且需要 SS ...
python模块之smtplib: 用python发送SSL/TLS安全邮件 -
zyb88325:
你好 我现在用的cakephp2.0,因为服务器不支持rewr ...
CakePHP常用技巧总结
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript"></script><script type="text/javascript"><!-- _uacct = "UA-99018-3"; urchinTracker(); // --></script>
1 Nevow Object Publishing
2 =======================
3
4 In Nevow Object Traversal, we learned about the
5 nevow.inevow.IResource.renderHTTP method, which is the most basic way to send
6 HTML to a browser when using Nevow. However, it is not very convenient (or
7 clean) to generate HTML tags by concatenating strings in Python code. In the
8 Nevow Deployment documentation, we saw that it was possible to render a Hello
9 World page using a nevow.rend.Page subclass and providing a "docFactory"::
10
11 >>> from nevow import rend, loaders
12 >>> class HelloWorld(rend.Page):
13 ... docFactory = loaders.stan("Hello, world!")
14 ...
15 >>> HelloWorld().renderSynchronously()
16 'Hello, world!'
17
18 This example does nothing interesting, but the concept of a loader is important
19 in Nevow. The rend.Page.renderHTTP implementation always starts rendering HTML
20 by loading a template from the docFactory.
21
22 * `The stan DOM`_
23 * `Tag instances`_
24 * `Functions in the DOM`_
25 * `Accessing query parameters and form post data`_
26 * `Generators in the DOM`_
27 * `Methods in the DOM`_
28 * `Data specials`_
29 * `Render specials`_
30 * `Pattern specials`_
31 * `Slot specials`_
32 * `Data directives`_
33 * `Render directives`_
34 * `Flatteners`_
35
36 The stan DOM
37 ------------
38
39 Nevow uses a DOM-based approach to rendering HTML. A tree of objects is first
40 constructed in memory by the template loader. This tree is then processed one
41 node at a time, applying functions which transform from various Python types to
42 HTML strings.
43
44 Nevow uses a nonstandard DOM named "stan". Unlike the W3C DOM, stan is made up
45 of simple python lists, strings, and instances of the nevow.stan.Tag class.
46 During the rendering process, "Flattener" functions convert from rich types to
47 HTML strings. For example, we can load a template made up of some nested lists
48 and Python types, render it, and see what happens::
49
50 >>> class PythonTypes(rend.Page):
51 ... docFactory = loaders.stan(["Hello", 1, 1.5, True, ["Goodbye", 3]])
52 ...
53 >>> PythonTypes().renderSynchronously()
54 'Hello11.5TrueGoodbye3'
55
56 Tag instances
57 -------------
58
59 So far, we have only rendered simple strings as output. However, the main
60 purpose of Nevow is HTML generation. In the stan DOM, HTML tags are represented
61 by instances of the nevow.stan.Tag class. Tag is a very simple class, whose
62 instances have an "attributes" dictionary and a "children" list. The Tag
63 flattener knows how to recursively flatten attributes and children of the tag.
64 To show you how Tags really work before you layer Nevow's convenience syntax on
65 top, try this horrible example::
66
67 >>> from nevow import stan
68 >>> h = stan.Tag('html')
69 >>> d = stan.Tag('div')
70 >>> d.attributes['style'] = 'border: 1px solid black'
71 >>> h.children.append(d)
72 >>> class Tags(rend.Page):
73 ... docFactory = loaders.stan(h)
74 ...
75 >>> Tags().renderSynchronously()
76 '<html><div style="border: 1px solid black"></div></html>'
77
78 So, we see how it is possible to programatically generate HTML by constructing
79 and nesting stan Tag instances. However, it is far more convenient to use the
80 overloaded operators Tag provides to manipulate them. Tag implements a __call__
81 method which takes any keyword arguments and values and updates the attributes
82 dictionary; it also implements a __getitem__ method which takes whatever is
83 between the square brackets and appends them to the children list. A simple
84 example should clarify things::
85
86 >>> class Tags2(rend.Page):
87 ... docFactory = loaders.stan(stan.Tag('html')[stan.Tag('div')(style="border: 1px solid black")])
88 ...
89 >>> Tags2().renderSynchronously()
90 '<html><div style="border: 1px solid black"></div></html>'
91
92 This isn't very easy to read, but luckily we can simplify the example even
93 further by using the nevow.tags module, which is full of "Tag prototypes" for
94 every tag type described by the XHTML 1.0 specification::
95
96 >>> class Tags3(rend.Page):
97 ... docFactory = loaders.stan(tags.html[tags.div(style="border: 1px solid black")])
98 ...
99 >>> Tags3().renderSynchronously()
100 '<html><div style="border: 1px solid black"></div></html>'
101
102 Using stan syntax is not the only way to construct template DOM for use by the
103 Nevow rendering process. Nevow also includes loaders.xmlfile which implements a
104 simple tag attribute language similar to the Zope Page Templates (ZPT) Tag
105 Attribute Language (TAL). However, experience with the stan DOM should give you
106 insight into how the Nevow rendering process really works. Rendering a template
107 into HTML in Nevow is really nothing more than iterating a tree of objects and
108 recursively applying "Flattener" functions to objects in this tree, until all
109 HTML has been generated.
110
111 Functions in the DOM
112 --------------------
113
114 So far, all of our examples have generated static HTML pages, which is not
115 terribly interesting when discussing dynamic web applications. Nevow takes a
116 very simple approach to dynamic HTML generation. If you put a Python function
117 reference in the DOM, Nevow will call it when the page is rendered. The return
118 value of the function replaces the function itself in the DOM, and the results
119 are flattened further. This makes it easy to express looping and branching
120 structures in Nevow, because normal Python looping and branching constructs are
121 used to do the job::
122
123 >>> def repeat(ctx, data):
124 ... return [tags.div(style="color: %s" % (color, ))
125 ... for color in ['red', 'blue', 'green']]
126 ...
127 >>> class Repeat(rend.Page):
128 ... docFactory = loaders.stan(tags.html[repeat])
129 ...
130 >>> Repeat().renderSynchronously()
131 '<html><div style="color: red"></div><div style="color: blue"></div><div style="color: green"></div></html>'
132
133 However, in the example above, the repeat function isn't even necessary, because
134 we could have inlined the list comprehension right where we placed the function
135 reference in the DOM. Things only really become interesting when we begin
136 writing parameterized render functions which cause templates to render
137 differently depending on the input to the web application.
138
139 The required signature of functions which we can place in the DOM is (ctx,
140 data). The "context" object is essentially opaque for now, and we will learn how
141 to extract useful information out of it later. The "data" object is anything we
142 want it to be, and can change during the rendering of the page. By default, the
143 data object is whatever we pass as the first argument to the Page constructor,
144 **or** the Page instance itself if nothing is passed. Armed with this knowledge,
145 we can create a Page which renders differently depending on the data we pass to
146 the Page constructor::
147
148 class Root(rend.Page):
149 docFactory = loaders.stan(tags.html[
150 tags.h1["Welcome."],
151 tags.a(href="foo")["Foo"],
152 tags.a(href="bar")["Bar"],
153 tags.a(href="baz")["Baz"]])
154
155 def childFactory(self, ctx, name):
156 return Leaf(name)
157
158
159 def greet(ctx, name):
160 return "Hello. You are visiting the ", name, " page."
161
162 class Leaf(rend.Page):
163 docFactory = loaders.stan(tags.html[greet])
164
165 Armed with this knowledge and the information in the Object Traversal
166 documentation, we now have enough information to create dynamic websites with
167 arbitrary URL hierarchies whose pages render dynamically depending on which URL
168 was used to access them.
169
170 Accessing query parameters and form post data
171 ---------------------------------------------
172
173 Before we move on to more advanced rendering techniques, let us first examine
174 how one could further customize the rendering of a Page based on the URL query
175 parameters and form post information provided to us by a browser. Recall that
176 URL parameters are expressed in the form::
177
178 http://example.com/foo/bar?baz=1&quux=2
179
180 And form post data can be generated by providing a form to a browser::
181
182 <form action="" method="POST">
183 <input type="text" name="baz" />
184 <input type="text" name="quux" />
185 <input type="submit" />
186 </form>
187
188 Accessing this information is such a common procedure that Nevow provides a
189 convenience method on the context to do it. Let's examine a simple page whose
190 output can be influenced by the query parameters in the URL used to access it::
191
192 def showChoice(ctx, data):
193 choice = ctx.arg('choice')
194 if choice is None:
195 return ''
196 return "You chose ", choice, "."
197
198 class Custom(rend.Page):
199 docFactory = loaders.stan(tags.html[
200 tags.a(href="?choice=baz")["Baz"],
201 tags.a(href="?choice=quux")["Quux"],
202 tags.p[showChoice]])
203
204 The procedure is exactly the same for simple form post information::
205
206 def greet(ctx, data):
207 name = ctx.arg('name')
208 if name is None:
209 return ''
210 return "Greetings, ", name, "!"
211
212 class Form(rend.Page):
213 docFactory = loaders.stan(tags.html[
214 tags.form(action="", method="POST")[
215 tags.input(name="name"),
216 tags.input(type="submit")],
217 greet])
218
219 Note that ctx.arg returns only the first argument with the given name. For
220 complex cases where multiple arguments and lists of argument values are
221 required, you can access the request argument dictionary directly using the
222 syntax::
223
224 def arguments(ctx, data):
225 args = inevow.IRequest(ctx).args
226 return "Request arguments are: ", str(args)
227
228 Generators in the DOM
229 ---------------------
230
231 One common operation when building dynamic pages is iterating a list of data and
232 emitting some HTML for each item. Python generators are well suited for
233 expressing this sort of logic, and code which is written as a python generator
234 can perform tests (if) and loops of various kinds (while, for) and emit a row of
235 html whenever it has enough data to do so. Nevow can handle generators in the
236 DOM just as gracefully as it can handle anything else::
237
238 >>> from nevow import rend, loaders, tags
239 >>> def generate(ctx, items):
240 ... for item in items:
241 ... yield tags.div[ item ]
242 ...
243 >>> class List(rend.Page):
244 ... docFactory = loaders.stan(tags.html[ generate ])
245 ...
246 >>> List(['one', 'two', 'three']).renderSynchronously()
247 '<html><div>one</div><div>two</div><div>three</div></html>'
248
249 As you can see, generating HTML inside of functions or generators can be very
250 convenient, and can lead to very rapid application development. However, it is
251 also what I would call a "template abstraction violation", and we will learn how
252 we can keep knowledge of HTML out of our python code when we learn about
253 patterns and slots.
254
255 Methods in the DOM
256 ------------------
257
258 Up until now, we have been placing our template manipulation logic inside of
259 simple Python functions and generators. However, it is often appropriate to use
260 a method instead of a function. Nevow makes it just as easy to use a method to
261 render HTML::
262
263 class MethodRender(rend.Page):
264 def __init__(self, foo):
265 self.foo = foo
266
267 def render_foo(self, ctx, data):
268 return self.foo
269
270 docFactory = loaders.stan(tags.html[ render_foo ])
271
272 Using render methods makes it possible to parameterize your Page class with more
273 parameters. With render methods, you can also use the Page instance as a state
274 machine to keep track of the state of the render. While Nevow is designed to
275 allow you to render the same Page instance repeatedly, it can also be convenient
276 to know that a Page instance will only be used one time, and that the Page
277 instance can be used as a scratch pad to manage information about the render.
278
279 Data specials
280 -------------
281
282 Previously we saw how passing a parameter to the default Page constructor makes
283 it available as the "data" parameter to all of our render methods. This "data"
284 parameter can change as the page render proceeds, and is a useful way to ensure
285 that render functions are isolated and only act upon the data which is available
286 to them. Render functions which do not pull information from sources other than
287 the "data" parameter are more easily reusable and can be composed into larger
288 parts more easily.
289
290 Deciding which data gets passed as the data parameter is as simple as changing
291 the "Data special" for a Tag. See the Glossary under "Tag Specials" for more
292 information about specials. Assigning to the data special is as simple as
293 assigning to a tag attribute::
294
295 >>> def hello(ctx, name):
296 ... return "Hello, ", name
297 ...
298 >>> class DataSpecial(rend.Page):
299 ... docFactory = loaders.stan(tags.html[
300 ... tags.div(data="foo")[ hello ],
301 ... tags.div(data="bar")[ hello ]])
302 ...
303 >>> DataSpecial().renderSynchronously()
304 '<html><div>Hello, foo</div><div>Hello, bar</div></html>'
305
306 Data specials may be assigned any python value. Data specials are only in scope
307 during the rendering of the tag they are assigned to, so if the "hello" renderer
308 were placed in the DOM inside the html node directly, "Hello, None" would be
309 output.
310
311 Before data is passed to a render function, Nevow first checks to see if there
312 is an IGettable adapter for it. If there is, it calls IGettable.get(), and
313 passes the result of this as the data parameter instead. Nevow includes an
314 IGettable adapter for python functions, which means you can set a Tag data
315 special to a function reference and Nevow will call it to obtain the data when
316 the Tag is rendered. The signature for data methods is similar to that of render
317 methods, (ctx, data). For example::
318
319 def getName(ctx, data):
320 return ctx.arg('name')
321
322 def greet(ctx, name):
323 return "Greetings, ", name
324
325 class GreetName(rend.Page):
326 docFactory = loaders.stan(tags.html[
327 tags.form(action="")[
328 tags.input(name="name"),
329 tags.input(type="submit")],
330 tags.div(data=getName)[ greet ]])
331
332 Data specials exist mainly to allow you to construct and enforce a
333 Model-View-Controller style separation of the Model code from the View. Here we
334 see that the greet function is capable of rendering a greeting view for a name
335 model, and that the implementation of getName may change without the view code
336 changing.
337
338 Render specials
339 ---------------
340
341 Previously, we have seen how render functions can be placed directly in the DOM,
342 and the return value replaces the render function in the DOM. However, these
343 free functions and methods are devoid of any contextual information about the
344 template they are living in. The render special is a way to associate a render
345 function or method with a particular Tag instance, which the render function can
346 then examine to decide how to render::
347
348 >>> def alignment(ctx, data):
349 ... align = ctx.tag.attributes.get('align')
350 ... if align == 'right':
351 ... return ctx.tag["Aligned right"]
352 ... elif align == 'center':
353 ... return ctx.tag["Aligned center"]
354 ... else:
355 ... return ctx.tag["Aligned left"]
356 ...
357 >>> class AlignmentPage(rend.Page):
358 ... docFactory = loaders.stan(tags.html[
359 ... tags.p(render=alignment),
1 Nevow Object Publishing
2 =======================
3
4 In Nevow Object Traversal, we learned about the
5 nevow.inevow.IResource.renderHTTP method, which is the most basic way to send
6 HTML to a browser when using Nevow. However, it is not very convenient (or
7 clean) to generate HTML tags by concatenating strings in Python code. In the
8 Nevow Deployment documentation, we saw that it was possible to render a Hello
9 World page using a nevow.rend.Page subclass and providing a "docFactory"::
10
11 >>> from nevow import rend, loaders
12 >>> class HelloWorld(rend.Page):
13 ... docFactory = loaders.stan("Hello, world!")
14 ...
15 >>> HelloWorld().renderSynchronously()
16 'Hello, world!'
17
18 This example does nothing interesting, but the concept of a loader is important
19 in Nevow. The rend.Page.renderHTTP implementation always starts rendering HTML
20 by loading a template from the docFactory.
21
22 * `The stan DOM`_
23 * `Tag instances`_
24 * `Functions in the DOM`_
25 * `Accessing query parameters and form post data`_
26 * `Generators in the DOM`_
27 * `Methods in the DOM`_
28 * `Data specials`_
29 * `Render specials`_
30 * `Pattern specials`_
31 * `Slot specials`_
32 * `Data directives`_
33 * `Render directives`_
34 * `Flatteners`_
35
36 The stan DOM
37 ------------
38
39 Nevow uses a DOM-based approach to rendering HTML. A tree of objects is first
40 constructed in memory by the template loader. This tree is then processed one
41 node at a time, applying functions which transform from various Python types to
42 HTML strings.
43
44 Nevow uses a nonstandard DOM named "stan". Unlike the W3C DOM, stan is made up
45 of simple python lists, strings, and instances of the nevow.stan.Tag class.
46 During the rendering process, "Flattener" functions convert from rich types to
47 HTML strings. For example, we can load a template made up of some nested lists
48 and Python types, render it, and see what happens::
49
50 >>> class PythonTypes(rend.Page):
51 ... docFactory = loaders.stan(["Hello", 1, 1.5, True, ["Goodbye", 3]])
52 ...
53 >>> PythonTypes().renderSynchronously()
54 'Hello11.5TrueGoodbye3'
55
56 Tag instances
57 -------------
58
59 So far, we have only rendered simple strings as output. However, the main
60 purpose of Nevow is HTML generation. In the stan DOM, HTML tags are represented
61 by instances of the nevow.stan.Tag class. Tag is a very simple class, whose
62 instances have an "attributes" dictionary and a "children" list. The Tag
63 flattener knows how to recursively flatten attributes and children of the tag.
64 To show you how Tags really work before you layer Nevow's convenience syntax on
65 top, try this horrible example::
66
67 >>> from nevow import stan
68 >>> h = stan.Tag('html')
69 >>> d = stan.Tag('div')
70 >>> d.attributes['style'] = 'border: 1px solid black'
71 >>> h.children.append(d)
72 >>> class Tags(rend.Page):
73 ... docFactory = loaders.stan(h)
74 ...
75 >>> Tags().renderSynchronously()
76 '<html><div style="border: 1px solid black"></div></html>'
77
78 So, we see how it is possible to programatically generate HTML by constructing
79 and nesting stan Tag instances. However, it is far more convenient to use the
80 overloaded operators Tag provides to manipulate them. Tag implements a __call__
81 method which takes any keyword arguments and values and updates the attributes
82 dictionary; it also implements a __getitem__ method which takes whatever is
83 between the square brackets and appends them to the children list. A simple
84 example should clarify things::
85
86 >>> class Tags2(rend.Page):
87 ... docFactory = loaders.stan(stan.Tag('html')[stan.Tag('div')(style="border: 1px solid black")])
88 ...
89 >>> Tags2().renderSynchronously()
90 '<html><div style="border: 1px solid black"></div></html>'
91
92 This isn't very easy to read, but luckily we can simplify the example even
93 further by using the nevow.tags module, which is full of "Tag prototypes" for
94 every tag type described by the XHTML 1.0 specification::
95
96 >>> class Tags3(rend.Page):
97 ... docFactory = loaders.stan(tags.html[tags.div(style="border: 1px solid black")])
98 ...
99 >>> Tags3().renderSynchronously()
100 '<html><div style="border: 1px solid black"></div></html>'
101
102 Using stan syntax is not the only way to construct template DOM for use by the
103 Nevow rendering process. Nevow also includes loaders.xmlfile which implements a
104 simple tag attribute language similar to the Zope Page Templates (ZPT) Tag
105 Attribute Language (TAL). However, experience with the stan DOM should give you
106 insight into how the Nevow rendering process really works. Rendering a template
107 into HTML in Nevow is really nothing more than iterating a tree of objects and
108 recursively applying "Flattener" functions to objects in this tree, until all
109 HTML has been generated.
110
111 Functions in the DOM
112 --------------------
113
114 So far, all of our examples have generated static HTML pages, which is not
115 terribly interesting when discussing dynamic web applications. Nevow takes a
116 very simple approach to dynamic HTML generation. If you put a Python function
117 reference in the DOM, Nevow will call it when the page is rendered. The return
118 value of the function replaces the function itself in the DOM, and the results
119 are flattened further. This makes it easy to express looping and branching
120 structures in Nevow, because normal Python looping and branching constructs are
121 used to do the job::
122
123 >>> def repeat(ctx, data):
124 ... return [tags.div(style="color: %s" % (color, ))
125 ... for color in ['red', 'blue', 'green']]
126 ...
127 >>> class Repeat(rend.Page):
128 ... docFactory = loaders.stan(tags.html[repeat])
129 ...
130 >>> Repeat().renderSynchronously()
131 '<html><div style="color: red"></div><div style="color: blue"></div><div style="color: green"></div></html>'
132
133 However, in the example above, the repeat function isn't even necessary, because
134 we could have inlined the list comprehension right where we placed the function
135 reference in the DOM. Things only really become interesting when we begin
136 writing parameterized render functions which cause templates to render
137 differently depending on the input to the web application.
138
139 The required signature of functions which we can place in the DOM is (ctx,
140 data). The "context" object is essentially opaque for now, and we will learn how
141 to extract useful information out of it later. The "data" object is anything we
142 want it to be, and can change during the rendering of the page. By default, the
143 data object is whatever we pass as the first argument to the Page constructor,
144 **or** the Page instance itself if nothing is passed. Armed with this knowledge,
145 we can create a Page which renders differently depending on the data we pass to
146 the Page constructor::
147
148 class Root(rend.Page):
149 docFactory = loaders.stan(tags.html[
150 tags.h1["Welcome."],
151 tags.a(href="foo")["Foo"],
152 tags.a(href="bar")["Bar"],
153 tags.a(href="baz")["Baz"]])
154
155 def childFactory(self, ctx, name):
156 return Leaf(name)
157
158
159 def greet(ctx, name):
160 return "Hello. You are visiting the ", name, " page."
161
162 class Leaf(rend.Page):
163 docFactory = loaders.stan(tags.html[greet])
164
165 Armed with this knowledge and the information in the Object Traversal
166 documentation, we now have enough information to create dynamic websites with
167 arbitrary URL hierarchies whose pages render dynamically depending on which URL
168 was used to access them.
169
170 Accessing query parameters and form post data
171 ---------------------------------------------
172
173 Before we move on to more advanced rendering techniques, let us first examine
174 how one could further customize the rendering of a Page based on the URL query
175 parameters and form post information provided to us by a browser. Recall that
176 URL parameters are expressed in the form::
177
178 http://example.com/foo/bar?baz=1&quux=2
179
180 And form post data can be generated by providing a form to a browser::
181
182 <form action="" method="POST">
183 <input type="text" name="baz" />
184 <input type="text" name="quux" />
185 <input type="submit" />
186 </form>
187
188 Accessing this information is such a common procedure that Nevow provides a
189 convenience method on the context to do it. Let's examine a simple page whose
190 output can be influenced by the query parameters in the URL used to access it::
191
192 def showChoice(ctx, data):
193 choice = ctx.arg('choice')
194 if choice is None:
195 return ''
196 return "You chose ", choice, "."
197
198 class Custom(rend.Page):
199 docFactory = loaders.stan(tags.html[
200 tags.a(href="?choice=baz")["Baz"],
201 tags.a(href="?choice=quux")["Quux"],
202 tags.p[showChoice]])
203
204 The procedure is exactly the same for simple form post information::
205
206 def greet(ctx, data):
207 name = ctx.arg('name')
208 if name is None:
209 return ''
210 return "Greetings, ", name, "!"
211
212 class Form(rend.Page):
213 docFactory = loaders.stan(tags.html[
214 tags.form(action="", method="POST")[
215 tags.input(name="name"),
216 tags.input(type="submit")],
217 greet])
218
219 Note that ctx.arg returns only the first argument with the given name. For
220 complex cases where multiple arguments and lists of argument values are
221 required, you can access the request argument dictionary directly using the
222 syntax::
223
224 def arguments(ctx, data):
225 args = inevow.IRequest(ctx).args
226 return "Request arguments are: ", str(args)
227
228 Generators in the DOM
229 ---------------------
230
231 One common operation when building dynamic pages is iterating a list of data and
232 emitting some HTML for each item. Python generators are well suited for
233 expressing this sort of logic, and code which is written as a python generator
234 can perform tests (if) and loops of various kinds (while, for) and emit a row of
235 html whenever it has enough data to do so. Nevow can handle generators in the
236 DOM just as gracefully as it can handle anything else::
237
238 >>> from nevow import rend, loaders, tags
239 >>> def generate(ctx, items):
240 ... for item in items:
241 ... yield tags.div[ item ]
242 ...
243 >>> class List(rend.Page):
244 ... docFactory = loaders.stan(tags.html[ generate ])
245 ...
246 >>> List(['one', 'two', 'three']).renderSynchronously()
247 '<html><div>one</div><div>two</div><div>three</div></html>'
248
249 As you can see, generating HTML inside of functions or generators can be very
250 convenient, and can lead to very rapid application development. However, it is
251 also what I would call a "template abstraction violation", and we will learn how
252 we can keep knowledge of HTML out of our python code when we learn about
253 patterns and slots.
254
255 Methods in the DOM
256 ------------------
257
258 Up until now, we have been placing our template manipulation logic inside of
259 simple Python functions and generators. However, it is often appropriate to use
260 a method instead of a function. Nevow makes it just as easy to use a method to
261 render HTML::
262
263 class MethodRender(rend.Page):
264 def __init__(self, foo):
265 self.foo = foo
266
267 def render_foo(self, ctx, data):
268 return self.foo
269
270 docFactory = loaders.stan(tags.html[ render_foo ])
271
272 Using render methods makes it possible to parameterize your Page class with more
273 parameters. With render methods, you can also use the Page instance as a state
274 machine to keep track of the state of the render. While Nevow is designed to
275 allow you to render the same Page instance repeatedly, it can also be convenient
276 to know that a Page instance will only be used one time, and that the Page
277 instance can be used as a scratch pad to manage information about the render.
278
279 Data specials
280 -------------
281
282 Previously we saw how passing a parameter to the default Page constructor makes
283 it available as the "data" parameter to all of our render methods. This "data"
284 parameter can change as the page render proceeds, and is a useful way to ensure
285 that render functions are isolated and only act upon the data which is available
286 to them. Render functions which do not pull information from sources other than
287 the "data" parameter are more easily reusable and can be composed into larger
288 parts more easily.
289
290 Deciding which data gets passed as the data parameter is as simple as changing
291 the "Data special" for a Tag. See the Glossary under "Tag Specials" for more
292 information about specials. Assigning to the data special is as simple as
293 assigning to a tag attribute::
294
295 >>> def hello(ctx, name):
296 ... return "Hello, ", name
297 ...
298 >>> class DataSpecial(rend.Page):
299 ... docFactory = loaders.stan(tags.html[
300 ... tags.div(data="foo")[ hello ],
301 ... tags.div(data="bar")[ hello ]])
302 ...
303 >>> DataSpecial().renderSynchronously()
304 '<html><div>Hello, foo</div><div>Hello, bar</div></html>'
305
306 Data specials may be assigned any python value. Data specials are only in scope
307 during the rendering of the tag they are assigned to, so if the "hello" renderer
308 were placed in the DOM inside the html node directly, "Hello, None" would be
309 output.
310
311 Before data is passed to a render function, Nevow first checks to see if there
312 is an IGettable adapter for it. If there is, it calls IGettable.get(), and
313 passes the result of this as the data parameter instead. Nevow includes an
314 IGettable adapter for python functions, which means you can set a Tag data
315 special to a function reference and Nevow will call it to obtain the data when
316 the Tag is rendered. The signature for data methods is similar to that of render
317 methods, (ctx, data). For example::
318
319 def getName(ctx, data):
320 return ctx.arg('name')
321
322 def greet(ctx, name):
323 return "Greetings, ", name
324
325 class GreetName(rend.Page):
326 docFactory = loaders.stan(tags.html[
327 tags.form(action="")[
328 tags.input(name="name"),
329 tags.input(type="submit")],
330 tags.div(data=getName)[ greet ]])
331
332 Data specials exist mainly to allow you to construct and enforce a
333 Model-View-Controller style separation of the Model code from the View. Here we
334 see that the greet function is capable of rendering a greeting view for a name
335 model, and that the implementation of getName may change without the view code
336 changing.
337
338 Render specials
339 ---------------
340
341 Previously, we have seen how render functions can be placed directly in the DOM,
342 and the return value replaces the render function in the DOM. However, these
343 free functions and methods are devoid of any contextual information about the
344 template they are living in. The render special is a way to associate a render
345 function or method with a particular Tag instance, which the render function can
346 then examine to decide how to render::
347
348 >>> def alignment(ctx, data):
349 ... align = ctx.tag.attributes.get('align')
350 ... if align == 'right':
351 ... return ctx.tag["Aligned right"]
352 ... elif align == 'center':
353 ... return ctx.tag["Aligned center"]
354 ... else:
355 ... return ctx.tag["Aligned left"]
356 ...
357 >>> class AlignmentPage(rend.Page):
358 ... docFactory = loaders.stan(tags.html[
359 ... tags.p(render=alignment),
发表评论
-
Trac Data Models and Schema
2010-09-15 10:56 6356The main models that developers ... -
在Mac OS上运行wxPython
2010-09-14 15:42 3215如果在一个64位的Mac上跑wxPython, 将会出现以下错 ... -
Trac SQL Database API
2010-09-14 13:41 1044Trac SQL Database API Trac use ... -
Trac系统相关文档
2010-02-01 12:53 10571. Trac组件架构 http://trac.edgewal ... -
Django上传文件
2009-11-26 18:06 1356之前写了一个上传文件模块,但是当文件很大时就会挂掉,分析了一下 ... -
50个Python重要模块
2009-10-20 09:32 1988原文地址:http://www.cnblogs.com/yd1 ... -
Trac系统的双重认证
2009-10-20 09:27 1144首先,需要导入urllib2及cookielib。 然后,关键 ... -
分享一个图表制作库
2009-06-18 15:15 1314该包名为ChartDirector,可以从其官方主页http: ... -
django newforms的更改
2009-06-16 13:34 1058Django升级之后,有一些应用包的名称也相应发生了变化,比如 ... -
Python版支付宝集成插件源代码
2009-05-08 15:34 4920之前在做一项目的时候需要集成支付宝功能,网站是用python做 ... -
Django多语言问题
2009-05-06 17:22 1912最近多Django比较感兴趣,打算用它来做一个网站,看了官方关 ... -
Installing Satchmo on Webfaction
2009-04-29 15:39 1655link: http://brianmckinney.net/ ... -
Satchmo配置注意事项
2009-04-25 16:10 1029Satchmo在同步数据库之后,在操作后台管理页面过程中,一直 ... -
Yaml与python类型的对照表
2009-04-22 23:03 1700因为常用yaml作为python程序的配置文件,特将其与pyt ... -
satchmo汉化
2009-04-21 15:21 1907转载:http://blog.csdn.net/huliuhe ... -
python模块之smtplib: 用python发送SSL/TLS安全邮件
2008-07-04 19:08 9462原文出自 http://blog.csdn.net/zhaow ... -
python模块之poplib: 用pop3收取邮件
2008-07-04 19:09 2204python的poplib模块是用来 ... -
python模块之email: 电子邮件编码解码 (转)
2008-07-04 19:11 3504用email模块来生成邮件也是很简单的,只是需要一些mime的 ... -
用iconv做通用的语言编码转换(转)
2008-07-04 19:13 1376#include <stdio.h> #in ... -
python模块之email: 电子邮件编码解码(转)
2008-07-04 19:16 3286出处:http://blog.csdn.net/zhaowei ...
相关推荐
XNA RenderState 3.0转4.0
render函数 ...但是,在特殊情况下,这种写死的模式无法满足需求,必须需要js的编程能力。...//未使用render函数 Vue.component('anchored-heading', { template: '#anchored-heading-template', props: { level:
现在我们将深入探讨如何在DataTables中结合使用`render` 和 `moment.js` 进行日期转换。 首先,`DataTables` 提供的`render` 函数让我们能够对表格中每一列的数据进行定制化处理。例如,如果你的原始数据源中的日期...
一键将角色的Animator或Animation去掉,将SkinnedMeshRender更换为一般的Mesh Render,完成将动画效果的实现从CPU转移到GPU运算的目的,来利用GPU Instancing技术减少Draw Call。 • Convert assets quickly and ...
通常,你需要先加载一个三维模型(如`.obj`文件),然后使用`pyrender.Mesh.from_trimesh()`方法创建一个Mesh对象,并与材质一起关联。例如,你可以创建一个具有金属质感和粗糙度的材质,然后将其附加到Mesh对象上。...
**使用方法** 要使用 JsRender,首先需要在页面中引入 `jsrender.js` 或 `jsrender.min.js` 文件。然后,你可以创建一个新的模板实例,如下所示: ```javascript var tmpl = $.templates("Hello, {{:name}}!"); ``...
为您列举一些renderDoc方面的下载的内容,renderdoc教程、render doc安装、renderdoc plugin等资源。把最新最全的renderDoc推荐给您,让您轻松找到相关应用信息,并提供renderDoc下载等功能。本站致力于为用户提供更好...
使用这个插件,开发者可以直接通过 jQuery 对象调用 `$.render` 或 `$.templates` 方法来注册和渲染模板。 在实际应用中,开发者通常会先引入 jQuery 和 jQuery-jsrender.js,然后定义模板,接着绑定数据并渲染到...
RenderDoc_1.8_64,Window版本,官网也可以下载,但是网速慢。上传CSDN方便后续使用。
Vue 中 render 函数的使用方法 在 Vue 中,render 函数是一种强大的工具,允许开发者使用 JavaScript 代码动态生成 HTML 内容。今天,我们将深入探讨 render 函数的使用方法,並探讨它在实际开发中的应用场景。 ...
在本文中,我们将详细探讨`render`属性在RichFaces 4中的使用,特别是如何利用它来更新页面上的特定区域。 `render`属性通常用于AJAX(异步JavaScript和XML)操作,它允许我们在用户与页面交互时,只更新页面的某些...
JsRender与jQuery库相独立,但可以与jQuery结合使用,为Web应用提供更高效的UI更新。 **JsRender的核心特性** 1. **模板语法**: JsRender 使用 `{{ }}` 符号作为模板标记,使得模板代码在HTML中清晰易读。例如,`{...
在Vue.js框架中,`props`是父组件向子组件传递数据的一种机制,而`render`函数则是Vue中用于自定义渲染逻辑的关键工具。...同时,`render`函数也是Vue.js高级用法的一部分,对于深入理解和优化Vue应用具有重要意义。
**JSRender:强大的JavaScript模板引擎** JSRender是一个轻量级但功能强大的JavaScript模板引擎,它由Microsoft的MVC团队成员Boris Moore开发。这个库旨在提供一个简洁、高效的模板解决方案,用于生成动态HTML和XML...
WPF使用一种基于XAML(Extensible Application Markup Language)的声明性方法来构建用户界面,而渲染过程则是将这些XAML元素转化为屏幕上可见的图形。在这个“WPF渲染Render范例C#代码”中,我们将探讨如何通过C#...
5. README:这是项目说明文件,通常包含了项目的简介、安装指南、使用示例、贡献方法等重要信息。对于理解和使用htmlrender库来说,README文件是必不可少的资源。 在实际使用htmlrender时,开发者首先需要将其集成...
2. **RenderFeature生命周期**:掌握`OnEnable`,`OnDisable`,`OnExecute`等生命周期方法,知道在何时何地执行自定义的渲染逻辑。 3. **渲染队列管理**:理解如何通过`renderQueue`设置渲染顺序,以确保不同的特效...
table.render({ id : 'table', type:'post', elem : '#table', url : url, where : {'Id' : $data.Id}, page:false, cols : [ [ //表头 ]] }) 最简单直接用ajax请求,确保url路径正确 $.ajax({ dataType:'...
主要介绍了element-ui table组件如何使用render属性的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
标题中的“DEMO_2_RENDER.rar”是一个压缩文件,它包含了一个3D GDI(Graphics Device Interface)演示程序,主要用于展示如何在Windows环境下使用C++和GDI技术来实现3D地形的渲染。"3D GDI_DEMO_render_terrian_...