====== Recipe to include a news system in DokuWiki ====== {{:config:warning.png |}} Based on this a plugin was developed [[plugin:anewssystem|⇒ a NEWS System]]. This is a recipe to include a news system in DokuWiki. You'll get a form to write news articles. You'll get one summary page, where the headlines and the first few lines of text will show up. You'll get one complete page, where all news articles are listed. Articles are tagged and displayed with a publishing date, and may have a perishing date. That means, while writing an article, you could say that the article should disappear in, oh, let's say two weeks. You may want to take a look at [[http://fsinfo.cs.uni-dortmund.de/|this stuff at work]]. And, oh, you can tinker around with that stuff, it all boils down to using the [[plugin:template|template plugin]] and a bit of PHP code in your site template. ===== Requirements ===== * [[:DokuWiki]] (tested with version 2006-03-09b, 2006-11-06 and 2007-06-26b) * [[plugin:command|Command]] plugin for DokuWiki * [[plugin:template|Template]] extension for the command plugin ===== Enhance your site template ===== You've got an "active template directory" in your dokuwiki installation. In my installation, it's in ''/var/www/dokuwiki/lib/tpl/mytemplate/''. Go there. Download and unpack one of the following archives there (or copy&paste them from far below on this page): * [[http://fsinfo.cs.uni-dortmund.de/~dave/newssystem-0.1.tar.bz2|newssystem-0.1.tar.bz2]] * [[http://fsinfo.cs.uni-dortmund.de/~dave/newssystem-0.1.zip|newssystem-0.1.zip]] user@server:/var/www/dokuwiki/lib/tpl/mytemplate$ wget http://fsinfo.cs.uni-dortmund.de/~dave/newssystem-0.1.tar.bz2 user@server:/var/www/dokuwiki/lib/tpl/mytemplate$ tar xvjf newssystem-0.1.tar.bz2 Edit your ''style.ini''. This here is just an excerpt, you'll have to add the line with ''news.css'' in the section ''[stylesheets]'': [stylesheets] layout.css = screen design.css = screen style.css = screen news.css = screen After everything works, you'll just //have// to edit ''news.css'' to get some sensible design matching your template. Maybe you'll want to edit the .php files too to get button text and error messages in your language. ===== How to use ===== ==== First: Set the format of the input form === You'll have to create a page with the following content. Let's assume you saved it as ''newstemplate''. * targetpage: newsdata * head: 40| |Headline * start: 10|date(now)|Publishing date (first appearance of the article in the list) * stop: 10|date(2 weeks)|Perishing date (on this day the article will disappear) * text: 50*5| |Your article ---- This form definition will be interpreted by ''datainput.php'', which outputs an HTML input form following this definition and saves the submitted form data in a data page. To invoke ''datainput.php'', see [[#Second: Generate input form|step two]]. === Excourse on what datainput.php does === This section may be skipped. It just contains some useful background information. You'll see the syntax of one line of the "template" right away: * fieldname: fieldvalue The fieldname is an arbitrary word at this point. It is used by ''datainput.php'' to name the form fields in HTML. After submitting the form, ''datainput.php'' saves the input on the wikipage denoted by the special field ''targetpage'', using the fieldnames "invented" here. Another PHP script has to be written to actually interpret the dataset. E.g., the submission of the form generated by the definition above will result in the following dataset on the page ''newsdata'': * head: Article Headline * start: 2007-12-12 * stop: 2007-12-24 * text: Sim salabim bam basela dusela dim. ---- Each form submission will be put on top of the existing datasets (that means: even if you make a typo in the ''targetpage'' field, the operation is non-destructive -- it just adds some data, never deletes any). The only way to edit or delete datasets is to manually edit the wikipage. The field's value (i.e. the size/type definiton of the form fields) could be divided into: Size | Default | Headline ... and 'Size' may be a lone integer (for one-lined text input) or something like ''X*Y'' (columns times rows of a multi-line input field). It may also be ''hidden'' (you'll need this in the case where multiple forms write to one datapage, but you want to distinct in the handling code between these forms ... simply create multiple form templates, all with the same ''targetpage'', but with different values in a hidden field). The 'Default' part is an arbitrary text, but may include the ''date()'' function, which really just calls the [[http://de3.php.net/manual/en/function.date.php|PHP date() function]] and uses its output as default. In this example, the news articles will disappear 2 weeks after they were written, if the article author does not input another date. 'Headline' is the text which describes the input field. It will be displayed next to the corresponding input field on the page. Therefore, ''datainput.php'' gives you a generic, configurable input form generator for your wiki. It outputs data pages in the syntax required by the [[plugin:template|template extension]] to the [[plugin:command|command plugin]]. You could create input forms for arbitrary data sets -- the only thing missing is the PHP code to actually display the data in your wiki. See the [[plugin:template|template extension]] for hints on how to do that -- for this recipe, ''newslist.php'' and ''newsdata.php'' contain the "display code", i.e. each one implements a different view on the saved datasets. See below on how to use these. ==== Second: Generate input form ==== This command just takes the above created data page, interprets it and generates a form out of it: #template(datainput.php|newstemplate)# It is good practice to write step four below that on the same wiki page, so after submitting you'll see the reassuring effects of the form. Complete suggestion for the news article input page (page ''writenews''): ====== Write new news ====== **[ [[news|all news]] | [[writenews|write news]] | [[newsdata|edit news]] ]** #template(datainput.php|newstemplate)# #template(newsitems.php|newsdata)# ==== Third: Show article preview ==== Put this stuff somewhere into the start page of your wiki or whereever you like. I'd suggest putting a [[plugin:box]] around it ;-) %template?previewlength=120&indexpage=news:news(newslist.php|newsdata)% **[ [[news:news|all news]] | [[news:writenews|write news]] | [[data:newsdata|edit news]] ]** Shows a preview of news in a data page (in this case from the page ''newsdata'' with a preview text length of 120 chars). The second line is just for convenience (access all news-related pages from there). ==== Fourth: Show complete news articles ==== This is the wiki page ''news:news'': ====== News ====== **[ [[news:news|all news]] | [[news:writenews|write news]] | [[data:newsdata|edit news]] ]** #template(newsitems.php|newsdata)# The first two lines are there for convenience, the actual stuff is done in the last line. ==== Fifth: Edit news articles ==== You'll have to do that by hand. Don't worry, just open your data page and edit it. The format of the data page should explain itself. Mostly you will just correct some minor details, I expect, so I did not write a script to edit the stuff. ===== Bugs ===== * You can't use bullet lists in news articles. The template plugin seems to disallow that. * You'll need to use ''~~NOCACHE~~'' on some pages. ===== Stuff to remember when tinkering around with this stuff ===== There are some reserved words among the field names, but not all of them are reserved by the same .php file. ==== datainput.php ==== You may use ''datainput.php'' to generate arbitrary data input forms. Just remember that the field name ''targetpage'' is reserved. All other field names will be used when writing to the target page -- therefore, you may invent some, and they will be used. The special default value ''date(something)'' will resolve the date represetation of the string 'something' on generation of the form. ==== newslist.php/newsitems.php ==== Here the field names ''start'', ''stop'', ''head'' and ''text'' are reserved. Any other field in the data page will be ignored. ===== Author ===== The author is Dave Kliczbor . Feel free to tinker around with this stuff and completely rewrite this wiki page (if you must). ===== Files ===== ==== datainput.php ===== */ $params = $TEMPLATECOMMAND_SOURCE->getParamHash(); $prefix = "plugin_datainput_"; //now, go through all data sets foreach( $TEMPLATECOMMAND_SOURCE->getHtmlRecords() as $rec_num => $record ) { //ok, display only if showonly is not set or showonly matches the record number if( (!isset($params['showonly'])) || ($params['showonly'] == "$rec_num") ) { //data record is only valid if "target" is set if( isset($record['targetpage']) ) { $targetpage = htmlspecialchars(trim($record['targetpage'])); //security check ... evaluate form only when template data set is unchanged // (i.e. committed hidden field is still in the same template data record number) //and check anyway if the user is allowed to edit teh targetpage if( ($_POST["X-".$prefix.$targetpage] == "$rec_num") && (auth_quickaclcheck($targetpage) >= AUTH_EDIT) ) { $newrecord = ''; foreach( $_POST as $postkey => $postvalue ) { // we only need $_POST fields that start with $prefix if( strpos($postkey, $prefix) === 0 ) { $key = substr($postkey, strlen($prefix)); //DEBUG-Code //echo '

' . $key . '

' . $postvalue . '

'; if( strpos(trim($postvalue), "\n") !== false ) { // this is a multilined value, so we need to prepend a linebreak // to achieve a multilined value for the template plugin $postvalue = "\n" . $postvalue; } $newrecord .= " * " . $key . ": " . $postvalue . "\n"; } } $newrecord .= "\n----\n\n"; $oldrecord = rawwiki($targetpage); saveWikiText($targetpage, $newrecord.$oldrecord, "New news article"); msg('Your news article has been saved successfully.'); } else if( isset($_POST["X-".$prefix.$targetpage]) ){ msg('Your news article could not be saved. Try to log in to gain permission to write news articles or politely ask your admin to give you permission.'); } echo '

'; echo ''; //walk through all fields in one data set foreach( $record as $fieldname => $fieldvalue ) { $fieldname = htmlspecialchars(trim($fieldname)); //...but not through certain fields if( $fieldname != 'targetpage' ) { //explode field value by '|' $matches = explode('|', $fieldvalue); //$matches[0] == field type; $matches[1] = default value; $matches[2] == friendly field title; $fieldtype = htmlspecialchars(trim($matches[0])); $fieldtitle = htmlspecialchars($matches[2]); // parse default values if( isset($params['default_'.$fieldname]) ) { $default_value = strtr($params['default_'.$fieldname], "_", " "); } else { $default_value = htmlspecialchars(trim($matches[1])); if( preg_match('/^date\((.*)\)/', trim($matches[1]), $dateparam) !== 0 ) { $default_value = date("Y-m-d", strtotime($dateparam[1])); } } // output fields if( fieldtype == 'hidden' ) { echo ''."\n"; } else if( preg_match('/^(\d+)\*(\d+)$/', $fieldtype, $dimensions) > 0 ) { echo '

' . $fieldtitle . '

' . '

'."\n"; } else if( preg_match('/^\d+$/', $fieldtype) == 1 ) { echo '

' . $fieldtitle . '

' . '

'."\n"; } else { //DEBUG-Code //echo '|' . $fieldtype . "|-|" . $fieldtitle . '|'; } } } echo ''; echo '
'; } } } ?>
==== newsitems.php ==== */ foreach( $TEMPLATECOMMAND_SOURCE->getTextRecords() as $rec_num => $record ) { if( (!isset($record['start']) || strtotime($record['start']) < time()) && (!isset($record['stop']) || strtotime($record['stop']) > time()) ) { //format start timestamp if( !isset($record['start']) ) { $date = ''; } else { $date = date('l, d.m.Y ', strtotime($record['start'])); } echo "\n\n=== " . $record['head'] . " ===\n//" . $date . "//\n\n"; echo $record['text'] . "\n\n----\n"; } } ?> ==== newslist.php ==== */ require_once(DOKU_INC.'inc/parser/xhtml.php'); $xhtml_renderer = new Doku_Renderer_xhtml(); echo '

"; ?> ==== news.css ==== li.newslist { padding-bottom:1ex; } .news_preview { font-size:90%; line-height:115%; color:__darker__; margin:0; padding:0; } .newsdate { font-size:90%; color:__darkgray__; } div.listabocheck { # display:inline; border:1px dotted __dark__; background-color:__light__; margin-bottom:1em; } I like the word "stuff", or didn't you notice? ;-) > I notice that. > Thank you very much for your recipe. >> No problem ;-)