A Primer op Ajax in het WordPress Frontend Eigenlijk Doing It

In deze serie bespreken we hoe Ajax moet worden geïmplementeerd in de WordPress-frontend. In de eerste post in de serie hebben we bekeken hoe Ajax op hoog niveau werkt, bekeken hoe Ajax in het Dashboard van WordPress kan worden geïntroduceerd en hebben we de twee beschikbare hooks voor integratie van Ajax in WordPress besproken.

Op dit moment is het tijd om daadwerkelijk iets te bouwen dat laat zien hoe we Ajax kunnen gebruiken in de WordPress-frontend. Om dit te doen, schrijven we onze eigen plug-in om ervoor te zorgen dat we de best practices van WordPress volgen.

Aan het einde van dit artikel hebben we een volledig werkende plug-in met broncode die openbaar beschikbaar is op GitHub. Met dat gezegd, laten we aan de slag gaan.


Plan het uit

Als u een van mijn eerdere artikelen hebt gelezen, weet u dat ik altijd graag mijn projecten begin met het plannen van wat we gaan doen. Dit project is niet anders.

In dit voorbeeld introduceren we een selectievakje waarmee lezers die zijn ingelogd op een WordPress-site, blogberichten die ze hebben gelezen kunnen afvinken. Op deze manier zien ze alleen berichten die ze nog moeten lezen sinds ze zich hebben aangemeld bij de site.

Om dit te bouwen, zullen we een aantal dingen gebruiken:

  • Een nieuwe installatie van WordPress
  • De WordPress Theme Unit Test geeft ons veel voorbeeldinhoud
  • Het Twenty Eleven-thema (omdat het zo wijd beschikbaar is)
  • Een gebruikersaccount met de rol 'Deelnemer'

Zodra u de omgeving hebt ingesteld, volgt hier het actieplan dat we zullen volgen voor onze plug-in:

  • We zullen een nieuwe plug-in maken in de plug-ins directory genaamd I've Read This (in de directory ive-read-this)
  • Bij elk bericht introduceren we een selectievakje en een label waarmee gebruikers kunnen aangeven dat ze dit bericht hebben gelezen
  • Zodra het bericht is gemarkeerd als gelezen, verdwijnt de optie uit het zicht

Begrepen? Ga je gang en meld je aan als de gebruiker die je hebt gemaakt met de rol 'Deelnemer' en laten we aan de slag gaan!


Gebouw Ik heb dit gelezen

Zodra u de testgegevens hebt geïmporteerd, ziet uw installatie er ongeveer zo uit:

Vanaf hier zijn we klaar om aan de slag te gaan met het schrijven van de plug-in.

Uitpluggen uit de plug-in

Voordat we daadwerkelijk een code schrijven, vind ik het leuk om door te gaan en de plugin-bestanden uit te zoeken. Dit betekent dat we de directory, de basisplugin-structuur en eventuele mappen die we mogelijk nodig hebben om plug-in afhankelijkheden te gebruiken, instellen..

Omdat we wat lichte styling en JavaScript-bestanden voor het initiëren van het Ajax-verzoek zullen aanbieden, is dit de structuur van de basisdirectory. De lang-directory is optioneel, hoewel ik het een best practice vind:

Laten we nu de tekst die nodig is voor de plugin.php. Merk op dat dit niets anders dan een skelet zal zijn. Het zal in de eerste plaats verantwoordelijk zijn voor het leggen van de basis voor wat we later in het artikel gaan bouwen:

 

Op dit punt kunt u de plug-in activeren in het WordPress plugin-dashboard, maar er gebeurt niets. Als je er klaar voor bent, ga je gang en doe dat nu - je zult in staat zijn om de plugin tot leven te zien komen terwijl we eraan werken.

Introduceer een checkbox op elke post

Aangezien we een selectievakje voor elk bericht introduceren waarmee gebruikers kunnen instellen of ze het bericht hebben gelezen, moeten we rekening houden met het volgende:

  • We moeten ervoor zorgen dat het selectievakje alleen wordt weergegeven wanneer de gebruiker is aangemeld
  • Het selectievakje moet onderaan het bericht op de enkele berichtpagina staan, omdat de gebruiker daar dan aangeeft dat ze het bericht hebben gelezen

