This file is indexed.

/usr/share/doc/python-nevow/howto/publishing.html is in python-nevow 0.10.0-4build1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE html  PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN'  'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html lang="en" xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>
      Nevow:
    
      Object Publishing
    </title>
    <link href="stylesheet.css" rel="stylesheet" type="text/css"/>
  </head>

  <body bgcolor="white">
    <h1 class="title">
      Object Publishing
    </h1>
    <div class="toc"><ol><li><a href="#auto0">The stan DOM</a></li><li><a href="#auto1">Tag instances</a></li><li><a href="#auto2">Functions in the DOM</a></li><li><a href="#auto3">Accessing query parameters and form post data</a></li><li><a href="#auto4">Generators in the DOM</a></li><li><a href="#auto5">Methods in the DOM</a></li><li><a href="#auto6">Data specials</a></li><li><a href="#auto7">Render specials</a></li><li><a href="#auto8">Pattern specials</a></li><li><a href="#auto9">Slot specials</a></li><li><a href="#auto10">Data directives</a></li><li><a href="#auto11">Render directives</a></li><li><a href="#auto12">Flatteners</a></li></ol></div>
    <div class="content">
    <span/>

    <p>
      In <a href="traversal.html" shape="rect">Object Traversal</a>, we learned about the
      <code class="API"><a href="nevow.inevow.IResource.renderHTTP" title="nevow.inevow.IResource.renderHTTP">nevow.inevow.IResource.renderHTTP</a></code> method, which
      is the most basic way to send HTML to a browser when using
      Nevow. However, it is not very convenient (or clean) to generate HTML
      tags by concatenating strings in Python code. In the <a href="deployment.html" shape="rect">Deployment</a> documentation, we saw that it was
      possible to render a <em>Hello World</em> page using a <code class="API"><a href="
" title="
">
      nevow.rend.Page</a></code> subclass and providing a <code>docFactory</code>:
    </p>

    <pre class="python-interpreter" xml:space="preserve">
&gt;&gt;&gt; from nevow import rend, loaders
&gt;&gt;&gt; class HelloWorld(rend.Page):
...     docFactory = loaders.stan(&quot;Hello, world!&quot;)
...
&gt;&gt;&gt; HelloWorld().renderSynchronously()
'Hello, world!'</pre>

    <p>
      This example does nothing interesting, but the concept of a loader is
      important in Nevow. The <code>rend.Page.renderHTTP</code> implementation
      always starts rendering HTML by loading a template from the
      <code>docFactory</code>.
    </p>


    <h2>The stan DOM<a name="auto0"/></h2>

    <p>
      Nevow uses a DOM-based approach to rendering HTML. A tree of objects is
      first constructed in memory by the template loader. This tree is then
      processed one node at a time, applying functions which transform from
      various Python types to HTML strings.
    </p>

    <p>
      Nevow uses a nonstandard DOM named &quot;stan&quot;. Unlike the W3C DOM, stan is
      made up of simple python lists, strings, and instances of the
      nevow.stan.Tag class.  During the rendering process, &quot;Flattener&quot;
      functions convert from rich types to HTML strings. For example, we can
      load a template made up of some nested lists and Python types, render it,
      and see what happens:
    </p>

    <pre class="python-interpreter" xml:space="preserve">
&gt;&gt;&gt; class PythonTypes(rend.Page):
...     docFactory = loaders.stan([&quot;Hello&quot;, 1, 1.5, True, [&quot;Goodbye&quot;, 3]])
...
&gt;&gt;&gt; PythonTypes().renderSynchronously()
'Hello11.5TrueGoodbye3'</pre>

    <h2>Tag instances<a name="auto1"/></h2>

    <p>
      So far, we have only rendered simple strings as output. However, the main
      purpose of Nevow is HTML generation. In the stan DOM, HTML tags are
      represented by instances of the <code class="API"><a href="nevow.stan.Tag" title="nevow.stan.Tag">nevow.stan.Tag</a></code>
      class. <code>Tag</code> is a very simple class, whose instances have an
      <code>attributes</code> dictionary and a <code>children</code> list. The
      <code>Tag</code> flattener knows how to recursively flatten attributes
      and children of the tag.  To show you how <code>Tag</code>s really work
      before you layer Nevow's convenience syntax on top, try this horrible
      example:
    </p>

    <pre class="python-interpreter" xml:space="preserve">
