Woocommerce displays the product gallery on a lightbox or new tab by default. I would like to display the product gallery on the box where the product image is displayed. I tried WooCommerce Dynamic Gallery but the LITE version doesn't allow me to display all the product gallery images on each product. Also, it displays the image on the product description.
Can anyone suggest me a wordpress plugin or coding that can display the product gallery dynamically ? Thanks a lot.
It's possible with some straightforward jquery (see below). You'll also need to override the default lightbox that WooCommerce includes for the gallery.
I believe that it's possible to disable it from the admin under WC -> Settings -> Products -> Display. But you can also remove the styles and scripts directly.
I haven't tested this code on a fresh install of WooCommerce--this is some modified code from a site with a heavily customized product gallery that includes video support.
You'll need to include this in your theme's functons.php file, etc. etc.
add_action( 'wp_enqueue_scripts', 'wc_remove_lightboxes', 99 );
/**
* Remove WooCommerce default prettyphoto lightbox
*/
function wc_remove_lightboxes() {
// Styles
wp_dequeue_style( 'woocommerce_prettyPhoto_css' );
// Scripts
wp_dequeue_script( 'prettyPhoto' );
wp_dequeue_script( 'prettyPhoto-init' );
wp_dequeue_script( 'fancybox' );
wp_dequeue_script( 'enable-lightbox' );
}
/* Customize Product Gallery */
/**
* Click on thumbnail to view image for single product page gallery. Includes
* responsive image support using 'srcset' attribute introduced in WP 4.4
* #link https://make.wordpress.org/core/2015/11/10/responsive-images-in-wordpress-4-4/
*/
add_action( 'wp_footer', 'wc_gallery_override' );
function wc_gallery_override()
{
// Only include if we're on a single product page.
if (is_product()) {
?>
<script type="text/javascript">
( function( $ ) {
// Override default behavior
$('.woocommerce-main-image').on('click', function( event ) {
event.preventDefault();
});
// Find the individual thumbnail images
var thumblink = $( '.thumbnails .zoom' );
// Add our active class to the first thumb which will already be displayed
//on page load.
thumblink.first().addClass('active');
thumblink.on( 'click', function( event ) {
// Override default behavior on click.
event.preventDefault();
// We'll generate all our attributes for the new main
// image from the thumbnail.
var thumb = $(this).find('img');
// The new main image url is formed from the thumbnail src by removing
// the dimensions appended to the file name.
var photo_fullsize = thumb.attr('src').replace('-300x300','');
// srcset attributes are associated with thumbnail img. We'll need to also change them.
var photo_srcset = thumb.attr('srcset');
// Retrieve alt attribute for use in main image.
var alt = thumb.attr('alt');
// If the selected thumb already has the .active class do nothing.
if ($(this).hasClass('active')) {
return false;
} else {
// Remove .active class from previously selected thumb.
thumblink.removeClass('active');
// Add .active class to new thumb.
$(this).addClass('active');
// Fadeout main image and replace various attributes with those defined above. Once the image is loaded we'll make it visible.
$('.woocommerce-main-image img').css( 'opacity', '0' ).attr('src', photo_fullsize).attr('srcset', photo_srcset).attr('alt', alt).load(function() {
$(this).animate({ opacity: 1 });
});
return false;
}
});
} )( jQuery );
</script>
<?php
}
}
Related
I am developing a plugin for wordpress and I want to add the button to the header of gutenberg editor just like the one added by Elementor plugin "Edit with Elementor"
Can anyone guide me what should i do to achieve this... Thanks in Advance
I've checked Guternberg source code on header toolbar and unfortunately right now there's only not a beautiful solution possible. You can have 'custom' buttons but they are only done through calling registerPlugin with PluginSidebar component which creates sidebar and button appears on right side for pinned\starred sidebars (like Yoast SEO does).
Elementor does it this way: it subscribes to wp.data store changes and whenever something happens it injects it's button if it's not yet injected. Just because React rerenders DOM it may eventually wipe button out, so subscribing to changes is important so if it wipes out custom button js code just reinjects it.
Below is simplified ES5 code to inject a custom link\button or really any custom HTML into it (just as Elementor does).
// custom-link-in-toolbar.js
// wrapped into IIFE - to leave global space clean.
( function( window, wp ){
// just to keep it cleaner - we refer to our link by id for speed of lookup on DOM.
var link_id = 'Your_Super_Custom_Link';
// prepare our custom link's html.
var link_html = '<a id="' + link_id + '" class="components-button" href="#" >Custom Link</a>';
// check if gutenberg's editor root element is present.
var editorEl = document.getElementById( 'editor' );
if( !editorEl ){ // do nothing if there's no gutenberg root element on page.
return;
}
var unsubscribe = wp.data.subscribe( function () {
setTimeout( function () {
if ( !document.getElementById( link_id ) ) {
var toolbalEl = editorEl.querySelector( '.edit-post-header__toolbar' );
if( toolbalEl instanceof HTMLElement ){
toolbalEl.insertAdjacentHTML( 'beforeend', link_html );
}
}
}, 1 )
} );
// unsubscribe is a function - it's not used right now
// but in case you'll need to stop this link from being reappeared at any point you can just call unsubscribe();
} )( window, wp )
So create a js file in your theme or plugin and then link it this way:
add_action( 'enqueue_block_editor_assets', 'custom_link_injection_to_gutenberg_toolbar' );
function custom_link_injection_to_gutenberg_toolbar(){
// Here you can also check several conditions,
// for example if you want to add this link only on CPT you can
$screen= get_current_screen();
// and then
if ( 'cpt-name' === $screen->post_type ){
wp_enqueue_script( 'custom-link-in-toolbar', get_template_directory_uri() . '/assets/js/custom-link-in-toolbar.js', array(), '1.0', true );
}
}
Again this solution isn't perfect because we just inject our custom HTML into DOM which is managed by Gutenberg(React) but at this point it seems like the only way to achieve it, may be in future we'll have something like filters or hooks which will allow us to inject our custom components being rendered in toolbar but not yet.
Still Elementor does it this way. you can check it's code at
https://github.com/elementor/elementor/blob/master/assets/dev/js/admin/gutenberg.js
Now there is a slot for the Main dashboard button you can use that one
import { registerPlugin } from '#wordpress/plugins';
import {
__experimentalFullscreenModeClose as FullscreenModeClose,
__experimentalMainDashboardButton as MainDashboardButton,
} from '#wordpress/edit-post';
import { close,image } from '#wordpress/icons';
const MainDashboardButtonIconTest = () => (
<MainDashboardButton>
<FullscreenModeClose icon={ close } href="http://wordpress.org" />
<Button variant="primary" icon={image}>
My Button
</Button>
</MainDashboardButton>
);
registerPlugin( 'main-dashboard-button-icon-test', {
render: MainDashboardButtonIconTest,
} );
ref: https://developer.wordpress.org/block-editor/reference-guides/slotfills/main-dashboard-button/
On my woocommerce e-commerce page https://www.vattenliv.se/produkt-kategori/filter/ozon-och-proteinskimmer/ there are some products that does not have any product image set. Instead the custom placeholder image shows. Is there a way to make these placeholder images link to each product page, just like the other products?
The site uses the theme OceanpWP and Elementor page builder.
Peter
I believe the best way to do this is by using a child theme, to ovewrite the woocommerce function. This code in your child theme functions.php file should work.
<?php
if (!function_exists('woocommerce_get_product_thumbnail')) {
function woocommerce_get_product_thumbnail($size = 'shop_catalog', $deprecated1 = 0, $deprecated2 = 0) {
global $post;
if (has_post_thumbnail()) {
return ''.get_the_post_thumbnail($post->ID, $size).'';
}
elseif(wc_placeholder_img_src()) {
return ''.wc_placeholder_img( $size ).'';
}
}
}
?>
I created a plugin in wordpress to add a button to the TinyMCE. I have at the moment the code below which follows very strictly the example here:
https://www.gavick.com/blog/wordpress-tinymce-custom-buttons#tc-section-1
Php file
< ? php
/*
Plugin Name: TinyMCE Custom Buttons
Plugin URI:
Description:
Version:
Author:
Author URI:
License:
License URI:
*/
//Hook the button on init, so after loading wordpress
add_action('init', 'add_button1234');
//add filters within th function which loads after loading wordpress
function add_button1234() {
// add new buttons
add_filter('mce_buttons', 'myplugin_register_buttons1234');
// Load the TinyMCE plugin
add_filter('mce_external_plugins', 'register_1234');
}
//Add the newly created button to ithe $buttons array
function register_1234($buttons) {
array_push($buttons, 'separator', 'button1234');
return $buttons;
}
//create the button
function myplugin_register_tinymce_javascript1234($plugin_array) {
$plugin_array['button1234'] = plugins_url('plugin.js', __FILE__);
return $plugin_array;
}
?>
javascript file
(function() {
tinymce.PluginManager.add('button1234', function(editor, url) {
editor.addButton('button1234', {
text: 'My test button',
icon : false,
onclick : function() {
editor.insertContent('Hello World!');
}
});
});
})();
Also when I follow exactly the code from the site (only adapting the JS url, it doesn't work.) What could I possible have done wrong?
It looks like you might not be calling the right function when adding the filter mce_buttons in the add_button1234() function.
Change this line:
add_filter( 'mce_buttons', 'myplugin_register_buttons1234' );
To:
add_filter( 'mce_buttons', 'myplugin_register_tinymce_javascript1234' );
I am new to wordpress.
I am creating a ecommerge website with wordpress 4.5(latest) + woocommerge 2.5.5(latest) + storefront theme.
I have a product with 2 variations with different prices.
When I select a variation from dropdown menu displaying variation price under dropdown.
Product detail page with 2 variations shown as below:
I want to select variantions with buttons instead dropdown, and update product price on product page instead show below of dropdown.
If I create different products for each variantion and add custom html for buttons and link each variation products with each other, this works but this is very painful.
How to make variations selection with buttons instead dropdown shown as below picture
I was made variantion selection with buttons instead select box with javascript plugin.
I created a plugin and included a js file to product page that creates buttons for each variant at product page and hide select box.
Pros:
Not changed any file of wordpress core, woocommerce and storefront theme.
myplugin.php
define('MYPLUGIN__VERSION', '1.0');
function variant_selection_with_buttons() {
if (is_product()) {
#TODO serve .min.js on production
$js_file = plugins_url('/js/variant-selection-with-buttons.js', __FILE__);
wp_register_script(
'variant_selection_with_buttons_js',
$js_file,
array('jquery'),
MYPLUGIN__VERSION,
true
);
wp_enqueue_script('variant_selection_with_buttons_js');
}
}
add_action( 'wp_enqueue_scripts', 'variant_selection_with_buttons');
js/variations-selection-with-buttons.js
;(function($, window, document, undefined){
var variations = $('.variations_form').data('product_variations'),
requiredVals = {},
selectedVariation;
$('.woocommerce-variation').remove();
$('table.variations').hide();
$(variations).each(function(i, item){
var variationSlug;
$.each(item['attributes'], function(key, value){
variationSlug = value;
return;
});
requiredVals[variationSlug] = {
'price_html': item['price_html'],
'variation_description': item['variation_description'],
};
});
var $variationChangerCon = $('<div/>', {
'id': 'variationChangerCon',
'style': 'margin-bottom:5px',
});
$variationChangerCon.append('<div class="variationBtns"/>');
$('table.variations').find('select option').each(function(index){
var $option = $(this);
if (!$option.val()) return;
if ($option.is(':selected')){
selectedVariation =$option.val();
}
var $button = $('<a/>', {
'class': 'variation-btn single_add_to_cart_button button btn-info PvariationLink',
'text': $option.text(),
'style': 'margin-right:2px;',
});
$button.attr('data-slug', $option.val());
$variationChangerCon.find('.variationBtns').append($button);
});
$variationChangerCon.append('<div class="variationDesc"/>');
$variationChangerCon.insertBefore('.entry-summary div[itemprop="description"]');
$('div.product').on('click', '.variation-btn', function(){
var $this = $(this),
item = requiredVals[$this.data('slug')];
itemDesc = requiredVals[$this.data('slug')];
$('.variation-btn').removeClass('disabled');
$this.addClass('disabled');
$('table.variations select').val($this.data('slug')).trigger('change')
$('.entry-summary div[itemprop="offers"] p.price')
.html(item['price_html'])
$variationChangerCon.find('.variationDesc').html(item['variation_description']);
});
if (selectedVariation) {
$('.variationBtns .variation-btn[data-slug="'+ selectedVariation +'"]').trigger('click');
} else {
/*
If default variation not selected in admin pane
`selectedVariation` become undefined . So select first variation/
*/
$('.variationBtns .variation-btn:eq(0)').trigger('click');
}
})( jQuery, window, document, undefined );
I would like to change the logo redirection when clicked. Right now when you click on the logo, the user is redirected to the homepage but I want it to redirect to another site. How do I do this?
I agree with Stu Mileham. Another way to implement what you are asking for would be to use JavaScript / jQuery.
Save the following code to a .js file (eg. pageRedirect.js, let's say placed in a js folder inside your theme's root folder):
(function($) {
$(document).ready(function() {
$('#pageLogo').on( "click", function(event) {
event.preventDefault();
window.location.assign("http://www.google.com/");
});
});
})(jQuery);
To make the previous code work, you would have to select somehow the page logo via jQuery.
On the previous code this is achived via $('#pageLogo') since I have made the assumption that your logo has an id with the value pageLogo.
Of course, to enable your theme to use this pageRedirect.js file, you have to enqueue it by placing the following code to your theme's functions.php file:
/**
* Enqueue pageRedirect script.
*/
function pageRedirect_scripts() {
wp_enqueue_script( 'page-redirect-js', get_template_directory_uri() . '/js/pageRedirect.js', array('jquery'), '20150528', true );
}
add_action( 'wp_enqueue_scripts', 'pageRedirect_scripts' );
Code Explanation:
//-jQuery selects html element with id='pageLogo'
//-when it is clicked, it calls a function in which it passes the event
$('#pageLogo').on( "click", function(event) {
//prevents page from redirecting to homepage
event.preventDefault();
//redirects to your desired webpage
window.location.assign("http://www.google.com/");
});
If you don't have the option to change the link from admin then you will have to edit your theme's header.php file (most likely, depends on how the theme is built though).
Many themes have a tag similar to the following:
<img src="logo.jpg">
You would need to change this to:
<img src="logo.jpg">
I've added the target tag to open the site in a new window, this is my personal preference when re-directing to a different site but it's optional.
Your theme files might look very different to this, it's impossible to know for sure without seeing some code, but this should give you an idea.
Also be aware that your changes could be overwritten by a theme update. This can be avoided by creating a child theme.
https://codex.wordpress.org/Child_Themes
Depends on your theme
Some theme creators gives you the possibility to change the link from admin
Some theme creators just believe that clicking the logo you need to go on homepage - so you need to edit the theme
Depending upon the theme you are using, you can try one of the following options.
Explore the admin options and see if the theme provides a direct way to change the link on the logo.
If not found in admin options, try looking for the code in header.php. Do an inspect element on your logo and see the html code surrounding the logo file, If the code is directly present in header.php, your task is simple. Just change the code to update the URL, instead of reading it from home_url(). Something like <a href="<?php echo home_url();?>"> will need to be replaced with <a href="https://www.example.com">
The other option to look for is get_custom_logo. Some themes get the logo code from this function. You can apply a filter to change the home_url just before this method is called in your theme and then remove filter afterwards. Or else you can copy the code from wordpress and update it with a differently named function say get_custom_link_logo in functions.php then where'ver your theme is using get_custom_logo you can use get_custom_link_logo instead of that.
function get_custom_link_logo ( $blog_id = 0 ) {
$html = "";
$switched_blog = false;
if ( is_multisite() && ! empty( $blog_id ) && (int) $blog_id !== get_current_blog_id() ) {
switch_to_blog( $blog_id );
$switched_blog = true;
}
$custom_logo_id = get_theme_mod( 'custom_logo' );
// We have a logo. Logo is go.
if ( $custom_logo_id ) {
$custom_logo_attr = array(
'class' => 'custom-logo',
'itemprop' => 'logo',
);
/*
* If the logo alt attribute is empty, get the site title and explicitly
* pass it to the attributes used by wp_get_attachment_image().
*/
$image_alt = get_post_meta( $custom_logo_id, '_wp_attachment_image_alt', true );
if ( empty( $image_alt ) ) {
$custom_logo_attr['alt'] = get_bloginfo( 'name', 'display' );
}
/*
* If the alt attribute is not empty, there's no need to explicitly pass
* it because wp_get_attachment_image() already adds the alt attribute.
*/
$html = sprintf( '%2$s',
esc_url( "https://www.example.com" ),
wp_get_attachment_image( $custom_logo_id, 'full', false, $custom_logo_attr )
);
}
// If no logo is set but we're in the Customizer, leave a placeholder (needed for the live preview).
elseif ( is_customize_preview() ) {
$html = sprintf( '<img class="custom-logo"/>',
esc_url( "https://www.example.com" )
);
}
if ( $switched_blog ) {
restore_current_blog();
}
/**
* Filters the custom logo output.
*
* #since 4.5.0
* #since 4.6.0 Added the `$blog_id` parameter.
*
* #param string $html Custom logo HTML output.
* #param int $blog_id ID of the blog to get the custom logo for.
*/
return apply_filters( 'get_custom_logo', $html, $blog_id ); }
This might not cover all the use cases, but you get the idea. Depending upon the theme you'll have a similar solution for your case. The important thing to figure out which case you fall under will be to identify the code where html for your logo is getting added. header.php is a good starting point.
Use this javascript in the header or footer of your theme:
<script>
document.getElementsByClassName("site-logo")[0].getElementsByTagName('a')[0].href="https://www.test.com";
</script>
i am assuming that site-logo is the class name of your LOGO.