Начиная с версии 5.8 существует возможность загрузки врезок (дополнительных шаблонов макетов дизайна) отдельно от всей страницы — «асинхронные врезки».
Данную возможность можно использовать для организации кэширования средствами веб-сервера (загрузка персонализированных или часто обновляющихся фрагментов отдельно от редко меняющихся частей веб-страниц), визуального ускорения загрузки основного контента страниц (более поздняя загрузка второстепенных частей макета), для динамического обновления частей макета в ответ на действия пользователя (через AJAX).
Содержимое асинхронной врезки может быть вставлено в макет страницы при его формировании, либо может быть загружено после основной части страницы отдельным запросом. При любом способе вставки на страницу асинхронная врезка может быть перезагружена позднее.
Для того, чтобы врезка была доступна для загрузки отдельным запросом, в её свойствах в панели управления должен быть установлен параметр «разрешить асинхронную загрузку».
При загрузке врезки отдельным запросом в ней будет определена переменная $nc_partial_async
, равная true
.
Если на странице есть асинхронная врезка, в <head>
будет добавлен JavaScript-код для загрузки врезок с отложенной загрузкой после получения страницы браузером, а также JavaScript-функции для управления перезагрузкой асинхронных врезок.
Для того, чтобы врезка была загружен отдельным запросом, необходимо добавить к коду её вставки в макет метод defer()
:
// врезка 'related' будет загружена после загрузки страницы: $this->partial('related')->defer();
В качестве аргумента в метод defer()
может быть передан флаг включения или выключения отложенной загрузки.
Если этот аргумент не передан, метод включает отложенную загрузку (как если бы было передано true
).
// будет ли 'related' загружен после загрузки страницы, зависит // от настройки макета для текущего раздела $this->partial('related')->defer($template_settings['enable_partial_loading']);
По умолчанию до загрузки на месте врезки с отложенной загрузкой не выводится какое-либо содержимое. Чтобы вывести «заглушку» на месте незагруженной врезки, используйте метод set_stub()
:
// HTML как «заглушка»: $this->partial('related')->defer()->set_stub('<span class="loading">загружается...</span>'); // Другая врезка как «заглушка»: $this->partial('related')->defer()->set_stub($this->partial('related_stub'));
Чтобы использовать ту же врезку как «заглушку», не используйте defer()
, а добавьте always_reload()
.
Внутри врезки можно отличить отдельную загрузку по наличию переменной $nc_partial_async
, равной true
.
$this->partial('related')->always_reload();
Метод store_in_browser()
включает сохранение (кэширование) загруженных врезок в sessionStorage
браузера.
Такой кэш работает только в текущей вкладке в браузере до её закрытия; также он автоматически сбрасывается при входе пользователя в систему и выходе из неё.
Хранение врезок в браузере позволяет ускорить отображение полной версии страницы и снижает нагрузку на сервер.
// включить кэширование в браузере для врезки с отложенной загрузкой 'related': $this->partial('related')->defer()->store_in_browser();
Можно передать true
(для включения) или false
(для отключения) кэширования в браузере. Если аргумент не передан, метод store_in_browser()
включает кэширование в браузере.
Сохранённые в браузере врезки не запрашиваются с сервера при перезагрузке страницы, если не установлен режим always_reload
.
Врезки с одинаковым ключевым словом кэшируются для всего сайта (но по отдельности для разных макетов дизайна). Если нужно кэшировать врезки в зависимости от внешних по отношению к ним данным, передавайте их через аргумент $data
метода partial()
или через метод with()
:
$this->partial('related', array('sub' => 100))->defer()->store_in_browser(); // альтернативный способ: $this->partial('related')->with('sub', 100)->defer()->store_in_browser();
Метод always_reload()
указывает, что врезка должна быть обновлена (получена с сервера) при каждой загрузке страницы (даже если она уже вставлена на странице или закэширована в sessionStorage
браузера).
Можно передать true
или false
для включения или выключения принудительной перезагрузки врезки. Если аргумент не передан, метод always_reload()
включает принудительную перезагрузку.
По умолчанию принудительная перезагрузка не используется: если врезка уже вставлена на странице, или закэширована в sessionStorage
, при загрузке страницы запрос на обновление такой врезки не будет выполняться.
// загрузить врезку отдельным запросом, и обновлять ей при каждой загрузке, // даже если она закэширована в браузере: $this->partial('related')->defer()->store_in_browser()->always_reload(); // вставить врезку на страницу, но после загрузки страницы обновить её: $this->partial('aside')->always_reload();
Если на странице есть асинхронные врезки, в <head>
страницы будет добавлен скрипт для работы с ними, и станут доступны функции nc_partial_load()
и nc_partial_clear_cache()
, которые можно использовать при необходимости реализации нестандартной логики работы с асинхронными врезками.
nc_partial_load([partialConditions], [successCallback], [failureCallback])
Функция nc_partial_load()
загружает с сервера одну или несколько врезок.
Аргументы функции:
partialConditions
(опционально): правила выбора врезок для обновления.undefined
, null
, false
, пустая строка), будут обновлены все врезки на странице.'footer'
footer
, независимо от наличия или отсутствия у них дополнительных параметров data
)'header footer'
data
).
null
, то будут обновлены только врезки без параметров.nc_partial_load([ 'header', ['footer', { show_menu: true, page_type: 'front' }], ['aside', null] ]);
Будут обновлены:
1) врезки 'header'
c любыми параметрами или без них;
2) врезки 'footer'
, у которых одновременно есть параметры show_menu = true
и page_type = 'front'
;
3) врезки 'aside'
без параметров.
// так неправильно: nc_partial_load( ['aside', { menu: true}] ) // так правильно: nc_partial_load([['aside', { menu: true}]])
successCallback
(опционально): обработчик, который будет выполнен при успешном выполнении запроса на обновление врезок. В качестве первого аргумента в указанную функцию будут переданы полученные в виде JSON данные (объект, где ключ — ключевое слово врезки, значение — её новое содержимое).failureCallback
(опционально): обработчик, который будет вызван в случае ошибки при запросе данных с сервера. Первым аргументом будет передан объект XMLHttpRequest
, из которого можно получить дополнительные сведения.Пример использования функции nc_partial_load
:
// перезагрузить врезки cart_count и cart_items nc_partial_load('cart_count, cart_items');
nc_partial_clear_cache()
Функция nc_partial_clear_cache()
удаляет все закэшированные в браузере врезки (они будут запрошены повторно при следующей перезагрузке страницы).
ncPartialUpdate
При загрузке врезки с сервера или из локального кэша (sessionStorage
) будет инициировано событие ncPartialUpdate
на элементе document
. Событие не инициируется, когда врезка не загружается отдельным запросом, а сразу вставлена на страницу (нет вызова defer()
, врезка не обновлена вызовом функции nc_partial_load()
).
В слушателе данного события можно, например, инициализировать необходимые обработчики для элементов внутри врезки или производить другие изменения её содержимого при помощи JavaScript.
Свойство detail
события содержит объект со свойством newTemplateContent
(event.detail.newTemplateContent
). В объекте newTemplateContent
именем свойства является ключевое слово врезки (и дополнительные переменные в виде query-строки, если они были заданы при вызове $this->partial()
в макете), значением — новое содержимое соответствующей врезки. При использовании jQuery данное значение доступно в event.originalEvent.detail.newTemplateContent
.
// Добавление слушателя события с использованием jQuery: $(document).on('ncPartialUpdate', function(event) { if ('aside_banner' in event.originalEvent.detail.newTemplateContent) { console.log('Обновилась врезка aside_banner'); } }); // Добавление слушателя события на чистом JavaScript: document.addEventListener('ncPartialUpdate', function(event) { if ('aside_banner' in event.detail.newTemplateContent) { console.log('Обновилась врезка aside_banner'); } });
Для загрузки врезок на стороне сервера используется скрипт /netcat/partial.php
. Необходимо передать следующие параметры:
template
— ключевое слово или идентификатор макета дизайна, к которому относится врезка;partial
— ключевое слово врезки (может быть указано несколько ключевых слов в массиве, либо через запятую или пробел);json
— если равно 1
, то результат будет отправлен в виде JSON-объекта, где именем свойства является ключевое слово врезки, а значением — её содержимое.json
не передан, результат будет возвращён без дополнительных преобразований — в том виде, как указано в самом шаблоне (при запросе нескольких врезок они будут выведены последовательно).Все прочие переданные параметры также будут доступны внутри врезки.
Пример запроса:
var params = { template: 'mysite', partial: 'header, footer', json: 1 }; $.getJSON('/netcat/partial.php', params).done(function(response) { $('#header').html(response.header); $('#footer').html(response.footer); });