&gt;&gt;&gt; from nevow import stan
&gt;&gt;&gt; h = stan.Tag('html')
&gt;&gt;&gt; d = stan.Tag('div')
&gt;&gt;&gt; d.attributes['style'] = 'border: 1px solid black'
&gt;&gt;&gt; h.children.append(d)
&gt;&gt;&gt; class Tags(rend.Page):
...     docFactory = loaders.stan(h)
...
&gt;&gt;&gt; Tags().renderSynchronously()
'&lt;html&gt;&lt;div style=&quot;border: 1px solid black&quot;&gt;&lt;/div&gt;&lt;/html&gt;'</pre>

    <p>
      So, we see how it is possible to programatically generate HTML by
      constructing and nesting stan <code>Tag</code> instances. However, it is
      far more convenient to use the overloaded operators <code>Tag</code>
      provides to manipulate them. <code>Tag</code> implements a
      <code>__call__</code> method which takes any keyword arguments and values
      and updates the attributes dictionary; it also implements a
      <code>__getitem__</code> method which takes whatever is between the square
      brackets and appends them to the children list. A simple example should
      clarify things:
    </p>

    <pre class="python-interpreter" xml:space="preserve">
&gt;&gt;&gt; class Tags2(rend.Page):
...     docFactory = loaders.stan(stan.Tag('html')[stan.Tag('div')(style=&quot;border: 1px solid black&quot;)])
...
&gt;&gt;&gt; Tags2().renderSynchronously()
'&lt;html&gt;&lt;div style=&quot;border: 1px solid black&quot;&gt;&lt;/div&gt;&lt;/html&gt;'</pre>

    <p>
      This isn't very easy to read, but luckily we can simplify the example
      even further by using the nevow.tags module, which is full of &quot;Tag
      prototypes&quot; for every tag type described by the XHTML 1.0 specification:
    </p>

    <pre class="python-interpreter" xml:space="preserve">
&gt;&gt;&gt; class Tags3(rend.Page):
...     docFactory = loaders.stan(tags.html[tags.div(style=&quot;border: 1px solid black&quot;)])
...
&gt;&gt;&gt; Tags3().renderSynchronously()
'&lt;html&gt;&lt;div style=&quot;border: 1px solid black&quot;&gt;&lt;/div&gt;&lt;/html&gt;'</pre>

    <p>
      Using stan syntax is not the only way to construct template DOM for use
      by the Nevow rendering process. Nevow also includes <code class="API"><a href="nevow.loaders.xmlfile" title="nevow.loaders.xmlfile">loaders.xmlfile</a></code> which implements a simple tag
      attribute language similar to the Zope Page Templates (ZPT) Tag Attribute
      Language (TAL). However, experience with the stan DOM should give you
      insight into how the Nevow rendering process really works. Rendering a
      template into HTML in Nevow is really nothing more than iterating a tree
      of objects and recursively applying &quot;Flattener&quot; functions to objects in
      this tree, until all HTML has been generated.
    </p>

    <h2>Functions in the DOM<a name="auto2"/></h2>

    <p>
      So far, all of our examples have generated static HTML pages, which is
      not terribly interesting when discussing dynamic web applications. Nevow
      takes a very simple approach to dynamic HTML generation. If you put a
      Python function reference in the DOM, Nevow will call it when the page is
      rendered. The return value of the function replaces the function itself
      in the DOM, and the results are flattened further. This makes it easy to
      express looping and branching structures in Nevow, because normal Python
      looping and branching constructs are used to do the job:
    </p>

    <pre class="python-interpreter" xml:space="preserve">
&gt;&gt;&gt; def repeat(ctx, data):
...     return [tags.div(style=&quot;color: %s&quot; % (color, ))
...         for color in ['red', 'blue', 'green']]
...
&gt;&gt;&gt; class Repeat(rend.Page):
...     docFactory = loaders.stan(tags.html[repeat])
...
&gt;&gt;&gt; Repeat().renderSynchronously()
'&lt;html&gt;&lt;div style=&quot;color: red&quot;&gt;&lt;/div&gt;&lt;div style=&quot;color: blue&quot;&gt;&lt;/div&gt;&lt;div style=&quot;color: green&quot;&gt;&lt;/div&gt;&lt;/html&gt;'</pre>

    <p>
      However, in the example above, the repeat function isn't even necessary,
      because we could have inlined the list comprehension right where we
      placed the function reference in the DOM. Things only really become
      interesting when we begin writing parameterized render functions which
      cause templates to render differently depending on the input to the web
      application.
    </p>

    <p>
      The required signature of functions which we can place in the DOM is
      (ctx, data). The &quot;context&quot; object is essentially opaque for now, and we
      will learn how to extract useful information out of it later. The &quot;data&quot;
      object is anything we want it to be, and can change during the rendering
      of the page. By default, the data object is whatever we pass as the first
      argument to the Page constructor, <em>or</em> the Page instance itself if
      nothing is passed. Armed with this knowledge, we can create a Page which
      renders differently depending on the data we pass to the Page
      constructor:
    </p>

    <pre class="python"><p class="py-linenumber"> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
