Wat te doen, wanneer shortcodes zich niet gedragen zoals verwacht?

Shortcodes. Ik kan mij eigenlijk WordPress niet meer voorstellen zonder shortcodes. Het is inmiddels al weer meer dan 18 1/2 jaar geleden, dat de shortcodes hun intrede deden in WordPress 2.5 (29 maart 2008). Ik kan het me nog goed herinneren (ja, ik ben stokoud) omdat met de gallery shortcode er eindelijk geen aparte ‘gallery’ plugin meer nodig was.
Nog steeds is een shortcode de ‘goto’ oplossing wanneer een moderne pagebuilder bepaalde opties van plugins niet standaard ondersteunt.
WXP Plugins – Elementor, Block, Shortcode
Toen ik de serie ‘WXP Plugins‘ begon te ontwikkelen, was mijn uitgangspunt dat alle output naar de WordPress pagina’s ondersteund moest worden, zonder dat de plugin zelf controle over de pagina’s over zou nemen. En aangezien WordPress blocks de standaard zijn, moesten natuurlijk Blocks ondersteund worden. Omdat ik zelf vooral met Elementor werk, wanneer ik websites bouw, moest ook Elementor ondersteund worden. En omdat je ook met een andere pagebuilder de plugins zou moeten kunnen gebruiken, kon ik natuurlijk niet om ‘shortcodes’ heen.
Prima. Hier geen vuiltje aan de lucht. Wanneer jij als eindgebruiker of webdesigner de plugins in de reeks van WXP Plugins wilt gebruiken, dan heb je daar alle gelegenheid toe.
Maar wat, wanneer je iets over deze plugins wilt schrijven? Of over willekeurige andere plugins die shortcodes gebruiken? Dan heb je als ‘Blogger over WordPress’ toch een ernstige beperking. Vooral wanneer je Elementor of sommige andere pagebuilders gebruikt. Dan loop je ineens aan tegen de problemen met shortcodes die eigenlijk net zo oud zijn als de shortcodes zelf.
Shortcodes ‘escapen’
Kort na de introductie van de shortcodes in 2008 werd al duidelijk, dat shortcodes een oplossing boden, maar bij die oplossing ook gelijk een nieuw probleem introduceerde. Want wat nu, wanneer ik een handleiding over het gebruik van shortcodes wil schrijven?
Stel je voor, ik heb een plugin ontwikkeld. En die plugin biedt onder meer een shortcode [myplugins_shortcode] aan. En in mijn handleiding voor die plugin wil ik je vertellen dat de code
[myplugins_shortcode action="make_coffee" milk="false" sugar="false"]
een heerlijke bak koffie klaarmaakt. Zonder melk, zonder suiker. Ik wil uitleggen hoe shortcodes werken, geen koffie zetten.
Maar zodra ik deze code intik, krijgt de bezoeker het volgende te zien.

Kortom, de koffie is klaar. Maar de code die hij in de pagina in moet voegen om WordPress te gebruiken om koffie te zetten, kent hij nog steeds niet. (ten overvloede, ik ken de juiste methode ook nog niet, als je weet hoe ik met WordPress koffie kan zetten, laat dan gerust een commentaar achter onder dit artikel).
En met twee blokhaken aan het begin, en twee blokhaken aan het einde vertelde je WordPress, dat nu eens geen shortcode uitgevoerd moest worden, maar de shortcode gewoon getoond moest worden.
Dus mensen waren creatief. En schreven dingen als
Om een heerlijke bak koffie te zetten moet je de shortcode [ myplugins_shortcode action=”make_coffee” milk=”false” sugar=”false”] intikken. Hierbij moet je wel de spatie tussen [ en myplugins_shortcode weglaten, die heb ik ingegeven om te voorkomen, dat deze plugin hier uitgevoerd wordt.
Je begrijpt het wel. Dat communiceert van geen kanten!
Om het mensen mogelijk te maken shortcodes te delen met andere mensen, is er dus een manier nodig om shortcodes ook te kunnen ‘escapen’. En aangezien de makers van WordPress best snel van begrip zijn, hadden ze al snel door, dat je deze ‘blokhaken’ ook moest kunnen escapen. En dat is heel makkelijk. Gewoon nog een stel blokhaken.
[[myplugins_shortcode action="make_coffee" milk="false" sugar="false"]]
Let op de dubbele haken!
laat niet dit zien:

maar gewoon de shortcode
[myplugins_shortcode action="make_coffee" milk="false" sugar="false"]
Dat is al een hele stap vooruit.
En toen kwamen de pagebuilders
En toen kwamen de pagebuilders. En veel pagebuilders zijn niet (goed) getest rond de vraag of shortcodes wel goed ge-escaped worden. En wat ik verder ook van Elementor vind (en dat is hoofdzakelijk positief), het vereist toch wel enige jaren van struisvogelpolitiek om nu al weer 8 jaar deze ‘bug’ in Elementor gewoon te negeren.
Ik begrijp het: Mensen die over shortcodes schrijven zijn nu niet direct Elementor’s primaire doelgroep. Maar toch.
Wat gaat er mis met Elementor
Op zich kan je op een ‘gewone’ Elementor pagina ongestraft shortcodes escapen. Als ik op mijn homepage in een tekst of paragraaf widget [[myplugins_shortcode]] intik, krijg je netjes, zoals verwacht [myplugins_shortcode] te zien.
Het wordt echter problematischer wanneer je shortcodes gebruikt binnen dynamic fields.
Even een opfrisser: Wanneer ik tekst in een widget op bijvoorbeeld een homepage ingeef, dan wordt die tekst opgeslagen in die pagina.
Wanneer ik echter een dynamic field laad (en dat doe ik bijvoorbeeld bij een template voor een blogpagina), dan wordt de informatie niet direct geladen, maar nog eens een keer ‘extra’ geĆ«valueerd.
Bij die ‘extra evaluatie’ hoort ook, dat shortcodes nogmaals worden uitgevoerd.
En daar gaat het fout! Goed Fout!!
Tweemaal zoveel is niet altijd beter!
Op het moment dat Elementor dynamische informatie ophaalt uit de WordPress database worden alle WordPress ‘hooks’ (die namens WordPress of plugins de opgeslagen content aanpassen) uitgevoerd. En dat is goed. Na het ophalen van die informatie voert Elementor ook nog een keer de do_shortcode() functie uit op de al aangepaste content. En dat is in principe niet fout. In 99% van de gevallen doet Elementor hier precies wat je wilt. Met als enige uitzondering… wanneer je gebruikt gemaakt hebt van dubbele haken. Want in de eerste run worden de buitenste haken verwijderd, en wordt de shortcode getoond. Precies wat je wilde.
In de tweede run ziet Elementor niet meer, dat het oorspronkelijk dubbele haken waren, en ziet de shortcode die je wilde tonen, als een shortcode die je uit wilde voeren.
En daar gaat het fout.
Van ongemak naar noodzaak
Ik heb in de loop der jaren heel wat geblogd en ook diverse malen beschreven ‘hoe shortcodes werken’. Toen ik in 2017 met Elementor begon begonnen al die shortcodes -wanneer ze betrekking hadden op plugins die ik ook zelf gebruikte- ineens ook echt te werken. Dat was nooit de bedoeling geweest.
Maar ik gebruikte de ‘spatie truc’ en dat heeft altijd goed voor mij gewerkt.
Tot ik begon met de WXP Plugins website. Voor de documentatie moest ik ineens een enorme hoeveelheid shortcodes documenteren. En iedere keer vertellen, dat die spatie verwijderd moet worden… het is niet alleen een hoop overbodig getik, maar ook een vervuilding van de documentatie zelf.
Dus ik besloot mijzelf eens goed boos te maken en een oplossing te vinden voor mijn probleem.
Als het ook een oplossing voor jouw probleem is, is het mooi meegenomen.
Wat doe ik?
Wat ik in principe doe, is het mechanisme van het interpreteren van shortcodes voor de gek houden. Maar op een manier die mij past, niet op een manier die universeel toepasbaar is.
Wanneer ik shortcodes gebruik, staan ze altijd tussen
<pre>...</pre>
of
<code>...</code>
tags.
Een alternatieve manier om een linker blokhaak te schrijven is
[
Helaas, dat weet Elementor ook, dus Elementor accepteert ook deze code als een linker blokhaak.
De volgende stap houdt Elementor echter compleet voor de gek.
Commentaar in HTML
Wanneer je aanwijzingen voor de designer of jezelf in HTML achter wilt laten, dan is het mogelijk om commentaar toe te voegen. Commentaar ziet er zo uit :
<!-- Dit is commentaar -->
Alles wat er tussen de het kleiner-dan en het groter-dan teken staat blijft onzichtbaar op de website.
En wanneer ik een kleiner-dan teken en een leeg commentaar als volgt plaats:
[<!---->
dan wordt dit niet als een shortcode herkend mits dit tussen de eerder genoemde tags staat:
<pre>[<!---->]</pre>
of
<code>[<!---->]</code>
Ok, zal je zeggen. Maar dit ga ik echt niet onthouden. En dat hoeft ook niet.
Laten we eens kijken naar het volgende code snippet:
De oplossing
function wxp_elementor_shortcode_escape( $content ) {
if ( ! is_string( $content ) || false === strpos( $content, '[' ) ) {
return $content;
}
return preg_replace_callback(
'#<(code|pre)\b[^>]*>.*?</\1>#is',
static function ( $match ) {
return str_replace( '[', '[<!---->', $match[0] );
},
$content
);
}
add_filter( 'the_content', 'wxp_elementor_shortcode_escape', 12 );
De werkelijke magie zit in regel 14.
WordPress ‘runt’ verschillende filters op ’the_content’. En het filter wat de shortcodes behandelt heeft prioriteit 11. Direct daarna vervangt de code de vierkante haken door de
[<!---->
code. En daardoor zal Elementor de shortcode niet meer als shortcode herkennen en gewoon de tekst uitvoeren.
Dat is leuk Wilko, maar verknuppel ik niet al mijn shortcodes op deze manier?
Nee. De code zal alleen shortcodes met dubbele haken aan beide kanten, die bovendien tussen ‘pre’ of ‘code’ tags moeten staan onderhanden nemen. Mist er ƩƩn van de twee, dan gebeurt er niets.
Bekende problemen met deze oplossing
- Natuurlijk, om een bug heen werken is nooit de ideale manier, maar aangezien deze bug in Elementor al bijna 10 jaar genegeerd wordt, verwacht ik dat dit nog enige jaren kan duren voor het wordt opgelost. En bovendien, als het wordt opgelost zal de code waarschijnlijk nog steeds werken, hoewel er niets meer te corrigeren valt.
- In principe werkt deze methode ook voor andere pagebuilders die op eenzelfde manier als Elementor ‘de fout in gaan’. Het kan echter, dat je voor deze andere pagebuilders de code enigszins aan zou moeten passen. Ik bied hier geen ondersteuning voor (niet gratis, en niet betaald. De tijd die het mij gekost heeft om dit voor Elementor op te lossen is het jou -omgezet in uren- waarschijnlijk niet waard om het voor jouw pagebuilder op te lossen.
- Wanneer je ‘code voorbeelden’ op je site toont, dan maak je waarschijnlijk ook gebruik van een ‘code highlighter’ plugin, een plugin die de code netjes in kleuren toont, naargelang de betekenis van de code. Ik kan niet garanderen, dat code ‘behandeld’ door mijn codefragment in iedere code highlighter plugin juist zal tonen.
De plugin
Eigenlijk is het een slecht idee om plugins te schrijven voor slechts enkele regels code. De overhead die de plugin heeft, is bijna net zo groot als de tijd die de plugin nodig heeft om het werk te doen. Maar toch heb ik hier ook een kleine plugin voor gemaakt. Doodgewoon omdat veel mensen zich wat ‘ongemakkelijk’ voelen, wanneer ze zelf code ergens moeten plaatsen.
Voor je besluit de plugin te downloaden, verzoek ik je toch eerst even deze twee blogartikelen te lezen:
Wanneer je na het lezen van deze artikelen nog steeds voelt ‘Nee, dit doe ik niet zelf’, dan is er ook een kleine plugin die dezelfde code implementeert. Daarnaast -vooral handig voor degenen die willen weten of de plugin ook voor de pagebuilder die zij gebruiken werkt- is de plugin ook handig, omdat er een ’testfunctie’ in zit.
Wanneer je een andere pagebuilder gebruikt en de ‘geescapete’ shortcode
[[wxp_esc_test]]
gebruikt, kunnen er twee resultaten zijn
[wxp_esc_test]
wat wil zeggen, dat de code ook voor jouw pagebuilder werkt.
Of
The test failed
wat eigenlijk geen toelichting nodig heeft.
Download het bestand
Voorlopig is het bestand hier te downloaden
Een nawoord
Een aantal trainingen, die je mogelijk interessant kan vinden
Wanneer je dit blogbericht leest en helemaal bij het einde bent gekomen, ga ik ervan uit, dat je of geïnteresseerd bent in het werken met Elementor, of het bouwen van plugins. Als één van beide zaken het geval is, wijs ik je graag op een tweetal cursussen van WordXPression
- Elementor 4 voor Designers: van losse widgets naar schaalbare componenten
- Cursus WordPress Developer



Recente reacties