FrontPage 

TB Wiki

Login

Regression Test

Expected HTML for page "DocProcessors"


expected html
nothing
t1 t
2<table align="right"><tr><td><div class="toc">
3Contents:
4<ul>
5  <li><a href="#Introduction">Introduction</a></li>
6  <li><a href="#Name_and_Location">Name&nbsp;and&nbsp;Location</a></li>
7  <li><a href="#Declaration_in_a_TBWiki_Page">Declaration&nbsp;in&nbsp;a&nbsp;TBWiki&nbsp;Page</a></li>
8  <li><a href="#Interface_from_TBWiki_to_the_processor">Interface&nbsp;from&nbsp;TBWiki&nbsp;to&nbsp;the&nbsp;processor</a></li>
9  <ul>
10    <li><a href="#main()_function">main()&nbsp;function</a></li>
11    <li><a href="#help()_function">help()&nbsp;function</a></li>
12    <li><a href="#other_functions_("action"_functions)">other&nbsp;functions&nbsp;("action"&nbsp;functions)</a></li>
13  </ul>
14  <li><a href="#Interface_from_the_processor_to_TBWiki">Interface&nbsp;from&nbsp;the&nbsp;processor&nbsp;to&nbsp;TBWiki</a></li>
15  <ul>
16    <li><a href="#request_object">request&nbsp;object</a></li>
17    <li><a href="#req_functions">req&nbsp;functions</a></li>
18    <li><a href="#tbwiki_functions">tbwiki&nbsp;functions</a></li>
19    <li><a href="#return_value">return&nbsp;value</a></li>
20  </ul>
21  <li><a href="#Example_Processor_-_FooReplace">Example&nbsp;Processor&nbsp;-&nbsp;FooReplace</a></li>
22  <ul>
23    <li><a href="#FooReplace_processor_code">FooReplace&nbsp;processor&nbsp;code</a></li>
24    <li><a href="#FooReplace_processor_invocation">FooReplace&nbsp;processor&nbsp;invocation</a></li>
25    <li><a href="#FooReplace_processor_result">FooReplace&nbsp;processor&nbsp;result</a></li>
26  </ul>
27  <li><a href="#Actions">Actions</a></li>
28  <ul>
29    <li><a href="#Action_invocation">Action&nbsp;invocation</a></li>
30    <ul>
31      <li><a href="#Reading_the_processor_block_content">Reading&nbsp;the&nbsp;processor&nbsp;block&nbsp;content</a></li>
32      <li><a href="#Reading_config_values">Reading&nbsp;config&nbsp;values</a></li>
33    </ul>
34    <li><a href="#Action_output">Action&nbsp;output</a></li>
35  </ul>
36  <li><a href="#Action_Sample_-_UserChoice">Action&nbsp;Sample&nbsp;-&nbsp;UserChoice</a></li>
37  <ul>
38    <li><a href="#UserChoice_processor_code">UserChoice&nbsp;processor&nbsp;code</a></li>
39    <li><a href="#UserChoice_processor_invocation">UserChoice&nbsp;processor&nbsp;invocation</a></li>
40    <li><a href="#UserChoice_processor_result">UserChoice&nbsp;processor&nbsp;result</a></li>
41    <li><a href="#UserChoice_processor_action_outcome">UserChoice&nbsp;processor&nbsp;action&nbsp;outcome</a></li>
42  </ul>
43</ul>
44</div></td></tr></table>
45<h1><a name="Introduction">Introduction</a>
46<span align=right class="section_edit_link">[<a href="/tbwiki/DocProcessors?action=edit&section=Introduction">edit section</a>]</font></span>
47</h1>
48TBWiki supports two kinds of extension mechanisms:  "macros" and "processors".
49<p>
50There are a few builtin macros, but add-on macros and processors
51can be created and are "run" when a page is parsed and sent by TBWiki.
52<p>
53The function of both of these extension mechanisms (or plugins) is
54to allow for dynamic creation of page content at the time a page
55is read by a user.  Thus, these act like a kind of embedded CGI-script
56inside of the TBWiki framework.
57<p>
58In general, Macros are used for simple transformations of content
59or for page-related content creation.  Processors are for doing
60more complicated processing of page or wiki data, possibly requiring
61configuration settings or multiple interactions with the user.
62<p>
63<h1><a name="Name_and_Location">Name and Location</a>
64<span align=right class="section_edit_link">[<a href="/tbwiki/DocProcessors?action=edit&section=Name_and_Location">edit section</a>]</font></span>
65</h1>
66By convention, the name of a processor is in CamelCase (words strung
67together with the first letter of each word capitalized).
68<p>
69Plugin processors are placed in the <code>data/plugin</code>
70directory.  They are python files and must have a filename starting with
71the "Processor", then the processor name, and ending in the extension
72".py".  For example the  "Foo" processor would have the path and filename
73<p>
74<code>/data/plugin/ProcessorFoo.py</code>
75<p>
76<h1><a name="Declaration_in_a_TBWiki_Page">Declaration in a TBWiki Page</a>
77<span align=right class="section_edit_link">[<a href="/tbwiki/DocProcessors?action=edit&section=Declaration_in_a_TBWiki_Page">edit section</a>]</font></span>
78</h1>
79A processor is declared on a tbwiki page with the syntax:
80<pre>
81{{{#!Foo
82configuration lines
83and content lines
84}} }
85</pre>
86<p>
87The processor name in the declaration must match the
88name part of the filename for the processor module
89in the plugin directory.  The lines inside the processor
90block can consist of anything, and are parsed and processed
91by the processor itself.  (That is, they are not interpreted
92by TBWiki engine, and are specific to the processor being invoked.)
93<p>
94<h1><a name="Interface_from_TBWiki_to_the_processor">Interface from TBWiki to the processor</a>
95<span align=right class="section_edit_link">[<a href="/tbwiki/DocProcessors?action=edit&section=Interface_from_TBWiki_to_the_processor">edit section</a>]</font></span>
96</h1>
97A processor must be an importable python module, with some specifically-named
98function definitions.  The TBWiki calls functions in the processor to perform
99actions, usually resulting the transformation or creation of new content that
100will be returned to the user as part of the page where the processor is
101declared.
102<p>
103<h2><a name="main()_function">main() function</a>
104<span align=right class="section_edit_link">[<a href="/tbwiki/DocProcessors?action=edit&section=main()_function">edit section</a>]</font></span>
105</h2>
106A processor must define a function called "main()".  As a page is rendered by TBWIKI, when the processor definition is encountered in the wiki page, TBWiki
107calls the 'main' function to invoke the processor functionality.
108<p>
109This "main" function takes two arguments, which are
110the request object and the content block string.
111<p>
112The processor operates on (i.e. processes) the content data, possibly using the
113information and functions provided in the request object, and
114returns a string of HTML data, for output as part of the returned page.
115<p>
116The block containing the processor declaration inside the page is
117replaced by TBWiki with the result of executing the processor.
118<p>
119<h2><a name="help()_function">help() function</a>
120<span align=right class="section_edit_link">[<a href="/tbwiki/DocProcessors?action=edit&section=help()_function">edit section</a>]</font></span>
121</h2>
122If a processor defines the special function "help()", then the system can
123provide online help for the processor, for a page displaying the SystemInfo.
124This function is accessed via a URL with the name: &lt;page_url&gt;?action=&lt;processor_name&gt;.help
125<p>
126<h2><a name="other_functions_("action"_functions)">other functions ("action" functions)</a>
127<span align=right class="section_edit_link">[<a href="/tbwiki/DocProcessors?action=edit&section=other_functions_("action"_functions)">edit section</a>]</font></span>
128</h2>
129In general, any of the functions in the processor can be accessed using
130a URL that includes the name of a page that declares the processor, the
131processor name, and the function name.  So if a page "Some_Page" had
132a declaration of processor "Foo" on it, that defined a function "bar", then
133the URL for causing the invocation of that function would be:
134<p>
135<pre>
136   ../SomePage?action=Foo.bar
137</pre>
138<p>
139These are referred to as "action functions" (or just "actions"), in this
140documentation.
141<p>
142Action functions are used to implement state machines or complex
143processors, which require multiple interactions with the user, or
144to display multiple pages in sequence (such as a blog or an image gallery).
145<p>
146See the <a href="#Actions">#Actions</a> section below for more details.
147<p>
148<h1><a name="Interface_from_the_processor_to_TBWiki">Interface from the processor to TBWiki</a>
149<span align=right class="section_edit_link">[<a href="/tbwiki/DocProcessors?action=edit&section=Interface_from_the_processor_to_TBWiki">edit section</a>]</font></span>
150</h1>
151<h2><a name="request_object">request object</a>
152<span align=right class="section_edit_link">[<a href="/tbwiki/DocProcessors?action=edit&section=request_object">edit section</a>]</font></span>
153</h2>
154The request object has all the data available to tbwiki about the request
155for this page.  This includes the page_name, the entire tbwiki config, and
156other stuff.
157<p>
158Here are some pertinent data fields that some processors use:
159<p>
160<ul><li>req.form = the CGI form data for the request (in the format provided by the python cgi module)
161</ul>
162<p>
163<ul><li>req.page_filename = filename (including full path) of the requested page
164<li>req.page_name = name of the requested page
165<li>req.config = configuration settings for the wiki
166<ul><li>req.config.data_dir = location in the local file system where the data
167     pages are located.
168</ul><li>req.data = data values (and data value functions) for this wiki
169<ul><li>req.data.version - version of the tbwiki engine
170<li>req.data.timestamp - timestamp string for the current time
171<li>and many more
172</ul>
173</ul>
174<p>
175<h2><a name="req_functions">req functions</a>
176<span align=right class="section_edit_link">[<a href="/tbwiki/DocProcessors?action=edit&section=req_functions">edit section</a>]</font></span>
177</h2>
178<ul><li>req.add_to_message() - a function to add to the status message for the page.
179   This is often used for debugging purposes, since it appears separately from
180   the page content
181<li>req.html_error() - show a string in red on the page
182<li>req.block_to_html() - convert a block of text from tbwiki markup to HTML
183<li>req.parse_conf() - used to parse configuration items from a block of text
184</ul>
185<p>
186<h2><a name="tbwiki_functions">tbwiki functions</a>
187<span align=right class="section_edit_link">[<a href="/tbwiki/DocProcessors?action=edit&section=tbwiki_functions">edit section</a>]</font></span>
188</h2>
189In some cases, it is necessary to load the tbwiki_engine module itself
190into the processor module, in order to access global module functions
191or data.  Here are some tbwiki_engine functions or data that might be useful
192for a processor:
193<ul><li>tbwiki_engine.make_url()
194<li>tbiki_engine.parse_state = state used for processing lines during page parsing
195<li>tbiki_engine.show_line() = function used to parse a line of TBWIKI-format text and convert it into HTML output (which is printed by show_line)
196</ul>
197<p>
198<h2><a name="return_value">return value</a>
199<span align=right class="section_edit_link">[<a href="/tbwiki/DocProcessors?action=edit&section=return_value">edit section</a>]</font></span>
200</h2>
201The processor's main() function should return a string consisting of HTML
202to be output as part of the returned page HTML.
203<p>
204If you want markup processed in the content string, you must process it
205yourself.  Usually, this means you would do whatever processing on the
206content is appropriate for your processor, then call
207req.block_to_html(content), and return the result of that.
208<p>
209<h1><a name="Example_Processor_-_FooReplace">Example Processor - FooReplace</a>
210<span align=right class="section_edit_link">[<a href="/tbwiki/DocProcessors?action=edit&section=Example_Processor_-_FooReplace">edit section</a>]</font></span>
211</h1>
212Here is sample code for a very simple processor:
213<p>
214<h2><a name="FooReplace_processor_code">FooReplace processor code</a>
215<span align=right class="section_edit_link">[<a href="/tbwiki/DocProcessors?action=edit&section=FooReplace_processor_code">edit section</a>]</font></span>
216</h2>
217This would be in the file ProcessorFooReplace.py
218<pre>
219import re
220 
221def main(req, content):
222        result = re.sub("foo", "bar", content)
223        return result
224</pre>
225<p>
226<h2><a name="FooReplace_processor_invocation">FooReplace processor invocation</a>
227<span align=right class="section_edit_link">[<a href="/tbwiki/DocProcessors?action=edit&section=FooReplace_processor_invocation">edit section</a>]</font></span>
228</h2>
229To use this processor, a user would place the following block on a page:
230<p>
231<pre>
232{{{#!FooReplace
233This text has foo, but it (foo) should be replaced with 'bar'.
234</pre>
235}}}
236<p>
237<h2><a name="FooReplace_processor_result">FooReplace processor result</a>
238<span align=right class="section_edit_link">[<a href="/tbwiki/DocProcessors?action=edit&section=FooReplace_processor_result">edit section</a>]</font></span>
239</h2>
240Here is what the resulting output would look like on the page:
241<p>
242<pre>
243This text has bar, but it (bar) should be replaced with 'bar'.
244</pre>
245<p>
246<h1><a name="Actions">Actions</a>
247<span align=right class="section_edit_link">[<a href="/tbwiki/DocProcessors?action=edit&section=Actions">edit section</a>]</font></span>
248</h1>
249You can cause the engine to invoke different functions in your processor.
250This is useful for handling a flow of operations requiring sequential
251displays or multiple user inputs.
252<p>
253To have the engine call a particular function in your processor,
254put the function name in the action portion of the the URL for some
255link, button or form element that is selected by the user for you system.
256The specific syntax is:
257<pre>
258   base_url/?action=&lt;processor_name&gt;.&lt;action&gt;
259</pre>
260<p>
261That is, specify the value for the 'action' argument in the URL
262as the processor name, followed by a period, followed by the name of
263the action function inside that processor to call.
264<p>
265<h2><a name="Action_invocation">Action invocation</a>
266<span align=right class="section_edit_link">[<a href="/tbwiki/DocProcessors?action=edit&section=Action_invocation">edit section</a>]</font></span>
267</h2>
268Action functions for your processor are invoked differently from
269the processor's <code>main()</code> function.
270<p>
271When an action function is specified in a URL to the TBWiki engine, the
272page in the URL is not rendered.  Instead, the processor is called,
273with the request object only.  If the content of the processor block is
274needed, or some other arguments are needed (e.g. passed from some other
275processor function to this one), then those need to loaded or transferred
276using some other mechanism.  This is usually done by passing session-specific
277arguments on the URL used to activate the action.
278<p>
279<h3><a name="Reading_the_processor_block_content">Reading the processor block content</a>
280<span align=right class="section_edit_link">[<a href="/tbwiki/DocProcessors?action=edit&section=Reading_the_processor_block_content">edit section</a>]</font></span>
281</h3>
282A action function does not receive the content block
283automatically, as one of its arguments.  However, it is common
284for an action function to need to read the content of the processor block.
285For example, the processor content block is often where the configuration
286for the processor is stored.
287<p>
288One way to accomplish this is to pass the block_name of the processor block
289to the action function, as part of the action URL.
290<p>
291in main:
292<pre>
293def main(req, content):
294  block_name = req.state.block_name
295  # add the block name to the URL, like so:
296  link = ...?action=Foo.bar&amp;block_name=" + block_name
297</pre>
298<p>
299in an action function:
300<pre>
301def bar(req):
302 block_name = req.form["block_name"].value
303 content = req.get_page_item(block_name)
304 # parse content as needed
305</pre>
306<p>
307<h3><a name="Reading_config_values">Reading config values</a>
308<span align=right class="section_edit_link">[<a href="/tbwiki/DocProcessors?action=edit&section=Reading_config_values">edit section</a>]</font></span>
309</h3>
310Some processors need to handle both configuration settings and content.
311This is true, for example, of the Table processor, which has table definition
312and display settings, as well as the actual content to be placed in the
313table.
314<p>
315One convention used to support this is to have configuration lines at
316the top of the processor block content, followed by a dashed line
317(a line consisting of only 3 dashes), like so:
318<pre>
319---
320</pre>
321<p>
322Here is an example showing configuration content in the same processor block.
323<p>
324<pre>
325{{{#!ColoredTimer
326color=red
327duration=10m30s
328interval=5s
329----
330Here is a timer:
331 &lt;&lt;  {{HTML(&lt;font color=red&gt;missing data value "timer"&lt;/font&gt;)}}  &gt;&gt;
332It should be counting down.
333} }}
334</pre>
335<p>
336Assuming you have the processor block content in the variable "content",
337you could use the following lines to parse this into two parts, including
338a configuration map (a python dictionary containing config items).
339<pre>
340   config_str, content_str = content.split("---\n")
341   config_map = req.parse_conf(config_str)
342   # do something with content_str (based on settings in config_map)
343</pre>
344<p>
345<h2><a name="Action_output">Action output</a>
346<span align=right class="section_edit_link">[<a href="/tbwiki/DocProcessors?action=edit&section=Action_output">edit section</a>]</font></span>
347</h2>
348Unlike your main processor function, action functions are not
349called in "page context".  That is, an action function does
350NOT return output to be placed on the page in place of the block,
351during page rendering.
352<p>
353Rather, when the function is entered, no html has been emitted yet
354 -- no header information, nav bars, nor even the "Content-type:" line.
355Thus they have complete control to emit any HTML output they want.
356<p>
357This is usually done by calling <code>req.show_header()</code> with some custom
358title to reflect the action or operation being performed.  Then
359the HTML for the page is printed directly by the action function.
360<p>
361Note that if your routine calls <code>req.show_header()</code> to output a standard
362wiki page header (with the current theme), then <code>req.show_footer()</code> is called after the processor action routine.  However, if the action routine
363does not call <code>req.show_header()</code>, then <code>req.show_footer()</code> will not be
364called automatically, and it is up to the action routine to complete the HTML output for the request.
365<p>
366<h1><a name="Action_Sample_-_UserChoice">Action Sample - UserChoice</a>
367<span align=right class="section_edit_link">[<a href="/tbwiki/DocProcessors?action=edit&section=Action_Sample_-_UserChoice">edit section</a>]</font></span>
368</h1>
369Here is sample code for a simple processor that shows what choice
370of two items a user selected. The choices are on two lines in the
371block content.
372<p>
373<h2><a name="UserChoice_processor_code">UserChoice processor code</a>
374<span align=right class="section_edit_link">[<a href="/tbwiki/DocProcessors?action=edit&section=UserChoice_processor_code">edit section</a>]</font></span>
375</h2>
376This would be in the file ProcessorUserChoice.py
377<pre>
378def UserChoice(req, content):
379         lines = content.split("\n")
380         if len(lines)&lt;2:
381                return "ERROR: not enough lines in UserChoice processor block"
382         link1 = req.page_url + "?action=UserChoice.choice1"
383         link2 = req.page_url + "?action=UserChoice.choice2"
384         html = """Please choose one of the following:
385                  &lt;ul&gt;
386                     &lt;li&gt;&lt;a href="%s"&gt;%s&lt;/a&gt;
387                     &lt;li&gt;&lt;a href="%s"&gt;%s&lt;/a&gt;
388                  &lt;/ul&gt;""" % (link1, lines[0], link2, lines[1])
389         return result
390 
391def choice1(req):
392         req.show_header("User Choice result")
393 
394         result = "You chose choice1 - this is inside the wiki page and theme"
395         print result
396 
397def choice2(req):
398         html = """Content-type: text/html
399 
400               &lt;body bgcolor="yellow"&gt;
401               &lt;h1&gt;User Choice result&lt;/h1&gt;
402               """
403 
404        html += "You chose choice2 - this is outside the wiki page and theme"
405        html += "&lt;br&gt; and it is bright yellow!"
406        html += "&lt;/body&gt;"
407        print html
408 
409</pre>
410<p>
411<h2><a name="UserChoice_processor_invocation">UserChoice processor invocation</a>
412<span align=right class="section_edit_link">[<a href="/tbwiki/DocProcessors?action=edit&section=UserChoice_processor_invocation">edit section</a>]</font></span>
413</h2>
414To use this processor, a user would place the following block on a page:
415<p>
416<pre>
417Stuff before the processor block
418 
419{{{#!UserChoice
420This is the first option: apples.
421This is the second option: bananas.
422} }}
423 
424Stuff after the processor block
425</pre>
426<p>
427<h2><a name="UserChoice_processor_result">UserChoice processor result</a>
428<span align=right class="section_edit_link">[<a href="/tbwiki/DocProcessors?action=edit&section=UserChoice_processor_result">edit section</a>]</font></span>
429</h2>
430Here is what the resulting output (from main) would look like on the page:
431<p>
432Stuff before the processor block
433<p>
434Please choose one of the following:
435<p>
436<ul><li><a href="/tbwiki/DocProcessors?action=UserChoice.choice1">This is the first option: apples.</a><li><a href="/tbwiki/DocProcessors?action=UserChoice.choice2">This is the first second option: bananas.</a></ul><p>
437Stuff after the processor block
438<p>
439<h2><a name="UserChoice_processor_action_outcome">UserChoice processor action outcome</a>
440<span align=right class="section_edit_link">[<a href="/tbwiki/DocProcessors?action=edit&section=UserChoice_processor_action_outcome">edit section</a>]</font></span>
441</h2>
442<p>
443Here is what would be displayed if the user selected the 'apples' option:
444<pre>
445You chose choice 1 - this is inside the wiki page and theme
446</pre>
447<p>
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

Differences for page "DocProcessors"


expected html
generated html
t No Differences Found t No Differences Found 
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

Update saved output

Back to diff page

Return to Regression_Test page
TBWiki engine 1.9.3 by Tim Bird