1 <chapter id="introduction">
2 <title>The producer framework</title>
4 <section><title>How to use the <filename>producers.xml</filename> file</title>
5 [FIXME: this should be in the user's guide, not here]
7 <section><title>Introduction</title>
10 With Mir, it is now possible to set up arbitrary producers using an xml file.
14 Producers consist of "nodes". Every node has a specific function.
15 For example, it is possible to use a node to generate a file out of a template.
16 Or it is possible to use a node to enumerate over a collection of articles.
22 A producer is defined using a Producer tag:
25 <producer name="content"/>
28 would define a producer named <code>content</code>.
32 In a producer, <emphasis>verbs</emphasis> must be defined.
33 Verbs are sub-tasks of a producer.
37 <producer name="content">
39 <verb name="new">
41 <verb name="all">
44 <producer name="content"/>
47 would define a producer with verbs named <code>all</code> and <code>new</code>.
50 And also the specific nodes and their relationship should be specified:
54 <producer name="content">
56 <verb name="new">
58 <verb name="all">
63 generator="/producer/startpage.template"
64 destination="${config.storageRoot}/index.shtml"/>
69 we will later learn that this producer generates a single file.
72 Producers can be made to do different things for different verbs:
76 <producer name="content">
78 <verb name="new">
79 <Set key="count" value="3"/>
81 <verb name="all">
82 <Set key="count" value="5"/>
87 generator="/producer/startpage.template"
88 destination="${config.storageRoot}/index.shtml"/>
93 if a producer is called with a specific verb, first the nodes of that verb
94 are processed, and only thereafter the body: in our case, if the producer
95 <code>content</code> is called with verb <code>new</code>, first the variable <code>count</code>
97 is set to <code>3</code>, and after that, a file is generated.
101 <section><title>Node arguments</title>
103 Nodes can have arguments.
104 Arguments that amount to integer values can be direct expressions.
105 Arguments that amount to text values can be enriched with expressions between ${}.
111 <Log message="This article has the following title: ${content.title}"/>
114 <code>Log</code> has 1 mandatory argument, <code>message</code>. This argument should be text,
115 but can be enriched with expressions enclosed by ${ and }. In this example,
116 the title of an article is logged.
119 <Set key="age" value="34+22*(3+2)"/>
121 <code>Set</code> has 2 mandatory argument: <code>key</code> and <code>value</code>.
122 The key arugment is a fixed text,
123 the value argument is a direct expression, in this case of arithmetic nature.
128 <section><title>Expressions</title>
132 Expressions, either direct expressions, or expressions between ${}, can contain the following
138 <tr><td>a string literal</td> <td><code>'hello'</code></td></tr>
139 <tr><td>a numeric literal</td> <td><code>2138</code></td></tr>
141 <tr><td>a variable reference</td> <td><code>content.title</code></td></tr>
142 <tr><td>arithmetic operators</td> <td><code> 3 + 4 *(2+5-2)</code></td></tr>
143 <tr><td>string operators</td> <td><code> 'hello' ++ ' ' ++ 'Mir'</code></td></tr>
145 <tr><td>boolean operators</td> <td><code>(content.id==3) or (content.id in (5,7,2,8) and (content.title!='hello')</code></td></tr>
150 <section><title>Node types and statements</title>
152 Here's a list of different node types that can be used inside
153 producer definitions.
154 Currently, there exists only one statement (<nodedefinition>), that
155 is declared outside producer definitions.
163 <tr><td>Name</td> <td bgcolor="#eea8a8"><code>Set</code></td></tr>
164 <tr><td>Purpose</td> <td>Alter a variable's using a free expression</td></tr>
167 <tr><td>key</td> <td>The variable</td></tr>
169 <tr><td>value</td> <td>The expression to set the variable to</td></tr>
174 <Set key="data.result" value="3 + 5 * (5-2)"/>
181 <tr><td>Name</td> <td bgcolor="#eea8a8"><code>Define</code></td></tr>
182 <tr><td>Purpose</td> <td>Alter a variable's using a string</td></tr>
186 <tr><td>key</td> <td>The variable</td></tr>
187 <tr><td>value</td> <td>The string to set the variable to</td></tr>
193 <Define key="filename" value="/var/www/${content.id}.shtml"/>
200 <tr><td>Name</td> <td bgcolor="#eea8a8"><code>If</code></td></tr>
202 <tr><td>Purpose</td> <td>Create a conditional part of a producer</td></tr>
205 <tr><td>condition</td> <td>The expression to test</td></tr>
209 <tr><td>then</td> <td>The part to process if the expression evaluates to true</td></tr>
210 <tr><td>else</td> <td>The part to process if the expression evaluates to false</td></tr>
213 <tr><td>Name</td> <td bgcolor="#eea8a8"><code>nodedefinition</code> (statement)</td></tr>
215 <tr><td>Purpose</td> <td>Acts as a "function" (or "macro") that can be "called" elsewhere in a producer.
216 More precisely, it is a way to define a new producer node type
217 inside the <filename>producers.xml</filename> file.
218 (check the <code>Language</code> node in that file for an example).
222 <tr><td>name</td> <td>The name of the newly created node ("function")</td></tr>
226 <tr><td>parameters</td> <td>a list describing the arguments the "function" must be given </td></tr>
227 <tr><td>definition</td> <td>the actual body of the function, containing the code that should be executed. Note that this may contain a <code><sub/></code> tag that is replaced by the child nodes of the calling node (FIXME is this true???) </td></tr>
232 <tr><td>Name</td> <td bgcolor="#eea8a8"><code>Log</code></td></tr>
234 <tr><td>Purpose</td> <td>Log a message in the producer log</td></tr>
237 <tr><td>message</td> <td>The message to log</td></tr>
241 <tr><td>Name</td> <td bgcolor="#eea8a8"><code>Enumerate</code></td></tr>
242 <tr><td>Purpose</td> <td>Enumerate over the results of a query</td></tr>
245 <tr><td>key</td> <td>The variable name that receives the enumerated record</td></tr>
247 <tr><td>table</td> <td>The table that is used to enumerate over</td></tr>
248 <tr><td>selection (optional)</td> <td>The condition (where clause) of the query.</td></tr>
249 <tr><td>order (optional)</td> <td>The order in which the results of the query are enumerated.</td></tr>
250 <tr><td>skip (optional)</td> <td>The number of records to skip</td></tr>
252 <tr><td>limit (optional)</td> <td>The maximum number of records to enumerate</td></tr>
256 This node can have subnodes that will be processed for every enumerated record</td></tr>
267 <Generate generator="/producer/content.template" destination="/var/www/${content.date.formatted.yyyy}/${content.date.formatted.MM}/${content.id}.shtml"/>
276 <tr><td>Name</td> <td bgcolor="#eea8a8"><code>List</code></td></tr>
278 <tr><td>Purpose</td> <td>Store the results of a query into a variable</td></tr>
281 <tr><td>key</td> <td>The variable name that receives the result list</td></tr>
282 <tr><td>table</td> <td>The table that is used to select from</td></tr>
284 <tr><td>selection (optional)</td> <td>The condition (where clause) of the query.</td></tr>
285 <tr><td>order (optional)</td> <td>The order in which the results of the query are put into the list.</td></tr>
286 <tr><td>skip (optional)</td> <td>The number of records to skip</td></tr>
287 <tr><td>limit (optional)</td> <td>The maximum size of the list</td></tr>
291 <tr><td>Name</td> <td bgcolor="#eea8a8"><code>Batch</code></td></tr>
292 <tr><td>Purpose</td> <td>Divide the results of a query into batches</td></tr>
296 <tr><td>key</td> <td>The variable name that receives the batch</td></tr>
297 <tr><td>infokey</td> <td>The variable name that receives meta information on the batches</td></tr>
298 <tr><td>table</td> <td>The table that is used to select from</td></tr>
299 <tr><td>batchsize</td> <td>The size of a batch (the first batch however varies in size)</td></tr>
301 <tr><td>selection (optional)</td> <td>The condition (where clause) of the query.</td></tr>
302 <tr><td>order (optional)</td> <td>The order in which the results of the query are put into the list.</td></tr>
303 <tr><td>skip (optional)</td> <td>The number of records to skip</td></tr>
304 <tr><td>process (optional)</td> <td>The maximum number of batches to process</td></tr>
306 <tr><td>minbatchsize (optional)</td> <td>The minimal size of the first batch</td></tr>
309 <tr><td>batches</td> <td>The part to process for every batch</td></tr>
310 <tr><td>batchlist</td> <td>The part to process once with the meta info</td></tr>
317 <tr><td>Name</td> <td bgcolor="#eea8a8"><code>Generate</code></td></tr>
318 <tr><td>Purpose</td> <td>Generate a page using a generator (i.e. an abstraction of a template)</td></tr>
323 <tr><td>generator</td> <td>the generator to use</td></tr>
324 <tr><td>destination</td> <td>the specification of the destination.</td></tr>
325 <tr><td>parameters</td> <td>Additional configuration info for the generator (for
326 freemarker this now only contains the wanted encoding,
327 empty for the default).</td></tr>
332 This node is used to have an actual page generated.
333 The generator parameter usually is the name of a template.
334 The destination is the file to be generated.
335 Variable references are possible in all arguments, and, especially for the
336 destination attribute, widely used.
344 <Generate generator="/producer/content.template" destination="/var/www/${content.date.formatted.yyyy}/${content.date.formatted.MM}/${content.id}.shtml"/>
352 <tr><td>Name</td> <td bgcolor="#eea8a8"><code>DeleteFile</code></td></tr>
353 <tr><td>Purpose</td> <td>Delete a file</td></tr>
356 <tr><td>filename</td> <td>The filename of the file to delete</td></tr>
362 <tr><td>Name</td> <td bgcolor="#eea8a8"><code>SetFileDate</code></td></tr>
363 <tr><td>Purpose</td> <td>Set a file's date</td></tr>
367 <tr><td>filename</td> <td>The filename</td></tr>
368 <tr><td>date</td> <td>The date to use</td></tr>
373 <tr><td>Name</td> <td bgcolor="#eea8a8"><code>Resource</code></td></tr>
374 <tr><td>Purpose</td> <td>Make a message resource bundle available</td></tr>
378 <tr><td>key</td> <td>The variable in which the bundle will be stored</td></tr>
379 <tr><td>bundle</td> <td>The bundle to use</td></tr>
380 <tr><td>language (optional)</td> <td>The specific language to use</td></tr>
386 <tr><td>Name</td> <td bgcolor="#eea8a8"><code>Execute</code></td></tr>
387 <tr><td>Purpose</td> <td>Execute a script</td></tr>
391 <tr><td>command</td> <td>The command to execute</td></tr>
398 <tr><td>Name</td> <td bgcolor="#eea8a8"><code>ModifyContent</code></td></tr>
399 <tr><td>Purpose</td> <td>Modify a field of an article</td></tr>
403 <tr><td>key</td> <td>The variable containing the article</td></tr>
404 <tr><td>field</td> <td>The field to modify</td></tr>
405 <tr><td>value</td> <td>The value to set the field to</td></tr>
409 <tr><td>Name</td> <td bgcolor="#eea8a8"><code>MarkContent</code></td></tr>
410 <tr><td>Purpose</td> <td>Mark an article as produced</td></tr>
414 <tr><td>key</td> <td>The variable containing the article</td></tr>
422 <section><title>How the producer framework is implemented</title>
424 <para>A Producer is a set of tasks, scripted in xml. Producers allow
425 mir installations to have their own actions that can be called for
426 instance when a new article is posted. Originally producers were
427 mostly used to generate pages, but they are used for a lot of
428 other tasks such as pulling rss feeds for the global wire on
429 indymedia.org. Producers are added and configured through the
430 <filename>producers.xml</filename> file.</para>
433 <para>The xml nodes contained within a <code><producer></code>
434 tag in the <filename>producers.xml</filename> file define
436 This program (or script) may contain constructs
437 such as <code>if</code> clauses, loops and variables... The program is parsed into a
438 tree of ProducerNodes (figure). The root of this tree is defined in a
439 NodedProducer (which is the only class that currently implements
440 the Producer interface). When the Producer is executed, the
441 <function>produce</function> methods of each node are recursively called, effectively
442 executing the program as it was scripted. </para>
444 <figure><title>A producer in the <filename>producer.xml</filename> file is parsed into a tree of <classname>ProducerNodes</classname></title>
447 <imagedata fileref="figures/producer-node-tree-example.eps" format="EPS"></imagedata></imageobject>
449 <imagedata fileref="figures/producer-node-tree-example.png" format="PNG"></imagedata></imageobject>