</p><span class="py-src-keyword">class</span> <span class="py-src-identifier">Root</span>(<span class="py-src-parameter">rend</span>.<span class="py-src-parameter">Page</span>):
    <span class="py-src-variable">docFactory</span> = <span class="py-src-variable">loaders</span>.<span class="py-src-variable">stan</span>(<span class="py-src-variable">tags</span>.<span class="py-src-variable">html</span>[
        <span class="py-src-variable">tags</span>.<span class="py-src-variable">h1</span>[<span class="py-src-string">&quot;Welcome.&quot;</span>],
        <span class="py-src-variable">tags</span>.<span class="py-src-variable">a</span>(<span class="py-src-variable">href</span>=<span class="py-src-string">&quot;foo&quot;</span>)[<span class="py-src-string">&quot;Foo&quot;</span>],
        <span class="py-src-variable">tags</span>.<span class="py-src-variable">a</span>(<span class="py-src-variable">href</span>=<span class="py-src-string">&quot;bar&quot;</span>)[<span class="py-src-string">&quot;Bar&quot;</span>],
        <span class="py-src-variable">tags</span>.<span class="py-src-variable">a</span>(<span class="py-src-variable">href</span>=<span class="py-src-string">&quot;baz&quot;</span>)[<span class="py-src-string">&quot;Baz&quot;</span>]])

    <span class="py-src-keyword">def</span> <span class="py-src-identifier">childFactory</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">ctx</span>, <span class="py-src-parameter">name</span>):
        <span class="py-src-keyword">return</span> <span class="py-src-variable">Leaf</span>(<span class="py-src-variable">name</span>)

<span class="py-src-keyword">def</span> <span class="py-src-identifier">greet</span>(<span class="py-src-parameter">ctx</span>, <span class="py-src-parameter">name</span>):
    <span class="py-src-keyword">return</span> <span class="py-src-string">&quot;Hello. You are visiting the &quot;</span>, <span class="py-src-variable">name</span>, <span class="py-src-string">&quot; page.&quot;</span>

<span class="py-src-keyword">class</span> <span class="py-src-identifier">Leaf</span>(<span class="py-src-parameter">rend</span>.<span class="py-src-parameter">Page</span>):
    <span class="py-src-variable">docFactory</span> = <span class="py-src-variable">loaders</span>.<span class="py-src-variable">stan</span>(<span class="py-src-variable">tags</span>.<span class="py-src-variable">html</span>[<span class="py-src-variable">greet</span>])
</pre>

    <p>
      Armed with this knowledge and the information in the <a href="traversal.html" shape="rect">Object Traversal</a> documentation, we now have
      enough information to create dynamic websites with arbitrary URL
      hierarchies whose pages render dynamically depending on which URL was
      used to access them.
    </p>

    <h2>Accessing query parameters and form post data<a name="auto3"/></h2>

    <p>
      Before we move on to more advanced rendering techniques, let us first
      examine how one could further customize the rendering of a Page based on
      the URL query parameters and form post information provided to us by a
      browser. Recall that URL parameters are expressed in the form:
    </p>

    <pre xml:space="preserve">http://example.com/foo/bar?baz=1&amp;quux=2</pre>

    <p>
      And form post data can be generated by providing a form to a browser:
    </p>

    <pre xml:space="preserve">
&lt;form action=&quot;&quot; method=&quot;POST&quot;&gt;
  &lt;input type=&quot;text&quot; name=&quot;baz&quot; /&gt;
  &lt;input type=&quot;text&quot; name=&quot;quux&quot; /&gt;
  &lt;input type=&quot;submit&quot; /&gt;
&lt;/form&gt;</pre>

    <p>
      Accessing this information is such a common procedure that Nevow provides
      a convenience method on the context to do it. Let's examine a simple page
      whose output can be influenced by the query parameters in the URL used to
      access it:
    </p>

    <pre class="python"><p class="py-linenumber"> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
</p><span class="py-src-keyword">def</span> <span class="py-src-identifier">showChoice</span>(<span class="py-src-parameter">ctx</span>, <span class="py-src-parameter">data</span>):
    <span class="py-src-variable">choice</span> = <span class="py-src-variable">ctx</span>.<span class="py-src-variable">arg</span>(<span class="py-src-string">'choice'</span>)
    <span class="py-src-keyword">if</span> <span class="py-src-variable">choice</span> <span class="py-src-keyword">is</span> <span class="py-src-variable">None</span>:
        <span class="py-src-keyword">return</span> <span class="py-src-string">''</span>
    <span class="py-src-keyword">return</span> <span class="py-src-string">&quot;You chose &quot;</span>, <span class="py-src-variable">choice</span>, <span class="py-src-string">&quot;.&quot;</span>

