Ajax Load More w/ Kirby Issue

thx, change $articles
$articles = $page->children()->listed()->sortBy('date', 'desc')->paginate($limit);

Why don’t you use the $articles variable defined before?

$articles = collection('post/articles');
$limit    = 16;
$articles = $articles->paginate($limit);

And you should do the filtering before you paginate.

Thank you, I did.

But I found that the load more button tries to load pages that don’t exist and gets an error: undefined (post.json/page:5 404)

Sorts by date not all entries, but the first ones loaded. And it gets (example):

Page 1
13-04-2023
10-04-2023
1-04-2023
28-03-2023
click load more
Page 2
12-04-2023
10-04-2023
20-01-2023
click load more
Page 3
13-04-2023
10-12-2022

I added a second selector in class and got an error. Removed it. it works.

I think you have to post your complete code, maybe you redefine the articles again in your json controller.

Also, the collection key with the slash looks rather weird as well.

post.php - template

<div class="feed-page__content-list">
	<div class="content-list" data-page="<?= $pagination->nextPage() ?>">
		<?php foreach ($articles as $article): ?>
			<?php snippet('excerpt', ['article' => $article]) ?>
		<?php endforeach ?>
	</div>
	<div class="content-more">
		<div class="loader content-list__loader">
			<button class="load-more" accesskey="m"><span class="hZ-gYeUD">load more</span></button>
		</div>
	</div>
</div>

post.php - controllers

return function ($page) {

	$tag      = param('tag');
	$articles = collection('post/articles');
	$limit    = 16;
	$articles = $articles->paginate($limit);

	if (empty($tag) === false) {
		$articles = $articles->filterBy('tags', $tag, ',');
	}

	return [
		'tag'      => $tag,
		'limit'      => $limit,
		'articles'   => $articles,  
		'pagination' => $articles->pagination(), 
	];

};

post.json.php - controllres

<?php

return function ($page) {

	$limit      = 16;
	$articles   = $page->children()->listed()->paginate($limit);
	$pagination = $articles->pagination();
	$more       = $pagination->hasNextPage();

	return [
		'articles' => $articles,
		'more'     => $more,
		'html'     => '',
		'json'     => [],
	];
};

post.json.php - templates

foreach($articles as $article) {

	$html .= snippet('excerpt', ['article' => $article], true);

}
$json['html'] = $html;
$json['more'] = $more;

echo json_encode($json);

articles.php - collections

return function () {
	return page('post')
		->children()
		->listed()
		->sortBy('date', 'desc');
};

post.js

document.documentElement.classList.replace('no-js', 'js');

const element = document.querySelector('.content-list');

const button  = document.querySelector('.load-more');
let page      = parseInt(element.getAttribute('data-page'));

const fetchProjects = async () => {
	let url = `${window.location.href.split('#')[0]}post.json/page;${page}`;
	// let url = `${window.location.href}post.json/page:${page}`; - not works with :
	try {
		const response       = await fetch(url);
		const { html, more } = await response.json();
		button.hidden        = !more;
		element.insertAdjacentHTML('beforeend', html);
		page++;
	} catch (error) {
		console.log('Fetch error: ', error);
	}
}

button.addEventListener('click', fetchProjects);

config

return [
	'home' => 'post',
	'debug' => true,
	'kirby' => [
		'post' => [
			'date' => 'd M Y',
			'pagination' => [
				'limit' => 24
			]
		]
	],

As I suspected, in your json controller, you don’t use your sorted collection, but define a new pages collection.

I sorted the entries in the collection. Now I just need to load them when I click the load more button. I don’t understand how to pass the already sorted records to post.json. :((

With the same code as in the standard post controller

I keep getting errors with the code in post controller. hasNextPage() on null, author() on null

@texnixe
Fixed it and it worked. thank you.