I have successfully added a custom Metabox to admin product pages. The above code generate an Input type text in the Admin-Area where I can insert the city name:
add_action( 'save_post_product', 'set_post_metas_city', 10, 3 );
function set_post_metas_city( $post_id, $post, $update ) {
if(isset($_POST['city']))
update_post_meta($post_id, 'city', esc_attr($_POST['city']));
}
add_action( 'add_meta_boxes', 'metas_boxes_city', 50 );
function metas_boxes_city(){
add_meta_box( "options-city", "City Name", 'edit_form_after_title_cidade', 'product', 'normal' );
}
function edit_form_after_title_city($post) { ?>
<div id="mdiv">
<input type="text" style="width: 100%" name="city" value="<?php echo($post ? get_post_meta($post->ID,'city',true) : ''); ?>" id="city" spellcheck="true" autocomplete="off" placeholder="<?php _e('Insert the city'); ?>">
</div>
<?php
}
Code is in the active theme's functions.php file.
Now I use the following the hooked function, trying to display on the Shop Page, the custom field value (the city name) as follows:
// define the woocommerce_after_shop_loop_item callback
function action_woocommerce_after_shop_loop_item( ) {
// make action magic happen here...
echo($post ? get_post_meta($post->ID,'city',true) : '');
};
// add the action
add_action( 'woocommerce_after_shop_loop_item', 'action_woocommerce_after_shop_loop_item', 10, 0 );
So I am trying to get something like:
[Product Picture]
**City**
Category
Cake Ananas
$4,00
[BUY BUTTON]
But it still doesn't shows nothing up.
If I use a static content inside the echo, I get the desired display on the Shop Page:
// define the woocommerce_after_shop_loop_item callback
function action_woocommerce_after_shop_loop_item( ) {
// make action magic happen here...
echo "Statictest";
};
But the correct variable is missing..
Another point is, I don't know in this case in which page to run the action.
// run the action
do_action( 'woocommerce_after_shop_loop_item' );
What am I doing wrong please? Could someone give a Help please?
The main problem was in your last function with $post->ID. Since WooCommerce 3, there is also a much better hook than save_post_product. Try the following revisited code instead:
// Add custom product meta box
add_action( 'add_meta_boxes', 'add_product_metas_box_city', 50 );
function add_product_metas_box_city(){
add_meta_box( "options-city", __("City Name"), 'product_metas_box_city_content_callback', 'product', 'normal', 'high' );
}
// custom product meta box
function product_metas_box_city_content_callback( $post ) {
$value = get_post_meta( $post->ID, 'city', true );
echo '<div id="mdiv">
<input type="text" style="width: 100%" name="city" value="'. $value .'" id="city" spellcheck="true" autocomplete="off" placeholder="'. __('Insert the city') .'">
</div>';
}
// Save city custom field value
add_action( 'woocommerce_admin_process_product_object', 'save_product_city_meta_value' );
function save_product_city_meta_value( $product ) {
if( isset($_POST['city']) ) {
$product->update_meta_data( 'city', sanitize_text_field( $_POST['city'] ) );
}
}
// Display city value on frontend products loop
add_action( 'woocommerce_after_shop_loop_item', 'action_woocommerce_after_shop_loop_item', 10, 0 );
function action_woocommerce_after_shop_loop_item() {
global $product;
$city = $product->get_meta('city');
if ( $city ) {
echo '<p class="city">'. $city .'</p>';
}
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
Related
I added a custom subtitle field for woo-commerce products. When I fill its field from the dashboard it appears in the product. I can update the text but I can't remove its value it appears again when I update the product.
Here the code. I copied from somewhere
<?php
// Display Fields
add_action('woocommerce_product_options_general_product_data',
'woocommerce_product_custom_fields');
// Save Fields
add_action('woocommerce_process_product_meta', 'woocommerce_product_custom_fields_save');
function woocommerce_product_custom_fields()
{
global $woocommerce, $post;
echo '<div class="product_custom_field">';
// Custom Product Text Field
woocommerce_wp_text_input(
array(
'id' => '_custom_product_subtitle',
'placeholder' => 'Custom Product Subtitle',
'label' => __('Custom Product Subtitle', 'woocommerce'),
'desc_tip' => 'true'
)
);
}
function woocommerce_product_custom_fields_save($post_id)
{
// Custom Product Text Field
$woocommerce_custom_product_text_field = $_POST['_custom_product_subtitle'];
if (!empty($woocommerce_custom_product_text_field))
update_post_meta($post_id, '_custom_product_subtitle',
esc_attr($woocommerce_custom_product_text_field));
}
// To show after the title
add_action( 'woocommerce_after_shop_loop_item_title', 'custom_field_display_below_title', 2 );
function custom_field_display_below_title(){
global $product;
// Get the custom field value
$custom_field = get_post_meta( $product->get_id(), '_custom_product_subtitle', true );
// Display
if( ! empty($custom_field) ){
echo '<p class="custom-product-subtitle">'.$custom_field.'</p>';
}
}
This is the result of the code, it also displays where I want to, but I can't make remove the text it appears again when I update
To be able to reset (empty) this custom field, just replace the code line (from your 2nd function):
if( ! empty($woocommerce_custom_product_text_field) ){
by:
if( isset($woocommerce_custom_product_text_field) ){
So now you can remove the field value and save it.
Now since WooCommerce 3, your code is a bit outdated… Also, you should use shorter keys and variable names.
Below is your revisited code (changed the field meta key from '_custom_product_subtitle' to simply '_subtitle', replaced a hook and made some other changes).
// Display a text Field (admin single product)
add_action( 'woocommerce_product_options_general_product_data', 'display_admin_product_custom_text_field' );
function woocommerce_product_custom_fields() {
echo '<div class="product_custom_field">';
woocommerce_wp_text_input( array(
'id' => '_subtitle',
'label' => __('Custom subtitle', 'woocommerce'),
'placeholder' => __('You can add optionally a custom subtitle', 'woocommerce'),
'desc_tip' => 'true'
) );
echo '</div>'; // <== missing
}
// Save Text Field value (admin)
add_action( 'woocommerce_admin_process_product_object', 'save_admin_product_custom_text_field_value' );
function save_admin_product_custom_text_field_value( $product ) {
if ( isset($_POST['_subtitle']) ) {
$product->update_meta_data( '_subtitle', sanitize_text_field($_POST['_subtitle']) );
}
}
// Display product subtitle (front end)
add_action( 'woocommerce_after_shop_loop_item_title', 'custom_field_display_below_title', 2 );
function custom_field_display_below_title(){
global $product;
$value = $product->get_meta('_subtitle'); // Get the custom field value
if( ! empty($value) ){
echo '<p class="product-subtitle">' . $value . '</p>'; // Display
}
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.
I'm trying to add a custom field just below the price in my Woocommerce theme. I was able to add simple html by using:
add_action( 'woocommerce_before_add_to_cart_form', 'SomeName' );
function SomeName() {
echo '<p>Some Text Here</p>';
}
But what I want to do is add a custom field key instead. I'm using this code for placing custom fields:
<?php
$naslov = get_post_meta($post->ID, 'Naslov', true);
if ($naslov) { ?>
<h2 class="single-naslov-kat"><? echo $naslov; ?></h2>
<?php
} else {
// do nothing;
}
?>
The code works great when I add it to content-single-product.php theme file. But I can't add it below the price through that file. And I have no idea how to incorporate it through functions.php.
If you have any other suggestions on how I might be able to add custom text below the price for each specific product that's ok too.
Any help would be greatly appreciated.
In your themes functions.php add the code,
//create custom field
function cfwc_create_custom_field() {
$args = array(
'id' => 'custom_field',
'label' => __( 'Custom Field', 'cfwc' ),
'class' => 'cfwc-custom-field',
'desc_tip' => true,
'description' => __( 'Enter Custom Field Description.', 'ctwc' ),
);
woocommerce_wp_text_input( $args );
}
add_action( 'woocommerce_product_options_general_product_data', 'cfwc_create_custom_field' );
// save custom field
function cfwc_save_custom_field( $post_id ) {
$link = wc_get_product( $post_id );
$title = isset( $_POST['custom_field'] ) ? $_POST['custom_field'] : '';
$link->update_meta_data( 'custom_field', sanitize_text_field( $title ) );
$link->save();
}
add_action( 'woocommerce_process_product_meta', 'cfwc_save_custom_field' );
// display custom field in single.php page
add_action('woocommerce_before_add_to_cart_form','cmk_additional_button');
function cmk_additional_button() {
global $product;
$custom_field = $product->get_meta('custom_field');
if(!empty($custom_field)) {
echo "<a href='$custom_field' target='_blank'><button type='button' class='button alt'>Custom Field</button></a>";
}
}
I want to display an additional button below the description to a specific product category: "bracelets"
so I developed a piece of code, which does not work:
add_action( 'woocommerce_single_product_summary', 'my_extra_button_on_product_page', 30 );
function my_extra_button_on_product_page() {
if ( is_product_category('bracelets')) {
global $product;
echo 'Extra Button';
}
}
Any idea about what's wrong here?
Your question is not really clear.
1) If you want to display a custom button for a specific product category on product category archives pages below the description of this product category you will use:
add_action( 'woocommerce_archive_description', 'extra_button_on_product_category_archives', 20 );
function extra_button_on_product_category_archives() {
if ( is_product_category('bracelets') ) {
echo '<a class="button" href="www.test.com">Extra Button</a>';
}
}
2) If you want to display a custom button in single product pages for a specific product category below the short description of this product you will use:
add_action( 'woocommerce_single_product_summary', 'extra_button_on_product_page', 22 );
function extra_button_on_product_page() {
global $post, $product;
if ( has_term( 'bracelets', 'product_cat' ) ) {
echo '<a class="button" href="www.test.com">Extra Button</a>';
}
}
3) If you want to display a custom button in single product pages for a specific product category below the description (in the product tab) of this product you will use:
add_filter( 'the_content', 'add_button_to_product_content', 20, 1 );
function add_button_to_product_content( $content ) {
global $post;
if ( is_product() && has_term( 'bracelets', 'product_cat' ) )
$content .= '<a class="button" href="www.test.com">Extra Button</a>';
// Returns the content.
return $content;
}
4) If you want to display a custom button in single product pages for a specific product category below the product tabs, you will use:
add_action( 'woocommerce_after_single_product_summary', 'extra_button_on_product_page', 12 );
function extra_button_on_product_page() {
global $post, $product;
if ( has_term( 'bracelets', 'product_cat' ) ) {
echo '<a class="button" href="www.test.com">Extra Button</a>';
}
}
Code goes in function.php file of your active child theme (or active theme).
Tested and works.
For product category archives pages use is_product_category().
For all other cases has_term().
add_action( 'woocommerce_after_single_product_summary', 'my_extra_button_on_product_page', 30 );
the following code adds the button before the loop on a product category archive
add_action( 'woocommerce_archive_description', 'extra_button_on_product_category_archives', 20 );
function extra_button_on_product_category_archives() {
if ( is_product_category('bracelets') ) {
echo '<a class="button" href="www.test.com">Extra Button</a>';
}
}
I want to include a link to a profile of the current user who submitted a checkout form through WooCommerce.
That is, to place automatically a current user’s author link like this in the hidden field: example.com/author/username
I want to achieve this by adding a hidden field in checkout form. So to get a link I would write something likes this:
<?php
$currentUser = get_current_user_id();
$user = get_user_by( 'id', $currentUser );
$userUrl = get_bloginfo( 'home' ) . '/author/' . $user->user_login;
echo $userUrl;
?>
My question is how can I create this type of hidden field in checkout form?
With a custom function hooked in woocommerce_after_order_notes action hook, you can also directly output a hidden field with this user "author link" as a hidden value, that will be submitted at the same time with all checkout fields when customer will place the order.
Here is that code:
add_action( 'woocommerce_after_order_notes', 'my_custom_checkout_hidden_field', 10, 1 );
function my_custom_checkout_hidden_field( $checkout ) {
// Get an instance of the current user object
$user = wp_get_current_user();
// The user link
$user_link = home_url( '/author/' . $user->user_login );
// Output the hidden link
echo '<div id="user_link_hidden_checkout_field">
<input type="hidden" class="input-hidden" name="user_link" id="user_link" value="' . $user_link . '">
</div>';
}
Then you will need to save this hidden field in the order, this way:
add_action( 'woocommerce_checkout_update_order_meta', 'save_custom_checkout_hidden_field', 10, 1 );
function save_custom_checkout_hidden_field( $order_id ) {
if ( ! empty( $_POST['user_link'] ) )
update_post_meta( $order_id, '_user_link', sanitize_text_field( $_POST['user_link'] ) );
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
The code is tested and working
Add this to your functions.php file (or a plugin file,etc.)
add_action( 'woocommerce_after_order_notes', 'hidden_author_field' );
function hidden_author_field( $checkout ) {
$currentUser = get_current_user_id();
$user = get_user_by( 'id', $currentUser );
$userUrl = get_bloginfo('home').'/author/'.$user->user_login;
woocommerce_form_field( 'hidden_author', array(
'type' => 'hidden',
'class' => array('hidden form-row-wide'),
), $userUrl);
}
This code is untested, more reading here https://docs.woocommerce.com/document/tutorial-customising-checkout-fields-using-actions-and-filters/ and here http://woocommerce.wp-a2z.org/oik_api/woocommerce_form_field/. Please let me know if this worked for you and if not what the problem is.
I am trying to have the "Add to Cart" button change to "Make an Inquiry" and I would like that to link to either a tab further down the page or to a separate page all together. I would like this change to be based on availibilty or whether or not the price is listed.I already have a basic understanding on how to change the link and text conditionally, but just not based on the parameters and to the scope I need.
I know this response is incredibly late but below is what I have. The problem I have is that it is not in the position of the the original add to cart button, and its too wide.
add_action('woocommerce_single_product_summary','replace_add_to_cart');
function replace_add_to_cart() {
global $product;
if ( ! $product->is_in_stock() ){
remove_action( 'woocommerce_single_product_summary','woocommerce_template_single_add_to_cart', 30 );
add_action( 'woocommerce_single_product_summary','consult_bezambar_expert', 30 );
function consult_bezambar_expert() {
global $product;
echo '<form action="' . esc_url($product->get_permalink( "#tab- reviews" )) . '" method="get">
<button type="submit" class="single_add_to_cart_button button alt">Consult Bez Ambar Expert</button>
</form>';
}
}
}
add_filter( 'woocommerce_product_single_add_to_cart_text', 'woo_custom_cart_button_text' );
function woo_custom_cart_button_text( $text )
{
if( has_term( 'your-special-category', 'product_cat' ) )
{
$text = __( 'Make an Inquiry', 'your-plugin' );
}
return $text;
}
Add this code in your functions.php file