Terug naar alle berichten
Custom Post Types inladen met Ajax op je WordPress Website
Development

Custom Post Types inladen met Ajax op je WordPress Website

Geupdate op mei 14, 2024

Voordat u doorgaat, moet u er rekening mee houden dat ik een meer bijgewerkte, eenvoudigere en modernere oplossing heb voor het maken van uw eigen knop ‘Laad meer berichten’ in WordPress met ajax!

Vorige week maakte ik mijn eerste WordPress ajax-oproep om meer berichten te laden om berichten op te halen van een aangepast berichttype. Ik maakte de Ajax-oproep simpelweg vanwege het feit dat elke keer dat ik op ‘volgende’ of ‘vorige’ klikte, de pagina opnieuw werd geladen en terug naar boven sprong. Met ajax laadde mijn pagina niet opnieuw en blijft daarom op de oorspronkelijke positie staan. Door dit bericht te schrijven hoop ik zelf een beter inzicht te krijgen in hoe dit werkt, omdat ik natuurlijk ook hoop dat het iemand anders kan helpen die voor het eerst kennis maakt met Ajax en WordPress.

Ajax wordpress custom post types

Dit bericht is behoorlijk lang omdat ik veel extra voorbeelden heb gegeven om het duidelijker te maken. Maar de enige drie bestanden die we nodig hebben om dit te laten werken, zijn een posts.php-pagina waarop al onze berichten worden weergegeven. Het WordPress function.php-bestand om onze WordPress API in te stellen en een custom.js-bestand om al onze ajax/js-code op te schrijven.

Voordat u doorgaat, moet u er rekening mee houden dat ik een meer bijgewerkte, eenvoudigere en modernere oplossing heb voor het maken van uw eigen knop ‘Laad meer berichten’ in WordPress met ajax!

Projectvoorbeeld waarbij we ajax kunnen gebruiken

Ik ga een voorbeeld geven van het gebruik van WordPress Ajax op basis van een eerder project. Mijn taak was om meer berichten van een aangepast berichttype op scroll te laden. De website gebruikte Pjax om paginaovergangen af te handelen en de laadtijden van pagina’s te verlengen. Het probleem hiermee was dat de plug-ins voor het laden van meer ajax-berichten niet werden geactiveerd of zelfs maar werden geladen toen ik naar de berichtenpagina navigeerde. Hierdoor moest ik mijn eigen load more ajax-script maken en ik vond dit de gemakkelijkste manier om dit te doen door de standaard WordPress API van de website te gebruiken.

De Setup

Elke recente versie van WordPress wordt geleverd met de ingebouwde WordPress API. Om het JSON-bestand van uw website te bekijken, gaat u naar yourwebsite.com/wp-json. Normaal gesproken zou dit u een JSON-bestand zonder fouten moeten opleveren. Om uw WordPress-berichten of berichten van een specifiek berichttype te zien, moeten we naar uwwebsite.com/wp-json/projects kunnen navigeren, aangezien /projects de naam van uw aangepaste berichttype zou moeten zijn. Maar… Wanneer we dit proberen, zou de pagina een JSON-foutbestand moeten retourneren waarin staat dat er “Geen route gevonden die overeenkomt met de URL en de verzoekmethode”.

Om een werkende URL op te geven, moeten we een REST API-route initiëren in ons function.php-bestand. Het is geen probleem en de volgende code maakt van /wp-json/projects een werkende URL voor onze website.

add_action('rest_api_init', 'custom_api_get_projects');
function custom_api_get_projects(){
  register_rest_route( 'projects', '/all-posts', array(
    'methods' => 'GET',
    'callback' => 'custom_api_get_projects_callback'
  ));
}

In dit voorbeeld zie je dat we de functie register_rest_route gebruiken om een route voor onze projecten te specificeren (aangepast berichttype) en een URL ‘/all-posts’. Als u dit aan uw project heeft toegevoegd, zou u toegang moeten hebben tot yoursite.com/wp-json/project en yoursite.com/wp-json/projects/all-projects.

Pagina setup

Onze PHP-sjabloon die onze projecten weergeeft, heeft eigenlijk geen extra update nodig om het laden van ajax te laten werken. Tenzij u uw jQuery-script op de pagina schrijft in plaats van in een afzonderlijk .js-bestand. Hoe dan ook, ik zal hier een voorbeeld van mijn WP_Query en lus neerzetten:

