Zowel WordPress core, WordPress plugins als WordPress thema’s bieden de developer veel mogelijkheden om zaken naar je eigen hand te zetten door gebruik van:

  • actions;
  • filters;
  • pluggable functions.

In dit artikel gaan we het hebben over pluggable functions. Als er geen action of filter aanwezig is, dan heb je misschien nog het geluk dat er sprake is van een ‘pluggable function’. Pluggable functions zijn te vinden in WordPress core, WordPress plugins en WordPress thema’s. Door het kopiëren van een pluggable function in je eigen plugin of in een functions.php bestand van je child theme kun je deze functie wijzigen.

Pluggable functions

Stel dat dit de orginele functie is:

if ( ! function_exists( 'hello_world' ) ) :
/**
 * Example pluggable function.
 */
function hello_world() {
	echo 'hello world';
}
endif; // hello_world

De echo zorgt ervoor dat er ‘hello world’ op je beeldscherm komt te staan. De if zorgt ervoor dat de hello_world functie overschreven kan worden door onze eigen hello_world functie. De php code if ( ! function_exists( 'hello_world' ) ) : betekent simpelweg: “Als de hello_world functie nog niet bestaat, voer dan deze originele hello_world functie uit”.

Wij hoeven er dus alleen maar voor te zorgen dat wij in onze eigen plugin of functions.php van ons child theme onze gewijzigde functie hebben staan met dezelfde naam, zoals in onderstaande voorbeeld.

if ( ! function_exists( 'hello_world' ) ) :
/**
 * Example pluggable function (overridden).
 */
function hello_world() {
	echo 'hello world, nice to meet you!';
}
endif; // hello_world

WordPress zit zo in elkaar, dat ze als eerste onze eigen functie tegenkomen als een website geladen wordt. Tegen de tijd dat ze bij de originele code komen wordt dus de check gedaan of er al een hello_world functie bestaat. Dat is nu het geval en daarom wordt de originele functie niet gebruikt. Er zal nu dus ‘hello world, nice to meet you!’ zichtbaar zijn op het beeldscherm. Meer over deze volgorde is te vinden in het WordPress Codex artikel Action Reference. Nu gaan we nog iets verder de diepte in!

Pluggable functions in WordPress core

Pluggable functions in WordPress core kun je vinden in het pluggable.php bestand. Meer informatie vind je in de WordPress Codex, artikel Pluggable Functions.

Belangrijk om op te merken in dit artikel zijn:

  • dat pluggable functions alleen overschreven kunnen worden door een plugin;
  • dat er geen nieuwe pluggable functions meer toegevoegd worden.

Dat pluggable functions van WordPress core alleen overschreven kunnen worden met een plugin, en dus niet met het functions.php bestand van je child theme, is omdat WordPress het functions.php pas leest nadat de oorspronkelijke pluggable functions uit pluggable.php al geladen zijn.

Het artikel Understanding WordPress Pluggable Functions and Their Usage legt dit erg goed uit. Ik quote de conclusie uit dat artikel:

You can find the complete execution procedure under Action Reference in the WordPress Codex. I’ll extract the necessary actions for my explanations in the screen below.
wordpress action execution order

WordPress action execution order

The above image shows the general WordPress action execution process. […]

You should clearly see that “must use” plugins are loaded first, followed by active plugins and pluggable functions. Finally the theme is loaded. So according to the process we can make the following conclusions on creating pluggable functions.

  • All the custom pluggable functions should be placed inside plugins since plugins are loaded first.
  • If plugins do not contain pluggable functions, the default core function will be used.
  • You shouldn’t be overriding core pluggable functions in your theme files since themes are loaded after pluggable functions. Hence the default function will be used.

Wanneer je pluggable functions gaat overschrijven in je plugin, moet je je gewijzigde functie ook vooraf laten gaan door hetzelfde if statement. Dit klinkt misschien onlogisch, maar lees dan eens het antwoord op deze vraag: Override pluggable functions in a plugin?. Is dat ook meteen duidelijk!

Tot slot was opvallend dat WordPress dus gestopt is met het toevoegen van pluggable functions. In plaats daarvan gebruiken ze actions en filters. In het artikel waarvan ik hierboven al een quote heb gebruikt wordt namelijk ook het gevaar uitgelegd van pluggable functions:

Next question will be what happens when two or more plugins override the same core function. It’s beyond your control since the first activated plugin will get the preference over others. So if another plugin is activated before your plugin, your pluggable function will not be used.

