Wanneer je in Elementor Pro widgets kijkt waarmee je posts op een pagina of in een template kunt laten zien, dan is één van de properties die je in kunt vullen de Query ID.
Elementor (Pro) is nogal karig met informatie over wat je nu precies met deze Query ID kunt doen. Het grootste deel van de documentatie vind je in de sourcecode zelf. Dat is nu niet de plek waar je graag gaat zoeken.
Voor een klant had ik ik echter nodig, dat er wel heel specifiek gefilterd zou worden. De klant heeft een custom post type waarin evenementen worden opgeslagen. En wat hij wilde, is dat uitsluitend evenementen in de toekomst getoond zouden worden.
Wat echter niet mocht, was deze evenementen ook verwijderen. De meeste van zijn evenementen zijn terugkerende evenementen en na het aanpassen van de datum moest het evenement weer opnieuw getoond worden. Deze datum staat in een ACF datum veld. Dus het is niet de post-datum, maar de evenement datum waarop gesorteerd en gefilterd moet worden.
Dat dit niet op de post datum mogelijk was, is omdat de post datum door WordPress zelf al gebruikt wordt voor het bepalen wanneer de post getoond mag worden. Als je de post datum dus voor de event-datum zou gebruiken, dan zou het event alleen op de dag van het event zichtbaar worden. Dat was niet echt de bedoeling.
Zijn webbouwer had met behulp van de plugin ‘Future’ van PublishPress al wat gebouwd, maar het werkte niet zoals verwacht. En aangezien de webbouwer zelf een WP Professional is, maar niet zelf programmeert had zij mijn hulp ingeroepen.
Wat ik niet doe in dit artikel
Wat ik in dit artikel niet ga doen is je in detail uitleggen hoe uiteindelijk die voor die klant geschreven code in elkaar zit. Per slot van rekening, het is de klant van mijn klant die ervoor betaald heeft. Wat ik je wel uit wil leggen, is hoe het nu eigenlijk werkt met die ‘Query ID’, Hoe gebruik je zo’n Query ID om de query op de database aan de server kant aan te passen?