<span class="py-src-keyword">class</span> <span class="py-src-identifier">Custom</span>(<span class="py-src-parameter">rend</span>.<span class="py-src-parameter">Page</span>):
    <span class="py-src-variable">docFactory</span> = <span class="py-src-variable">loaders</span>.<span class="py-src-variable">stan</span>(<span class="py-src-variable">tags</span>.<span class="py-src-variable">html</span>[
        <span class="py-src-variable">tags</span>.<span class="py-src-variable">a</span>(<span class="py-src-variable">href</span>=<span class="py-src-string">&quot;?choice=baz&quot;</span>)[<span class="py-src-string">&quot;Baz&quot;</span>],
        <span class="py-src-variable">tags</span>.<span class="py-src-variable">a</span>(<span class="py-src-variable">href</span>=<span class="py-src-string">&quot;?choice=quux&quot;</span>)[<span class="py-src-string">&quot;Quux&quot;</span>],
        <span class="py-src-variable">tags</span>.<span class="py-src-variable">p</span>[<span class="py-src-variable">showChoice</span>]])
</pre>

    <p>
      The procedure is exactly the same for simple form post information:
    </p>

    <pre class="python"><p class="py-linenumber"> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
</p><span class="py-src-keyword">def</span> <span class="py-src-identifier">greet</span>(<span class="py-src-parameter">ctx</span>, <span class="py-src-parameter">data</span>):
    <span class="py-src-variable">name</span> = <span class="py-src-variable">ctx</span>.<span class="py-src-variable">arg</span>(<span class="py-src-string">'name'</span>)
    <span class="py-src-keyword">if</span> <span class="py-src-variable">name</span> <span class="py-src-keyword">is</span> <span class="py-src-variable">None</span>:
        <span class="py-src-keyword">return</span> <span class="py-src-string">''</span>
    <span class="py-src-keyword">return</span> <span class="py-src-string">&quot;Greetings, &quot;</span>, <span class="py-src-variable">name</span>, <span class="py-src-string">&quot;!&quot;</span>

<span class="py-src-keyword">class</span> <span class="py-src-identifier">Form</span>(<span class="py-src-parameter">rend</span>.<span class="py-src-parameter">Page</span>):
    <span class="py-src-variable">docFactory</span> = <span class="py-src-variable">loaders</span>.<span class="py-src-variable">stan</span>(<span class="py-src-variable">tags</span>.<span class="py-src-variable">html</span>[
        <span class="py-src-variable">tags</span>.<span class="py-src-variable">form</span>(<span class="py-src-variable">action</span>=<span class="py-src-string">&quot;&quot;</span>, <span class="py-src-variable">method</span>=<span class="py-src-string">&quot;POST&quot;</span>)[
            <span class="py-src-variable">tags</span>.<span class="py-src-variable">input</span>(<span class="py-src-variable">name</span>=<span class="py-src-string">&quot;name&quot;</span>),
            <span class="py-src-variable">tags</span>.<span class="py-src-variable">input</span>(<span class="py-src-variable">type</span>=<span class="py-src-string">&quot;submit&quot;</span>)],
        <span class="py-src-variable">greet</span>])
</pre>

    <p>
      Note that <code>ctx.arg</code> returns only the first argument with the
      given name. For complex cases where multiple arguments and lists of
      argument values are required, you can access the request argument
      dictionary directly using the syntax:
    </p>

    <pre class="python"><p class="py-linenumber">1
2
3
</p><span class="py-src-keyword">def</span> <span class="py-src-identifier">arguments</span>(<span class="py-src-parameter">ctx</span>, <span class="py-src-parameter">data</span>):
    <span class="py-src-variable">args</span> = <span class="py-src-variable">inevow</span>.<span class="py-src-variable">IRequest</span>(<span class="py-src-variable">ctx</span>).<span class="py-src-variable">args</span>
    <span class="py-src-keyword">return</span> <span class="py-src-string">&quot;Request arguments are: &quot;</span>, <span class="py-src-variable">str</span>(<span class="py-src-variable">args</span>)
</pre>

    <h2>Generators in the DOM<a name="auto4"/></h2>

    <p>
      One common operation when building dynamic pages is iterating a list of
      data and emitting some HTML for each item. Python generators are well
      suited for expressing this sort of logic, and code which is written as a
      python generator can perform tests (<code>if</code>) and loops of various
      kinds (<code>while</code>, <code>for</code>) and emit a row of html
      whenever it has enough data to do so. Nevow can handle generators in the
      DOM just as gracefully as it can handle anything else:
    </p>

    <pre class="python-interpreter" xml:space="preserve">
