2 This XML file defines a set of producers intended for a typical indymedia
12 please check the mir user's guide and developer's guide
13 for documentation on the syntax of this file
17 <!-- This first section contains nodedefinitions. -->
18 <!-- A nodedefinition is a sort of "function" that can be "called" later -->
19 <!-- in a producer. -->
21 <!-- The Language node enumerates over all the available languages -->
22 <!-- and calls the subnode for each language. This way the subnode -->
23 <!-- is succesivelly called with its pathprefix set to "en", "de", -->
25 <nodedefinition name="Language">
27 <!-- by default, use all valid languages -->
28 <!-- 'ot' = "Other": used for translations. -->
29 <string name="languagecondition" defaultvalue="code != 'ot'"/>
30 <!-- prefix of bundles that contain language translations -->
31 <!-- this will be: etc/bundles/producer_xx.properties -->
32 <string name="bundle" defaultvalue="bundles.producer" />
33 <!-- "sub": reference to subnode of the calling node -->
38 <List key="languages" table="language" selection="${languagecondition}" order="code"/>
39 <Enumerate key="language" table="language" selection="${languagecondition}" order="code">
40 <!-- The Resource node defines a function that can be used -->
41 <!-- in expressions. The name of the function is given by the -->
42 <!-- "key" parameter. So in this case, it's lang. One -->
43 <!-- can henceforth use expressions like ${lang("page.title")} to -->
44 <!-- refer to a bundle value. -->
45 <Resource bundle="${bundle}" key="lang" language="${language.code}"/>
46 <Define key="pathprefix" value="${language.code}" />
47 <Define key="languagepreference" value="${language.code}" />
48 <!-- This <sub/> tag is replaced by the node arguments of this -->
49 <!-- "function". In other words, if this function (nodedef) was -->
50 <!-- called this way: <Language> <Generate ... > </Language> then -->
51 <!-- the <sub/> tag is replaced by the <Generate ... > node. -->
53 <!-- This condition is meant for sites where the startpage for, -->
54 <!-- say, english prefer english translations over non-english -->
55 <!-- originals. For those sites, an "original" startpage is also -->
56 <!-- generated, which always has articles in their original -->
57 <!-- language. A concrete example: -->
59 <!-- * say the site has languages english and german. -->
60 <!-- * say article 1 was written in german -->
61 <!-- * say article 2 was written in english, with a german -->
64 <!-- Then the english startpage might have article 1 in german -->
65 <!-- and article 2 in english -->
67 <!-- The german startpage might have article 1 in german and -->
68 <!-- the german translation of article 2 -->
70 <!-- The Original startpage might have article 1 in german -->
71 <!-- and article 2 in english -->
72 <If condition="language.code=='en'">
74 <Define key="pathprefix" value="or" />
75 <Define key="languagepreference" value="" />
83 <nodedefinition name="RSSChannel">
85 <string name="articleSelection"/>
86 <string name="extratables" defaultvalue="none" />
87 <integer name="limit" defaultvalue="15"/>
88 <string name="channelidentifier" defaultvalue=""/>
89 <string name="channelfilename"/>
90 <string name="channeltitle"/>
91 <string name="articleprefix" defaultvalue="${config['Producer.PublicationHost']}/or" />
92 <string name="iconprefix" defaultvalue="${config['Producer.PublicationHost']}/icon" />
93 <string name="channelpublisher" defaultvalue="${config['Mir.Name']}" />
94 <string name="encoding" defaultvalue="UTF-8" />
95 <string name="channeldescription" defaultvalue=""/>
96 <string name="generator" defaultvalue="/RSS.template" />
100 <If condition="extratables == 'none' ">
102 <List key="articles" table="content c" selection="${articleSelection}" order = "c.webdb_create desc, c.date desc" limit="limit" />
105 <List key="articles" table="content c" selection="${articleSelection}" order = "c.webdb_create desc, c.date desc" limit="limit" extratables="${extratables}" />
108 <If condition="channeldescription==''">
110 <Define key="channeldescription" value="${channeltitle}"/>
113 <If condition="channelidentifier==''">
115 <Define key="channelidentifier" value="${config['Producer.PublicationHost']}/or/${channelfilename}"/>
120 parameters="${encoding}"
121 generator="${generator}"
122 destination="${config.storageRoot}/${channelfilename}"/>
126 <nodedefinition name="RSSChannelBundle">
128 <string name="extratables" defaultvalue="none" />
129 <string name="selection" defaultvalue="c.is_published='1'" />
130 <string name="basefilename" defaultvalue="main" />
135 articleSelection="(c.to_article_type in (${articletype.newswire}) or (c.to_article_type=${articletype.translation} and c.to_original.to_articletype in (${articletype.newswire}))) and ${selection}"
136 channelfilename="${basefilename}-newswire.rss"
137 channeltitle="${config['Mir.Name']} ${basefilename} newswire"
139 extratables="${extratables}"
142 articleSelection="(c.to_article_type in (${articletype.newswire}) or (c.to_article_type=${articletype.translation} and c.to_original.to_articletype in (${articletype.newsire}))) and ${selection}"
143 channelfilename="${basefilename}-newswire-content.rss"
144 channeltitle="${config['Mir.Name']} ${basefilename} newswire"
146 generator="RSS-full.template"
147 extratables="${extratables}"
151 articleSelection="(c.to_article_type in (${articletype.feature},${articletype.startspecial},${articletype.topicspecial}) or (c.to_article_type=${articletype.translation} and c.to_original.to_articletype in (${articletype.feature},${articletype.startspecial},${articletype.topicspecial}))) and ${selection}"
152 channelfilename="${basefilename}-features.rss"
153 channeltitle="${config['Mir.Name']} ${basefilename} features"
155 extratables="${extratables}"
158 articleSelection="(c.to_article_type in (${articletype.feature},${articletype.startspecial},${articletype.topicspecial}) or (c.to_article_type=${articletype.translation} and c.to_original.to_articletype in (${articletype.feature},${articletype.startspecial},${articletype.topicspecial}))) and ${selection}"
159 channelfilename="${basefilename}-features-content.rss"
160 channeltitle="${config['Mir.Name']} ${basefilename} features"
162 generator="RSS-full.template"
163 extratables="${extratables}"
169 <!-- This second section contains actual producers that will appear -->
170 <!-- on the admin->"Generate manually"->"advanced page". -->
172 <!-- This producer generates html pages, as well as media and video -->
173 <!-- files for articles stored in the database. -->
175 <!-- It's a good example of the use of the "verb" concept. The
176 "articles" producer (the producer responsible for generating
177 article pages), can be called in 3 modes:
179 * changed, to regenerate articles with changes (new ones,
180 recently edited ones, or ones with added/removed/changed
181 comments/media). Note that in this case it will regenerate at
182 most 10 changes articles.
184 * all, to regenerate all articles
186 * sample to regenerate the 10 latest articles -->
187 <producer name="articles">
188 <!-- verbs define the different actions that may be done by -->
189 <!-- this producer -->
191 <!-- only generate articles that have changed (including new article) -->
192 <verb name="changed" default="1">
193 <Define key="verbcondition" value="(not is_produced)"/>
194 <Set key="limit" value="10"/>
196 <!-- generate all articles in the db (under certain condiftions...) -->
198 <Define key="verbcondition" value=""/>
199 <Set key="limit" value="-1"/>
202 <!-- only generate the last 10 articles in the db -->
204 <Define key="verbcondition" value=""/>
205 <Set key="limit" value="10"/>
209 <!-- loop on all articles requested by the "verb" -->
210 <Enumerate key="article" table="content" selection="${verbcondition}"
211 limit="limit" order="webdb_create desc">
212 <!-- For each article, generate it's corresponding image files -->
213 <!-- The following sql statements select images that are -->
214 <!-- associated with the article (either directly or -->
215 <!-- through comments). -->
217 key="media" table="image"
218 selection="exists (select * from content_x_media where media_id=images.id and content_id=${article.id})
219 or exists (select * from comment_x_media, comment
220 where comment_id = comment.id and media_id=images.id and comment.to_media=${article.id})"
222 <!-- The generateMedia node instructs the media handler
223 associated with the media to "reproduce" the media. In
224 practice this can mean generate an icon from an image,
225 writing an image from the database to the web root, or
226 create an m3u file or so. Media handling is limited at
227 this moment, but a serious redesign is planned -->
228 <GenerateMedia key="media" />
230 <!-- for each article, generate it's corresponding video files -->
232 key="media" table="video"
233 selection="exists (select * from content_x_media where media_id=video.id and content_id=${article.id})
234 or exists (select * from comment_x_media, comment
235 where comment_id = comment.id and media_id=video.id and comment.to_media=${article.id})"
237 <GenerateMedia key="media" />
239 <!-- for each article, generate it's corresponding audio files -->
241 key="media" table="audio"
242 selection="exists (select * from content_x_media where media_id=audio.id and content_id=${article.id})
243 or exists (select * from comment_x_media, comment
244 where comment_id = comment.id and media_id=audio.id and comment.to_media=${article.id})"
247 <GenerateMedia key="media" />
249 <!-- for each article, generate it's corresponding other media files
252 key="media" table="otherMedia"
253 selection="exists (select * from content_x_media where media_id=other_media.id and content_id=${article.id})
254 or exists (select * from comment_x_media, comment
255 where comment_id = comment.id and media_id=other_media.id and comment.to_media=${article.id})"
258 <GenerateMedia key="media" />
261 <If condition="article.is_published == '1'">
262 <!-- only generate published articles -->
264 <!-- loop on all available languages -->
266 <!-- actually generate the article -->
268 generator="/article.template"
269 destination="${config.storageRoot}/${pathprefix}/${article.date.formatted.yyyy}/${article.date.formatted.MM}/${article.id}.shtml"/>
271 <!-- generate the article's languagebar -->
273 generator="/languagebar.template"
274 destination="${config.storageRoot}/languagebar/${article.to_original.date.formatted.yyyy}/${article.to_original.date.formatted.MM}/${article.to_original.id}.shtml"/>
275 <!-- add article to the "search engine" index (lucene) -->
276 <IndexContent key="article" pathToIndex="${config['IndexPath']}"/>
278 <!-- if article is not published, remove it from the search index -->
280 <UnIndexContent key="article" pathToIndex="${config['IndexPath']}"/>
283 <!-- mark (tag) the article as produced -->
284 <MarkContent key="article"/>
289 <!-- generates the left column -->
290 <producer name="navigation">
292 <verb name="generate" default="1" description="generates the left column"/>
297 generator="/navigation.template"
298 destination="${config.storageRoot}/${pathprefix}/navigation.inc"/>
303 <producer name="staticimages">
305 <verb name="generate" default="1" description="copies all the static image files into place"/>
308 <CopyDir destination="img" source="etc/producer/images"/>
312 <producer name="newswirearchive">
315 <Set key="pages" value="3"/>
318 <Set key="pages" value="-1"/>
322 <Define key="docSuffix" value=".shtml"/>
323 <Define key="storageSuffix" value=".shtml"/>
325 <Batch key="articles" infokey="batch" table="content"
326 process="pages" batchsize="20" minbatchsize="10"
327 selection="is_published='1' and to_article_type = ${articletype.newswire}"
328 order="webdb_create asc">
331 <Define key="pagePrefix" value="${pathprefix}/newswire/archive"/>
332 <Define key="storagePrefix" value="${config["Producer.StorageRoot"]}/${pagePrefix}"/>
333 <Define key="docPrefix" value="${config["Producer.DocRoot"]}/${pagePrefix}"/>
336 generator="newswirearchive.template"
337 destination="${storagePrefix}${batch.current.identifier}${storageSuffix}"/>
343 <Define key="pagePrefix" value="${pathprefix}/newswire/archive"/>
344 <Define key="storagePrefix" value="${config["Producer.StorageRoot"]}/${pagePrefix}"/>
345 <Define key="docPrefix" value="${config["Producer.DocRoot"]}/${pagePrefix}"/>
347 generator="batchnav.template"
348 destination="${storagePrefix}nav${storageSuffix}"/>
355 <producer name="featurearchive">
358 <Set key="pages" value="3"/>
361 <Set key="pages" value="-1"/>
365 <Define key="docSuffix" value=".shtml"/>
366 <Define key="storageSuffix" value=".shtml"/>
368 <Batch key="articles" infokey="batch" table="content"
369 process="pages" batchsize="20" minbatchsize="10"
370 selection="is_published='1' and to_article_type in (${articletype.feature}, ${articletype.startspecial})"
371 order="webdb_create asc">
374 <Define key="pagePrefix" value="${pathprefix}/feature/archive"/>
375 <Define key="storagePrefix" value="${config["Producer.StorageRoot"]}/${pagePrefix}"/>
376 <Define key="docPrefix" value="${config["Producer.DocRoot"]}/${pagePrefix}"/>
379 generator="featurearchive.template"
380 destination="${storagePrefix}${batch.current.identifier}${storageSuffix}"/>
386 <Define key="pagePrefix" value="${pathprefix}/feature/archive"/>
387 <Define key="storagePrefix" value="${config["Producer.StorageRoot"]}/${pagePrefix}"/>
388 <Define key="docPrefix" value="${config["Producer.DocRoot"]}/${pagePrefix}"/>
390 generator="batchnav.template"
391 destination="${storagePrefix}nav${storageSuffix}"/>
398 <producer name="topicpages">
401 <Set key="_topics" value="-1"/>
402 <Set key="pages" value="3"/>
405 <Set key="_topics" value="-1"/>
406 <Set key="pages" value="-1"/>
409 <Set key="_topics" value="2"/>
410 <Set key="pages" value="4"/>
414 <Enumerate key="topic" table="topic" limit="_topics">
415 <Define key="docSuffix" value=".shtml"/>
416 <Define key="storageSuffix" value=".shtml"/>
418 <List key="special" table="content c"
419 selection="c.is_published='1' and c.to_article_type = ${articletype.topicspecial} and c.id=cxt.content_id and cxt.topic_id = ${topic.id}"
420 order = "webdb_create desc" limit="1"
421 extratables="content_x_topic cxt"/>
423 <Batch key="articles" infokey="batch" table="content c"
424 process="pages" batchsize="20" minbatchsize="10"
425 selection="c.is_published='1' and c.to_article_type in (${articletype.newswire}, ${articletype.feature}) and c.id=cxt.content_id and cxt.topic_id = ${topic.id}"
426 order="webdb_create asc" extratables="content_x_topic cxt">
429 <Define key="pagePrefix" value="${pathprefix}/${topic.filename}/archive"/>
430 <Define key="storagePrefix" value="${config["Producer.StorageRoot"]}/${pagePrefix}"/>
431 <Define key="docPrefix" value="${config["Producer.DocRoot"]}/${pagePrefix}"/>
434 generator="topicpage.template"
435 destination="${storagePrefix}${batch.current.identifier}${storageSuffix}"/>
441 <Define key="pagePrefix" value="${pathprefix}/${topic.filename}/archive"/>
442 <Define key="storagePrefix" value="${config["Producer.StorageRoot"]}/${pagePrefix}"/>
443 <Define key="docPrefix" value="${config["Producer.DocRoot"]}/${pagePrefix}"/>
445 generator="batchnav.template"
446 destination="${storagePrefix}nav${storageSuffix}"/>
454 <!-- generates the main html page (startpage) of an indymedia site -->
455 <producer name="startpage">
457 <verb name="generate" default="1" description="Generates the startpage"/>
461 <List key="startspecial" table="content" limit="1"
462 selection="is_published=true and to_article_type=${articletype.startspecial}"
463 order="webdb_create desc"/>
465 <List key="features" table="content" limit="10"
466 selection="is_published=true and to_article_type=${articletype.feature}"
467 order="webdb_create desc"/>
469 <List key="newswire" table="content" limit="30"
470 selection="is_published=true and to_article_type=${articletype.newswire}"
471 order="webdb_create desc"/>
473 <List key="breakingnews" table="breakingNews" limit="10"
474 order="webdb_create desc"/>
478 generator="/startpage.template"
479 destination="${config.storageRoot}/${pathprefix}/index.shtml"/>
484 <!-- Use rsync to copy static site to mirrors (only if requested -->
485 <!-- in config file) -->
486 <producer name="synchronization">
488 <verb name="run" default="1" description="Synchronizes the publication site with the production site"/>
492 <ReportChanges format="${config.now.formatted['HH:mm:ss']} ${change.type} ${config['Producer.ProductionHost']}${change.path}"
493 file="${config['Producer.StorageRoot']}/changes/changes${config.now.formatted['yyyyMMdd']}.txt"
494 basepath="${config['Producer.StorageRoot']}" />
499 <If condition="config['Rsync'] in ('1', 'y', 'yes', 'Y')">
501 <Execute command="${config['Rsync.Script.Path']}"/>
508 <producer name="media">
510 <verb name="new" default="1">
511 <Define key="verbcondition" value="(not is_produced)"/>
512 <Set key="limit" value="10"/>
515 <Define key="verbcondition" value=""/>
516 <Set key="limit" value="-1"/>
520 <Define key="verbcondition" value=""/>
521 <Set key="limit" value="10"/>
526 key="media" table="image"
527 selection="${verbcondition}"
529 order="webdb_create desc">
531 <GenerateMedia key="media" />
534 key="media" table="video"
535 selection="${verbcondition}"
537 order="webdb_create desc">
539 <GenerateMedia key="media" />
542 key="media" table="audio"
543 selection="${verbcondition}"
545 order="webdb_create desc">
547 <GenerateMedia key="media" />
550 key="media" table="otherMedia"
551 selection="${verbcondition}"
553 order="webdb_create desc">
555 <GenerateMedia key="media" />
560 <producer name="syndication">
562 <verb name="generate" />
565 <!-- the main features and newswire -->
568 <!-- the topic features and newswires -->
569 <Enumerate key="topic" table="topic">
571 basefilename="${topic.filename}"
572 selection="c.id=cxt.content_id and cxt.topic_id = ${topic.id}"
573 extratables="content_x_topic cxt"
583 <producer name="radicalendar">
588 <!-- groupname you will see as the value of "group" in the url for your radicalendar page, -->
589 <!-- gmtoffset is in minutes -->
590 <Radicalendar key="calendar" groupname="_imc" gmtoffset="60" />
592 generator="/radicalendar.template"
593 destination="${config.storageRoot}/calendarinclude.shtml"/>