Плагины в Nano-CMS.

Подключение модуля с собственным функционалом.

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

Такой способ, разумеется, есть.

Если Вы можете формализовать, с какими именно переменными работает Ваш модуль, то ничего не стоит подключить его к сайту сразу же за тем модулем, после которого нужные переменные оказываются определёнными.

Тут нужен пример.

Как Вы успели заметить, данный сайт практикует демонстрацию на своих страницах фрагментов кода, подсвеченных на манер PHP редактора. Что, конечно же, делается не руками, а каким-то специальным модулем. В простейшем случае данную задачу можно решить, не выдумывая себе никаких сложностей, нативной функцией PHP highlight_string();

Итого нам потребуется только переменная $_s['content'], становящаяся доступной перед построением меню, но в неизменном виде сохраняющаяся до подключения модуля с дизайном:

   $_s['modules']=array(
      
'err'    => '_error_404.php',
                                    
# Возможное место для нашего модуля.
      
'nav'    => '_menu.php',
                                    
# Ещё одно такое место.
      
'des'    => '_design.php',
   );

Выберем второй вариант:

   $_s['modules']=array(
      
'err'    => '_error_404.php',
      
'nav'    => '_menu.php',
      
'code'   => '_highlight.php'# Внедрённый собственный модуль.
      
'des'    => '_design.php',
   );

Пусть для определённости код модуля будет таким:

<?php /* Выше этой строки в файле ничего не должно быть */

function highlighter($code) {
   
$highlight='';
   
ob_start();
   
highlight_string('<?'.$code.'?>');
   
$highlight=ob_get_contents();
   
ob_end_clean();
   return 
str_replace(
      array(
'?&gt;<','>&lt;?'),
      array(
'<','>'),
   
$highlight);
}

function 
detect_php_and_highlight($code='code') {
   global 
$_s;

   if (
$_s['loc']['path']!='/admin/' and preg_match_all(
      
'~<'.$code.'>(.+)<\/'.$code.'>~Usi',
      
$_s['content'],
      
$arr)
   )  foreach (
$arr[1] as $item)
         
$_s['content']=str_replace(
            
$item,
            
highlighter($item),
            
$_s['content']
         );

   
$_s['content']=preg_replace(
      array(
         
'~<span style="color:([^"]+)"><\/span>~si',
         
'~<'.$code.'><span style="color:([^"]+)">~si',
         
'~</span>([^<]+)</'.$code.'>~si',
      ),
'',
   
$_s['content']);
   
$_s['highlight']=true;
   return;
}

   
detect_php_and_highlight();

/* Ниже этой строки в файле ничего не должно быть. */ ?>

Код службы подсветки PHP-тегов очевидно избыточен, ибо автор счёл нужным убрать лишние теги, создаваемые нативной функцией языка. Также тут есть избыточная сложность, без которой данный код наотрез отказывался корректно отображать сам себя вследствие возникающей рекурсии.

Внимательному наблюдателю также может быть не совсем понятно, зачем тут определена переменная $_s['highlight'], ежели она не используется. Но это важная и нужная переменная - ключ элемента массива ассоциирован с именем файла модуля (его имя _highlight.php), а сама переменная своим существованием сообщает движку, что модуль нашёлся, и был успешно подключен.

Вы обязаны создать переменную такого вида с фрагментом имени файла модуля в качестве ключа, и приравнивать её чему-либо, что не равно false. Иначе движок сайта скажет, что модуль не найден, и откажется работать дальше.

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

Где размещать файл модуля?

Идеология та же, что и для собственных модулей движка - если модуля не окажется в папке файла с контентом собираемого документа, он будет заимствован из корневой папки документов ./data/content/ - туда свой модуль и кладите.

Как им пользоваться?

Просто написать в HTML коде документа:

<code> /* Внутри контейнера какой-то PHP код. Пример: */ phpinfo(); </code>

Получится так:

 /* Внутри контейнера какой-то PHP код. Пример: */ phpinfo(); 

Собственный модуль для отдельного документа.

Если требуется подключить модуль для работы с ним из отдельного документа, причём сайту в целом этот модуль для работы не нужен, можно прямо в самом документе переназначить массив с модулями. Либо тупо целиком:

   $_s['modules']=array(
      
'err'    => '_error_404.php',
      
'nav'    => '_menu.php',
      
'code'   => '_highlight.php',     # Внедрённый собственный модуль.
      
'des'    => '_design.php',
   );

Либо, если все нужные модули уже указаны в файле настроек, а нам надо всего лишь внедрить ещё один, то добавляем его к массиву модулей:

   $_s['modules']['code']='_highlight.php';

На вопрос, не проще ли было модуль заинклюдить в код файла документа, ответ чрезвычайно прост: на этом этапе сборки документа те объекты, к которым применяется функционал модуля, могут быть ещё даже не сформированы. То есть отсутствовать в наличии, и появляться лишь в дальнейшем.