We kunnen beide bereiken door de volgende functie toe te voegen:

 / ** * Voegt een selectievakje toe aan het einde van een bericht in één weergave waarmee gebruikers die zijn aangemeld * hun bericht als gelezen kunnen markeren. * * @param $ content De inhoud van het bericht * @return Het postcontent met of zonder het toegevoegde selectievakje * / public function add_checkbox ($ content) // We willen alleen de inhoud wijzigen als de gebruiker is aangemeld als (is_user_logged_in ( ) && is_single ()) // Bouw het element dat zal worden gebruikt om dit bericht te markeren als gelezen $ html = '
'; $ html. = ''; $ html. = '
'; // Voeg het toe aan de inhoud $ content. = $ Html; // einde als return $ inhoud; // einde add_checkbox

Lees de opmerkingen aandachtig door, aangezien ze precies moeten uitleggen wat er aan de hand is; Als je echter onduidelijk bent, aarzel dan niet om een ​​reactie achter te laten.

Vervolgens moeten we de volgende regel toevoegen in de constructor, zodat de inhoud filter heet:

 // Stel de actie in voor het renderen van het aankruisvak add_filter ('the_content', array (& $ this, 'add_checkbox'));

Laten we tenslotte een klein beetje stijl toevoegen om het selectievakje een enigszins unieke look en feel te geven binnen de context van het Twenty Eleven-thema. In de plug-ins plugin.css bestand, voeg de volgende code toe:

 # ive-read-this-container margin: 1em 0 1em; achtergrond: #eee; border: 1px solid #ccc; opvulling: 0.25em; 

Nu, als u zich aanmeldt bij de WordPress-installatie en naar de onderkant van een enkel bericht navigeert, ziet u ongeveer zoiets als de volgende afbeelding:

Op dit moment zijn we klaar om JavaScript te gaan schrijven.

Een aanvraag doen: de Click-handler instellen voor het selectievakje

Het eerste dat we moeten doen, is JavaScript instellen zodat het alleen wordt geactiveerd als de container 'Ik heb dit gelezen' op de pagina staat. Er zijn verschillende manieren om dit te doen, maar omdat we het JavaScript op elke pagina laden, gebruiken we JavaScript om te controleren of het selectievakje 'Ik heb dit gelezen' is dat we aan het schrijven zijn naar de pagina.

