Hoe zorg je ervoor dat bepaalde producten of variaties van variabele producten niet gekocht kunnen worden door klanten met een bepaalde gebruikersrol. Dat is de vraag die ik voorgelegd kreeg. De eerste gedachte is dat je dan de ‘In winkelwagen’ buttons verwijderd, en daar gaat dit artikel over. Het laat goed zien hoe ik stap voor stap de bestanden van de WooCommerce plugin doorloop om de buttons te lokaliseren en te bepalen hoe ik ze kan verwijderen uit de layout.
Opmerking: in deze casus heb ik uiteindelijk gebruik gemaakt van de woocommerce_variation_is_purchasable filter en woocommerce_is_purchasable filter. Sowieso kon je voor versie 2.4 van WooCommerce voor variable products de winkelwagen button op de productpagina alleen maar verwijderen door gebruik te maken van het eerstgenoemde filter (dit is nu anders, lees daarvoor de rest van het artikel!). De echte reden om van deze filters gebruik te maken is dat hiermee het product echt niet meer aangeschaft kan worden! Als je de buttons verwijderd zoals omschreven in dit artikel kunnen slimmeriken alsnog het product in het winkelmandje krijgen. En dat is nou juist wat ik beslist wil voorkomen.
In winkelwagen buttons WooCommerce archiefpagina verwijderen
Eén van de plekken waar je de ‘In winkelwagen’ buttons tegenkomt is op de archiefpagina’s. Dit zijn alle pagina’s met een overzicht van meerdere producten. Een voorbeeld van een archiefpagina met twee producten zie je hieronder.
Zoals je ziet is hier een sprake van een ‘Simpel product’ die je direct in je winkelwandje kunt stoppen, en een ‘Variabel product’ waar de bezoeker eerst een variatie moet kiezen op de productpagina. Zodoende dat je daar ziet staan ‘Opties selecteren’, hoewel dit in feite wel deze button is.
Het templatebestand van de archiefpagina’s is woocommerce/templates/archive-product.php
, en de code voor elk afzonderlijk product dat op de archiefpagina getoont wordt kun je vinden in the loop. Dat is dit stukje code:
Hier zie je de regel wc_get_template_part( 'content', 'product' )
dat betekend dat elk product op deze archiefpagina een eigen template bestand heeft, namelijk content-product.php
, te vinden via woocommerce/templates/content-product.php
. Handig is ook dat WooCommerce bij elk template bestand bovenin een uitleg geeft, en hier staat ook netjes The template for displaying product content within loops
. In dit stukje code zie je dat de function woocommerce_template_loop_add_to_cart
gehooked is aan de do_action( 'woocommerce_after_shop_loop_item' );
. Op die locatie in het template bestand wordt dus de function uitgevoerd. Aan de function naam kun je uiteraard herleiden dat dit gaat over de ‘add to cart’ button.
Vervolgens kun je woocommerce_template_loop_add_to_cart
in de zoekbalk van Github plaatsen. Je komt dan onder andere het bestand woocommerce/includes/wc-template-hooks.php
tegen. Hier vind je de code die de function laat uitvoeren op de eerder besproken locatie do_action( 'woocommerce_after_shop_loop_item' );
, zie dit stukje code:
add_action( 'woocommerce_after_shop_loop_item', 'woocommerce_template_loop_add_to_cart', 10 );
Er is ook nog een bestand woocommerce/includes/wc-template-functions.php
waar de function zelf staat, zie dit stukje code:
if ( ! function_exists( 'woocommerce_template_loop_add_to_cart' ) ) {
/**
* Get the add to cart template for the loop.
*
* @subpackage Loop
*/
function woocommerce_template_loop_add_to_cart( $args = array() ) {
wc_get_template( 'loop/add-to-cart.php' , $args );
}
}
Daar zie je dat de button code te vinden is een het template bestand, wc_get_template( 'loop/add-to-cart.php' , $args );
, te weten woocommerce/templates/loop/add-to-cart.php
.
Zoals je hierboven hebt gelezen wordt deze function uitgevoerd door de add_action
, dit moeten we dus ongedaan maken en dat kan met remove_action
. De oplossing ziet er dan als volgt uit:
function remove_add_to_cart() {
remove_action( 'woocommerce_after_shop_loop_item', 'woocommerce_template_loop_add_to_cart', 10 );
}
add_action('init','remove_add_to_cart');
In winkelwagen buttons WooCommerce productpagina verwijderen
Zoals je hierboven al kon zien bestaan er ‘simpele producten’ en ‘variabele producten’ in WooCommerce. Het verwijderen van de In winkelwagen buttons van variabele producten is sinds de recente update naar WooCommerce 2.4 een stuk makkelijker geworden! WooCommerce heeft overigens ook nog ‘grouped products’ en ‘external products’, al die buttons kunnen gewoon verwijderd worden.
Naast informatie als de prijs, de voorraadstatus en onderaan het SKU nummer zie je op een productpagina ook de In winkelwagen button samen met een inputveld voor het aantal dat de klant wil bestellen. Hieronder een voorbeeld van een variatie van een variabel product:
Onze zoektocht start nu met de template voor de productpagina. Daarvoor is er de template woocommerce/templates/single-product.php
. Hier staat ook weer netjes in The Template for displaying all single products
. In the loop vinden we nu dit stukje code:
In het templatebestand woocommerce/templates/content-single-product.php
vinden we vervolgens dit stukje code:
Hier zie je dat er een hele hoop functions uitgevoerd worden op de locatie do_action( 'woocommerce_single_product_summary' );
, waaronder de function woocommerce_template_single_add_to_cart
. Aan de function naam met ‘add_to_cart’ erin kun je uiteraard weer snappen dat dit de functie is die we verder moeten bestuderen.
Als je dat zoekt in Github van WooCommerce kom je weer het bestand woocommerce/includes/wc-template-hooks.php
tegen waar je dit stukje code ziet:
add_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30 );
Deze function wordt dus uitgevoerd op de eerder besproken do_action( 'woocommerce_single_product_summary' );
. Om te kijken wat deze function doet, zoeken we die weer op in het bestand woocommerce/includes/wc-template-functions.php
, dit stukje code:
if ( ! function_exists( 'woocommerce_template_single_add_to_cart' ) ) {
/**
* Trigger the single product add to cart action.
*
* @subpackage Product
*/
function woocommerce_template_single_add_to_cart() {
global $product;
do_action( 'woocommerce_' . $product->product_type . '_add_to_cart' );
}
}
Dit is een interessante functie, want deze function voegt een do_action
toe aan de locatie do_action( 'woocommerce_single_product_summary' );
. Deze do_action
is afhankelijk van het producttype (simpel, variabel, grouped, external) dat bekeken wordt, daar zorgt het stukje . $product->product_type .
voor.
Bekijk je een simple product dan wordt do_action( 'woocommerce_' . $product->product_type . '_add_to_cart' );
dus omgezet naar do_action( 'woocommerce_simple_add_to_cart' );
. Zo krijg je afhankelijk van welk type product je bekijkt vier nieuwe do_actions, en dat op die locaties ook daadwerkelijk weer een function uitgevoerd wordt kun je weer zien in woocommerce/includes/wc-template-hooks.php
, namelijk dit stukje code:
add_action( 'woocommerce_simple_add_to_cart', 'woocommerce_simple_add_to_cart', 30 );
add_action( 'woocommerce_grouped_add_to_cart', 'woocommerce_grouped_add_to_cart', 30 );
add_action( 'woocommerce_variable_add_to_cart', 'woocommerce_variable_add_to_cart', 30 );
add_action( 'woocommerce_external_add_to_cart', 'woocommerce_external_add_to_cart', 30 );
Zoals je ziet hebben de function namen hier dezelfde naam gekregen als de do_action
. Al deze functies kun je weer opzoeken in woocommerce/includes/wc-template-functions.php
en die functies laden (eindelijk) het juiste template bestand, hier het stukje code inzake een simpel product:
if ( ! function_exists( 'woocommerce_simple_add_to_cart' ) ) {
/**
* Output the simple product add to cart area.
*
* @subpackage Product
*/
function woocommerce_simple_add_to_cart() {
wc_get_template( 'single-product/add-to-cart/simple.php' );
}
}
Zo zie je dat de andere functions voor de andere producttypes een ander bestand dan simple.php
laden, je vindt in de woocommerce/templates/single-product/add-to-cart/
folder dan ook voor elk producttype een eigen bestand:
- external.php
- grouped.php
- simple.php
- variable.php
In de function voor variable products wordt ook nog een stukje javascript geladen, dat laat ik nu even buiten beschouwing. Mocht je bovenstaande hebben kunnen volgen, dan weet je inmiddels dat je kunt voorkomen dat die php bestanden geladen worden door de volgende code:
function remove_add_to_cart(){
remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30 );
}
add_action('init','remove_add_to_cart');
Mocht je de draad even kwijt zijn, doordat simple.php niet meer geladen wordt verwijder je dit gedeelte van de productpagina van een simple product:
Er is een kleine maar aan deze methode, als je namelijk de productpagina van een variable product bekijkt, is er misschien wel meer verdwenen dan je lief is. Dit is omdat in variable.php
ook de code staat voor de dropdowns, ofwel het selecteren van variaties, en verdwijnt dus dit gedeelte in zijn geheel:
Wat nou als je alleen de winkelwagen button met links daarvan het input veld voor het aantal producten wilt verwijderen? Sinds de recente WooCommerce 2.4 update is dit gelukkig heel makkelijk gemaakt! In woocommerce/templates/single-product/add-to-cart/variable.php
vind je namelijk dit stukje code:
/**
* woocommerce_single_variation hook. Used to output the cart button and placeholder for variation data.
* @since 2.4.0
* @hooked woocommerce_single_variation - 10 Empty div for variation data.
* @hooked woocommerce_single_variation_add_to_cart_button - 20 Qty and cart button.
*/
do_action( 'woocommerce_single_variation' );
Als je gewoon dezelfde stappen doorloopt zoals hierboven al twee keer uitgelegd, kom je tot de conclusie dat je met onderstaande code nu alleen de winkelwagen button met inputvuld ernaast kunt verwijderen voor variable products:
function remove_add_to_cart(){
// @since 2.4.0
remove_action( 'woocommerce_single_variation', 'woocommerce_single_variation_add_to_cart_button', 20 );
}
add_action('init','remove_add_to_cart');
De function woocommerce_single_variation_add_to_cart_button
fabriceert nu namelijk de code van alleen het inputveld en de winkelwagen button terwijl dit voorheen hard gecodeerd stond in variable.php
.
F.Vrijhof zegt
Goedemorgen,
Na een update van WP krijg is verschillende “opties selecteren” op mijn website. http://www.bragardnederland.com te zien. Geen idee om dat weer uniform te krijgen. Heb er al wat aardig veel zoekuurtjes in gestoken.
Misschien dat u de gouden tip heeft?
Patrick Verrijk zegt
Klinkt heel mooi, maar ik zou graag willen weten hoe ik opties selecteren verander in meer informatie of zoiets op de winkelpagina en product overzichten.. Kunt u mij helpen
Ilona zegt
Goedendag,
ik puzzel al dagen op een probleem zonder resultaat. Op mijn product pagina overzicht staat de artikelnaam direct naast de prijs waardoor de benaming onlogisch wordt afgekort zoals:
Pingp
oogba
lletje
Hoe krijg ik de benaming languit met de prijs erboven of onder?
Mijn dank is alvast groot!
Chrissy zegt
Ik ben een beginner en loop er ook tegen aan dat op de overzichtspagina met producten eronder staat in winkelwagen of opties selecteren. Ik was blij dat ik deze NL uitleg tegenkwam, maar helaas gaat het boven mijn petje. Wat moet ik nu precies waar vervangen om dit weg te krijgen? Een korte instructie: ga naar … .php en vervang op regel xx function… voor dit stukje “xxx” zou ik beter begrijpen dan de tekst hierboven met veel uitleg ertussen. Is het mogelijk om mij een ingekorte versie met alleen de opdrachten aan de hand te doen?
Willem-Siebe Spoelstra zegt
Hoi Chrissy, het is inderdaad niet een beginnersartikel ;-). Je moet in WordPress of WordPress plugins nooit iets ‘vervangen’ voor een ander stuk code, want als WordPress of de WordPress plugin een update krijgt ben je die veranderingen weer kwijt. Als je net met WordPress begint plaats je de codes die ik aandraag in dit artikel meestal in het functions.php bestand van een childtheme. Maak je gebruik van een childtheme?
Chrissy zegt
Ha Willem. Nog niet… ben er in aan het duiken om het goed voor elkaar te krijgen omdat ik ook bij het updaten van het thema al had dat er dingen verdwenen. Je hebt gelijk, moet wel in child thema werken. Ga ik eerst voor elkaar zien te krijgen en dan kom ik hier weer terug om de buttons te laten verdwijnen 🙂
Willem-Siebe Spoelstra zegt
Helemaal goed, succes!
Mitchell zegt
Geweldig dit, had ik net nodig en dan ook nog in het Nederlands.
Willem-Siebe Spoelstra zegt
Mooi dat je er wat aan gehad hebt, en bedankt voor je bericht!