Display an ACF field values in WooCommerce product archive loop - php

i'm currently playing around on localhost since i'm going to design an ecommerce for a client who owns a records store. I've installed Elementor, WooCommerce and ACF, and at first tried to use elementor custom skin to create a custom loop for my products, where i easily added the field i wanted with dynamic data.
However, this turned out to be a nightmare since being a post archive i lost the sorting etc and also for some reason the add to cart button behaved weirdly (it took me to the single product page after clicking it).
So i've ditched that custom posts archive and used the classic product archive instead, which doesn't allow me to add anything to the product loop directly.
I tried adding this code in my functions.php file (my custom field is named vinyl_genre and it's part of a custom field group):
add_action( 'woocommerce_after_shop_loop_item_title', 'custom_field_display_below_title', 2 );
function custom_field_display_below_title(){
global $product;
// Display ACF text
if( $text = get_field( 'vinyl_genre', $product->get_id() ) ) {
echo '<p class="archive-genre">' . $text . '</p>';
}
}
But it didnt work, instead below each product title in the archive i get this warning:
Warning: : Array to string conversion in [...] \wp-content\themes\hello-theme-child-master\functions.php on line 36 Array
I'm an absolute n00b at php, but i found the above example here on stack and just changed the field name, but to no avail.
Any advice?
-- EDIT --
Using print_r($text) gives an array of values (because vinyl can have multiple genres)

That means that your custom field value is an array with multiple values.
Instead use the following:
add_action( 'woocommerce_after_shop_loop_item_title', 'custom_field_display_below_title', 2 );
function custom_field_display_below_title(){
global $product;
$values = (array) get_field( 'vinyl_genre', $product->get_id() ); // Get custom field values
// Display custom field values
if( ! empty($values) ) {
echo '<p class="archive-genre">' . implode( ', ', $values ) . '</p>';
}
}
Code goes in functions.php file of the active child theme (or active theme). It should work.

Related

Wordpress Filtering Woocommerce Structured Data

I'm figuring out a filter but can't be figured :)
Just want to change PrimaryImageOfPage value with an og:image value in CollectionPage for Taxonomies.
It may be that I have to use woocommerce_structured_data_product to filter here and look for the image $markup['image'] = $image;
I have created some filters, but it isn't woocommerce_structured_data_product I guess.
One of them was like that but it... nah.
add_filter( 'woocommerce_structured_data_product', function( $markup ) {
$markup['image'] = ('rank_math/opengraph/{$network}/image');
return $markup;
});
What am I doing wrong? I have been doing this whole day -_-
If You inspect the code of the class WC_Structured_Data, You would see that woocommerce_structured_data_product filter is executed inside function generate_product_data
WC Complete Source of the class WC_Structured_Data : https://github.com/woocommerce/woocommerce/blob/b88b868ab8919b7c854173098b7d6d4ab227f9ee/includes/class-wc-structured-data.php
$this->set_data( apply_filters( 'woocommerce_structured_data_product', $markup, $product ) );
And generate_product_data function is executed on action woocommerce_single_product_summary
add_action( 'woocommerce_single_product_summary', array( $this, 'generate_product_data' ), 60 );
So, your code would work on product single page only and not archive/list pages, such as the taxonomy page.
The feature you want to achieve is not feasible out of the box in WC, You will need to customize yourself.
Logically, structured data on a single product page is feasible due to the fact there is only one product and product information is available, on the other hand, product list has more than one product (you might need to consider like you want to show details of first product) so it is ambiguous and not feasible out of the box for WC.

Add a red asterisk at the end of all attributes labels in Woocommerce variable products

How do I add a red asterisk to the end of all attributes labels in Woocommerce? It seems like it should be simple, but I'm having a hard time with figuring it out. Wouldn't it be in the functions.php file?
The required attributes are actually working because the Add to Cart button is grayed out until an option is selected. However, apparently my customers don't realize this because they are telling me my Add to Cart button doesn't work. So, if I could draw their attention to the variations dropdown menu maybe they would realize that an option must be chosen before they can add the item to their cart.
To add a red asterisk at then end of product attribute labels on single variable products, just like in required checkout fields, you can use the following very simple hooked function:
add_filter( 'woocommerce_attribute_label', 'filter_single_variable_product_attribute_label', 10, 3 );
function filter_single_variable_product_attribute_label( $label, $name, $product ) {
if ( is_product() ){
$label .= ' <abbr class="required" title="required" style="color:#FF3333;">*</abbr>';
}
return $label;
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.

Hide Button only on External/Affiliate Product Page / NOT in shop

I would like to hide all buttons only for Eternal/Affiliate and only on the produce page
TLDR
On my site I have a few Pricing tables where the customer can select the appropriate one and then add that item to the cart.
The issue is trying to make an empty product where you cannot purchase it but the pricing table is in the description. So I had to user Eternal/Affiliate product. Which works perfectly as the URL is the product page itself which is great for the shop.
The issue is on the product page you can see a button which says add to cart.
I would like to hide this button only for Eternal/Affiliate and only on the produce page.
You see I already have this code below but obviously I do not want to restrict it to ID numbers and variable products.
Update
so the code below works but if I put a URL link in on the product page then it does not work. Unfortunately now a little bit stumped.
What would be great is if I could remove the button and replace it with some text for example please read below.
function woocommerce_add_aff_link(){
$product = wc_get_product(get_the_ID());
if ($product->is_type('external'))
echo '<a href="' .
$product->get_product_url() .
'" class="woocommerce-LoopProductImage-link">';
}
Update +
After some digging around I found that it is actually more logical to create a new product however the solution below works perfectly:
Reference : https://www.businessbloomer.com/woocommerce-how-to-create-a-new-product-type/
To remove add to cart button on single external product pages use the following:
add_action( 'woocommerce_single_product_summary', 'remove_external_product_add_to_cart_button', 4 );
function remove_external_product_add_to_cart_button(){
global $product;
if ( ! is_a($product, 'WC_Product') ) {
$product = wc_get_product(get_the_ID());
}
if ( $product->is_type('external') ) {
remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30 );
}
}
Code goes in functions.php file of the active child theme (or active theme). TIt should work.

Remove WooCommerce product tabs for specific products with Avada

Using WooCommerce 3.6.5 within the Avada theme.
We have one product with variations. The products with variation use WooCommerce Tabs in the presentation to give more information about the product. I need to retain this.
[I do not see WooCommerce Tabs as an option within my Wordpress/WooCommerce admin panel that I see on so many videos detailing how to change or use Tabs, or any plugin that looks like they manage this, so I am at a loss to how the tabs are being handled.]
I have a new simple product added to the site, but the simple product also gets the tabs prepopulated with information that is not relevant to the simple product, from the product with variations.
I have identified the Tabs as belonging to WooCommerce through using Firebug to reveal information on the Divs within the webpage.
I need to prevent the tabs being displayed on the one simple product and/or change the tabs presentation order, or number. Would be happy to limit this within PHP code.
Have found this page with what looks like useful information to limit the presentation of tabs -
https://docs.woocommerce.com/document/editing-product-data-tabs/
Section of code -
/**
* Remove product data tabs
*/
add_filter( 'woocommerce_product_tabs', 'woo_remove_product_tabs', 98 );
function woo_remove_product_tabs( $tabs ) {
unset( $tabs['description'] ); // Remove the description tab
unset( $tabs['reviews'] ); // Remove the reviews tab
unset( $tabs['additional_information'] ); // Remove the additional information tab
return $tabs;
}
What bothers me is the implementation of this code.
What is the "98" element after 'woo_remove_product_tabs', ? and how can I limit this bit of code to only operate with the one simple product I have, rather than all the products and variations, or other simple products I may add in the future ?
Would appreciate some guidance.
First if you look to add_filter() function documentation, you will see that the third argument is related to the hook priority (in your case 98)…
To target simple products only you will use the WC_Product is_type() method and you will define your desired product Ids in the code below:
add_filter( 'woocommerce_product_tabs', 'removing_product_tabs', 98 );
function removing_product_tabs( $tabs ) {
// Get the global product object
global $product;
// HERE define your specific product Ids
$targeted_ids = array( 37, 56, 63 );
if( $product->is_type( 'simple' ) && in_array( $product->get_id(), $targeted_ids ) ) {
unset( $tabs['description'] ); // Remove the description tab
unset( $tabs['reviews'] ); // Remove the reviews tab
unset( $tabs['additional_information'] ); // Remove the additional information tab
}
return $tabs;
}
Code goes in functions.php file of your active child theme (active active theme). It should work.

Hide variable product dropdown that has a unique variation selected by default in Woocommerce

I have a unique issue. I am using a plugin where they are not able to support the request. I need to split out variations into separate items, but if I copy and paste and turn them into a simple product, then I can't sync the count for the product to track inventory stock. As a workaround I needed to be able to disable the variations I do not need, keeping only the one that I do need. But here is where I am having trouble. If I have one variation enabled, then I do not want to show the dropdown, and instead want it to look like a simple product on the UI. I tried everything and cannot get it to work.
I even tried using
add_filter( 'woocommerce_hide_invisible_variations', '__return_true', 10, 3 );
with no success as they are visible and not hidden even though the counts are 0, the price is 0, and the item is disabled.
How can I show the product page with no drop-down? Take it one step further; I delete all variations except the one that I need to keep. I need to keep it in variations mode due to the plugin that syncs. How do I display it without any dropdowns showing?
Example logic:
If product type is a variation and enabled count == 1 then special ui display, else normal.
Thanks.
IMPORTANT: The code only works when the unique variation is selected as default form value:
The following code will hide from variable products that have only one variation enabled and selected by default, the attribute dropdown and the selected variation price:
add_action( 'woocommerce_before_add_to_cart_form', 'single_unique_variation_ui', 10 );
function single_unique_variation_ui(){
global $product;
if( ! $product->is_type('variable') )
return; // Only variable products
$available_variations = $product->get_available_variations(); // Get available variations
$default_attributes = $product->get_default_attributes(); // Get default attributes
// Only for a unique selected variation by default
if( ! ( sizeof($available_variations) == 1 && sizeof($default_attributes) == 1 ) )
return;
// Get the unique variation
$variation = reset($available_variations);
// Loop through
if( reset($variation['attributes']) == reset($default_attributes) ) :
// Styles
?>
<style>
div.woocommerce-variation-price, table.variations { display:none; }
</style>
<?php
endif;
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
Without the code (the normal woocommerce behavior):
With the code (that hide the attribute dropdown and the price):
It will give you the same UI than simple products

Categories