Hiertoe voegt u de volgende code toe aan plugin.js. De opmerkingen in de code moeten voor zichzelf spreken. Zo niet, laat een reactie achter!

 (functie ($) $ (function () // Als de "ik heb deze container gelezen" op deze pagina staat, laten we dan de gebeurtenishandler instellen als (1 === $ ('# ive-read-this- container '). length)  // end if); (jQuery));

In de code die u hierboven ziet, zal alles dat we plaatsen binnen de voorwaardelijke voorwaarde alleen worden geactiveerd als het container-element "I've Read This" aanwezig is.

In dit geval weten we dat we de ID van het bericht naar de server moeten sturen. Omdat de gebruiker is ingelogd, kunnen we zijn / haar ID aan de serverzijde krijgen.

Dus de volgende stap is om de ID van het bericht te krijgen waar we aan toe zijn. Gelukkig bewaart Twenty Eleven het nummer van de post in de artikel ID van het element. We moeten het gewoon analyseren.

Laten we dat nu doen:

 // We gebruiken het kenmerk change, zodat de gebeurtenishandler // vuurt wanneer op het selectievakje of het bijbehorende label wordt geklikt. $ ('input [naam = "ive-read-this"]'). change (function (evt) // We kunnen de ID van dit bericht ophalen uit de 
's ID. Dit is verplicht // zodat we kunnen aangeven dat de gebruiker dit bericht heeft gelezen en dat we het kunnen verbergen. var sArticleId, iPostId; // Haal de artikel-ID op en deel deze - de tweede index is altijd de bericht-ID in Twenty Eleven sArticleId = $ ("article"). Attr ('id'); iPostId = parseInt (sArticleId.split ('-') [1]); );

Op dit moment zijn we klaar om een ​​Ajax-aanvraag in te stellen. We zullen jQuery's gebruiken $ .post methode om dit te doen en we zullen de standaard van WordPress gebruiken ajaxurl om ons antwoord te behandelen.

Het evenement afhandelen: markeer de post als gelezen

Laten we doorgaan en de code schrijven waarmee de ID van het bericht wordt verzonden. We zullen ons later in dit artikel zorgen maken over de reactie, vandaar de opmerking "TODO" in de code.

 // Initialiseer het verzoek om dit specifieke bericht te markeren als lees $ .post (ajaxurl, post_id: iPostId, function (response) // TODO);

Op dit punt in ontwikkeling zou de volledige JavaScript-bron er als volgt uit moeten zien:

 (functie ($) $ (function () // Als de "ik heb deze container gelezen" op deze pagina staat, laten we dan de gebeurtenishandler instellen als (1 === $ ('# ive-read-this- container '). length) // We gebruiken het wijzigingsattribuut zodat de gebeurtenishandler // vuurt telkens wanneer op het selectievakje of het bijbehorende label wordt geklikt. $ (' input [naam = "ive-read-this"] '). veranderen (functie (evt) // We kunnen de ID van dit bericht ophalen uit de 
's ID. Dit is verplicht // zodat we kunnen aangeven dat de gebruiker dit bericht heeft gelezen en dat we het kunnen verbergen. var sArticleId, iPostId; // Haal de artikel-ID op en deel deze - de tweede index is altijd de bericht-ID in Twenty Eleven sArticleId = $ ("article"). Attr ('id'); iPostId = parseInt (sArticleId.split ('-') [1]); // Initialiseer het verzoek om dit specifieke bericht te markeren als gelezen $ .post (ajaxurl, post_id: iPostId, function (response) // TODO); ); // stop als ); (JQuery));

Voor degenen onder u die de voorbeeldcode hebben doorlopen terwijl u het artikel hebt gelezen, merkt u meteen dat uw browser een consolefout genereert:

Uncaught ReferenceError: ajaxurl is niet gedefinieerd

Oops! En deze is waar we moeten zorgen dat de Ajax-bibliotheek van WordPress correct wordt opgenomen.

Inclusief de Ajax-bibliotheek van WordPress op de frontend

Om dit te doen, moeten we inhaken op de wp_head actie. Voeg de volgende regel code toe aan de constructor van uw plug-in:

 // Voeg de Ajax-bibliotheek toe aan de frontend add_action ('wp_head', array (& $ this, 'add_ajax_library'));

Voeg vervolgens de volgende functie toe. Dit is wat verantwoordelijk is voor het opnemen van de Ajax-bibliotheek:

 / ** * Voegt de WordPress Ajax-bibliotheek toe aan de frontend. * / public function add_ajax_library () $ html = ''; echo $ html;  // end add_ajax_library

Als u nu probeert de code uit te voeren, zou u geen probleem moeten hebben. Op dit punt zijn we klaar om door te gaan.

Behandel de gebeurtenis: markeer de post als gelezen

Nu we het verzoek naar de server hebben gestuurd, kunnen we onze gebeurtenishandler aan de serverzijde schrijven. Dit is hoe de handler moet werken:

  • Controleer of de waarde van de inkomende post-ID is ingesteld en dat het een numerieke waarde is (dit is een zeer rudimentaire parodiebeveiliging, maar het werkt voor alle doeleinden en doeleinden).
  • Probeer vervolgens de meta van de huidige gebruiker bij te werken met behulp van zijn / haar ID en de bericht-ID.
  • Als de update mislukt, keren we terug -1; anders komen we terug 1. We zullen deze waarden verwerken in de antwoordbehandelaar in JavaScript.

Eerst voegen we de haak toe aan de constructor van de plug-in:

 // Stel de gebeurtenishandler in om deze post te markeren als gelezen voor de huidige gebruiker add_action ('wp_ajax_mark_as_read', array (& $ this, 'mark_as_read'));

Vervolgens implementeren we de handler:

 / ** * Gebruikt het huidige gebruikers-ID en het inkomende bericht-ID om dit bericht te markeren als gelezen * voor de huidige gebruiker. * * We slaan de ID van dit bericht op in de meta van de bijbehorende gebruiker, zodat we deze later * kunnen verbergen in de lijst. * / public function mark_as_read () // Eerst moeten we ervoor zorgen dat de parameter post ID is ingesteld en dat het een numerieke waarde is als (isset ($ _POST ['post_id']) && is_numeric ($ _POST ['post_id '])) // Als we de gebruikers-meta niet bijwerken, antwoord dan met -1; anders, antwoord met 1. echo false == update_user_meta (wp_get_current_user () -> ID, $ _POST ['post_id'], 'ive_read_this')? "-1": "1";  // end if die ();  // end mark_as_read

Laten we daarvoor het nog openstaande document opnieuw bekijken TE DOEN in de responsfunctie van de JavaScript waaraan we aan het werken waren. Dit is het volledige script:

 (functie ($) $ (function () // Als de "ik heb deze container gelezen" op deze pagina staat, laten we dan de gebeurtenishandler instellen als (1 === $ ('# ive-read-this- container '). length) // We gebruiken het wijzigingsattribuut zodat de gebeurtenishandler // vuurt telkens wanneer op het selectievakje of het bijbehorende label wordt geklikt. $ (' input [naam = "ive-read-this"] '). veranderen (functie (evt) // We kunnen de ID van dit bericht ophalen uit de 
's ID. Dit is verplicht // zodat we kunnen aangeven dat de gebruiker dit bericht heeft gelezen en dat we het kunnen verbergen. var sArticleId, iPostId; // Haal de artikel-ID op en deel deze - de tweede index is altijd de bericht-ID in Twenty Eleven sArticleId = $ ("article"). Attr ('id'); iPostId = parseInt (sArticleId.split ('-') [1]); // Initialiseer het verzoek om dit specifieke bericht te markeren als gelezen $ .post (ajaxurl, action: 'mark_as_read', post_id: iPostId, function (response) // Als de server '1' retourneert, kunnen we markeren deze post als gelezen, dus we zullen de checkbox // container verbergen. De volgende keer dat de gebruiker de index doorbladert, zal deze post niet verschijnen als (1 === parseInt (response)) $ ('# ive-read- this-container '). slideUp (' snel '); // Anders laten we de gebruiker weten dat er een probleem was.In een grotere omgeving zouden we // dit met meer sierlijk willen behandelen. else alert (" Er is een fout opgetreden bij het markeren van dit bericht. Probeer het opnieuw. "); // end if / else); ); // stop als ); (JQuery));

One More Change

Als de gebruiker toevallig de weg naar een individuele berichtpagina vindt (zoals eraan gekoppeld zijn), moeten we controleren of deze eerder zijn gemarkeerd om te worden gelezen.

Om dit te doen, moeten we het add_checkbox functioneert, zodat het controleert of de gebruiker is aangemeld en de gebruikers-meta leest om te bepalen of het bericht eerder als gelezen is gemarkeerd:

 / ** * Voegt een selectievakje toe aan het einde van een bericht in één weergave waarmee gebruikers die zijn aangemeld * hun bericht als gelezen kunnen markeren. * * @param $ content De berichtinhoud * @return Het postcontent met of zonder het toegevoegde selectievakje * / public function add_checkbox ($ content) // We willen alleen de inhoud wijzigen als de gebruiker is ingelogd als (is_single ( )) // Als de gebruiker is aangemeld ... if (is_user_logged_in ()) // En als ze eerder deze post hebben gelezen ... if ('ive_read_this' == get_user_meta (wp_get_current_user () -> ID, get_the_ID () , waar)) // Bouw het element om aan te geven dat dit bericht is gelezen $ html = '
'; $ html. = ''; $ html. = __ ("Ik heb dit bericht gelezen.", 'ive-read-this'); $ html. = ''; $ html. = '
'; // Anders geven ze de optie om dit bericht te markeren als gelezen else // Bouw het element dat zal worden gebruikt om dit bericht te markeren als gelezen $ html = '
'; $ html. = ''; $ html. = '
'; // einde if // Voeg het toe aan de content $ content. = $ html; // end if // end if return $ content; // einde add_checkbox

Zie het in actie!

Op dit moment heeft u een werkende plug-in:

  • Je zou naar elk bericht kunnen navigeren
  • Als je het nog niet hebt gelezen, zou je op het selectievakje moeten kunnen klikken om het te laten verdwijnen
  • Als u de pagina opnieuw laadt, ziet u de melding dat het bericht is gemarkeerd als gelezen.

Niet slecht, toch??

Natuurlijk is er altijd ruimte om hiermee zelf te experimenteren. U zou bijvoorbeeld kunnen werken aan het uitsluiten van deze berichten uit de hoofdlus als ze zijn gemarkeerd als gelezen. Een andere optie is om een ​​aangepaste klassenaam toe te voegen en vervolgens het bericht te stylen om aan te geven dat de huidige gebruiker het heeft gelezen.

Onthoud tenslotte dat je alle broncode in zijn geheel kunt pakken op GitHub.


Gerelateerd lezen

  • Filterreferentie
  • Action Reference
  • Ajax in Plugins
  • Update gebruikers-meta