You can view the active plugin order using the value of the active_plugins key in the WordPress options table.

Ik weet zeker dat de schrijver van het artikel Pluggable Functions Suck erg blij is dat WordPress core geen nieuwe pluggable functions meer gaat toevoegen. Zelf heb ik me er nog niet aan gewaagd pluggable functions van WordPress te wijzigen, dus geen voorbeelden uit de praktijk.

Pluggable functions in WordPress plugins

Net als WordPress core maken plugins ook gebruik van hun eigen pluggable functions. Plugin developers zorgen er schijnbaar voor dat hun pluggable functions pas zo laat geladen worden, dat je ze kunt overschrijven via een eigen plugin maar ook via het functions.php bestand van je child theme, waar dit laatste niet mogelijk was bij WordPress core pluggable functions.

In het artikel How to give your plugin pluggable functions wordt dit goed uitgelegd:

Pluggable functions are functions that can be overridden by others. The key is which is defined first. So to make one your plugin’s functions pluggable one should define it as late as possible. So others can get in first of course, but not so late that your plugin tries to use it before it is defined.

Een voorbeeld uit de praktijk. In WooCommerce vind je bijvoorbeeld in het bestand wc-template-functions.php diverse pluggable functions.

Ik overschrijf dit met een simple plugin voor WordPress. De plugin bestaat uit één PHP bestand die ik upload naar de plugin folder van WordPress. Zie hieronder de code. Hier zet ik alle wijzigingen in die ik doorvoer voor de plugin WooCommerce, ook actions en filters. Omdat dit artikel gaat over pluggable functions heb ik er daar twee van in de code laten staan.

<?php
/*
Plugin Name: WS Internet Services: WooCommerce functions
Description: Changing functionality of WooCommerce plugin.
Author: Willem-Siebe Spoelstra
Author URI: http://wsinternetservices.nl
*/

// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) exit;

/***************************/
/*** Pluggable functions ***/
/***************************/

// Change the UL for WooCommerce product loop start and end if your are not using a list, but for example Twitter Bootstrap. See https://gist.github.com/Willem-Siebe/2f2f64012b9cfe36df1a.
if ( ! function_exists( 'woocommerce_product_loop_start' ) ) {
	/**
	 * Output the start of a product loop. By default this is a UL
	 *
	 * @param bool $echo
	 * @return string
	 */
	function woocommerce_product_loop_start() { 
		echo '<div id="wsis-wc-product-loop">'; 
	}
}

if ( ! function_exists( 'woocommerce_product_loop_end' ) ) {
	/**
	 * Output the end of a product loop. By default this is a UL
	 *
	 * @param bool $echo
	 * @return string
	 */
	function woocommerce_product_loop_end() { 
		echo '</div>'; 
	}
}

/***************/
/*** Filters ***/
/***************/

/***************/
/*** Actions ***/
/***************/

Voorheen deed ik alle wijzigingen zoals bovenstaande altijd in het functions.php bestand van mijn child theme plakken. Maar dat is naar mijn huidige inzichten helemaal niet handig! Als ik van thema verander, werken namelijk ook al mijn functies voor WooCommerce niet meer. Nu wel, omdat het gewoon een plugin is. Wil ik deze WooCommerce aanpassingen tijdelijk uitschakelen om te debuggen. Kan nu ook, door simpelweg mijn plugin te deactiveren. Dat dit de juiste werkwijze is kun je vinden in het WordPress Theme Handbook, What is the difference between a theme and a plugin.

Pluggable functions in WordPress thema’s

Heb je een leuk thema gevonden voor je WordPress website dan wil je ook dit thema wel eens wat verder naar je wensen aanpassen. Dit doe je altijd via een child theme, zodat bij een update van het parent theme je wijzigingen niet overschreven worden!

In je child theme kun je in je eigen functions.php bestand weer wijzigingen aanbrengen. Deze theme developer legt het in zijn docs heel goed uit Editing Theme Functions – Pluggable Functions. Hier zegt hij ook:

Since WordPress loads the Child theme’s functions.php before the Parent theme, this allows you to declare your function first, before the parent theme gets to them.

Hier kun je de if check wél weglaten! Meer valt er niet over te zeggen.

Heb je vragen, stel ze gerust!

One comment on “Pluggable functions in WordPress core, plugins en thema’s

Geef een reactie

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