Finar.ru
web.finar.ru
video.finar.ru
Темы для BootstrapNew!

PmWiki как CMS: шаг первый

делаем из pmwiki мультидоменную систему управления сайтами

Автор: Люди, дата: 2009-08-22, просмотров 6425
Тэги

темы: PmWiki

Постановка задачи для web.finar.ru

Сайт для собственного детища никак не назовешь заурядной задачей - ведь его хочется сделать просто-таки идеальным со всех сторон, как капля дистиллированной воды в невесомости. Как вы уже могли прочитать, web.finar.ru задуман как подраздел Finar.ru и является первым шагом к реструктуризации основного сайта.

Итак, требования для web.finar.ru включают требования к будущему обновленному Finar.ru и сводятся к следующему:

  • упрощение рутинной верстки: все частые операции должны быть автоматизированны;
  • автоматическая генерирование фотогалереи и вывод одиночных фотографий для упрощения публикаций;
  • java-кнопки для создания спрятанных областей контента;
  • широкий набор GUI-кнопок, поддерживающих большую часть синтаксиса;
  • скрытие служебных элементов интерфейса сайта для неавторизованных пользователей;
  • возможность включения любой части контента finar.ru в дизайне web.finar.ru

Установлено на этапе localhost: до первой публикации сайта

  • LazyWebLinks  с некоторой доработкой. Всякий текст, начинающийся на "www." становится ссылкой на внешний ресурс; все ссылки на внешние ресурсы открываются в новом окне, а также снабжаются стрелочкой. В config.php это выглядит следующим образом:
  1. ## make link every "www."-starting text| Finar
  2. Markup('lazyweb','<wikilink', "/\\bwww\\.[^\\s$UrlExcludeChars]*[^\\s.,?!$UrlExcludeChars]/e", "Keep(MakeLink(\$pagename,'http://$0','$0'),'L')");
  3. ## open every external link in a new window by default | Finar
  4. $UrlLinkFmt = "<a class='urllink' target='_blank' title='\$LinkUrl' rel='nofollow' href='\$LinkUrl'>\$LinkText&nbsp;</a><img src='$PubDirUrl/external.png' width='11' height='12' alt='External Link to \$LinkUrl' title='External Link to \$LinkUrl' border='0' />";
  • Toggle  - добавляет javascript-овые кнопочки для скрытия части контента страницы и облегчения ее восприятия. Кнопочки, как видите, тут повсюду, а в config.php это выглядит следующим образом:
  1. ## JAVAScript open/close buttons for content hiding | Finar
  2. include_once("$FarmD/cookbook/toggle.php");
  3. $ToggleConfig = array(
  4.         'init' => 'hide',       //show div
  5.         'show' => XL("подробнее"),  //link text 'Show'
  6.         'hide' => XL("скрыть"),  //link text 'Hide'
  7.         'ttshow' => XL("подробнее"),  //tooltip text 'Show'
  8.         'tthide' => XL("скрыть"),  //tooltip text 'Hide'
  9.         'set' => false,         //set no cookie to remeber toggle state
  10.         'id' => '',            //no default div name
  11.         'id2' => '',           //no default div2 name
  12.         'set' => false,         //set no cookie to remeber toggle state
  13.         'printhidden' => true,  // hidden divs get printed
  14.     );
  • PageTableOfContents  и BreakPage  - первый автоматически генерирует содержание страницы и расставляет по ней якоря; второй разбивает большие статьи на несколько страниц. Удобно, например, для отделения комментариев от основной статьи. Первый рецепт рекомендуется применять вместе со вторым. Пример работы вы видите в начале статьи, а в config.php это выглядит следующим образом:
  1. ## automatic Table of Contents generation | Finar
  2. $ToggleText = array('спрятать', 'показать');
  3. include_once('cookbook/pagetoc.php');
  4. $DefaultTocTitle = "Содержание:";
  5. $NumberToc = false;
  6. $TocFloat = true;
  7. ## divides pages on few parts. Required for pagetoc.php (Table of Contents) | Finar
  8. include_once('cookbook/break_page.php');
  • RememberEditPosition  - запоминает положение фрейма с кодом при нажатии кнопки "preview". В config.php это выглядит следующим образом:
  1. ## cursor restore after preview | Finar
  2. if ( $action == 'edit' ) {
  3.   $InputTags['e_scrolltop'][':html'] =
  4.     "<input type='hidden' name='prev_scroll' id='prev_scroll' value='".
  5.     intval(@$_POST['prev_scroll'])."'/>";
  6.   $HTMLHeaderFmt[] = "<script type='text/javascript'>
  7.    function addEvent( obj, evt, fn ) {
  8.      if (obj.addEventListener) obj.addEventListener( evt, fn, false );
  9.      else if (obj.attachEvent) obj.attachEvent( 'on'+evt, fn );
  10.    }
  11.    var ps;
  12.    addEvent( window, 'load', function() {
  13.     ps = document.getElementById('prev_scroll');
  14.      if ( ps.value > 0 ) document.getElementById('text').scrollTop = ps.value;
  15.      addEvent( ps.form, 'submit', function() { ps.value = ps.form.text.scrollTop; } )
  16.    } );
  17.    </script>";
  18. }
  • Обнулен $UploadPrefixFmt - чтобы все аплоады хранить в папке uploads кучей, без разделения на поддиректории (как и сами страницы pmwiki, что со структурной точки зрения вполне логично). В config.php это выглядит банально как "$UploadPrefixFmt = '';" но честно говоря я еще не уверен, что это правильный шаг. Возможно, от всеобщей коллективизации лучше все же воздержаться.
  • В Site.PageActions добавлено примерно такое условие: "(:if auth edit:) [[Edit -> ?action=edit]] (:if:)", скрывающее от неавторизованного пользователя служебные элементы интерфейса. В шаблон дизайна добавлена скрытая кнопка авторизации.
  • GuiEdit  и расширение MyGuiEdit - набор GUI-кнопочек для удобства редактирования. Кнопочки были доработаны в соответствии с моим набором расширений.
  • ThumbList  - автоматизированный генератор фотогалерей. Самостоятельно создает превьюшки для графических файлов при первом запросе. Интегрирован с Lightbox - известной javascript'овой фотогалереей. Автор скрипта Petko  по моей просьбе любезно доработал скрипт с тем, чтобы титлы превьюшек, если они заданы, передавались в описание фотографии при полноэкранном просмотре. Думаю, он включит изменения в новый релиз; ну а если нет, обращайтесь - вышлю. Примеры работы и синтаксиса здесь, а в config.php это выглядит следующим образом:
  1. ## lightbox JAVAScript gallery with autotrumbs generation | Finar
  2. include_once("$FarmD/cookbook/thumblist2.php");
  3.  
  4. $ThumbList['fPreChecks'] = 'uThumbLightbox';
  5. function uThumbLightbox(&$opt)
  6. {
  7.   global $HTMLHeaderFmt, $ThumbList;
  8.   $linkrel = IsEnabled($opt['rel'], $ThumbList['LinkRel']);
  9.   if(preg_match("/lightbox/i", $linkrel))
  10.   {
  11.     $LightboxDirUrl = "/pub/lb"; # LIGHTBOX DIRECTORY
  12.    $opt['rel'] = 'lightbox[?G]';
  13.     $HTMLHeaderFmt['lightbox'] =<<<EOF
  14. <script type="text/javascript" src="$LightboxDirUrl/prototype.js"></script>
  15. <script type="text/javascript" src="$LightboxDirUrl/scriptaculous.js?load=effects"></script>
  16. <script type="text/javascript"><!--
  17. LightboxDirUrl = "$LightboxDirUrl";//--></script>
  18. <script type="text/javascript" src="$LightboxDirUrl/lightbox.js"></script>
  19. <link rel="stylesheet" href="$LightboxDirUrl/lightbox.css" type="text/css" media="screen"/>
  20. EOF;
  21.   }
  22. }
  23.  
  24. $ThumbList['_tmpl']['awrap'] = "<a href='?L' class='thumblink' title='?2' %2\$s>%1\$s</a> ";
  25. $ThumbList['LinkRel'] = 'lightbox';

Интеграция с Finar.ru

Интеграция одной установленной PmWiki с другими возможна несколькими способами. Расскажу обо всех в порядке уменьшения их кривости и увеличения пригодности к моей задаче. Напомню ее - получить возможность включения любой части контента finar.ru в дизайне web.finar.ru Проследив за моим поиском, вы сможете представить путь продвижения исследования от постановки задачи к очень неожиданному решению. Это именно то, что доставляет мне наибольшее удовольствие при разработке.

  1. Викифермы
Викифермы  как оказалось решают почти противоположную задачу: разделяют контент pmwiki-сайтов, сохраняя общими часть их настроек.
  1. Include через php
Довольно бронебойный способ: через PHPScriptAsWikiMarkupSource  включаем поддержку php внутри wiki-страниц, и грубым инклюдом встраиваем все, что угодно. Способ - весь один большой недостаток, с одним достоинством - универсальностью. Аналогичный я использовал еще в фирме Альт под NetCat для трансляции своего блога.
  1. Прочие вариации разнообразных инклюдов внешнего контента
Здесь  много разнообразных решений на основе готовых php-расширений или внедрения html-тегов (iframe, embed и пр.), но все они обладают очевидным недостатком - включают внешний контент as is, оставляя все ссылки относительными исходному домену. Любой "клик" приведет к уходу с сайта.
  1. Парсинг чужой PmWiki.Страницы через внешний линк с приставкой ?action=source
Чуть более элегантный способ предлагает рецепт IncludeWikiPage . В качестве параметра он просит адрес целевой страницы в режиме просмотра исходного кода (заканчивается на ?action=source), после чего встраивает полученный код в свою страницу. Интересно задумано, но не подходит: все uploads, cookbooks и пр. останутся на другом домене и никак не встроятся в страничку.
  1. Парсинг чужой PmWiki.Страницы через файловую систему "изнутри"
Рецепт Sisterly  доводит идею парсинга чужих страниц до абсолюта: обращение к страницам происходит "изнутри" файловой системы на Сервере, причем скрипт заменяет при этом все относительные ссылки на абсолютные, подставляя верное значение домена. Рецепт крайне любопытен и при определенном старании на нем можно было бы решить поставленную задачу (как-то примерно так: в качестве шаблона для несуществующей страницы делать инклюд аналогичной страницы через Sisterly) но... я нашел куда более простой способ. Отмечу, что Sisterly временно остался в моем арсенале (до завершения миграции Finar.ru), а также что в процессе изучения рецепта был найден следующий баг:

Trouble with recipe I'm trying to start this recipe on pmwiki-2.2.4 under Windows XAMPP. After installing clean pmwiki-2.2.4, the only thing I did was adding

  1. $EnableLinkPageRelative = 0;
  2. $SisterFmt = array(
  3.     'Test' => array(
  4.         'dirfmt' => '$FarmD/wiki.d/{$FullName}',
  5.         'scripturl' => "http://localhost/",
  6.         'attachurlprefix' => "http://localhost/" ),
  7. );
  8. include_once("$FarmD/cookbook/sisterly.php");

to my config.php (I took the values pointing to wiki itselt just to see if it can work. Any other values also does not work)

Immediately after this I get these two warnings in all my pages: "Warning: Invalid argument supplied for foreach() in W:\S(serving).@exc\pmwiki.php on line 406"

"Warning: Cannot modify header information - headers already sent by (output started at W:\S(serving).@exc\pmwiki.php:406) in W:\S(serving).@exc\pmwiki.php on line 1084"

Could you please help me to find how do to solve this problem? Thanks!

Finar, 2009-08-18

Ah, found the bug. I'll need to verify this later (no server access just now), but it should get fixed either by patching sisterly.php's line 40 from

SDVA( $SearchPatterns['farm'], $SearchPatterns['default'] );

to

if (!empty($SearchPatterns['default'])) SDVA($SearchPatterns['farm'], $SearchPatterns['default']);