$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$get_projects = new WP_Query(array( 
	'post_type'     => 'project', 
	'status'        => 'published', 
	'posts_per_page'=> 9,
	'orderby'	=> 'post_date',
	'order'         => 'DESC',
	'paged'         => $paged
));

Zorg ervoor dat u paginering aan de query toevoegt! Dit geeft je de optie hoeveel berichten je wilt weergeven en wanneer onze ajax de volgende reeks berichten moet laden.

De lus voor het weergeven van de eerste pagina van ons project (in mijn geval worden er 9 projecten getoond):

if($get_projects->have_posts()){
<ul class="project-list"><?php while($get_projects->have_posts()) : $get_projects->the_post(); ?>
 	<li class="post"><strong>View Project</strong></li>
</ul>
endwhile; 
if($get_projects->post_count < 9){
 	<div class="load-more"&gta class="btn secondary-button">no more projects</a></div>
}else{
 	<div id="project-loader" class="loading-banner"><a class="btn" href="#!">Load more posts</a></div>
}else{
 	<p class="no-results">No results found for your filter. Please try again.</p>
}

Let op: ik kon geen tags aan mijn code toevoegen, omdat er speciale tekens in mijn WordPress-editor werden weergegeven. Excuseer mij hiervoor, maar dit zou niets nieuws moeten zijn en lijkt op een gewone WordPress-loop. Ook aan het einde zal ik controleren of mijn vraag minder dan 9 berichten oplevert. Als dat zo is, hebben we geen knop ‘Meer laden’ nodig, omdat we alle berichten al hebben.

Functions.php

Eindelijk, daar gaan we! Wat jQuery-plezier aan het project toevoegen. Maar niet zo faaast… we moeten nog 1 ding aanmaken in ons function.php-bestand. Omdat onze ajax-oproep meer berichten van onze WordPress-site moet laden, moet dit uiteraard in PHP worden gedaan. Voeg de volgende code ook toe aan uw function.php-bestand:

function custom_api_get_projects_callback($request){
    $posts_data = array();
    $paged = $request->get_param('page');
    $paged = (isset($paged) || !(empty($paged))) ? $paged : 1;
    $posts = get_posts( array(
      'post_type'       => 'project',
      'status'          => 'published',
      'posts_per_page'  => 9,
      'orderby'         => 'post_date',
      'order'           => 'DESC',
      'paged'           => $paged
    ));
    foreach($posts as $post){
      $id = $post->ID;
      $post_thumbnail = (has_post_thumbnail($id)) ? get_the_post_thumbnail_url($id) : null;
      $post_cat = get_the_category($id);
      $featured = (get_field('project_featured', $id)) ? true : false;
      $posts_data[] = (object)array(
        'id' => $id,
        'slug' => $post->post_name,
        'type' => $post->post_type,
        'title' => $post->post_title,
        'featured_img_src' => $post_thumbnail,
        'featured' => $featured,
        'category' => $post_cat[0]->cat_name
      );
    }
    return $posts_data;
}

De get_posts array bovenaan ziet er hetzelfde uit als de WP_Query-lus die we op onze pagina hebben. We laden dus de juiste berichten op de pagina. Voordat we get_posts() uitvoeren, controleren we of onze URL ons een specifieke pagina heeft gegeven om te laden. Als we al op pagina 3 van onze paginering zijn, hoeft het script alleen de berichten voor pagina 4 op te vragen.

Na onze vraag maken we een nieuwe lus die onze nieuwe berichtgegevens instelt als een JSON-bestand. U kunt hieraan zoveel gegevensvelden toevoegen als u wilt. Ik heb een paar extra’s toegevoegd om een voorbeeld te geven. Als u print_r($post); Uitgang; in de foreach kun je zien welke velden je kunt gebruiken. Ik heb je ook een verborgen voorbeeld van een aangepast veld gegeven.

In mijn foreach-lus declareer ik een variabele met de naam $featured. In mijn project had ik dit nodig om een extra ‘uitgelicht’ label aan mijn project toe te voegen. Ik heb dit in het voorbeeld toegevoegd voor het geval je zoiets ook nodig hebt in je project.

Ajax script

Oké, nu echt, hier is de Ajax-code die ik in mijn project gebruik. Het is een beetje lang, maar ik vind het vrij basic. Het bevat mijn volledige voorbeeld, zodat je alles kunt verwijderen wat je niet nodig hebt, maar ik heb het toch verstrekt om je te laten zien wat mogelijk is. De functie getSJON() roept onze WP-API-url aan en voegt een ?page-parameter toe om de juiste pagina op te halen. Als onze oproep gegevens bevat, doorlopen we deze gegevens en pushen we elk bericht dat al als string is opgemaakt, naar een array.

Na onze lus voegen we de volledige reeks met al onze nieuwe berichten toe aan de bestaande berichtenlijst die we al op onze pagina hebben. Ik heb een extra controle toegevoegd om te zien of onze vraag meer dan 9 berichten kan krijgen of niet. Als dat niet het geval is, hebben we het einde van onze pagina bereikt en hoeft ons Ajax-script niet opnieuw te worden uitgevoerd.

let pull_page = 1; let jsonFlag = true;
if(jsonFlag){
jsonFlag = false; pull_page++;
$.getJSON("/wp-json/projects/all-posts?page=" + pull_page, function(data){
	if(data.length){
		var items = [];
		$.each(data, function(key, val){
			const arr = $.map(val, function(el) { return el });
			const post_url = arr[1];
			const post_title = arr[3];
			const post_img = arr[4];
			const post_featured = arr[5];
			const post_cat = arr[6];
			let featured = "";
			if(post_featured){
				featured = "featured";
			}
			let item_string = '<ul><li class="item">' + post_title + '</li></ul>'; 
			items.push(item_string);
		}); 
		if(data.length >= 9){ 
			$('li.loader').fadeOut(); 
			$("#project-list").append(items);
		}else{ 
			$("#project-list").append(items); 
			$('#project-loader').hide(); 
			$('#ajax-no-posts').fadeIn(); 
		} 
	}else{ 
		$('#project-loader').hide(); 
		$('#ajax-no-posts').fadeIn(); 
	} 
}).done(function(data){ 
	if(data.length){ jsonFlag = true; } 
});}

Aan het begin van ons JS-bestand declareren we een jsonFlag en een pull_page variabele. De jsonFlag voorkomt dat ons json-script meerdere keren wordt uitgevoerd terwijl het zijn werk al doet. als ons script actief is, zal de jsonFlag false zijn en kan ons script niet opnieuw worden uitgevoerd. Als ons script klaar is en er nieuwe berichten zijn geretourneerd, zetten we onze jsonFlag weer op true en kunnen we ons script opnieuw aanroepen. Je kunt dit script ook gebruiken om de ‘load-more’-knop een ‘uitgeschakelde’ status te geven.

De jsonFlag wordt ingesteld op false als het script voor de eerste keer wordt uitgevoerd. ALLEEN als ons script meer dan 9 berichten retourneert (of wat je ook in je paginering hebt), kunnen we de vlag weer op True zetten. Als er minder dan 9 berichten worden geretourneerd, betekent dit dat we geen berichten meer hoeven te laden.

Ajax laadt meer berichten met een klik

De functie die we eerder maakten is eigenlijk al goed te gebruiken voor een onClick-evenement. Verpak de volledige code in een .on(‘klik’) en de knop zou elke keer dat u erop klikt de nieuwe berichten moeten retourneren.

Ajax laadt meer berichten op scroll

Om ons vorige script in een .on(‘scroll’) gebeurtenis te plaatsen, moeten we wat extra validatie toevoegen. On scroll wordt op elke pagina uitgevoerd, in plaats van alleen op de pagina waarop onze berichten staan.

$(document).on('scroll', function(){
	const fromBottom = $(window).scrollTop() + $(window).height();
	if($('#project-list').length && $('#project-loader').length){
		const loader_height = $('#project-loader').offset().top + $('#project-loader').height();
		if(jsonFlag){
			/* our previous ajax script */
		}
	}
}
In onze scrollfunctie controleren we of onze projectlijst op de pagina staat of niet. Als dat niet het geval is, hoeven we ons scrollscript niet uit te voeren. Als deze aanwezig is op de pagina, controleren we ook of onze projectladerknop aanwezig is op de pagina. Omdat we onze knop verbergen als er geen berichten meer zijn. Dus als er geen berichten meer zijn, is de knop verborgen en wordt ons script niet meer uitgevoerd bij scrollen.

– Extra –

Ik voeg wat extra voorbeelden toe aan dit bericht omdat ik een paar extra problemen had die ik moest oplossen voor mijn project. Dus misschien loop jij daar ook tegenaan.

Ajax laadt berichten uit een specifieke categorie

Om aangepaste berichttypen met een specifieke categorie te laden, hoeven we alleen ons WP_Query-script bij te werken, zowel op onze posts.php-pagina ALS op onze function.php-pagina. De query om aangepaste berichttypen met een categorie te laden ziet er als volgt uit. Houd er rekening mee dat ik de gevraagde categorie op ID krijg en deze aan de pagina-URL toevoeg als een $_GET[] parameter.

$get_cat = $_GET['cat']; // ONLY IN POSTS.PHP
$get_cat = $request->get_param('cat'); // ONLY IN FUNCTIONS.PHP
$get_projects = new WP_Query(array( 
	'post_type'     => 'project', 
	'status'        => 'published', 
	'posts_per_page'=> 9,
	'order'         => 'DESC',
	'category__and' => $get_cat,
	'paged'         => $paged
));

Dit moet worden bijgewerkt in zowel ons posts.php- als function.php-bestand. Ik hoop dat het een beetje duidelijk is in mijn codevoorbeeld, maar op onze posts.php-pagina halen we de categorie uit de URL door $_GET[‘cat’] aan te vinken. MAAR in functies.php moeten we $request->param(‘cat’) gebruiken in plaats van $_GET[‘cat’] om hetzelfde resultaat te krijgen.

Het makkelijke (denk ik) aan het gebruik van de WP API voor dit soort dingen, is dat we onze Ajax-URL gemakkelijk kunnen bijwerken als we dit soort wijzigingen willen. In onze query zoeken we naar een GET-parameter met de naam ‘cat’. Dus nu hoeven we alleen maar onze jQuery bij te werken en deze parameter ook in onze Ajax-URL op te geven:

let cat_string = $('#le_current_cat').text();
$.getJSON("/wp-json/projects/all-posts?page=" + pull_page + "&cat=" + cat_string, function(data){
	/* the regular ajax script */
}

Omdat jQuery PHP niet kan lezen en ik al mijn jQuery in een apart bestand heb, plaats ik de huidige categorie van de pagina in een verborgen div met de ID#le_current_cat. In mijn jQuery-bestand kan ik gewoon uitlezen op welke categorie we filteren en dit doorgeven aan mijn URL

Berichten bestellen op basis van een aangepast veld

Ook dit was een worsteling. Ik moest alle ‘uitgelichte’ projecten bovenaan de pagina plaatsen, en ook mijn ajax-script moest eerst alle features-projecten laden, voordat de rest werd geladen. Dit kan door onze berichten te bestellen op mijn aangepaste veld ‘uitgelicht’ in plaats van op datum. Om dit op te lossen hoeven we ons ajax-script niet aan te raken. Alleen onze PHP-query op zowel de posts.php-pagina als in ons function.php-bestand.

$get_projects = new WP_Query(array( 
      'post_type'       => 'project',
      'status'          => 'published',
      'posts_per_page'  => 9,
      'meta_key'        => 'project_featured',
      'orderby'         => 'meta_value_num',
      'order'           => 'DESC',
      'category__and'   => $get_cat,
      'paged'           => $paged
));

Om te filteren op aangepaste berichttypen gebruiken we de ‘meta_key’ met het aangepaste veld dat we eraan hebben gegeven. In mijn geval heet dit ACF-veld ‘project_featured’ en zal het alleen waar/onwaar retourneren. Dus ik bestel eerst alle berichten met TRUE en daarna alle berichten die geen uitgelicht project zijn.

Dus dit is hoe ik een aangepaste ajax-lader op scroll heb gemaakt met behulp van de WordPress API. Ik weet dat dit een groot bericht is, maar ik hoop dat het je heeft geholpen! Ik heb veel voorbeelden en extra’s gegeven, maar misschien zal ik dit bericht in 2 afzonderlijke berichten splitsen om het duidelijker te maken. Gewoon de basis ajax loader en dan alle andere extra’s…

Hoe dan ook, ik hoop dat je het begrijpt en dat je het nuttig vond 🙂

Best Bob

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *