В сети, а в частности в новостных порталах, блогах и т.д. все чаще встречается автоматическая подгрузка контента, т.е когда вы дочитали статью, происходит автоматическая подгрузка предыдущей статьи – на таких ресурсах это работает достаточно удобно, ибо нет необходимости переходить на страницу тизеров.
Сегодня мы реализуем подобную систему в 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)
А как сделать, чтобы подгружалась не одна нода по клику, а несколько? Что в коде нужно изменить?
Подгрузка осуществляется через плагин, а в самом плагине это не предусмотрено. Конечно, в теории можно создать кастомную отдельную страницу, которая будет принимать аргументы из строки (те же NID материалов) и формировать вывод контента в зависимости от переданных ей значений и далее формировать ссылку на кастомную страницу с необходимыми аргументами, но только как по мне, это тот еще костыль, хотя работать будет. Лучше использовать подгрузку с использованием Ajax API, там это все просто можно решить и без костылей