&gt;&gt;&gt; from nevow import rend, loaders, tags
&gt;&gt;&gt; def generate(ctx, items):
...     for item in items:
...         yield tags.div[ item ]
...
&gt;&gt;&gt; class List(rend.Page):
...     docFactory = loaders.stan(tags.html[ generate ])
...
&gt;&gt;&gt; List(['one', 'two', 'three']).renderSynchronously()
'&lt;html&gt;&lt;div&gt;one&lt;/div&gt;&lt;div&gt;two&lt;/div&gt;&lt;div&gt;three&lt;/div&gt;&lt;/html&gt;'</pre>

    <p>
      As you can see, generating HTML inside of functions or generators can be
      very convenient, and can lead to very rapid application
      development. However, it is also what I would call a &quot;template
      abstraction violation&quot;, and we will learn how we can keep knowledge of
      HTML out of our python code when we learn about patterns and slots.
    </p>

    <h2>Methods in the DOM<a name="auto5"/></h2>

    <p>
      Up until now, we have been placing our template manipulation logic inside
      of simple Python functions and generators. However, it is often
      appropriate to use a method instead of a function. Nevow makes it just as
      easy to use a method to render HTML:
    </p>

    <pre class="python"><p class="py-linenumber">1
2
3
4
5
6
7
8
</p><span class="py-src-keyword">class</span> <span class="py-src-identifier">MethodRender</span>(<span class="py-src-parameter">rend</span>.<span class="py-src-parameter">Page</span>):
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">__init__</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">foo</span>):
        <span class="py-src-variable">self</span>.<span class="py-src-variable">foo</span> = <span class="py-src-variable">foo</span>

    <span class="py-src-keyword">def</span> <span class="py-src-identifier">render_foo</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">ctx</span>, <span class="py-src-parameter">data</span>):
        <span class="py-src-keyword">return</span> <span class="py-src-variable">self</span>.<span class="py-src-variable">foo</span>

    <span class="py-src-variable">docFactory</span> = <span class="py-src-variable">loaders</span>.<span class="py-src-variable">stan</span>(<span class="py-src-variable">tags</span>.<span class="py-src-variable">html</span>[ <span class="py-src-variable">render_foo</span> ])
</pre>

    <p>
      Using render methods makes it possible to parameterize your Page class
      with more parameters. With render methods, you can also use the Page
      instance as a state machine to keep track of the state of the
      render. While Nevow is designed to allow you to render the same Page
      instance repeatedly, it can also be convenient to know that a Page
      instance will only be used one time, and that the Page instance can be
      used as a scratch pad to manage information about the render.
    </p>

    <h2>Data specials<a name="auto6"/></h2>

    <p>
      Previously we saw how passing a parameter to the default Page constructor
      makes it available as the &quot;data&quot; parameter to all of our render
      methods. This &quot;data&quot; parameter can change as the page render proceeds,
      and is a useful way to ensure that render functions are isolated and only
      act upon the data which is available to them. Render functions which do
      not pull information from sources other than the &quot;data&quot; parameter are
      more easily reusable and can be composed into larger parts more easily.
    </p>

    <p>
      Deciding which data gets passed as the data parameter is as simple as
      changing the &quot;Data special&quot; for a Tag. See the <a href="glossary.html" shape="rect">Glossary</a> under &quot;Tag Specials&quot; for more
      information about specials. Assigning to the data special is as simple as
      assigning to a tag attribute:
    </p>

    <pre class="python-interpreter" xml:space="preserve">
&gt;&gt;&gt; def hello(ctx, name):
...     return &quot;Hello, &quot;, name
...
&gt;&gt;&gt; class DataSpecial(rend.Page):
...     docFactory = loaders.stan(tags.html[
...     tags.div(data=&quot;foo&quot;)[ hello ],
...     tags.div(data=&quot;bar&quot;)[ hello ]])
...
&gt;&gt;&gt; DataSpecial().renderSynchronously()
'&lt;html&gt;&lt;div&gt;Hello, foo&lt;/div&gt;&lt;div&gt;Hello, bar&lt;/div&gt;&lt;/html&gt;'</pre>

    <p>
      Data specials may be assigned any python value. Data specials are only in
      scope during the rendering of the tag they are assigned to, so if the
      &quot;hello&quot; renderer were placed in the DOM inside the html node directly,
      &quot;Hello, None&quot; would be output.
    </p>

    <p>
      Before data is passed to a render function, Nevow first checks to see if
      there is an <code class="API"><a href="IGettable" title="IGettable">IGettable</a></code> adapter for it. If there
      is, it calls <code>IGettable.get()</code>, and passes the result of this
      as the data parameter instead. Nevow includes an <code>IGettable</code>
      adapter for python functions, which means you can set a Tag data special
      to a function reference and Nevow will call it to obtain the data when
      the Tag is rendered. The signature for data methods is similar to that of
      render methods, (ctx, data). For example:
    </p>

    <pre class="python"><p class="py-linenumber"> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
</p><span class="py-src-keyword">def</span> <span class="py-src-identifier">getName</span>(<span class="py-src-parameter">ctx</span>, <span class="py-src-parameter">data</span>):
    <span class="py-src-keyword">return</span> <span class="py-src-variable">ctx</span>.<span class="py-src-variable">arg</span>(<span class="py-src-string">'name'</span>)

