Конфиг
(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