====== Руководство по включению системы новостей в DokuWiki ====== Данный документ предлагает рецепт включения системы новостей в Докувики. Вы получаете: * форму для написания новых новостных заметок; * одну страницу с аннотацией новостей, на которой отображается заголовок и несколько первых строчек новости; * одну страницу с полным списком новостей. Новостные заметки помечаются и отображаются датой публикации, а также могут содержать дату потери актуальности (perishing date). Это означает, что при написании заметки можно указать что заметка станет неактуальной, скажем, через две недели. Можно увидеть [[http://fsinfo.cs.uni-dortmund.de/|пример работы]] данного решения. 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. ===== Требования ===== * [[:DokuWiki]] (тестировалось с версией 2006-03-09b, 2006-11-06 и 2007-06-26b) * [[plugin:command|Command]] плагин для Докувики * [[plugin:template|Template]] расширение для плагина //command// ===== Дополнение шаблона Вашего сайта ===== Надо перейти в каталог с **активным** шаблоном Докувики . В моей установке это каталог ''/var/www/dokuwiki/lib/tpl/mytemplate/''. Скачать и распаковать в папку с **активным** шаблоном один из следующих архивов (или скопировать и вставить в файл прямо с этой страницы чуть ниже): * [[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 Далее, редактируем ''style.ini'' **активного** шаблона. В разделе ''[stylesheets]'' добавляем строчку ''news.css'', что показано в отрывке, приведенном ниже: [stylesheets] layout.css = screen design.css = screen style.css = screen news.css = screen После выполненной работы Вам должны отредактировать ''news.css'' для получения удобного дизайна соответсвующего Вашему шаблону. Возможно потребуется редактирование .php файлов для получения названий кнопкок и сообщений об ошибках на Вашем языке. ===== Как использовать ===== ==== Во-первых: установить формат формы ввода сообщений === Нужно создать страницу со следующим содержанием (предположим, Вы сохранили ее под именем ''newstemplate''): * targetpage: newsdata * head: 40| |Заголовок новости * start: 10|date(now)|Дата публикации (1-е появление в списке анонса новостей) * stop: 10|date(2 weeks)|Perishing date (on this day the article will disappear) * text: 50*5| |Your article ---- Данное описание формы будет интерпретироваться ''datainput.php'', который генерирует HTML из формы ввода следуя этому описанию и сохраняет отосланные данные формы на странице данных. Для активации ''datainput.php'', см. [[#Во-вторых: генерация формы ввода|2-й шаг]]. === Замечания по поводу того, что делает datainput.php === Данная секция может быть пропущена. Она содержит некоторую полезную вспомогательную информацию. Вы видите ниже синтаксис одной строчки шаблона "template": * fieldname: fieldvalue В данном случае ''fieldname'' это обычное слово. Оно используется ''datainput.php'' для именования поля формы в HTML. После отсылки формы, ''datainput.php'' сохраняет введенную информацию на специальной странице, обозначенной специальным полем ''targetpage'', используя "вымышленные" здесь имена полей. Другой PHP скрипт написан для интерпритации набора данных. Например, отосланное формой генеруируется с использованием определений, определенных выше, и получая в результате следующий набор данных на странице ''newsdata'': * head: Заголовок Статьи * start: 2007-12-12 * stop: 2007-12-24 * text: Сим салабим бам базелла дузелла дим. ---- Каждый набор данных отосланный формой будет помещаться перед существующими наборами "старых" данных (что означает: даже если сделать опечатку в поле ''targetpage'', операция не деструктивная -- только добавяться некоторые новые данные, никогда никакие данные не удаляются). Единственный путь отредактировать новость или удалить - "вручную" редактировать страницу с данными. Значения поля (например, определение размера/типа поля формы) могут быть: Size | Default | Headline ... и 'Size' может быть единственным целым (для ввода однострочного текста) или что-то подобное ''X*Y'' (''столбцов * строчек'' для ввода многострочного текста). Также может быть ''hidden'' (это Вам может пригодится в случае когда множество форм пишут в одну страницу данных, но Вы хотите разделить обработывающий код между этими формами ... проще создать множество шаблонов форм, все с одинаковым ''targetpage'', но с различными значениями в ''hidden'' поле). 'Default' - эта часть обычный текст, но может включать функцию ''date()'', которая really just calls the [[http://de3.php.net/manual/en/function.date.php|PHP date() function]] and uses its output as default. В данном примере, новостная заметка исчезнет через 2 недели после она была опубликована, если только автор записи не введет другую дату. 'Headline' - текст который описывает поле ввода. Он будет отображен напротив соответствующего поля ввода. Вследствие этого ''datainput.php'' дает Вам обобщенный, конфигурируемый генератор форм ввода данных. Он выдает страницы данных в синтаксисе требуемых плагином [[plugin:template|template]] для [[plugin:command|command]]. Вы можете создать формы ввода для обычных наборов данных -- за исключением одной вещи - PHP кода отображающего дату в Вашей вики. Смотрите [[plugin:template|template extension]] для for советов как сделать это -- для этого рецепта, ''newslist.php'' and ''newsdata.php'' содержат "display code", т.е. each one implements a different view on the saved datasets. См. ниже как использовать это. ==== Во-вторых: генерация формы ввода ==== Эта команда только берет созданную выше страницу данных, интерпретирует ее и генерирует на выходе форму: #template(datainput.php|newstemplate)# Это хорошая практика, чтобы написать ниже шаг 4 который на той же самой вики странице, так что после отсылки вы увидите убеждающий эффект на форме. Завершающий совет для новостной странице ввода (страница ''writenews''): ====== Write new news ====== **[ [[news|all news]] | [[writenews|write news]] | [[newsdata|edit news]] ]** #template(datainput.php|newstemplate)# #template(newsitems.php|newsdata)# ==== В третьих: показать превью статьи ==== Поместите эту штуковину где нибудь на стартовой странице Вашей вики или где Вам нравится. Я бы посоветовал поместить внутрь [[plugin:box]] ;-) %template?previewlength=120&indexpage=news:news(newslist.php|newsdata)% **[ [[news:news|all news]] | [[news:writenews|write news]] | [[data:newsdata|edit news]] ]** Просмотр превью новости на странице данных (в этом случае со страницы ''newsdata'' с длиной превью текста в 120 символов). Вторая строка только для удобства (доступ отсюда ко всем связанным с данной страницами). ==== 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. ==== В-четвертых: Редактирование новостной статьи ==== Вы это сделаете вручную. Не беспокойтесь - откройте Вашу страницу данных и редактирйте ее. Формат страницы данных должен обяснять сам себя. В основном вы будите корректировать незначительные детали, я полагаю, так что я не пишу скрипты для редактирования этой штуковины. ===== 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 ;-)