FieldProcessing (создание полей) дополнительные input-поля для удобства ввода данных

По-умолчанию PmWiki, как и Википедия, не предоставляет пользователям никаких полей, кроме собственно текста страницы, имени автора, вносящего изменения, и комментария к ним. Для более классических применений движка это не очень удобно: хочется иметь возможность редактировать, как минимум, название, описание, дату создания страницы.

Кроме того, для создания структурированной навигации пригодится дополнительная фильтрация статьей по типам, которую можно реализовать через удобные поля вида <checkbox> или <radio>.

Что это делает?

Этот рецепт позволяет автоматизировать создание новых полей:

  • строк (тип text)
  • логических галок (тип checkbox)
  • текстовых блоков (тип textarea)

Эти поля появятся в режиме редактирования сайта и их смогут заполнять редакторы сайта. Содержимое полей можно будет вызывать через переменные, как макете дизайна, так и в контенте страницы, или же при pagelist'инге.

Демо

Техническая информация

Требования

Предположительно, рецепт совместим с оригинальной PmWiki и не имеет никаких специальных требований.

Как это работает

Функционал получает на вход массив необходимых полей, примерно вот такой:

'title' => 'text', 
'description' => 'text',
'CustomHeadCode' => 'textarea',
'NewChekbox' => 'chechkbox'

Важно! Все нестандартные (т.е. новые) переменные должны начинаться с заглавной буквы!

Для каждого элемента входного массива:

  • создается Page Variable: расширяем массив $FmtPV названиями наших полей, значения забирая из физического файла страницы, если оно там есть. Теперь их можно использовать как угодно: в шаблоне макета дизайна, при pagelist'инге и т.д.
    • отдельно создаются Page Variable для полей типа checkbox, вида phFieldProcessing_".%имя_поля% . При листинге это позволяет создавать CSS-классы для тех страниц, где стоят галки
  • если мы в режиме редактирования, генерим правильные intput'ы для этих полей;
  • при сохранении, значения из input'ов формы редактирования записываем в файл.

Таким образом достигается возможность сохранять новые поля в страницах. Поля можно использовать для:

  • простого хранения информации (в полях типа «text»)
  • сортировки по категориям (в полях типа «radio»)
  • специфического оформления (в полях типа «checkbox»)
  • выборки материалов по значениям полей.

Подключение, настройки, использование

Подключение в (farm)config.php:

 $phFieldProcessing_AccessLevel = "admin";
 include_once("$FarmD/cookbook/phFieldProcessing.php");
 $phFieldProcessingArr = array( … )
 phFieldProcessing($phFieldProcessingArr);         
 phCtimeProcessing();

Здесь:

  • $phFieldProcessing_AccessLevel  — необязательный параметр, уровень доступа пользователей, которым будет доступен функционал (по-умолчанию — edit);
  • $phFieldProcessingArr - массив полей, которые вы хотите создать;
  • phFieldProcessing() — вызов основной функции;
  • phCtimeProcessing() — вызов функции для поля ctime

Иллюстрирующий пример:

Создаем в config.php новые поля следующей командой:

$phFieldProcessingArr = array( 	
            'Marked' => 'checkbox', // важно, поле должно называться в заглавной буквы!
            'Archive' => 'checkbox',      
             );
phFieldProcessing($phFieldProcessingArr);

В результате, если в режиме редактирования будет установлена соответствующая галка, будут созданы следующие PageVariables:

  1. {$Marked} со значением 1
  2. {$Class_Marked}: со значением "phFieldProcessing_Marked"

Внимание, если галка не стоит, соответствующие переменные вообще не будут созданы.

Затем необходимо создать input'ы , добавив их на страницу режима редактирования с помощью wiki-синтаксиса.

  • либо командой (:input e_ИмяПоля:) для текстовых полей и чекбоксов
  • либо вручную командой вида (:input select name=ИмяПоля[] ИмяОпшена ТитлОпшена multiple size=10:) для radio, select.

