Подгрузка нового набора записей без перезагрузки страницы в «Болте»

Решил я на сайте сделать в каждой записи блок «Читайте также», в котором предлагать набор случайных записей. У меня их будет три. Но что делать если рандомный сет окажется неинтересным посетителю? В таком случае логичным будет сделать кнопку «Другие записи», после нажатия которой без перезагрузки страницы набор постов обновляется.

Для решения задачи мне понадобятся:

  • Техническая сущность blocks, в блоках я храню кусочки кода, тексты и прочие фрагменты, которые надо где-то вставлять. Например, в одном из блоков хранится приветственный текст на главной странице этого сайта, что позволяет мне его быстро и удобно править.
  • Твиг-шаблон, в котором будет формироваться моя подборка.
  • Аякс.

Готовим шаблоны

В папке темы создаю шаблоны. По одному на каждую сущность, в записях которой мне нужны подборки других постов. У меня это будут more-blog.twig, more-lab.twig и more-birds.twig.

В шаблонах прописываю структуру. В примере она будет упрощена для наглядности, выведу только заголовки записей.

{% setcontent notes = 'blog/random/3' %}
{% for note in notes %}
    {{ note.title }}<br>
{% endfor %}

В примере я сделал рандомную подборку трех записей из сущности blog. Для каждой записи из массива будет выводится заголовок, то есть поле title.

Готовим блоки

В блоках, как в сущности понадобится поле выбора шаблона. Добавляется оно из админ. панели: «Настройки → Сущности».

        template:
            type: templateselect
            filter: '*.twig'
            group: base

В примере выше я указал имя поля, тип, фильтр, который отсеет всё кроме .twig шаблонов и рассказал в какой группе я хочу увидеть новое поле.

После создаю три блока, для каждой из сущностей и выбираю нужный шаблон. Например для блога я создал блок «Другие записи — Блог» со слагом more-blog в котором выбрал шаблон more-blog.twig.

Работаем в шаблоне записи

У меня один шаблон записи на все сущности — entry.twig. Чтобы понимать для какой сущности, что выводить я декларирую переменную в которую записываю имя сущности и затем в разных местах проверяю. Если сущность такая-то то ей соответствует свой кусок кода.

{% set x = record.contenttype.name %}

Далее в шаблоне записи у меня идут:

  1. блок с первоначальной подборкой записей;
  2. кнопка, по клику на которую набор меняется;
  3. скрипт, который делает замену.
<div id="more">
    {% setcontent records = x~'/random/3' %}
    {% for record in records %}
    {{ record.title }}<br>
    {% endfor %}
</div>
<button id="refresh">Перезагрузить</button>
<script>
    $('#refresh').click(function(){
        var h = $('#more').outerHeight();
        $('#more').css("min-height", h);
        $('#more').empty();
        $("#more").load("/block/more-{{ x }}");
        function delete_css() {
            $('#more').removeAttr('style');
        }
        setTimeout(delete_css, 500);
    });
</script>

Чуть подробнее о скрипте. По клику на кнопку я сперва получаю текущую высоту блока и присваиваю свойство минимальной высоты. Это нужно чтобы блок впоследствии сильно не прыгал. Затем очищаю контейнер от первоначального содержимого и подгружаю содержимое нужного блока. Так как в имени блока я использую имя сущности, то лишнего городить не приходится, достаточно в разных сущностях подставлять переменную, о которой сказал выше. И в конце с небольшой задержкой удаляю свойство, указывающее минимальную высоту.

Резюме

Да, решение местами громоздкое, однако, вполне рабочее для небольших проектов. Посмотреть как всё работает можно уже в этой записи.

comments powered by HyperComments

Ещё записи

Подгрузка нового набора записей без перезагрузки страницы в «Болте»

Рассказываю как я решил задачу обновления набора записей в блоке «Читайте также», без перезагрузки страницы, при помощи Аякса и пары хитростей.

Почему не запускается Adobe Experience Design после обновления

Короткое описание возникшей проблемы

Управление миниатюрами изображений в Bolt CMS

Краткая памятка. Вольный пересказ оф. документации.