This question already has answers here:
Adding multiple tabs to WooCommerce single product pages
(3 answers)
WooCommerce single product custom Tab displaying a page content
(1 answer)
Closed 4 years ago.
Using official documentation I added custom tab in woocommerce:
/**
* Add a custom product data tab
*/
add_filter( 'woocommerce_product_tabs', 'woo_new_product_tab' );
function woo_new_product_tab( $tabs ) {
// Adds the new tab
$tabs['test_tab'] = array(
'title' => __( 'New Product Tab', 'woocommerce' ),
'priority' => 50,
'callback' => 'woo_new_product_tab_content'
);
return $tabs;
}
function woo_new_product_tab_content() {
// The new tab content
echo '<h2>New Product Tab</h2>';
echo '<p>Here\'s your new product tab.</p>';
}
The problem is that if I try to add another tab using this code, then I get the error.
The code snippet you are trying to save produced a fatal error on line 17:
Cannot redeclare woo_new_product_tab() (previously declared in /var/www/html/sport-print.online/wp-content/plugins/code-snippets/php/snippet-ops.php(352) : eval()'d code:5)
Can you please tell me how to add another tab?
I understand my mistake =).
Work code:
/**
* Add a custom product data tab
*/
add_filter( 'woocommerce_product_tabs', 'woo_new_product_tab' );
function woo_new_product_tab( $tabs ) {
// Adds the new tabs
$tabs['new_tab_1'] = array(
'title' => __( 'new_tab_1', 'woocommerce' ),
'priority' => 11,
'callback' => 'new_tab_1'
);
$tabs['new_tab_2'] = array(
'title' => "new_tab_2",
'priority' => 12,
'callback' => 'new_tab_2'
);
$tabs['new_tab_3'] = array(
'title' => "new_tab_3",
'priority' => 13,
'callback' => 'new_tab_3'
);
return $tabs;
}
function new_tab_1() {
// The new tab content
echo '<ol>
<li>content new_tab_1</li>
</ol>';
}
function new_tab_2() {
echo'
<h3>content new_tab_2</h3>';
}
function new_tab_3() {
echo'<p style="font-weight: bold;">content new_tab_3</p>';
}
The problem is solved.
add_filter( 'woocommerce_product_tabs', 'woo_new_product_tab' );
function woo_new_product_tab( $tabs ) {
// Adds the new tab
$tabs['desc_tab'] = array(
'title' => __( 'Additional Information', 'woocommerce' ),
'priority' => 50,
'callback' => 'woo_new_product_tab_content'
);
}
Paste this code your active theme.
Related
I'm using the following code in my theme functions.php file to add a additional data field to the product inventory tab:
// Add Custom Field to woocommerce inventory tab for product
add_action('woocommerce_product_options_inventory_product_data', function() {
woocommerce_wp_text_input([
'id' => '_number_in_package',
'label' => __('Number of Pages', 'txtdomain'),
'type' => 'number',
]);
});
add_action('woocommerce_process_product_meta', function($post_id) {
$product = wc_get_product($post_id);
$num_package = isset($_POST['_number_in_package']) ? $_POST['_number_in_package'] : '';
$product->update_meta_data('_number_in_package', sanitize_text_field($num_package));
$product->save();
});
add_action('woocommerce_product_meta_start', function() {
global $post;
$product = wc_get_product($post->ID);
$num_package = $product->get_meta('_number_in_package');
if (!empty($num_package)) {
printf('<div class="custom-sku">%s: %s</div>', __('Number of Pages', 'txtdomain'), $num_package);
}
});
add_filter('woocommerce_product_data_tabs', function($tabs) {
$tabs['additional_info'] = [
'label' => __('Additional info', 'txtdomain'),
'target' => 'additional_product_data',
'class' => ['hide_if_external'],
'priority' => 25
];
return $tabs;
});
However, on the single product page, the custom field is added before category and ISBN. I want to place the custom field at the end after the product ISBN. Any advice?
Some comments/suggestions regarding your code attempt
To save fields you can use the woocommerce_admin_process_product_object hook, opposite the outdated woocommerce_process_product_meta hook
WooCommerce contains by default no ISBN field, but it looks like the woocommerce_product_meta_end hook will answer your question
So you get:
// Add custom field
function action_woocommerce_product_options_inventory_product_data() {
woocommerce_wp_text_input( array(
'id' => '_number_in_package',
'label' => __( 'Number of Pages', 'woocommerce' ),
'description' => __( 'This is a custom field, you can write here anything you want.', 'woocommerce' ),
'desc_tip' => 'true',
'type' => 'number'
) );
}
add_action( 'woocommerce_product_options_inventory_product_data', 'action_woocommerce_product_options_inventory_product_data' );
// Save custom field
function action_woocommerce_admin_process_product_object( $product ) {
// Isset
if ( isset( $_POST['_number_in_package'] ) ) {
// Update
$product->update_meta_data( '_number_in_package', sanitize_text_field( $_POST['_number_in_package'] ) );
}
}
add_action( 'woocommerce_admin_process_product_object', 'action_woocommerce_admin_process_product_object', 10, 1 );
// Display on single product page
function action_woocommerce_product_meta_end() {
global $product;
// Is a WC product
if ( is_a( $product, 'WC_Product' ) ) {
// Get meta
$number = $product->get_meta( '_number_in_package' );
// NOT empty
if ( ! empty ( $number ) ) {
echo '<p>' . $number . '</p>';
}
}
}
add_action( 'woocommerce_product_meta_end', 'action_woocommerce_product_meta_end', 10 );
This question already has answers here:
WooCommerce conditional custom checkout fields
(1 answer)
Conditional custom checkout fields based on product category in Woocommerce
(1 answer)
Closed 10 months ago.
I need to provide conditional required fields on 2 of 3 products in my very specific "store" . 1st product has no added fields. Second one has 1 required. 3rd has the same as the second plus one more required. I have tried plugins as I am right brained but they all cause cart failure. I have cobbled together some code from the inter web that has gotten me passed the cart failure but it presents both of the fields to all of the products (I set the second condition to optional in the code so that it would at least work on a basic level with placeholder text in the second field about requirement). In addition I need these conditional fields to be passed to to the completed order so that they show up in the order tables in admin. here is my rudimentary code.
/**
* checkout field addition License Plate.
*
* #param array $fields List of existing billing fields.
* #return array List of modified billing fields.
*/
function parking_add_checkout_fields( $fields ) {
$fields['billing_FIELD_ID'] = array(
'label' => __( 'License Plate & State' ),
'type' => 'text',
'class' => array( 'form-row-wide' ),
'priority' => 110,
'required' => true,
);
return $fields;
}
add_filter( 'woocommerce_billing_fields', 'parking_add_checkout_fields' );
function js_woocommerce_admin_billing_fields( $fields ) {
$fields['FIELD_ID'] = array(
'label' => __( 'License Plate & State' ),
'show' => true,
);
return $fields;
}
add_filter( 'woocommerce_admin_billing_fields', 'js_woocommerce_admin_billing_fields' );
/* checkout field addition Citation.
*
* #param array $fields List of existing billing fields.
* #return array List of modified billing fields.
*/
function citation_add_checkout_fields( $fields ) {
$fields['billing_FIELD2_ID'] = array(
'label' => __( 'Enter Citation #' ),
'type' => 'text',
'class' => array( 'form-row-wide' ),
'priority' => 112,
'required' => false,
'placeholder' => 'If you are purchasing a Citation Dismissal Permit, enter Citation number here',
);
return $fields;
}
add_filter( 'woocommerce_billing_fields', 'citation_add_checkout_fields' );
$fields['FIELD2_ID'] = array(
'label' => __( 'Enter Citation #' ),
'show' => true,
);
return $fields;
add_filter( 'woocommerce_admin_billing_fields', 'js_woocommerce_admin_billing_fields' );
/**
* Remove optional label
* https://elextensions.com/knowledge-base/remove-optional-text-woocommerce-checkout-fields/
*/
add_filter( 'woocommerce_form_field' , 'elex_remove_checkout_optional_text', 10, 4 );
function elex_remove_checkout_optional_text( $field, $key, $args, $value ) {
if( is_checkout() && ! is_wc_endpoint_url() ) {
$optional = ' <span class="optional">(' . esc_html__( 'optional', 'woocommerce' ) . ')</span>';
$field = str_replace( $optional, '', $field );
}
return $field;
}
I've got a custom product tab that should appear first (over the Long Description) in my tab lineup. Problem is two of the products should not be seeing this tab at all. So I did a display: none; for that custom tab in CSS for those pages, which worked, but then you see no content in what becomes the first product tab, the long description.
So realistically, that doesn't work. It's just a band aid. So can I add some kind of an if statement to this?
add_filter( 'woocommerce_product_tabs', 'woo_new_product_tab1' );
function woo_new_product_tab1( $tabs1 ) {
// Adds the new tab
$tabs1['shade_tab'] = array(
'title' => __( 'Product Tab Name', 'woocommerce' ),
'priority' => 100,
'callback' => 'woo_new_product_tab_content1'
);
return $tabs1;
}
Try the below code, change 11 and 12 to your products ID's
add_filter( 'woocommerce_product_tabs', 'woo_new_product_tab1' );
function woo_new_product_tab1( $tabs1 ) {
global $product;
// Adds the new tab
if( !$product->get_id() == 11 && !$product->get_id() == 12 ){
$tabs1['shade_tab'] = array(
'title' => __( 'Product Tab Name', 'woocommerce' ),
'priority' => 100,
'callback' => 'woo_new_product_tab_content1'
);
}
return $tabs1;
}
Here's the solution. Ahmad was close but the line should be:
if( ! in_array( $product->get_id(), array( 232, 280 ) ) ){
I'd like show images product in a new order and completed an order for customers.
I tried this code, but show big images in email, I need eg 100 x 100 px
function sww_add_wc_order_email_images( $table, $order ) {
ob_start();
$template = $plain_text ? 'emails/plain/email-order-items.php' : 'emails/email-order-items.php';
wc_get_template( $template, array(
'order' => $order,
'items' => $order->get_items(),
'show_download_links' => $show_download_links,
'show_sku' => $show_sku,
'show_purchase_note' => $show_purchase_note,
'show_image' => true,
'image_size' => array( 100, 50 ),
'image_size' => $image_size
) );
return ob_get_clean();
}
add_filter( 'woocommerce_email_order_items_table', 'sww_add_wc_order_email_images', 10, 2 );
I don't know if you already fixed this issue. I'm new here at StackOverflow and saw this question when looking for some other stuff :)
But I've just added this simple snippet to my functions.php:
/**
* Display Product Image in WooCommerce Order Emails
*
* #author James Kemp (Iconic)
*/
add_filter( 'woocommerce_email_order_items_args', 'iconic_email_order_items_args', 10, 1 );
function iconic_email_order_items_args( $args ) {
$args['show_image'] = true;
return $args;
}
I'm trying to add in grid builder a custom shortcode. The shortcode is working as expected but the printed value is empty.
add_filter( 'vc_grid_item_shortcodes', 'my_module_add_grid_shortcodes' );
function my_module_add_grid_shortcodes( $shortcodes ) {
$shortcodes['vc_custom_post_press_link'] = array(
'name' => __( 'Press link', 'domain' ),
'base' => 'vc_custom_post_press_link',
'category' => __( 'Content', 'my-text-domain' ),
'description' => __( 'Show custom post meta', 'my-text-domain' ),
'post_type' => Vc_Grid_Item_Editor::postType(),
);
return $shortcodes;
}
// output function
add_shortcode( 'vc_custom_post_press_link', 'vc_custom_post_press_link_render' );
function vc_custom_post_press_link_render($atts, $content, $tag) {
return 'test1 {{ press_link }}';
}
add_filter( 'vc_gitem_template_attribute_press_link', 'vc_gitem_template_attribute_press_link ', 10, 2 );
function vc_gitem_template_attribute_press_link( $value, $data ) {
return 'test2';
}
The expected output should be
test1 test2
but i only get
test1
The original code came from the official doc but it doesn't seem to work.
EDIT:
I just tried and the code in the documentation dont work too. I guess its not updated. I need a way to get the value of an ACF field and append some HTML around it.
Solved! The problem was in this line
add_filter( 'vc_gitem_template_attribute_press_link', 'vc_gitem_template_attribute_press_link ', 10, 2 );
that should have been
add_filter( 'vc_gitem_template_attribute_press_link', 'vc_gitem_template_attribute_press_link', 10, 2 );
Notice the missing space at the end of vc_gitem_template_attribute_press_link.