<span class="py-src-keyword">def</span> <span class="py-src-identifier">greet</span>(<span class="py-src-parameter">ctx</span>, <span class="py-src-parameter">name</span>):
    <span class="py-src-keyword">return</span> <span class="py-src-string">&quot;Greetings, &quot;</span>, <span class="py-src-variable">name</span>

<span class="py-src-keyword">class</span> <span class="py-src-identifier">GreetName</span>(<span class="py-src-parameter">rend</span>.<span class="py-src-parameter">Page</span>):
    <span class="py-src-variable">docFactory</span> = <span class="py-src-variable">loaders</span>.<span class="py-src-variable">stan</span>(<span class="py-src-variable">tags</span>.<span class="py-src-variable">html</span>[
        <span class="py-src-variable">tags</span>.<span class="py-src-variable">form</span>(<span class="py-src-variable">action</span>=<span class="py-src-string">&quot;&quot;</span>)[
            <span class="py-src-variable">tags</span>.<span class="py-src-variable">input</span>(<span class="py-src-variable">name</span>=<span class="py-src-string">&quot;name&quot;</span>),
            <span class="py-src-variable">tags</span>.<span class="py-src-variable">input</span>(<span class="py-src-variable">type</span>=<span class="py-src-string">&quot;submit&quot;</span>)],
            <span class="py-src-variable">tags</span>.<span class="py-src-variable">div</span>(<span class="py-src-variable">data</span>=<span class="py-src-variable">getName</span>)[ <span class="py-src-variable">greet</span> ]])
</pre>

    <p>
      Data specials exist mainly to allow you to construct and enforce a
      Model-View-Controller style separation of the Model code from the
      View. Here we see that the greet function is capable of rendering a
      greeting view for a name model, and that the implementation of getName
      may change without the view code changing.
    </p>

    <h2>Render specials<a name="auto7"/></h2>

    <p>
      Previously, we have seen how render functions can be placed directly in
      the DOM, and the return value replaces the render function in the
      DOM. However, these free functions and methods are devoid of any
      contextual information about the template they are living in. The
      render special is a way to associate a render function or method with a
      particular Tag instance, which the render function can then examine to
      decide how to render:
    </p>

    <pre class="python-interpreter" xml:space="preserve">
&gt;&gt;&gt; def alignment(ctx, data):
...     align = ctx.tag.attributes.get('align')
...     if align == 'right':
...         return ctx.tag[&quot;Aligned right&quot;]
...     elif align == 'center':
...         return ctx.tag[&quot;Aligned center&quot;]
...     else:
...         return ctx.tag[&quot;Aligned left&quot;]
...
&gt;&gt;&gt; class AlignmentPage(rend.Page):
...     docFactory = loaders.stan(tags.html[
...     tags.p(render=alignment),
...     tags.p(render=alignment, align=&quot;center&quot;),
...     tags.p(render=alignment, align=&quot;right&quot;)])
...
&gt;&gt;&gt; AlignmentPage().renderSynchronously()
'&lt;html&gt;&lt;p&gt;Aligned left&lt;/p&gt;&lt;p align=&quot;center&quot;&gt;Aligned center&lt;/p&gt;&lt;p align=&quot;right&quot;&gt;Aligned right&lt;/p&gt;&lt;/html&gt;'</pre>

    <p>
      Note how the alignment renderer has access to the template node as
      <code>ctx.tag</code>. It can examine and change this node, and the return value of
      the render function replaces the original node in the DOM. Note that
      here we are returning the template node after changing it. We will see
      later how we can instead mutate the context and use slots so that the
      knowledge the renderer requires about the structure of the template is
      reduced even more.
    </p>

    <h2>Pattern specials<a name="auto8"/></h2>

    <p>
      When writing render methods, it is easy to inline the construction of
      Tag instances to generate HTML programatically. However, this creates a
      template abstraction violation, where part of the HTML which will show
      up in the final page output is hidden away inside of render methods
      instead of inside the template. Pattern specials are designed to avoid
      this problem. A node which has been tagged with a pattern special can
      then be located and copied by a render method. The render method does
      not need to know anything about the structure or location of the
      pattern, only it's name.
    </p>

    <p>
      We can rewrite our previous generator example so that the generator
      does not have to know what type of tag the template designer would like
      repeated for each item in the list:
    </p>

    <pre class="python-interpreter" xml:space="preserve">
