Load content dinamically with ajax, one more time

This is possibly trivial for most of you, but as I’ve been struggling with it for the last days, I’ll leave it here for the next newb to suffer less :skull_and_crossbones: plus feel free to Comment & Correct my approach, please :slight_smile:

The question is how to load page content, dynamically. Say load title, text, images from a page into a div, on button click.

My approach uses parts of, mainly this post, and the Load more with Ajax cookbook recipe.

1, First we create, in the content/ folder, a subfolder named ‘api’ and within it an a ‘api.txt’ file. Beware multilanguage sites, you’ll need to create a txt per lang.

2, Second, in the templates folder, we create an ‘api.php’ template:

    if(kirby()->request()->ajax()) {
    	$data[] = snippet('outsider', array('laPage' => $_POST['laPage'] ), true);	
    	echo json_encode($data);
    else {

… in it we check if the template is being accessed through an ajax request, else throw a 404 error. If it is an ajax request, then we call a snippet named “outsider.php” to build and return an html fragment as json.

The snippet call uses “$POST[‘laPage’]” being ‘laPage’ a variable containing the page name, that we pass to the snippet to build the html. This var we will send it from within the ajax post request in our js code (step 4), and catch it here with the $POST[] superglobal variable.

3, The snippet named ‘outsider.php’ goes of course under the snippets/ folder and I’ll keep it simple for demo purposes

<article id='outsider'>
	<?php $p = page(laPage) ?>
	<h1><?= $p->title()->html() ?></h1>
	<p><?= $p->text()->kt()  ?></p>
	<?php foreach($p->images() as $im): ?>
 			<img src="<?= $im->url() ?>">
	<?php endforeach ?>

…the snippet uses ‘laPage’ variable as a page’s name within page(), to get such page and extract the title and text fields, then loops over images, building our html fragment.

4, Finally we write the POST function in a .js file that we’ll make sure is linked in the header of whatever template into which we want to inject the dynamic content. This part uses jquery, and assumes the presence of an element with id=‘place’

function loadAjax(laPage) {
	$.post( "api", { laPage: laPage }, function( data ) {
	}, "json");

…see how we pass the ‘laPage’ function argument as a variable in the post call. See also how, as we use $.post, and we are expecting JSON in the response, we can specify “json” at the end of it. We append the response, a json html fragment built by the snippet and sent by the api template, to the #place html element in our current template.

Now we can attach our function to some event listener, such as the click of a button, passing it the name of the page we want to load

$('#home').click( function(){
	loadAjax( $(this).attr('id') ); 

TaDa! :tada:

I modified parts of the code on the fly, so please let me know if there are errors.

Hope it helps.

instead of your custom loadAjax function you could use a lib like infinite-scroll which support updating the url, back button and other cool stuff usefull for onepagers.

1 Like

Yeah, I agree it’s a nice library, but it adds some extra load to your page and you have to buy a license unless you develop an open source app.

1 Like