Last active
March 1, 2024 04:09
-
-
Save piotrpog/e900e8807ef31ca27929f8827a925455 to your computer and use it in GitHub Desktop.
Lazy loading for Craft CMS. Reead more: http://craftsnippets.com/articles/infinite-scrolling-and-lazy-loading-with-craft-cms
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{% if article is defined %} | |
<li> | |
{{article.id}} - {{article.title}} | |
</li> | |
{% endif %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{# settings #} | |
{% set element_api_url = 'lazy-load' %} | |
{% set settings = { | |
section: 'articles', | |
variableName: 'article', | |
templatePath: '_article.twig', | |
orderBy: 'id', | |
limit: 3, | |
} %} | |
{# hashed settings #} | |
{% set hashed_settings = [] %} | |
{% for key, setting in settings %} | |
{% set hashed_settings = hashed_settings|merge({(key): setting|hash}) %} | |
{% endfor %} | |
{# initial content #} | |
<div class="js-lazy-wrapper"> | |
<ul class="js-lazy-list"> | |
{% for page in craft.entries.section(settings.section).order(settings.orderBy).limit(settings.limit) %} | |
{% include settings.templatePath with {(settings.variableName): page} %} | |
{% endfor %} | |
</ul> | |
<button class="button js-load-more">{{'load more'|t}}</button> | |
</div> | |
{# ajax request #} | |
{% js %} | |
// twig to js | |
var lazy_settings = {{hashed_settings|json_encode|raw}}; | |
var element_api_url = '{{url(element_api_url)}}'; | |
//variables | |
var lazy_offset = 1 | |
var current_request = null; | |
//html elements | |
var lazy_wrapper = $('.js-lazy-wrapper'); | |
var lazy_button = lazy_wrapper.find('.js-load-more'); | |
var lazy_list = lazy_wrapper.find('.js-lazy-list'); | |
lazy_button.on('click', function(){ | |
if (current_request == null){ | |
current_request = $.ajax({ | |
url: element_api_url, | |
method: 'GET', | |
data: { | |
offset: lazy_offset, | |
settings: lazy_settings, | |
}, | |
beforeSend: function(){ | |
lazy_button.addClass('is-loading'); | |
}, | |
}).always(function(returned) { | |
lazy_button.removeClass('is-loading'); | |
current_request = null; | |
}).done(function(returned) { | |
lazy_offset ++ | |
var html = '' | |
$.each(returned.data, function(index, article){ | |
html += article.html | |
}) | |
lazy_list.append(html) | |
if(returned.data.length == 0){ | |
lazy_button.hide(); | |
} | |
}).fail(function(data){ | |
alert('error'); | |
}) | |
} | |
}); | |
{% endjs %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{# settings #} | |
{% set element_api_url = 'lazy-load' %} | |
{% set settings = { | |
section: 'articles', | |
variableName: 'article', | |
templatePath: '_article.twig', | |
orderBy: 'id', | |
limit: 3, | |
} %} | |
{# hashed settings #} | |
{% set hashed_settings = [] %} | |
{% for key, setting in settings %} | |
{% set hashed_settings = hashed_settings|merge({(key): setting|hash}) %} | |
{% endfor %} | |
{# initial content #} | |
<div class="js-lazy-wrapper"> | |
<ul class="js-lazy-list"> | |
{% for page in craft.entries.section(settings.section).order(settings.orderBy).limit(settings.limit) %} | |
{% include settings.templatePath with {(settings.variableName): page} %} | |
{% endfor %} | |
</ul> | |
<div class="js-lazy-preloader" hidden>{{'Loading'|t}}</div> | |
</div> | |
{# ajax request #} | |
{% js %} | |
// twig to js | |
var lazy_settings = {{hashed_settings|json_encode|raw}}; | |
var element_api_url = '{{url(element_api_url)}}'; | |
//variables | |
var lazy_offset = 1 | |
var current_request = null; | |
var not_all_displayed = true | |
//html elements | |
var lazy_wrapper = $('.js-lazy-wrapper'); | |
var lazy_list = lazy_wrapper.find('.js-lazy-list'); | |
var lazy_preloader = $('.js-lazy-preloader'); | |
$('body').bind('wheel', function(e) { | |
if(e.originalEvent.wheelDelta / 120 <= 0) { | |
if (current_request == null && not_all_displayed === true){ | |
current_request = $.ajax({ | |
url: element_api_url, | |
method: 'GET', | |
data: { | |
offset: lazy_offset, | |
settings: lazy_settings, | |
}, | |
beforeSend: function(){ | |
lazy_preloader.show(); | |
}, | |
}).always(function(returned) { | |
lazy_preloader.hide(); | |
current_request = null; | |
}).done(function(returned) { | |
lazy_offset ++ | |
var html = '' | |
$.each(returned.data, function(index, article){ | |
html += article.html | |
}) | |
lazy_list.append(html) | |
if(returned.data.length == 0){ | |
not_all_displayed = false; | |
} | |
}).fail(function(data){ | |
alert('error'); | |
}) | |
} | |
} | |
}); | |
{% endjs %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use Craft; | |
use craft\elements\Entry; | |
use League\Fractal\TransformerAbstract; | |
use craft\web\View; | |
class TwigTransformer extends TransformerAbstract | |
{ | |
public function __construct($settings) | |
{ | |
$this->settings = $settings; | |
} | |
public function transform( $entry ) | |
{ | |
$oldMode = Craft::$app->view->getTemplateMode(); | |
Craft::$app->view->setTemplateMode(View::TEMPLATE_MODE_SITE); | |
$html = Craft::$app->view->renderTemplate( $this->settings['templatePath'], [$this->settings['variableName'] => $entry]); | |
Craft::$app->view->setTemplateMode($oldMode); | |
return [ | |
'id' => $entry->id, | |
'html' => $html | |
]; | |
} | |
} | |
return [ | |
'endpoints' => [ | |
'lazy-load' => function() { | |
// validate and decode settings | |
$hashed_settings = Craft::$app->request->getParam('settings'); | |
$settings = []; | |
foreach ($hashed_settings as $key => $value) { | |
$value = Craft::$app->security->validateData($value); | |
if($value === false){ | |
return false; | |
}else{ | |
$settings[$key] = $value; | |
} | |
} | |
// criteria | |
$criteria = [ | |
'section' => $settings['section'], | |
'limit' => $settings['limit'], | |
'offset' => $settings['limit'] * Craft::$app->request->getParam('offset'), | |
'order' => $settings['orderBy'], | |
]; | |
return [ | |
'elementType' => Entry::class, | |
'criteria' => $criteria, | |
'paginate' => false, | |
'transformer' => new TwigTransformer($settings), | |
]; | |
}, | |
] | |
]; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment