Last active
December 8, 2020 16:13
-
-
Save LichP/154a0ee846f7cdd57a3b462f8ccc2ab0 to your computer and use it in GitHub Desktop.
Rendering product and variation images for a Drupal Commerce product gallery
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Implements template_preprocess_commerce_product(). | |
*/ | |
function dotorg_shop_default_preprocess_commerce_product(&$variables) { | |
if (isset($variables['elements']['#commerce_product'])) { | |
// Get view mode & assign variable. | |
$view_mode = $variables['elements']['#view_mode']; | |
$variables['view_mode'] = $view_mode; | |
// Get product and variations. | |
$product = $variables['elements']['#commerce_product']; | |
$product_variations = $product->getVariations(); | |
// Product gallery images: The product gallery always looks like this: | |
// | |
// * Primary product image | |
// * Product Variation images | |
// * Additional product images (if available) | |
// | |
// Multiple variations can share a single image, which might in turn be | |
// the same as the product primary image, so we make sure each | |
// referenced entity is only included once. | |
$product_gallery_images = []; | |
// Primary product image | |
if (isset($product->field_primary_image->entity)) { | |
$product_gallery_images[$product->field_primary_image->target_id] = [ | |
'variations' => [], | |
'image' => $variables['product']['field_primary_image'], | |
]; | |
} | |
// Product Variation images | |
if (!empty($product_variations)) { | |
// Get the variation field renderer so we can use it to render out any | |
// image fields that are present | |
$variation_view_builder = \Drupal::entityTypeManager()->getViewBuilder('commerce_product_variation'); | |
foreach ($product_variations as $key => $variation) { | |
// If variation is active. | |
if ($variation->status->value == '1') { | |
// If variation has an image. | |
if (isset($variation->field_image->entity)) { | |
$product_gallery_images[$variation->field_image->target_id]['variations'][] = $variation->variation_id->value; | |
$product_gallery_images[$variation->field_image->target_id]['image'] ??= $variation_view_builder->viewField($variation->get('field_image'), $view_mode); | |
$product_gallery_images[$variation->field_image->target_id]['thumbnail'] ??= $variation_view_builder->viewField($variation->get('field_image'), $view_mode); | |
} | |
} | |
} | |
} | |
// TODO: Additional product images | |
$variables['product_gallery_images'] = $product_gallery_images; | |
// ... | |
} | |
} | |
/** | |
* Implements hook_form_alter(). | |
*/ | |
function dotorg_shop_default_form_alter(&$form, &$form_state, $form_id) { | |
// ... | |
// Commerce Add to Cart form. | |
if ((strpos($form_id, 'commerce_order_item_add_to_cart_form_commerce_product_') === 0)) { | |
$selected_variation = $form_state->get('selected_variation') ? ProductVariation::load($form_state->get('selected_variation')) : $form_state->get('product')->getDefaultVariation(); | |
if (isset($selected_variation)) { | |
// Set form data attribute for the product variation id. | |
$form['#attributes']['data-product-variation-id'] = $selected_variation->id(); | |
if ($selected_variation->hasField('commerce_stock_always_in_stock') && $selected_variation->get('commerce_stock_always_in_stock')->value) { | |
$form['stock'] = [ | |
'#type' => 'markup', | |
'#markup' => '<div class="field-type-commerce-stock-level"><div class="stock-level always-in-stock">Available</div></div>', | |
]; | |
} elseif ($selected_variation->hasField('field_stock')) { | |
$form['stock'] = $selected_variation->get('field_stock')->view('full'); | |
} else { | |
$form['stock'] = [ | |
'#type' => 'markup', | |
'#markup' => '<div class="field-type-commerce-stock-level"><div class="stock-level unknown">No stock information available for this product variation</div></div>', | |
]; | |
} | |
$form['stock']['#weight'] = 0; | |
} | |
// ... | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function($, Drupal) { | |
var thumbnailSlider; | |
var gallerySlider; | |
$(document).ready(function() { | |
// Create and mount the thumbnails slider. | |
thumbnailSlider = new Splide( '#thumbnail-slider', { | |
rewind : true, | |
fixedWidth : 100, | |
isNavigation: true, | |
gap : 10, | |
focus : 'center', | |
pagination : false, | |
cover : true, | |
breakpoints : { | |
'600': { | |
fixedWidth : 66, | |
} | |
} | |
} ).mount(); | |
// Create the main slider. | |
gallerySlider = new Splide( '#gallery-slider', { | |
type : 'fade', | |
pagination : false, | |
arrows : false, | |
cover : true, | |
} ); | |
// Set the thumbnails slider as a sync target and then call mount. | |
gallerySlider.sync( thumbnailSlider ).mount(); | |
}); | |
// Product Image Slider Ajax. | |
Drupal.behaviors.productSlider = { | |
attach: function (context, settings) { | |
// Commerce add to cart form. | |
$('form.commerce-order-item-add-to-cart-form', context).once('dotorg_shop_default.product_slider').each(function () { | |
// Grab the current product variation ID. | |
var current_product_variation_id = $(this).data('product-variation-id'); | |
// Determine the gallery image that matches (if any) | |
if ($('#thumbnail-slider').length && $('#thumbnail-slider .splide__slide[data-product-variation-ids~="' + current_product_variation_id +'"]').length) { | |
var $nav_item = $('#thumbnail-slider .splide__slide[data-product-variation-ids~="' + current_product_variation_id +'"]'); | |
var item_position = $nav_item.index(); | |
// Trigger Splide to go to current variation image. | |
thumbnailSlider.go(item_position); | |
} | |
}); | |
} | |
}; | |
})(jQuery, Drupal); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment