Конфиг
(farm)Config.php
farmconfig.php основной файл, включающий в себя все нижеследующие
<?php if (!defined('PmWiki')) exit(); include_once("$FarmD/local/farmconfig-core.php"); // НАСТРОЙКИ ЯДРА : определяют базовое поведение PmWiki на уровне ее ядра // ВРЕМЕННО, только для XAMPP: $PubDirUrl = "https://www.pmwiki.ru/pub"; $FarmPubDirUrl = $PubDirUrl; include_once("$FarmD/local/farmconfig-markup.php"); // НАСТРОЙКИ РАЗМЕТКИ : определяют обработку разметки и отображение контентной области include_once("$FarmD/local/farmconfig-patterns.php"); // НАСТРОЙКИ ПАТТЕРНОВ : определяют логику исключений листингов страниц при выборках и поиске, настройки pagelist if (file_exists("$LocalDir/config-ThisSite.php")) include_once("$LocalDir/config-ThisSite.php"); // ЛОКАЛЬНАЯ КОНФИГУРАЦИЯ include_once("$FarmD/local/farmconfig-REXT.php"); // REXT-переменные и модификации include_once("$FarmD/local/farmconfig-editMode.php"); // РЕЖИМ РЕДАКТИРОВАНИЯ ### РЕЦЕПТЫ ### if (!$rextKeepCore) { include_once("$FarmD/cookbook/phFieldProcessing.php"); $phFieldProcessingArr = array( 'title' => 'text', 'description' => 'text', // 'CustomHeadCode' => 'textarea', // внимание, с Заглавной Буквы! ); phFieldProcessing($phFieldProcessingArr); phCtimeProcessing(); $phKeepFields = $phFieldProcessingArr; $phKeepFields['ctime'] = 'text'; // блокируем перезапись полей старницы if ($action == "pmform") phFieldsKeeper($phKeepFields); } if (!CondAuth($pagename,'edit')) $EnablePostCaptchaRequired = 1; include_once("$FarmD/cookbook/captcha.php"); // https://www.pmwiki.org/wiki/Cookbook/Captcha временно! include_once("$FarmD/cookbook/phAddObjectModalForm.php"); include_once("$FarmD/cookbook/phAdminPanel.php"); include_once("$FarmD/cookbook/phMultyTags.php"); include_once("$FarmD/cookbook/pagelistmultitargets.php"); // PageListMultiTargets ( http://www.pmwiki.org/wiki/Cookbook/PageListMultiTargets ) $EnablePLMTLink = 1; include_once("$FarmD/cookbook/phWikirama.php"); // требует Mini! include_once("$FarmD/cookbook/mini.php"); // Mini ( https://www.pmwiki.org/wiki/Cookbook/Mini ) include_once("$FarmD/cookbook/ddmu.php"); // DragDropMultiUpload include_once("$FarmD/cookbook/phAttachMan.php"); $phAttachman['EnableDelete'] = true; $phAttachman['TableClass'] = 'table sortable'; $phAttachman['TextareaInsertCommands']['gif'] = 'Mini:%filename%'; $phAttachman['TextareaInsertCommands']['jpg'] = 'Mini:%filename%'; $phAttachman['TextareaInsertCommands']['jpeg'] = 'Mini:%filename%'; $phAttachman['TextareaInsertCommands']['png'] = 'Mini:%filename%'; $phAttachman['TextareaInsertTemplate'] = "<a href='#' class='ph-dashed'><span>%TextareaInsertCommand%</span></a><br>"; SDV($HandleAuth['pmform'], 'read'); include_once("$FarmD/cookbook/pmform.php"); $PmForm['comments'] = 'saveto={$FullName} form=#commentform fmt=#talkpost'; $PmFormTemplatesFmt = array_merge(array('ThisSite.CommentsTemplates'),$PmFormTemplatesFmt); // add new templates sources $MarkupExpr['inc'] = 'MxInc($args[0])'; // used for comments counting function MxInc ($arg) { if(!is_numeric($arg)) return $arg; return $arg + 1; } if (file_exists("$LocalDir/config-ThisSite-finality.php")) include_once("$LocalDir/config-ThisSite-finality.php"); // ЛОКАЛЬНАЯ КОНФИГУРАЦИЯ: построцессинг
ЯДЕРНЫЕ НАСТРОЙКИ (farmconfig-core.php)
<?php if (!defined('PmWiki')) exit(); ### ЯДЕРНЫЕ НАСТРОЙКИ: определяют базовое поведение PmWiki ### $DefaultGroup = 'Index'; $DefaultPage = 'Index.Index'; $ScriptUrl = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://"; $ScriptUrl = $ScriptUrl.$_SERVER['HTTP_HOST']; $WikiDir = new PageStore('wiki.d/{$Group}/{$FullName}'); // см. pmwiki.org/wiki/Cookbook/PerGroupSubDirectories // - In international wikis, this code should appear before the call to the XLPage() function. // - использование $FullName обязательно $EnablePathInfo = 1; // Use "Clean URLs" include_once("$FarmD/scripts/xlpage-utf-8.php"); // Unicode (UTF-8) allows the display of all languages and all alphabets. XLPage('ru','PmWikiRu.XLPage'); $EnableLinkPageRelative = 1; // генерить относительные ссылки вместо абсолютных $TimeFmt = '%Y-%m-%d, %H:%M'; // представление времени на всем сайте // $EnableRedirectQuiet = 1; // todo: при случае удалить, непонятно, зачем это $FarmPubDirUrl = "https://".basename(realpath(dirname(__FILE__) . '/..'))."/pub"; // это автоматическое определение директории фермы (например, "http://master.pmwiki.ru/pub"). В зависимоти от хостинга оно может глючить, в этом случае пропишите путь статично; if (@$rextMaster) $LockFile = "$FarmD/wikilibThis.d/.flock"; $WikiLibDirs = array(&$WikiDir, new PageStore('$FarmD/wikilibThis.d/{$FullName}', @$rextMaster), // служебные страницы REXT редактируются только из мастера new PageStore('$FarmD/wikilib.d/{$FullName}'));
НАСТРОЙКИ РАЗМЕТКИ (farmconfig-markup.php)
<?php if (!defined('PmWiki')) exit(); ### РАЗМЕТКА и ее Настройки ### $HTMLPNewline = '<br>'; // теперь перенос строки = <br> $WikiStyleApply['a'] = 'a'; // возможность назначать классы/стили прицельно для ссылок через %apply=a ...%. Нужно, например, чтобы делать %apply=a class="btn btn-default" data-toggle="collapse"%[[#collapseExample|Показать меню раздела]], т.е. применять классы к ссылкам на якоря. Внимание: классы нельзя будет применять к ссылкам на wiki-страницы (см. pmwiki.org/wiki/PmWiki/WikiStyles-Talk), для этого придется переназначить шаблон генерации ссылок вот так: $LinkPageExistsFmt = "<a href='\$LinkUrl' title='\$LinkAlt'>\$LinkText</a>"; SDVA($WikiStyleAttr,array( // чтобы можно было делать кнопки-действия Bootstrap с помощью PmWiki-разметки 'data-toggle' => 'a', 'data-target' => 'a', )); $ToggleNextSelector = 'div.pmtoggle, p.pmtoggle, dl.pmtoggle dt, h4'; // ( см. pmwiki.org/wiki/Cookbook/ToggleNext, pmwiki.ru/Cooks/Toggles ) // Настройки -> Таблицы: $SimpleTableDefaultClassName = "table"; // дефолтный класс таблиц $EnableSortable = 1; // класс 'sortable' добавляет сортировку по содержимому столбцов (при клике на заголовок) // Контентная разметка Markup('lazyweb','<wikilink', "/\\bwww\\.[^\\s$UrlExcludeChars]*[^\\s.,?!$UrlExcludeChars]/e", "Keep(MakeLink(\$pagename,'http://$0','$0'),'L')"); // Делать ссылкой любой текст, начинающийся с "www." Markup('--', 'inline', '/ \-\- /', ' — '); // замена двойного дефиса ("--") на тире Markup('...', 'inline', '/\.\.\./', '…'); // замена трех точек на троеточие // Дополнительные html-теги # Общий принцип создания новых тегов: @%html_тег%@ ... @@. Исключение plainText, см. ниже Markup('@mark@','inline','/@mark@(.*?)@@/','<mark>$1</mark>'); Markup("plainText","block","/@-@(.*?)@@/",'<:block,1>$1'); // разметка @-@вики-код@@ для вывода чего-либо "как оно есть", т.е. без обвязывания в <p>. Используется, например, чтобы в макете дизайна выводить классы из настроек, заданных через PTV на страницах сайта вот так: <!--markup:@-@{ThisSite/SkinConfig$:Container}@@-->
НАСТРОЙКИ ПАТТЕРНОВ (farmconfig-patterns.php)
<?php if (!defined('PmWiki')) exit(); ###BASENAME PATTERNs: какие страницы считать "дополнительными" # "дополнительные" страницы позволяют обратиться к родителю через {$BaseName} PageVariable (см. pmwiki.org/wiki/PmWiki/BasicVariables#BaseName) # в REXT такие страницы участвуют в генерации Хлебных Крошек; # также они могут как-то влиять на поведение страниц, ведь у них есть родитель. Можно это использовать и создавать локальное поведение прямо через wiki-разметку # также полезно не забывать о таких страницах в групповых шаблонах (GroupHeader, GroupFooter), например при выводе комментариев $BaseNamePatterns['/-Archive$/'] = ''; // страницы вида *-Archive $BaseNamePatterns['/-Template$/'] = ''; // страницы вида *-Template $BaseNamePatterns['/-Sub-.+/'] = ''; // страницы вида *-Sub-* // почему не добавлено '*-Demo' ? Потому что пока не очевидна необходимость, т.к., вероятно, демо-страниц чаще больше, чем одна ### PAGELISTS ### $SearchPatterns['normal']['ph-MainsOfGroups'] = '!^(.*?)\\.\\1$!'; // удаляем страницы вида Name.Name, т.е. Главные групп $SearchPatterns['normal']['ph-exclude-groups'] = '!ThisSite!'; // удаляем из листингов формата "list=normal" все группы вида ThisSite* . $SearchPatterns['normal']['self'] = 0; //для list = normal добавляем листинг текущей страницы. /* Давайте-ка я поясню, почему сделано так :) В pagelist.php оно описано вот так: SDVA($SearchPatterns['normal'], array( 'recent' => '!\.(All)?Recent(Changes|Uploads)$!', 'group' => '!\.Group(Print)?(Header|Footer|Attributes)$!', 'self' => str_replace('.', '\\.', "!^$pagename$!"))); Что это значит? Что при осуществлении pagelist'инга все на тот момент еще не существующие элементы массива будет созданы. В данный момент массива вообще еще нет, поэтому создадим его, соответствующий ключ, и занулим его. TODO: возможно, его надо не занулять а... я не знаю что, но зануление вроде тоже работает. */ SDV($FPLTemplatePageFmt, array('{$FullName}','ThisSite.PageListTemplates','{$SiteGroup}.PageListTemplates')); // расширяем список страниц, где следует искать шаблоны pagelist SDV($MetaRobots, // закрываем от индексации группу ThisSite, в дополнение к уже закрытым ($action!='browse' || !PageExists($pagename) || preg_match('#^PmWiki[./](?!PmWiki$)|^Site(Admin)?[./]|^ThisSite?[./]#', $pagename)) ? 'noindex,nofollow' : 'index,follow');
Локальные настройки текущего сайта (config-ThisSite.php)
Этот файл вызывается из farmconfig.php командой
if (file_exists("$LocalDir/config-ThisSite.php")) { include_once("$LocalDir/config-ThisSite.php")};
Таким образом он выполняется только тогда, когда существует в локальной файловой системе.
Этот файл должен существовать в локальной файловой системе всегда (даже на дочерней ферме), т.к. в нем определены доступы к системе.
Локальные настройки нужны для индивидуализации сайта, работающего на REXT. Минимальный набор этих настроек вот такой:
$WikiTitle = 'PmWikiRUS'; // название вашего сайта $Skin = 'thisSite'; // скин $DefaultPasswords['edit'] = pmcrypt('secret_pass1'); // пароль на редактирование $DefaultPasswords['admin'] = pmcrypt('secret_pass2'); // пароль администратора
Дальнейшую индивидуализацию системы рекомендуется производить в этом же файле. К примеру, вот что сделано на pmwiki.ru :
# Локальные настройки pmwiki.ru : $EnableHighlight = 1; $HTMLHeaderFmt['Highlight'] = '<link rel="stylesheet" href="$FarmPubDirUrl/!phph/!phph-pack-collection/highlightjs/default.min.css" /> <script src="$FarmPubDirUrl/!phph/!phph-pack-collection/highlightjs/highlight.min.js"></script>'; $PmTOC['Enable'] = 1; // автоматическая генерация содержания $PmTOC['MaxLevel'] = 3; if (isset($_GET['skin'])) $Skin = $_GET['skin']; // скин можно менять через GET
НАСТРОЙКИ REXT (farmconfig-REXT.php)
<?php if (!defined('PmWiki')) exit(); ### REXT-переменные: используются в REXT-функционалах ### # Эти переменные не рекомендуется использовать, если нет полной уверенности что задача не решается по-другому. # Не используйте их вне (farm)config.php # Старайтесь реализовать задуманное через переменные ядра PmWiki (см. pmwiki.org/wiki/PmWiki/Variables). ###---------------------------------------------------### # $rextMaster = true; -- эта переменная определена в index.php. Она нужна, как минимум, для определения мастер-копии и открытия /wikilibThis.d/* на запись. $rextMainSkin = $Skin; // нужно, чтобы в editMode.tmpl (и других шаблонах) знать, какой у нас "был" скин, чтобы подтянуть соответствующий CSS $makeRedirect = strpos($pagename,"."); // страницы вида /ThisSite.EditForm почему-то тоже обрабатываются движком, сделаем редирект (предлагал внести в ядро: pmwiki.org/wiki/Cookbook/CleanUrls-Talk ) if ($makeRedirect !== false && $action == "browse") { $makeRedirect = str_replace(".","/",$pagename); header("HTTP/1.1 301 Moved Permanently"); header("Location: $ScriptUrl/$makeRedirect"); exit(); } unset($makeRedirect); $rextName = explode("/", $pagename); $rextGroup = $rextName[0]; // текущее Имя страницы $rextName = $rextName[1]; // ...и Группу. Сделано вручную, т.к. см. pmwiki.org/wiki/PITS/01423 if ($rextGroup == 'Site' || $rextGroup == 'SiteAdmin' || ($rextGroup == 'ThisSite' && $rextName == 'EditForm')) $rextKeepCore = true; // чтобы при необходимости оставлять "базовый" функционал движка, отключая всё, что может быть не совместимо с ним if ($rextKeepCore) unset($Skin); // удаление $Skin возвращает системный скин
РЕЖИМ РЕДАКТИРОВАНИЯ (farmconfig-editMode.php)
<?php if (!defined('PmWiki')) exit(); ### РЕЖИМ РЕДАКТИРОВАНИЯ ### $UploadPrefixFmt = '/$Group/$Name'; // сортировать uploads по файловой структуре в соответствии с URL $UploadMaxSize = 20971520; // лимит на загружаеый файл - 20 МБ $UploadExts['pdf'] = 'application/pdf'; $UploadExts['csv'] = 'text/csv'; $EnableNotSavedWarning = 1; $EnableUpload = 1; // замена пробелов на подчеркивание, конвертация в транслит (см. pmwiki.org/wiki/PmWiki/UploadVariables-Talk ) $UploadNameChars = "-a-zA-Z0-9_. "; $MakeUploadNamePatterns = array( '/^.*$/' => 'cyr2ascii', # your custom function '/ +/' => '_', # space(s) to underscore "/[^$UploadNameChars]/" => '', # same as in scripts/upload.php '/(\\.[^.]*)$/' => 'cb_tolower', '/^[^[:alnum:]_]+/' => '', '/[^[:alnum:]_]+$/' => '' ); function cyr2ascii($m) { # the filename is $m[0] $cyr = [ 'а','б','в','г','д','е','ё','ж','з','и','й','к','л','м','н','о','п', 'р','с','т','у','ф','х','ц','ч','ш','щ','ъ','ы','ь','э','ю','я', 'А','Б','В','Г','Д','Е','Ё','Ж','З','И','Й','К','Л','М','Н','О','П', 'Р','С','Т','У','Ф','Х','Ц','Ч','Ш','Щ','Ъ','Ы','Ь','Э','Ю','Я' ]; $lat = [ 'a','b','v','g','d','e','io','zh','z','i','y','k','l','m','n','o','p', 'r','s','t','u','f','h','ts','ch','sh','sht','a','i','y','e','yu','ya', 'A','B','V','G','D','E','Io','Zh','Z','I','Y','K','L','M','N','O','P', 'R','S','T','U','F','H','Ts','Ch','Sh','Sht','A','I','Y','E','Yu','Ya' ]; return str_replace($cyr, $lat, $m[0]); } if (@$_POST['diffclass'] == 'minor') { // не вносить минорные изменения в *RecentChanges unset($RecentChangesFmt['$SiteGroup.AllRecentChanges']); unset($RecentChangesFmt['$Group.RecentChanges']);} $EnableGUIButtons = 1; // далее определяем кнопки режима редактирования. Цифры - это "приоритет", они определяют последовательность кнопок. $GUIButtons ['underline'] = array(115, '{+', '+}', '$[text]', '$GUIButtonDirUrlFmt/underline.gif"$[Underline]"'); $GUIButtons ['strikout'] = array(120, '{-', '-}', 'Crossed Out Text', '$GUIButtonDirUrlFmt/strikethrough.gif"Strike Out"'); $GUIButtons ['pagelink'] = array(200, '[[Group.Page|',']]', '$[Page link]', '$GUIButtonDirUrlFmt/pagelink.gif"Link to internal page"'); $GUIButtons ['extlink'] = array(210, '[[http:// |',']]', '$[http:// | link text]', '$GUIButtonDirUrlFmt/extlink.gif"Link to external page"'); $GUIButtons ['attach'] = array(220, 'Attach:','', '$[file.ext]', '$GUIButtonDirUrlFmt/attach.gif"Attach File"'); $GUIButtons ['left'] = array(405, '%left%', '', '', '$GUIButtonDirUrlFmt/left.gif"$[Align Left]"'); $GUIButtons ['right'] = array(420, '%right%', '', '', '$GUIButtonDirUrlFmt/right.gif"$[Align Right]"'); $GUIButtons ['textblue'] = array(450, '%blue%', '%%', '$[Blue Text]', '$GUIButtonDirUrlFmt/hightextblue.gif"$[Blue Text]"'); $GUIButtons ['textred'] = array(460, '%red%', '%%', '$[Red Text]','$GUIButtonDirUrlFmt/hightextred.gif"$[Red Text]"'); $GUIButtons ['bgblue'] = array(480, '%bgcolor=blue white%', '%%', '$[Background Blue]', '$GUIButtonDirUrlFmt/highbgblue.gif"$[Blue Text]"'); $GUIButtons ['bgred'] = array(481, '%bgcolor=red white%', '%%', '$[Background Red]', '$GUIButtonDirUrlFmt/highbgred.gif"$[Red Text]"'); $GUIButtons ['bgyellow'] = array(482, '%bgcolor=yellow%', '%%', '$[Background Yellow]', '$GUIButtonDirUrlFmt/highbgyellow.gif"$[Yellow Text]"'); $GUIButtons ['anchor'] = array(500, '[[#', ']]', '$[Anchor Name]', '$GUIButtonDirUrlFmt/anchor.gif"$[Invisible Anchor to Link To]"'); $GUIButtons ['hr'] = array(590, '\\n----\\n', '', '', '$GUIButtonDirUrlFmt/hr.gif"$[Horizontal rule]"'); $GUIButtons ['quotes'] = array(595, '«', '»', '$[Quoted Text]', '$GUIButtonDirUrlFmt/quotes.gif"russian quotes"'); $GUIButtons ['code'] = array(600, '[@', '@]', '$[UnCoded Text]', '$GUIButtonDirUrlFmt/code.gif"Preformated Code"'); $GUIButtons ['return'] = array(650, '[[<<]] \\n', '', '','$GUIButtonDirUrlFmt/return.gif"Return"'); if ( $action == 'edit' && !$rextKeepCore ) { $_REQUEST['preview'] = 1; // чтобы (:e_preview:) показывалось всегда $Skin = 'editMode'; $PageEditForm = 'ThisSite.EditForm'; // кастомная форма редактирования # phOnClickMarkupper $HTMLFooterFmt['scripts']['OnClickMarkupper.js-sitemap']= "<script>phOnClickMarkupper('#sitemap a', 'HREF', '[[%GOAL%|+]]', 'clicked-by-user', 'text');</script>"; $HTMLFooterFmt['scripts']['OnClickMarkupper.js-attaches']= "<script>phOnClickMarkupper('#attachman .phAttachman_markup a', 'span', '%GOAL%', 'clicked-by-user', 'text');</script> <style>a.clicked-by-user {opacity: 0.5;}</style>"; }
О последовательности исполнения файлов
В обычном режиме последовательность такая (определена в farmconfig.php):
- local/ farmconfig-core.php
- local/ farmconfig-markup.php
- local/ farmconfig-patterns.php
- local/ config-ThisSite.php — этот файл обязан существовать, рекомендуется всю локальную конфигурацию стремиться хранить в нём
- local/ farmconfig-REXT.php
- local/ farmconfig-editMode.php
- подключение Рецептов из cookbook/
- local/ config-ThisSite-finality.php — этот файл может существовать, он предназначен для site-wide кастомизаций, требующих наличия подключенных рецептов;
- страничные файлы вида local/ Group.Name.php
- групповые файлы вида local/ Group.php
В режиме дочернего сайта вики-фермы:
- master_local/ farmconfig-core.php — внимание, код забирается с master-фермы
- master_local/ farmconfig-markup.php
- master_local/ farmconfig-patterns.php
- local/ config-ThisSite.php — внимание, код забирается из локальной файловой системы дочернего сайта. Этот файл обязан существовать, рекомендуется всю локальную конфигурацию стремиться хранить в нём.
- master_local/ farmconfig-REXT.php
- master_local/ farmconfig-editMode.php
- подключение Рецептов из master_cookbook/
- local/ config-ThisSite-finality.php — этот файл может существовать, но в режиме вики-фермы не рекомендуется его использовать,
- local/ config.php — файл будет исполнен, если он существует. Можно использовать для локального подключения Рецептов или перенастройки параметров существующих Рецептов.
- страничные файлы вида local/ Group.Name.php
- групповые файлы вида local/ Group.php