I”n de afbeelding hierboven zie je het blokje over de Query ID in een rode rechthoek uitgelicht. De omschrijving is echter weinig-zeggend ‘Geef je query een aangepaste unieke ID om filteren op de server mogelijk te maken’.
De ID
Leuk… maar hoe bepaal ik die ID en hoe kan ik deze op de server gebruiken? Daar wordt helaas geen antwoord op gegevens. Gelukkig is het allemaal niet zo moeilijk.
Wat wel belangrijk is, is dat de ID uniek is. Wanneer je werkt aan een site met meerdere maatwerk plugins, is het altijd verstandig jouw ID een prefix te geven, die op de één of andere manier naar jouw persoon, of je bedrijf verwijst. Zo gebruik ik altijd ‘wxp’ als prefix. voor een ID. In dit voorbeeld gebruik ik echter ‘pfx’ als prefix, omdat ik al een paar keer tegen situaties aan ben gelopen, waar mensen direct zonder aanpassingen de snippet-code van deze site kopiëren en plakken… zo voorkom ik in ieder geval, dat ik aanloop tegen ‘prefix fouten’ van anderen.
Wat je waarschijnlijk ook opvalt, is dat de Query ID ook dynamisch in te stellen is (zie de stapel ‘pannenkoeken’ aan het eind van het veld). Je kan dus eventueel die Query ID ook door andere -aan de server kant bepaalde- parameters in laten vullen.
Wat we in dit voorbeeld doen, is een aantal posts tonen, waarbij we -afhankelijk van het ingelogd zijn- alleen de publieke, of zowel de publieke als private posts willen laten zien. En dit doen we slechts voor één post-type. De tips.
We bepalen eerst de naam voor de ID. Laten we zeggen pfx_members_only. Denk erom, de naam mag letters, cijfers en underscores bevatten. Houdt om fouten te voorkomen ook altijd kleine letters aan.
Een actie toevoegen – en Namespaces
De code die hieronder staat, vul je in in je functions.php of in de maatwerk plugin voor je site.
Je moet hier gebruik maken van een ‘action hook’. En de manier waarop we het hier doen, heb ik nog niet in andere voorbeelden laten zien. En dat is omdat Elementor gebruik maakt van Name Spaces. Name Spaces worden al heel lang gebruikt in PHP -sinds versie 5.3- maar binnen WordPress begon het pas in PHP versie 7 gemeengoed te worden. En in complexe omgevingen als Elementor kom je er eigenlijk niet omheen.
Waarom dat niet in de WordPress code is gedaan? De belangrijkste reden is wel, dat toen men met WordPress begon, begon met niet direct met het gebruik van namespaces. Het was destijds ‘iets nieuws’ en het integreren met de bestaande code die voor WordPress gebruikt werd, zou teveel tijd kosten. Bovendien was de implementatie van namespaces in die eerste versies van PHP niet echt geweldig.
De meeste communicatie met de hooks en functies in de code API is dus niet gebaseerd op name spaces, en omdat we tot nu toe hoofdzakelijk in snippets hebben gecommuniceerd met de core, was het gebruik van namespaces niet nodig… of eigenlijk, niet mogelijk.
In Elementor kom je echter niet om die namespaces heen. En wanneer je precies wilt weten hoe namespaces werken, is de cursus voor WordPress Developer wellicht het juiste pad voor je om dit te leren, in deze snippet beperk ik mij tot de uitleg van hoe je action hooks met namespaces kan gebruiken. En dat is eigenlijk best eenvoudig.
Je moet het gewoon zo zien, dat ieder bedrijf wat grotere plugins bouwt, begint met het reserveren voor een plekje voor hun eigen code. Dat doen ze natuurlijk fysiek al, door een directory binnen de filestructuur van WordPress te claimen, maar dat kunnen ze ook ‘in het geheugen’ doen. Wanneer code binnen een bepaalde namespace geladen wordt, zijn de functies binnen die code alleen toegankelijk voor functies binnen diezelfde namespace. En zo kan je aardig wat conflicten voorkomen.
Wat je voor de communicatie met de Elementor action hooks hoeft te weten, is dat deze aanroepbaar zijn via ‘elementor/’. En alle action hooks die betrekking hebben op server-side queries zijn aanroepbaar via ‘elementor/query’.
De specifieke code die server-side gebruikt moet worden om jouw maatwerk query te laden wordt geactiveerd door ‘elementor/query/{naam van jouw Query ID}’, dus in jouw geval ‘/elementor/query/pfx_members_only’.
De complete functieaanroep zou er dus zo uit komen te zien:
<?php
add_action('elementor/query/pfx_members_only', function (\WP_Query $query)) {
}
Omdat we hier in principe onze actie beginnen in de namespace ‘\Elementor\Query’ moeten we WordPress wel even vertellen, waar het object type van $query gevonden kan worden.
Maar deze functie doet nog niets. Omdat we niet willen, dat in de admin-interface de resultaten van een query beïnvloed worden, vertellen we eerst, dat er niets mag gebeuren, wanneer we ‘in de WP Admin’ zitten.
<?php
add_action('elementor/query/pfx_members_only', function (\WP_Query $query)) {
if ( is_admin() ) {
return;
}
}
En dan is het nu tijd om de daadwerkelijke actie toe te voegen. Wat we hier gaan doen is de query aan te passen door de post_status van de query -een object met de vraag aan de database- aan te passen. Denk er hierbij wel aan, dat door het aanpassen van de query je eventueel parameters zou kunnen overschrijven die al gezet zijn in de instellingen voor de Query binnen de widget zelf.
<?php
add_action('elementor/query/pfx_members_only', function (\WP_Query $query)) {
if ( is_admin() ) {
return;
}
if (! is_user_logged_in()) {
$query->set('post_status', 'publish');
} else {
$query->set('post_status', Array('publish', 'private'));
//vanaf PHP 8 mag je ook schrijven
//$query->set('post_status',['publish','private']);
//dat is minder tikwerk, en geeft duidelijker de begrenzing van het array aan
}
}
Afronding
Dit is dus hoe je vraagstellingen op de server vanuit Elementor kan filteren. En zoals je ziet, is het gebruik van Elementor om gegevens te filteren niet echt complex. De werkelijke complexiteit zit hem in het WordPress WP_Query object, de interface tussen WordPress en de post typen in de onderliggende database. Wanneer je daar meer over wilt weten, vind je de volledige API documentatie op de WordPress website.