&gt;&gt;&gt; from nevow import rend, loaders, tags, inevow
&gt;&gt;&gt; def generate(ctx, items):
...     pat = inevow.IQ(ctx).patternGenerator('item')
...     for item in items:
...         ctx.tag[ pat(data=item) ]
...     return ctx.tag
...
&gt;&gt;&gt; def string(ctx, item):
...     return ctx.tag[ str(item) ]
...
&gt;&gt;&gt; class List(rend.Page):
...     docFactory = loaders.stan(tags.html[
...     tags.ul(render=generate)[
...         tags.li(pattern=&quot;item&quot;, render=string)]])
...
&gt;&gt;&gt; List([1, 2, 3]).renderSynchronously()
'&lt;html&gt;&lt;ol&gt;&lt;li&gt;1&lt;/li&gt;&lt;li&gt;2&lt;/li&gt;&lt;li&gt;3&lt;/li&gt;&lt;/ol&gt;&lt;/html&gt;'</pre>

    <p>
      Note that we have to mutate the tag in place and repeatedly copy the
      item pattern, applying the item as the data special to the resulting
      Tag. It turns out that this is such a common operation that nevow comes
      out of the box with these two render functions:
    </p>

    <pre class="python-interpreter" xml:space="preserve">
&gt;&gt;&gt; class List(rend.Page):
...     docFactory = loaders.stan(tags.html[
...     tags.ul(render=rend.sequence)[
...         tags.li(pattern=&quot;item&quot;, render=rend.data)]])
...
&gt;&gt;&gt; List([1, 2, 3]).renderSynchronously()
'&lt;html&gt;&lt;ul&gt;&lt;li&gt;1&lt;/li&gt;&lt;li&gt;2&lt;/li&gt;&lt;li&gt;3&lt;/li&gt;&lt;/ul&gt;&lt;/html&gt;'</pre>

    <h2>Slot specials<a name="auto9"/></h2>

    <p>
      The problem with render methods is that they are only capable of making
      changes to their direct children. Because of the architecture of Nevow,
      they should not attempt to change grandchildren or parent nodes. It is
      possible to write one render method for every node you wish to change,
      but there is a better way. A node with a slot special can be &quot;filled&quot;
      with content by any renderer above the slot. Creating a slot special is
      such a frequent task that there is a prototype in <code>nevow.tags</code>
      which is usually used.
    </p>

    <p>
      Let us examine a renderer which fills a template with information about
      a person:
    </p>

    <pre class="python-interpreter" xml:space="preserve">
&gt;&gt;&gt; from nevow import loaders, rend, tags
...
&gt;&gt;&gt; person = ('Donovan', 'Preston', 'Male', 'California')
...
&gt;&gt;&gt; def render_person(ctx, person):
...     firstName, lastName, sex, location = person
...     ctx.fillSlots('firstName', firstName)
...     ctx.fillSlots('lastName', lastName)
...     ctx.fillSlots('sex', sex)
...     ctx.fillSlots('location', location)
...     return ctx.tag
...
&gt;&gt;&gt; class PersonPage(rend.Page):
...     docFactory = loaders.stan(tags.html(render=render_person)[
...     tags.table[
...         tags.tr[
...             tags.td[tags.slot('firstName')],
...             tags.td[tags.slot('lastName')],
...             tags.td[tags.slot('sex')],
...             tags.td[tags.slot('location')]]]])
...
&gt;&gt;&gt; PersonPage(person).renderSynchronously()
'&lt;html&gt;&lt;table&gt;&lt;tr&gt;&lt;td&gt;Donovan&lt;/td&gt;&lt;td&gt;Preston&lt;/td&gt;&lt;td&gt;Male&lt;/td&gt;&lt;td&gt;California&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/html&gt;'</pre>

    <p>
      Using patterns in combination with slots can lead to very powerful
      template abstraction. Nevow also includes another standard renderer
      called &quot;mapping&quot; which takes any data which responds to the &quot;items()&quot;
      message and inserts the items into appropriate slots:
    </p>

    <pre class="python-interpreter" xml:space="preserve">
&gt;&gt;&gt; class DictPage(rend.Page):
...     docFactory = loaders.stan(tags.html(render=rend.mapping)[
...         tags.span[ tags.slot('foo') ], tags.span[ tags.slot('bar') ]])
...
&gt;&gt;&gt; DictPage(dict(foo=1, bar=2)).renderSynchronously()
'&lt;html&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;/html&gt;'</pre>

    <h2>Data directives<a name="auto10"/></h2>

    <p>
      So far, we have always placed data functions directly in the Data
      special attribute of a Tag. Sometimes, it is preferable to look up a
      data method from the Page class as the Page has being rendered. For
      example, a base class may define a template and a subclass may provide
      the implementation of the data method. We can accomplish this effect by
      using a data directive as a Tag's data special:
    </p>

    <pre class="python"><p class="py-linenumber">1
