- Что такое
- Как создать
- Вызов сниппета
- Параметры
- Подборка полезных мини сниппетов для разработчиков
- Красивый вывод цифр (цен) с пробелами, используя php number_format
- Удаляем последний символ в строке
- Формирование корректной ссылки с атрибутом tel при выводе телефона на сайте
- Склоняем числовые определения
- Убирает лишние символы в строке
- Запись в сессию и вывода значения какой-либо переменной
- Время чтения
- Breadcrumb JSON-LD
- alternate hreflang
- FileSize — вывод размера файла и расширения файла
- FaviconGenerator — aвтоматическая генерация favicon
В предыдущей статье мы разбили шаблон на чанки (мы к ним еще вернемся по мере разработки). Теперь разберемся, что такое сниппеты и создадим первый сниппет «year», который будет автоматически выводить текущий год. Год нам пригодится, например, в подвале, где указан Copyright. Чтобы каждый год его не менять вручную, MODX будет подставлять год автоматически.
Что такое
MODX сниппет — это контейнер (как чанк), но содержащий в себе не HTML, а PHP код, и их можно подключать в любые места: страниц, шаблоны, ресурсы, чанки.
Как создать
Что бы создать сниппет в MODX в дереве документов на вкладке «Элементы» нажмите на копку «Новый сниппет». Затем на открывшейся странице укажите имя (year), описание, категорию и вставьте код.
Код сниппета «year» следующий (см. синтаксис языка PHP):
<?php
echo date('Y');
“?>” прописывать не нужно. Если пропишите, то парсер MODX всё равно её проигнорирует. В принципе, и объявление PHP скрипта в виде “<?php” можно не прописывать, код будет исполняться корректно и без этого. Но для наглядности я привык прописывать это указание на то, что перед нами скрипт на языке PHP.
Если вы используете парсер fenom и у вас включена настройка pdotools_fenom_php, то вы можете вывести текущий год так.
{'' | date : 'Y'}
Получается так мы избавились от сниппета, как и до этого от чанков)
Вызов сниппета
Вывод сниппетов аналогичен чанкам, для вызова не кэшируемого сниппета используем [[name_snippet]]:
© Copyright 2022 - [[year]] [[++site_name]]. Все права защищены.
В код выведется: Copyright 2022 — 2023 Название сайта. Все права защищены.
Где название сайта берется из системных настроек: site_name (скоро до них дойдем).
Если нужен не кэшируемый вывод, то вызывается всегда по аналогии — с восклицательным знаком вначале [[!name_snippet]].
Вышеприведенный код на fenom.
© Copyright 2022 - {'year' | snippet} {$_modx->config.site_name}. Все права защищены.
или
© Copyright 2022 - {'' | date : 'Y'} {$_modx->config.site_name}. Все права защищены.
В общем открываете чанк в котором хранятся сквозные блоки, или шаблон base и в подвале в блоке copyright прописываем одну из конструкций указанных выше.
Параметры
Сниппеты могут иметь параметры — php-переменные, которые можно инициализировать во время вызова.
Например усложним код нашего сниппета, до
<?php
$year = date("Y");
if($year == $start) {
return $year;
} else {
return ''.$start.' – '.$year.'';
}
Здесь мы добавили параметр start, следовательно, можем указать:
Copyright [[year? &start=`2022`]] [[++site_name]]. Все права защищены.
В код выведется то же самое, что и в предыдущем случае.
Указываются параметры в вызове сниппета после знака вопроса (?).
В случае с феном вызов будет следующим.
{'year' | snippet : [
'start' => '2022'
]}
Если вы не особо знаете PHP (или вообще не знаете) — не переживайте, его знание для создания среднестатистического сайта не требуется. Тем более есть куча готовых решений, часть из них ниже. На худой конец если вообще не шарите в php и не нашли готового сниппета, то код снипетов (по крайней мере простеньких), может сгенерить chat gpt.
Подборка полезных мини сниппетов для разработчиков
Красивый вывод цифр (цен) с пробелами, используя php number_format
Вариант 1. (numformat)
<?php
if(strlen($input)==0) return '';
$input = floatval(str_replace(array(' ',','), array('','.'), $input));
return number_format($input,(floor($input) == $input ? 0 : 2),'.',' ');
Использование:
[[*price:numformat]]
Было: 33354567
Стало: 33 354 567
Вариант 2. (nPrice)
<?php
if ($price == "")
$price_output = $modx->resource->getTVValue('Price');
else
$price_output = $price;
return number_format($price_output, 0, '', ' ' );
Использование:
В месте, где у Вас выводится цифровое поле (цена), вставляем (пусть будет TV с именем price):
[[nPrice?price=`[[*price]]`]]
Ну или если у вас магазин на minishop2 то, вместо вывода [[+prise]] пишем:
[[nPrice?price=`[[+price]]`]]
Удаляем последний символ в строке
last
<?php
return mb_substr($input, 0, -1);
Примечание: Полезно при формировании каких-либо последовательностей (например, ID ресурсов через запятую), у которой последний символ вызывает ошибку.
Использование:
[[*resources:last]]
Было: 33,35,45,67,
Стало: 33,35,45,67
Формирование корректной ссылки с атрибутом tel при выводе телефона на сайте
phone
<?php
$p1 = array(" ", "-", "(", ")");
$p2 = array("", "", "", "");
return str_replace($p1, $p2, $input);
Примечание: Удаляются скобки, дефисы и т. д.
Использование:
<a href="tel:[[++phone:phone]]">[[++phone]]</a>
на fenom можно без создания сниппета вывести, так.
<a href="tel:{$_modx->config.phone | preg_replace : '/[^0-9+]/' : ''}"> {$_modx->config.phone}</a>
Было: 8 (927) 778-45-45
Стало: 89277784545
Склоняем числовые определения
plural
<?php
if($n!=''){
$plural = $n%10==1&&$n%100!=11?$w1:($n%10>=2&&$n%10<=4&&($n%100<10||$n%100>=20)?$w2:$w3);
return $plural;
}
Примечание: Данное решение позволяет склонять числовые определения. То есть, не «1 штук», а «1 штука», «3 штуки» и т. д.
Использование:
[[plural? &n=`число` &w1=`штука` &w2=`штуки` &w3=`штуки`]]
Убирает лишние символы в строке
title
<?php
$str = preg_replace ("#([^=])\"([^\"]+)\"#", "\\1«\\2»", $input);
return str_replace('&', '', $str);
Данный снииппет полезен тем, что зачастую заказчики в pagetitle вводят название ресурса типа О компании «Рога и копыта» и в код выводятся двойные кавычки, если такие кавычки вывести в meta или в img, например так:
<img src="[[*image]]" alt="[[*pagetitle]]"/>
выведется:
<img src="путь к изображению" alt="О компании "Рога и копыта""/>
Получаются двойные кавычки, что приводит к ошибкам.
Данный модификатор заменяет кавычки на «» и дополнительно убивает символ &.
Использование:
<img src="[[*image]]" alt="[[*pagetitle:title]]" />
Запись в сессию и вывода значения какой-либо переменной
getGet
<?php
$get = htmlentities(trim(strip_tags((string) $_GET[$var])), ENT_QUOTES, 'UTF-8', false);
session_start();
if ($get == '' ) {
return $_SESSION[$var];
}
else {
$_SESSION[$var] = $get;
return $_SESSION[$var];
}
Для чего он: Например нужно передать на страницу формы заказа название товара, на котором нажата ссылка «Купить».
Примечание: Можно в первой строке вместо $GET[$var] прописать $_REQUEST[$var] — тогда будет работать и с GET и с POST.
Использование:
Ссылка:
<a href="[[~id? &item=`[[*pagetitle]]`]]">Заказать</a>
В форме:
<input type="hidden" name="item" value="[[!getGet? &var=`item`]]" />
Поскольку всё пишется в сессию, значение подставляется и при перезагрузке страницы после, к примеру, не прошедшей валидацию, формы.
Время чтения
простенький сниппет, который оценивает время, которое читатель будет читать контент.
readtime
<?php
$options = (int) $modx->getOption('options', $scriptProperties, 220, true); // 220 слов в минуту
$wordCount = (int) str_word_count(strip_tags($input)); // Чтобы отобразить количество слов, установите для параметров значение 0
if ($options === 0) return $wordCount;
return ceil($wordCount / abs($options));
Использование:
<p>Время чтения [[*content:readtime]] мин.</p>
Если ваш сайт с jQuery то можете воспользоваться продвинутым, настраиваемым миниатюрным скриптом выводящим время чтения.
Breadcrumb JSON-LD
Данный сниппет нужно вызвать в секции head.
<?php
$res = $modx->resource;
$site_url = $modx->getOption('site_url');
$site_start = $modx->getOption('site_start') ?: 1;
$ids = $modx->getParentIds($res->id, 10, array('context' => $modx->context->key));
$pids = ($res->id != $site_start) ? [$res->id] : [];
foreach($ids as $id) {
if($res->id != $id) {
$pids[] = $id;
}
}
$pids = array_reverse($pids);
$output = [];
$index = 0;
foreach($pids as $id) {
if ($id == 0) {
$id = $site_start;
}
if($res->id != $id) {
$res = $modx->getObject('modResource', $id);
}
$uri = $site_url . $res->get('uri');
if($res->get('id') == $site_start) {
$uri = $site_url;
}
$output[] = '{
"@type": "ListItem",
"position": '.++$index.',
"name": "'.$res->get('pagetitle').'",
"item": "'.$uri.'"
}';
}
$wrapper = implode(',', $output);
return '<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": ['.$wrapper.']
}
</script>';
alternate hreflang
Для мультиязычных сайтов (выводить в секции head), подробнее зачем и почему можно почитать здесь: https://netpeak.net/ru/blog/tegi-alternate-hreflang-media-type-zachem-i-kak-ikh-ispol-zovat/
<?php
$ctxDefault = $modx->getOption('x-default', $scriptProperties, 'web', true);
$tplDefault = '<link rel="alternate" href="{$page}" hreflang="x-default"/>';
$tpl = '<link rel="alternate" href="{$page}" hreflang="{$lang}"/>';
$output = '';
$contexts = $modx->getCollection('modContext', array('key:!=' => 'mgr'));
if(!count($contexts)) return;
foreach($contexts as $context) {
$ctx = $modx->getContext($context->key);
$site_url = $ctx->getOption('site_url');
$site_start = $ctx->getOption('site_start');
if($modx->resource->uri != 'index') {
$site_url .= $modx->resource->uri;
}
$cultureKey = $ctx->getOption('cultureKey');
if($context->key == $ctxDefault) {
$parseTpl = str_replace('{$page}', $site_url, $tplDefault);
$output .= $parseTpl;
}
$parseTpl = str_replace('{$page}', $site_url, $tpl);
$parseTpl = str_replace('{$lang}', $cultureKey, $parseTpl);
$output .= $parseTpl;
}
return $output;
FileSize — вывод размера файла и расширения файла
Использование:
[[!FileSize? &input=`assets/files/myfile.pdf`]]
— Будет автоматически выбрана единица измерения.[[*file_catalog:FileSize]]
— Вывод размера файла из TV-параметра.[[!FileSize? &input=`assets/files/myfile.pdf` &unit=`b`]]
— Явно указываем единицу измерения.[[!FileSize? &input=`assets/files/myfile.pdf` &get_ext=`1`]]
— Получить расширение файла, а не размер.[[*file_catalog:FileSize?&get_ext=`1`]]
— расширение файла из TV-параметра.{'!FileSize' | snippet : ['input' => 'assets/files/myfile.pdf']}
— Fenom.
<?php
if(!empty($get_ext)){
//Получить расширение файла в нижнем регистре
$ext = mb_strtolower(pathinfo($input, PATHINFO_EXTENSION));
return $ext;
}else{
//Получить размер файла
$units = array(
'gb' => array('size' => 1073741824, 'label' => 'ГБ'),
'mb' => array('size' => 1048576, 'label' => 'МБ'),
'kb' => array('size' => 1024, 'label' => 'КБ'),
'b' => array('size' => 0, 'label' => 'байт')
);
$input = MODX_BASE_PATH . $input;
$size = is_file($input) ? filesize($input) : 0;
$unit = (isset($unit) && isset($units[$unit])) ? $unit : false;
if ($size > 0) {
if ($unit === false) {
foreach ($units as $key => $properties) {
if ($size >= $properties['size']) {
$unit = $key;
break;
}
}
}
if ($unit != 'b'){
$size = $size / $units[$unit]['size'];
}
}
else {
if ($unit === false) $unit = 'b';
}
return round($size, 2) . ' ' . $units[$unit]['label'];
}
FaviconGenerator — aвтоматическая генерация favicon
Размеры генерит дополнение phpthumbof, если оно не установлено, то нужно установить с основного репозитория, также можно использовать pthumb или phpthumbon.
Допустим, название FaviconGenerator, код:
<?php
if (version_compare(PHP_VERSION, '5.4.0') < 0) {
return '<!-- Your version of PHP is very ancient -->';
}
$output = '';
// Цвет фона. Если не указан, то не применяется.
$backgroundColor = (string)$modx->getOption('backgroundColor', $scriptProperties, '');
// Путь до изображения
$image = (string)$modx->getOption('image', $scriptProperties, '');
// Нужно ли генерировать favicon.ico
$ico = (int)$modx->getOption('ico', $scriptProperties, 0);
// Сниппет, создающий миниатюры (phpthumbof, pthumb, phpthumbon)
$snippet = (string)$modx->getOption('snippet', $scriptProperties, 'phpthumbof');
// Цвет вкладки для мобильных браузеров
$tabColor = (string)$modx->getOption('tabColor', $scriptProperties, '');
// Apple
$sizes = ['57x57', '72x72', '144x144', '60x60', '120x120', '76x76', '152x152'];
foreach ($sizes as $size) {
$as = explode('x', $size);
$options = 'w='.$as[0].'&h='.$as[1].'&zc=1&f=png&bg='.$backgroundColor;
$output .= '<link rel="apple-touch-icon-precomposed" sizes="'.$size.'" href="'.$modx->runSnippet($snippet, ['input' => $image, 'options' => $options]).'" />'.PHP_EOL;
}
// Classic
$sizes = ['32x32', '16x16', '96x96', '128x128', '196x196'];
foreach ($sizes as $size) {
$as = explode('x', $size);
$options = 'w='.$as[0].'&h='.$as[1].'&zc=1&f=png';
if (!empty($backgroundColor)) {
$options .= '&bg='.$backgroundColor;
}
$output .= '<link rel="icon" type="image/png" sizes="'.$size.'" href="'.$modx->runSnippet($snippet, ['input' => $image, 'options' => $options]).'" />'.PHP_EOL;
}
// Microsoft
$output .= '<meta name="msapplication-TileColor" content="#FFFFFF" />'.PHP_EOL;
$output .= '<meta name="msapplication-TileImage" content="'.$modx->runSnippet($snippet, ['input' => $image, 'options'=>'w=144&h=144&zc=1&f=png&bg='.$backgroundColor]).'" />'.PHP_EOL;
$sizes = ['70x70', '150x150', '310x310'];
foreach ($sizes as $size) {
$as = explode('x',$size);
$options = 'w='.$as[0].'&h='.$as[1].'&zc=1&f=png';
if (!empty($backgroundColor)) {
$options .= '&bg='.$backgroundColor;
}
$output.='<meta name="msapplication-square'.$size.'logo" content="'.$modx->runSnippet($snippet, ['input' => $image, 'options' => $options]).'" />'.PHP_EOL;
}
// favicon.ico
if ($ico == 1) {
$options = 'w=16&h=16&zc=1&f=ico';
if (!empty($backgroundColor)) {
$options .= '&bg='.$backgroundColor;
}
$output .= '<link rel="shortcut icon" href="'.$modx->runSnippet($snippet, ['input' => $image, 'options' => $options]).'" type="image/x-icon" />'.PHP_EOL;
$output .= '<link rel="icon" href="'.$modx->runSnippet($snippet, ['input' => $image, 'options'=>$options]).'" type="image/x-icon" />'.PHP_EOL;
}
if (!empty($tabColor)) {
$output .= '<meta name="theme-color" content="#'.$tabColor.'" />'.PHP_EOL;
$output .= '<meta name="msapplication-navbutton-color" content="#'.$tabColor.'" />'.PHP_EOL;
$output .= '<meta name="apple-mobile-web-app-status-bar-style" content="#'.$tabColor.'" />'.PHP_EOL;
}
return $output;
Пример использования
[[FaviconGenerator?
&image=`favicon.png`
&backgroundColor=`f00`
&tabColor=`f00`
&ico=`1`
&snippet=`phpthumbof`
]]
Параметры
Параметр | Значение по умолчанию | Пример значения |
image | — | assets/images/favicon.png |
backgroundColor | — | bada55 |
tabColor | — | bada55 |
ico | 0 | 1 |
snippet | phpthumbof | pthumb |
Большинство сниппетов взято на просторах интернета.
В следующем уроке разберем поля ресурсов MODX и как их выводить.
Продолжение будет?
Будет как время появится, сейчас немного не до ведения блога
А есть в modx возможность вставки карты от яндекс например как в wordpress, плагином?
А зачем вам плагин, создайте чанк поместите в него код карты и вызовите в любом месте сайта