or by including the following line in your config.php before including Sisterly:

SDV($SearchPatterns['default'], array());

It's a matter of Sisterly incorrectly assuming that some default search pattern has been set, which obviously isn't the default case. — Eemeli Aro August 18, 2009, at 03:52 PM

  1. Расшаривание части страниц
SharedPages  позволяет сделать часть страниц разных pmwiki общими. Фактически все сводится к созданию "публичной" директории и прописывании пути к ней во всех pmwiki. Однако убедительных механизмов перемещения страниц между публичной и закрытой директориями нет. Впрочем, в моем случае нет и особого смысла прятать остальной контент finar.ru от web.finar.ru. Так что вместо расшаривания директории, можно просто направить оба движка на одно общее хранилище страниц. И на один общий /uploads. И /cookbooks. И /Pub... И файл настроек... И... Бинго!
  1. Мой рецепт: использование одной-единственной инсталляции pmwiki
Вместо хитрых схем включения и выключения контента, просто через переменные окружения php обучим pmwiki понимать, по какому домену к ней обращается пользователь. В зависимости от значений будем менять несколько основных переменных в config.php, подключая разный дизайн и создавая у посетителей полную иллюзию независимости сайтов! Никакой головной боли с расширенным синтаксисом, параллельным развитием двух сайтов, правами доступа, обновлениями и пр. Единственное требование - умение хостинга направлять домен второго и третьего уровня на одну директорию (либо создавать "жесткие ссылки"), которое как нельзя кстати реализовано на моем американском www.hostgator.com  Итак, в config.php решение выглядит примерно так:
  1. #определеяем титл в зависимости от домена, по которому обращается посетитель. Меняем необходимые переменные.
  2. if ($_SERVER['HTTP_HOST'] == 'finar.ru' || $_SERVER['HTTP_HOST'] == 'www.finar.ru' ) {
  3.     $WikiTitle = 'Finar.ru - информационный портал';
  4.     #$Skin =
  5.     }
  6.     else if ($_SERVER['HTTP_HOST'] == 'web.finar.ru' || $_SERVER['HTTP_HOST'] == 'www.web.finar.ru' ) {
  7.     $WikiTitle = 'Web-студия "Ph & Ph"'; 
  8.     $DefaultGroup = 'Web';
  9.     $DefaultPage = 'Web.PhPh';
  10.     #$Skin =
  11.     }
  12.     else {
  13.     $WikiTitle = 'домен не определен';
  14.     $DefaultGroup = 'Web';
  15.     $DefaultPage = 'Web.PhPh';
  16.     #$Skin =
  17.     }
2011-01-31: кроме этих настроек, при включенном кэшировании, необходимо также прописывать различные пути для кэша страниц для разных доменов.

К установке при размещении на хостинге

Некоторые рецепты нет смысла применять на локальной машине, но перед публичным релизом я их обязательно задействую:

  • CleanUrls  - человекопонятные ссылки (ЧПУ) через mod_rewrite;
  • FastCache  - кэширование;
  • SEO  - базовая оптимизация для поисковых систем.

Еще несколько рецептов, обязательных к применению в ближайшем будущем

  • RSS  - настройка RSS;
  • EditAttributes  - поля для редактирования title, description.

И, наконец, любопытные рецепты, которые возможно понадобятся в будущем

  • Creole  - включение поддержки универсальной wiki-разметки Creole. Пока плохо реализовано, ждем-с;
  • SocialBookmarkIcons   - кнопки добавления страниц в популярные сервисы закладок. Стоит проверить, есть ли поддержка специфики Рунета;
  • AddThisWidget  - некая автоматизация публикаций контента в блогах. Стоит проверить, есть ли поддержка специфики Рунета;
  • ExcelPaste  - вставка таблиц из excel;
  • PmDocConvert  - интеграция офисных форматов файлов;
  • ConfirmEditNotSaved  - предупреждать, если уходишь со страницы не сохранившись.

О дальнейшей настройке сайта читайте в статье PmWiki как CMS: шаг второй


Оставить комментарий 


Ваше имя:
->