2
3
4
5
6
7
</p><span class="py-src-keyword">class</span> <span class="py-src-identifier">Base</span>(<span class="py-src-parameter">rend</span>.<span class="py-src-parameter">Page</span>):
    <span class="py-src-variable">docFactory</span> = <span class="py-src-variable">loaders</span>.<span class="py-src-variable">stan</span>(<span class="py-src-variable">tags</span>.<span class="py-src-variable">html</span>[
        <span class="py-src-variable">tags</span>.<span class="py-src-variable">div</span>(<span class="py-src-variable">data</span>=<span class="py-src-variable">tags</span>.<span class="py-src-variable">directive</span>(<span class="py-src-string">'name'</span>), <span class="py-src-variable">render</span>=<span class="py-src-variable">rend</span>.<span class="py-src-variable">data</span>)])

<span class="py-src-keyword">class</span> <span class="py-src-identifier">Subclass</span>(<span class="py-src-parameter">Base</span>):
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">data_name</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">ctx</span>, <span class="py-src-parameter">data</span>):
        <span class="py-src-keyword">return</span> <span class="py-src-string">&quot;Your name&quot;</span>
</pre>

    <p>
      The data directive is resolved by searching for the
      <code>IContainer</code> implementation in the context.
      <code>rend.Page</code> implements <code>IContainer.get</code> by
      performing an attribute lookup on the Page with the prefix 'data_*'. You
      can provide your own <code>IContainer</code> implementation if you wish,
      and also you should know that <code>IContainer</code> implementations for
      list and dict are included in the <code class="API"><a href="nevow.accessors" title="nevow.accessors">nevow.accessors</a></code>
      module.
    </p>

    <p>
      A common gotcha is that the closest <code>IContainer</code> is used to
      resolve data directives. This means that if a list is being used as the
      data during the rendering process, data directives below this will be
      resolved against the <code>IContainer</code> implementation in
      <code>nevow.accessors.ListAccessor</code>. If you are expecting a data
      directive to invoke a Page's data_* method but instead get a
      <code>KeyError</code>, this is why.
    </p>

    <h2>Render directives<a name="auto11"/></h2>

    <p>
      Render directives are almost exactly the same, except they are resolved
      using the closest <code>IRendererFactory</code> implementation in the
      context. Render directives can be used to allow subclasses to override
      certain render methods, and also can be used to allow Fragments to
      locate their own prefixed render methods.
    </p>

    <h2>Flatteners<a name="auto12"/></h2>

    <p>
      TODO This section isn't done yet.
    </p>

    <p>
      Nevow's flatteners use a type/function registry to determine how to
      render objects which Nevow encounters in the DOM during the rendering
      process.  &quot;Explicit is better than implicit&quot;, so in most cases,
      explicitly applying render methods to data will be better than
      registering a flattener, but in some cases it can be useful:
    </p>

    <pre class="python"><p class="py-linenumber"> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
</p><span class="py-src-keyword">class</span> <span class="py-src-identifier">Person</span>(<span class="py-src-parameter">object</span>):
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">__init__</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">firstName</span>, <span class="py-src-parameter">lastName</span>):
        <span class="py-src-variable">self</span>.<span class="py-src-variable">firstName</span> = <span class="py-src-variable">firstName</span>
        <span class="py-src-variable">self</span>.<span class="py-src-variable">lastName</span> = <span class="py-src-variable">lastName</span>

<span class="py-src-keyword">def</span> <span class="py-src-identifier">flattenPerson</span>(<span class="py-src-parameter">person</span>, <span class="py-src-parameter">ctx</span>):
    <span class="py-src-keyword">return</span> <span class="py-src-variable">flat</span>.<span class="py-src-variable">partialflatten</span>(<span class="py-src-variable">ctx</span>, (<span class="py-src-variable">person</span>.<span class="py-src-variable">firstName</span>, <span class="py-src-string">&quot; &quot;</span>, <span class="py-src-variable">person</span>.<span class="py-src-variable">lastName</span>))

<span class="py-src-keyword">from</span> <span class="py-src-variable">nevow</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">flat</span>
<span class="py-src-variable">flat</span>.<span class="py-src-variable">registerFlattener</span>(<span class="py-src-variable">flattenPerson</span>, <span class="py-src-variable">Person</span>)

<span class="py-src-keyword">def</span> <span class="py-src-identifier">insertData</span>(<span class="py-src-parameter">ctx</span>, <span class="py-src-parameter">data</span>):
    <span class="py-src-keyword">return</span> <span class="py-src-variable">data</span>

<span class="py-src-keyword">class</span> <span class="py-src-identifier">PersonPage</span>(<span class="py-src-parameter">rend</span>.<span class="py-src-parameter">Page</span>):
    <span class="py-src-variable">docFactory</span> = <span class="py-src-variable">loaders</span>.<span class="py-src-variable">stan</span>(<span class="py-src-variable">tags</span>.<span class="py-src-variable">html</span>[<span class="py-src-variable">insertData</span>])
</pre>
  </div>

    <p><a href="index.html">Index</a></p>
    <span class="version">Version: </span>
  </body>
</html>