Теперь можно редактировать страницы и добавить вызов новых полей через соответствующие PageVariables там, где они вам нужны.

Если есть необходимость заменить системные поля, например author, ctime, title, то надо отдельно озаботиться отключением их обработки движком PmWiki с помощью системной функции DisableMarkup().

Также в рецепте предусмотрена служебная функция phFieldsKeeper(). Функция принимает на вход массив из полей и обеспечивает их сохранение при перезаписи страницы. Функция нужна для того, чтобы сохранять поля при обработке страниц другими функционалами.

Пример использования:

 $phKeepFields = $phFieldProcessingArr; $phKeepFields['ctime'] = 'text'; // блокируем перезапись полей старницы
 if ($action == "pmform") phFieldsKeeper($phKeepFields); 

Служебная информация

Status
stable
Core
yes
PHPcookbook
phFieldProcessing.php

Version
20200612

ChangeLog

2020-07: автоматический вызов DisableMarkup();

При сохранении полей "title" и "description", в момент сохранения теперь вызывается DisableMarkup(); для соответствующего поля. Таким образом, используемый в разметке страницы вызов (:description:), если он будет, не сработает. До этого патча наличие директивы (:description:) в теле страницы приводило к дополнительной дозаписи его значения в конец поля. Чтобы избежать этого, приходилось выполнять DisableMarkup(); на более общем уровне (например, для целой Группы), из-за чего в html-коде страницы появлялся соответствующий текст вызова, а обработка директивы не производилась.

Таким образом, теперь приоритет всегда отдан значению, вписанному в поле вручную, но сохранена и обратная совместимость с вызовом из кода.

2020-06: проведен еще один рефакторинг:

  • добавлена функция phFieldsKeeper();
  • добавлен параметр $phFieldProcessing_AccessLevel: проведена работа над ошибками с безопасностью;
  • обработка поля даты снова вернулась в основной файл, а Мультитеги окончательно отделились в MultyTags (структурированные теги)
  • добавлен HTML5 DatePicker

2017-02-10: проведен рефакторинг: рецепт обновлен и разделен на три части:

  • phFieldProcessing-ctime.php
  • phFieldProcessing-multytags.php
  • phFieldProcessing.php

2017-11-17:

PV с названием класса для чекбоксов теперь делается о шаблону phFieldProcessing_%имя_поля%

~2011: рецепт создан

Рецепт изначально создавался для личных нужд и не предполагал публичного применения. Поэтому написан был криво, косо и небезопасно.

Todo

Рецепт очень старый, и его код выглядит "рыхло". Но при этом он работает. Переписывать всё целиком не хочется, а делать рефакторинг стоит тогда, когда будет конкретная задача.

Рецепт довольно сложный. Описание его [большого] смысла и [разнообразных] способов применения требует отдельной статьи.

Todo:git

  • важный баг: при установке checkbox в поле первый раз записывается "on", а не 1, как ожидается. Ожидаемое значение записывается при втором сохранении страницы.
  • значения текстовых полей вообще не попадают в поисковый индекс. Как минимум, нужно наметить пути решения этой проблемы.

Todo:someday

Некоторые идеи:

  • возможно, следует создавать PV для всех полей, а не только для checkbox
  • предложить подход и сделать обработку внешнего вида форм в зависимости от уровня доступа текущего юзера:
    • input-формы создаются только если есть доступ [ см. вызов phMakeFields($key,$value) ]. Из-за этого у пользователей с недостаточными правами формы не видны вообще. Лучше было бы показывать формы как readonly, а также не обрабатывать их на серверной стороне. Для этого придется перетащить условия if (CondAuth($pagename, "$phFieldProcessing_AccessLevel")) из phFieldProcessing внутрь функции phMakeFields(). И аналогично переработать phCtimeProcessing
  • проверить совместимость рецепта с ядром PmWiki. Если совместимо — возможно стоит перевести и выложить на pmwiki.org