Онлайн-руководство разработчика NetCat
Новогодние скидки до 25%!
Подробнее
Модуль «Поиск по сайту» 12.2.1Начало работы с модулем 12.2.2Язык запросов 12.2.3Способы хранения индекса 12.2.4Интерфейс модуля в панели управления сайтом 12.2.5Области индексирования 12.2.6Области HTML-страниц 12.2.7Области поиска на сайте 12.2.8Индексирование по расписанию, запуск индексирования в фоновом режиме 12.2.9Правила индексирования 12.2.10Постановка задачи переиндексирования в очередь 12.2.11Интеграция модуля в макеты дизайна сайта 12.2.12Простая форма поиска 12.2.13Расширенная форма поиска 12.2.14Вывод результатов поиска 12.2.15Стилизация списка подсказок 12.2.16Расширенные настройки 12.2.17Разработка расширений модуля 12.2.18Обзор архитектуры модуля 12.2.19Обработчики документов различных типов 12.2.20Текстовые фильтры 12.2.21Анализаторы текста 12.2.22Корректировщики запросов 12.2.23Подключение других поисковых систем 12.2.24Решение проблем с поиском 12.2.25Решение проблем с индексированием 12.2.26Справочник API

Асинхронные врезки: динамическая загрузка дополнительных шаблонов

Начиная с версии 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();

Методы для управления отложенной загрузкой в макете дизайна

Использование локального хранилища браузера (sessionStorage) для кэширования асинхронных врезок

Метод 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();

Функции для работы с асинхронными врезками в JavaScript

Если на странице есть асинхронные врезки, в <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'
    • в виде массива, где каждый элемент также представляет из себя массив:
      1) первый элемент — ключевое слово врезки (или несколько через пробел или запятую);
      2) второй элемент (опционально) — параметры для выборки по дополнительным параметрам (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);
});

См. также

Описание проекта