Андрей
С нами с 09 апреля 2015; Место в рейтинге пользователей: #68contentSync - синхронизация контента прода и дева для MODX Revolution
Привет, я снова тут!
Одна из дегенеративных особенностей MODX — хранить все в базе. Кони, люди, контент — все хранится в базе.
Еще более дегенеративная особенность — MODX учит вас хранить все в ресурсах и это не сказать что правильная логика.
Часто возникает ситуация, что тестовая версия сайта начинает плотно отставать по контенту от продакшена и необходимо как-то синхронизировать изменения.
Я придумал решение, которое отчасти решает мою задачу и потребность. Если решение вам понравится — я упакую все в пакет и выложу в бесплатный доступ.
Одна из дегенеративных особенностей MODX — хранить все в базе. Кони, люди, контент — все хранится в базе.
Еще более дегенеративная особенность — MODX учит вас хранить все в ресурсах и это не сказать что правильная логика.
Часто возникает ситуация, что тестовая версия сайта начинает плотно отставать по контенту от продакшена и необходимо как-то синхронизировать изменения.
Я придумал решение, которое отчасти решает мою задачу и потребность. Если решение вам понравится — я упакую все в пакет и выложу в бесплатный доступ.
Выдаем вместо кэша html файлик
Предыстория. Возник такой вопрос. Есть какой то сайт, и в нем получается в каталоге было так. В вызов mFilter2 вложено в чанк еще парочка вызовов msProducts ну и так далее. В итоге, раздел грузился за овер 10 секунд. Да, сейчас напишите, что вот надо оптимизировать. Это понятно, но я решил подойти с другой стороны.
Итак, идея была такая, что бы вместо кэша выдавать уже готовую разметку целой страницы.
В итоге, у нас есть плагин:
Вопрос знатокам, на сколько такой подход вообще жизнеспособный по отношению к системе? Очень бы хотелось услышать комментарии.
Спасибо за донаты:
@Павел Бигель
Итак, идея была такая, что бы вместо кэша выдавать уже готовую разметку целой страницы.
В итоге, у нас есть плагин:
<?php
switch($modx->event->name){
case 'OnWebPagePrerender':
// Тут просто условие, чтобы срабатывал только на категории (можно по сути задавать разные условия)
if($modx->resource->class_key != 'msCategory'){
return;
}
//Забираю отрендеренный ресурс
$_output = &$modx->resource->_output; //Забираю отрендеренный ресурс
// Создаю файлик разметки этого ресурса (можно по сути указать любой путь и так далее, сейчас и так сойдет)
$file = MODX_BASE_PATH . 'resourcecache/' . $modx->resource->uri . '/' . $modx->resource->id . '.txt';
if(is_file($file)){
// Если такой файлик уже существует, то просто отдаю его содержимое
$output = file_get_contents($file);
}else{
// Если файлика нету, то записываю туда отрендеренную страницу
$cache = $modx->getCacheManager();
$cache->writeFile($file, $_output);
$output = $_output;
}
// Подменяю вывод на готовый
$modx->resource->_output = $output;
break;
case 'OnLoadWebPageCache':
// Это событие срабатывает до рендера страницы, оно проверяет, есть ли кэш страницы, и если он есть...
$file = MODX_BASE_PATH . 'resourcecache/' . $modx->event->params['resource']->uri . '/' . $modx->event->params['resource']->id . '.txt';
//...мы проверяем файлик, так как страница уже грузилась и файлик есть и подменяем кэш на содержимое неашего файлика.
if(is_file){
$modx->event->params['resource']->_content = file_get_contents($file);
}
break;
}
Итог, раздел грузился за 10 секунд (ну да, такой раздел, идея в другом), после плагина уже за 0.006 секунды, так как выдается готовая разметка.Вопрос знатокам, на сколько такой подход вообще жизнеспособный по отношению к системе? Очень бы хотелось услышать комментарии.
Спасибо за донаты:
@Павел Бигель
siteDev - установка компонента
Обновил компонент для разработки сайтов/компонентов. Добавил немного полезных плюше.
Так как разработку своих компонентов я всегда начинаю именно с siteDev
Например, во время установки можно переименовать modExtra, который перед переименованием копируется в папку:
Так как разработку своих компонентов я всегда начинаю именно с siteDev
modExtra
Например, во время установки можно переименовать modExtra, который перед переименованием копируется в папку:
[FAQ] Делаем сниппет-обёртку
Данное руководство предназначено в первую очередь для разработчиков, только начинающих знакомиться с MODX. При разработке сайта они как правило используют уже готовые решения. И часто так случается, что такое решение нужно подогнать под текущую задачу. Самая первая мысль, которая приходит им в голову — изменить тот или иной сниппет. Ведь именно сниппеты отвечают за логику работы. Ну ещё плагины, но новички обычно в них не лезут.
Совсем зелёный разработчик лезет в исходный сниппет и творит там своё колдовство. И безумно довольный выкатывает своё творение заказчику, раздуваясь от своего величия.
Но более осторожный юнец сначала зайдет в сообщество, чтобы поинтересоваться, нет ли такого же решения, но с перламутровыми пуговицами. И случайным образом узнаёт, что править исходный код ни в коем случае нельзя, потому что следующее обновление затрёт все изменения, и что есть достаточно простой способ решить задачу кастомизации. Это сниппет-обёртка.
Совсем зелёный разработчик лезет в исходный сниппет и творит там своё колдовство. И безумно довольный выкатывает своё творение заказчику, раздуваясь от своего величия.
Но более осторожный юнец сначала зайдет в сообщество, чтобы поинтересоваться, нет ли такого же решения, но с перламутровыми пуговицами. И случайным образом узнаёт, что править исходный код ни в коем случае нельзя, потому что следующее обновление затрёт все изменения, и что есть достаточно простой способ решить задачу кастомизации. Это сниппет-обёртка.
Шпаргалка на все случаи жизни
Полезные ссылки, которые Вам пригодятся в некоторых ситуациях.
Сравнение дат в админке
Добрый день.
Есть два TV поля с типом «дата».
Первое поле — «Дата начала»
Второе поле — «Дата завершения»
Есть ли возможность сделать так, чтобы менеджер не мог поставить дату завершения меньше даты начала?
Есть два TV поля с типом «дата».
Первое поле — «Дата начала»
Второе поле — «Дата завершения»
Есть ли возможность сделать так, чтобы менеджер не мог поставить дату завершения меньше даты начала?
Выборка (where) по дате в pdoResources
Добрый день!
Понадобилось вывести только те записи, в которых ТЕКУЩАЯ дата попадает в период с (tv поле nacpr) по (tv поле konpr)
Перерыл весь интернет — не могу найти работающий пример выборки по периоду!
Я ПОНИМАЮ, что в where нужно задать сложное условие (AND) вида
текущая_дата>=nacpr AND текущая_дата<=kon_pr
К сожалению, навыков работы с датами в MODx пока не имею, но я быстро учусь…
Понадобилось вывести только те записи, в которых ТЕКУЩАЯ дата попадает в период с (tv поле nacpr) по (tv поле konpr)
Перерыл весь интернет — не могу найти работающий пример выборки по периоду!
Я ПОНИМАЮ, что в where нужно задать сложное условие (AND) вида
текущая_дата>=nacpr AND текущая_дата<=kon_pr
К сожалению, навыков работы с датами в MODx пока не имею, но я быстро учусь…
[[pdoResources?
&parents=`2`
&depth=`0`
&tpl=`TestListRowTpl`
&includeTVs=`tvimage,nacpr,konpr`
&where=`["FROM_UNIXTIME(nacpr, '%Y-%m-%d') .....___код___`
]]
Заранее буду благодарен за работающий пример сложной выборки по текущей дате. pdoTools->getChunk не парсит вложенный контент
Добрый день.
modx 2.6.5
pdoTools 2.12.3-pl
php 7.3
Написал свой плагин для поиска.
Всё нормально работает, но вот ресурсы, у которых class_key === modWebLink и в content есть теги fenom (например у меня там просто ссылки на внутренние ресурсы {`id` | url}), он их не обрабатывает и выплёвывает необработанными тегами.
пытался сделать так
Код:
modx 2.6.5
pdoTools 2.12.3-pl
php 7.3
Написал свой плагин для поиска.
Всё нормально работает, но вот ресурсы, у которых class_key === modWebLink и в content есть теги fenom (например у меня там просто ссылки на внутренние ресурсы {`id` | url}), он их не обрабатывает и выплёвывает необработанными тегами.
пытался сделать так
/* И getChunks и parseChunk */
$obj->content = $pdoTools->getChunk('@INLINE {$c}', ['c'=>$obj->content]);
Обработка тегов в ресурсах включена, конечно.Код:
<?php
if ($modx->event->name != 'OnPageNotFound') {return false;}
$alias = $modx->context->getOption('request_param_alias', 'q');
$searchQueryAlias = 's';
if (!array_key_exists($alias, $_REQUEST) || $_REQUEST[$alias] !== 'search' || !array_key_exists($searchQueryAlias, $_REQUEST)) {return false;}
$searchQuery = trim($_REQUEST[$searchQueryAlias]);
if (!isset($modx->resource)) {
$modx->resource = $modx->newObject('modResource');
$modx->resource->pagetitle = 'Поиск по сайту';
}
$fqn = $modx->getOption('pdoTools.class', null, 'pdotools.pdotools', true);
if ($pdoClass = $modx->loadClass($fqn, '', false, true)) {
$pdoTools = new $pdoClass($modx, $scriptProperties);
}
elseif ($pdoClass = $modx->loadClass($fqn, MODX_CORE_PATH . 'components/pdotools/model/', false, true)) {
$pdoTools = new $pdoClass($modx, $scriptProperties);
}
else {
$modx->log(modX::LOG_LEVEL_ERROR, 'Could not load pdoTools from "MODX_CORE_PATH/components/pdotools/model/".');
return false;
}
$pdoTools->addTime('pdoTools loaded');
$out = '';
$stmt = $modx->newQuery('modResource');
$stmt->limit(15);
$preparedSQ = str_replace(' ', ' ', trim($searchQuery));
$preparedSQ = preg_replace('#[^\w]#u', ' ', $preparedSQ);
$preparedSQ = str_replace(' ', ' ', trim($preparedSQ));
$preparedSQPieces = explode(' ', $preparedSQ);
$stmt->where(['id:!=' => 1]);
$stmt->andCondition(['pagetitle:LIKE' => "%$preparedSQ%"]);
$stmt->orCondition(['longtitle:LIKE' => "%$preparedSQ%"]);
if (count($preparedSQPieces) > 1) {
foreach($preparedSQPieces as $idx => $piece) {
$stmt->orCondition(['pagetitle:LIKE' => "%$piece%"]);
$stmt->orCondition(['longtitle:LIKE' => "%$piece%"]);
}
}
$out = '';
$count = $modx->getCount('modResource', $stmt);
if (intval($count) > 0) {
$objs = $modx->getIterator('modResource', $stmt);
foreach($objs as $obj) {
$obj->content = $pdoTools->getChunk('@INLINE {$c}', ['c' => $obj->content]);
$out .= $pdoTools->getChunk('@FILE chunks/particles/search-list.item.tpl', $obj->toArray());
}
} else {
$out .= '<div class="col-12">По вашему запросу «'.$searchQuery.'», ничего не найдено, уточните запрос.</div>';
}
$out = $pdoTools->getChunk('@FILE pages/search.tpl', [
'title' => 'Результат по запросу «'.$searchQuery.'»',
'items' => $out
]);
die($out);
AjaxForm + Register
Нигде не нашел решения как сделать регистрацию из стандартного пакета Login через AjaxForm, ниже мое решение может кому пригодиться.
1 Размещаем сниппет AjaxForm где требуется (на странице, в попап окне и т.п.)
Рейтинга для размещения в разделе Решения не хватило, поэтому публикую здесь.
1 Размещаем сниппет AjaxForm где требуется (на странице, в попап окне и т.п.)
[[!AjaxForm?
&snippet=`custRegister`
&form=`tpl.register.form`
&submitVar=`signup-btn`
&activationResourceId=`9`
&activationEmailTpl=`lgnActivateEmailTpl`
&activationEmailSubject=`Thanks for Registering!`
&usergroups=`Users`
&usernameField=`email`
&generatePassword=`1`
&validate=`nospam:blank,
fullname:required:minLength=^3^,
email:required:email`
&placeholderPrefix=`reg.`
]]
2 Создаем чанк tpl.register.form с формой<form id="signup-form" action="[[~[[*id]]]]" method="post">
<input type="hidden" name="nospam">
<input type="hidden" name="password" value="11111111">
<input type="text" name="fullname">
<small class="alert-fullname"></small>
<input type="email" name="email">
<small class="alert-email"></small>
<input type="submit" name="signup-btn" form="signup-form" value="Signup">
</form>
3 Создаем сниппет custRegister<?php
$result = $modx->runSnippet('Register', $scriptProperties);
foreach($modx->placeholders as $key => $ph){
if(strpos($key, $scriptProperties[placeholderPrefix].'error.') === 0) $placeholders[$key] = $ph;
}
if($modx->getPlaceholder($scriptProperties[placeholderPrefix].'validation_error')) return $AjaxForm->error('Form has errors', array('error' => $placeholders));
else return $AjaxForm->success('Form is valid');
4 На странице с формой добавляем скрипт, который заполнит алерты или сообщит об успехе или еще все что угодно<script>
$(document).on('af_complete', function(event, response){
$.each(response.data.error, function(index, value){$(response.form).find('.alert-' + index.split(".").pop()).html(value);});
response.message='';//jGrowl - off
});
</script>
Вот и всё!Рейтинга для размещения в разделе Решения не хватило, поэтому публикую здесь.
Подготовка дополнения для работы в MODX 3.
Добрый день!
Возникает много вопросов как обновить дополнения для работы в MODX 3.
Предлагаю вашему вниманию заметку от разработчика theboxer, на примере дополнения Collection
Возникает много вопросов как обновить дополнения для работы в MODX 3.
Предлагаю вашему вниманию заметку от разработчика theboxer, на примере дополнения Collection