Тест вложенности ресурса в контейнер [с блекджеком и плюхами]
Проверить, есть ли контейнер в списке родителей ресурса, можно разными способами:
P.S.: За то, что так скрупулёзно отношусь к нагрузке на сервер и скорости работы скрипта, спасибо Михаилу Воеводскому, что ткнул носом однажды. =)
- Можно сделать это используя карту ресурсов, которую MODX создаёт для каждого контекста после обновления кеша. Для этого необходимо воспользоваться методом $modx->getParentIds. Таким образом нагрузка и время затрачиваемое на проверку будет минимальным.
- Не заморачиваться и сделать всё исключительно на Fenom, без модификаторов. Тут мы тоже можем воспользоваться методом $_modx->getParentIds, который Василий услужливо вынес в список доступных в Fenom.
- Можно даже извратиться до того, что на каждую такую проверку получать объект через getObject('modResource') + получать объекты его родителей через getOne('Parent'). К слову, что будет в случае, если нам, к примеру, надо проверить 50 товаров на странице на вложенность в определённую категорию?
Ради интереса, я воспроизвёл подобную ситуацию на тестовом сайте Modhost:
- Без каких-либо проверок 50 товаров в списке категории выводятся за 0,0282 сек.
- С подобной проверкой, за 0.1304 сек.
- С проверкой, которую мы рассматриваем в этом посте, за 0.0307 сек.
А потом заказчики сходят с ума, почему их сайт так долго открывается...
Поймите меня правильно
Дело даже не столько в единичном сниппете, сколько в самом подходе к разработке. Если для исполнителя нет ничего страшного в подобном сниппете, который прибавляет 0.1 секунду ко времени загрузки страницы при определённых условиях, то заказчику потом приходится тратить в двое больше на оптимизацию сайта или жить с тем, что есть.Преимущества данного решения
В чём же преимущества данного решения в отличие, к примеру, от этого:- Скорость работы и низкая нагрузка на сервер,
- Возможность передавать опции, вроде ключа контекста,
- Возможность указать уровень вложенности проверки,
- Основной параметр проверки (id контейнера) не вшит в сниппет, а указывается извне.
Сниппет-модификатор проверки вложенности ресурса в контейнер
Каким же должен быть правильный сниппет-модификатор проверки вложенности ресурса в контейнер:// Parent
$parent = ($options['parent'] ?: null);
unset($options['parent']);
if (empty($input) || empty($parent)) {
return null;
}
// Height
$height = ($options['height'] ?: 10);
unset($options['height']);
// Alt keys
foreach (array(
'context_key' => 'context',
'ctx' => 'context',
) as $k => $v) {
if (isset($options[$k])) {
$options[$v] = $options[$k];
}
}
if (!$parents = $modx->getParentIds($input, $height, $options)) {
return null;
}
return in_array($parent, $parents) ?: null;Создаём сниппет inParent с этим кодом.Пример использования
Использовать его до безобразия просто:{if ($_modx->resource['id'] | inParent : [
'parent' => 2,
'height' => 3,
'ctx' => 'web',
])?}
Родитель с id 2 найден на 3 уровня вверх в контексте web.
{else}
Не найден.
{/if}P.S.: За то, что так скрупулёзно отношусь к нагрузке на сервер и скорости работы скрипта, спасибо Михаилу Воеводскому, что ткнул носом однажды. =)
Комментарии: 8
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
Сам внимательно отношусь к нагрузке на сервер и скорости загрузки, т.к. как покупатель не люблю тормозные сайты.
Сильно не хватает таких постов с разбором внутренних механизмов кеширования модх.
Хотя про getParentids и getchildIds все должны знать.
Есть еще полезный findResource
В вот так нужный getResourceURI так и не появился(( forums.modx.com/index.php/topic,58207.msg332426.html
Вот пример как делают настоящие хардкорные программисты для получения тайтла родителя верхнего уровня:
Сегодня получил этот код от своих тру сеошников
Хотя даже с получением объектов можно было сделать цикл, где выискивался бы самый верхний родитель.
Подходить лишь для такой структуры:
Родитель 1
— Родитель 2
— Родитель 3
— Ресурс
P.S. Как я думаю, супер скорость будет при getParentIds и запроса newQuery с лимитом 1 и выборкой pagetitle.
Вот кусочек кода, который сам использую для вытаскивания всех тайтлов родителей просто для примера:
Сейчас хочу в функцию его завернуть, чтобы можно было конкретный тайтл конкретного родителя с нужного уровня тащить, например.
1. Самая первая переменная называется $parent, а проверяется $parent_id. Явная опечатка.
2. Блок с Alt key непонятно зачем нужен. Достаточно просто указать ключ context вместо ctx и context_key. Думаю, программисту это будет не сложно.
3. В коде
можно сразу возвращать null. Зачем тратить время на дальнейшие операции.
П.С. Ещё желательно, чтобы переменная height была необязательная. Она явно ограничивает применение фильтра.
2 — это для личного удобства. Постоянно путаю, где указать context_key, а где context.
Тут не понял. Разве сейчас она обязательна?