• статья
  • pantey

Drupal 8 – Ajax подгрузка контента (плагин jScroll)

28.08.2017

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

Сегодня мы реализуем подобную систему в Drupal 8, с использованием плагина jQuery - jScroll. Плагин выбрал практически первый попавшийся, посмотрел его возможности и понял, что нам он полностью подходит.

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

Создадим блок, который должен содержать ссылку на предыдущую статью сайта, в зависимости от текущего NID определенного типа контента, в моем случае этот тип будет – Article. Как всегда, все действия реализуем в кастомном модуле под названием – jscroll_content.

Файл jscroll_content.info.yml

name: Jscroll Content
description: Пример подгрузки статей сайта с использование jQuery плагина jScroll
core: 8.x
type: module

Далее создадим кастомный блок, кто не в курсе как создается плагин, читаем статью – Drupal 8 - Программное создание блока.

Файл JscrollContentBlock.php

<?php
/**
 * @file
 * Contains \Drupal\jscroll_content\Plugin\Block.
 */
namespace Drupal\jscroll_content\Plugin\Block;

use Drupal\Core\Block\BlockBase;
/**
 * Provides a jscroll_content.
 *
 * @Block(
 *   id = "jscroll_content",
 *   admin_label = @Translation("Jscroll content"),
 *   category = @Translation("Custom block for load content")
 * )
 */
class JscrollContentBlock extends BlockBase {
  /**
   * {@inheritdoc}
   */
  public function build() {

    # Default return content
    $output = '';

    # Type content
    $type_node = 'article';

    # Get NID node
    $node = \Drupal::request()->attributes->get('node');

    if($node){
      $nid = $node->id();

      # Get prev NID node
      $query = \Drupal::database()->select('node', 'n');
      $query->addField('n', 'nid');
      $query->condition('n.type', $type_node);
      $query->condition('n.nid', $nid, '<');
      $query->orderBy('n.nid', 'DESC');
      $query->range(0, 1);
      $prev_nid = $query->execute()->fetchField();

      if($prev_nid){
        # Get alias path
        $href = \Drupal::service('path.alias_manager')->getAliasByPath('/node/' .$prev_nid);
        $output = '<a href="' .$href .'">next page</a>';
      }
    }

    # Return content
    return array(
      '#type' => 'markup',
      '#markup' => $output,
    );

  }
}

Как вы могли заметить, при формировании контента блока, мы получаем NID ноды, далее ищем предыдущую статью сайта через запрос в БД, с использованием Database API и если NID предыдущей статьи существует, то получаем алиас пути и возвращаем результат в блок.

Хочу заметить, что подгрузка контента осуществляется только в полном содержимом ноды, поэтому имеет смысл выводить блок для конкретного типа материала, в моем случае тип материала – Article.

Далее нам необходимо создать библиотеку, которая будет содержать плагин jScroll и файл инициализации.

Файл jscroll_content.libraries.yml

library_jscroll:
  version: 1.x
  js:
    js/jquery.jscroll.js: {}
    js/jscroll_content.js: {}
  dependencies:
    - core/jquery
    - core/jquery.once

Теперь переходим к файлу инициализации, в котором мы указываем необходимые параметры и настройки для запуска плагина jScroll.

Файл jscroll_content.js

(function ($) {
  Drupal.behaviors.jscrollContent = {
    attach: function () {
      $('.region-content').jscroll({
        contentSelector: '.region-content',
        nextSelector: '.block-jscroll-content .content a',
        autoTrigger: false,
        debug: false
      });
    }
  };
})(jQuery);

Где:

  • contentSelector – принимает селектор DOM дерева страницы, который необходимо подгрузить
  • nextSelector – принимает селектор, в котором расположена ссылка на страницу подгрузки, в нашем случае предыдущая статья
  • autoTrigger – по умолчанию true, определяет поведение подгрузки страницы. Если true, то подгрузка будет осуществляться автоматически при скролле до ссылки, false – подгрузка будет осуществляться по клику по ссылке
  • debug – включает режим отладки. Выводит объект в консоль

Кроме того существуют еще дополнительные параметры, которые я не использовал

  • autoTriggetUntil – по умолчанию false, принимает целое число (не ноль). Данный параметр отключит подгрузку контента, после подгрузки указанного кол-ва страниц
  • loadingHTML – принимает HTML, который используется для отображения во время подгрузки контента (прелоадер)
  • padding – по умолчанию 0 (ноль). Расстояние от нижней части текущего содержимого на страницы, после которой необходимо выполнить подгрузку контента
  • callback – по умолчанию false. Принимает функцию, которая будет вызываться после каждой подгрузки контента.

Теперь нам осталось только подключить нашу библиотеку на необходимые страницы, я буду подключать для полного содержимого нод, с типом материала – Article.

Файл jscroll_content.module

<?php

/**
 * @param $variables
 * Implements hook_preprocess_page()
 */
function jscroll_content_preprocess_page(&$variables){

  # Add library for content type 'Article'
  if(isset($variables['node'])){
    $content_type = $variables['node']->getType();
    if($content_type == 'article'){
      $libraries['#attached']['library'][] = 'core/drupal.ajax';
      $variables['#attached']['library'][] = 'jscroll_content/library_jscroll';
      render($libraries);
    }
  }

}

Теперь вы можете активировать модуль, вывести блок «Содержимое» и проверить работу.

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

На этом можно закончить. Скачать модуль, используемый в примере.

Скачать

-->
Узнавай о новых статьях сайта - первым. Просто подпишись на рассылку.

Комментарии (2)

Profile picture for user 1541
Александр
30.08.2017

А как сделать, чтобы подгружалась не одна нода по клику, а несколько? Что в коде нужно изменить?

Profile picture for user pantey
pantey
30.08.2017

Подгрузка осуществляется через плагин, а в самом плагине это не предусмотрено. Конечно, в теории можно создать кастомную отдельную страницу, которая будет принимать аргументы из строки (те же NID материалов) и формировать вывод контента в зависимости от переданных ей значений и далее формировать ссылку на кастомную страницу с необходимыми аргументами, но только как по мне, это тот еще костыль, хотя работать будет. Лучше использовать подгрузку с использованием Ajax API, там это все просто можно решить и без костылей