Skip to content

Instantly share code, notes, and snippets.

@SitesByYogi
Created February 4, 2026 10:31
Show Gist options
  • Select an option

  • Save SitesByYogi/8f875381062a958a2aa00a88c6d76f46 to your computer and use it in GitHub Desktop.

Select an option

Save SitesByYogi/8f875381062a958a2aa00a88c6d76f46 to your computer and use it in GitHub Desktop.
Global woocommerce pdp testing snippet for EOW A/B Test
<?php
/**
* =========================================================
* EOW PDP Test Base (Nelio-ready)
* - One-time “foundation” snippet for WooCommerce PDP tests
* - Provides stable selectors, body classes, header offset helpers
* - Exposes a small JS API so Nelio variants can be toggled safely
*
* Usage:
* 1) Install this once (Code Snippets plugin)
* 2) For each Nelio PDP experiment, run a JS Test that:
* - adds a body class (ex: eow-pdp-test-xyz)
* - optionally calls window.EOWPDPTests.refresh()
* =========================================================
*/
add_action('wp_enqueue_scripts', function () {
if ( ! function_exists('is_product') || ! is_product() ) {
return;
}
/* ===============================
CONFIG
=============================== */
// Divi header id is usually #main-header. Change if needed.
$header_selector = '#main-header';
// If your site has a known sticky header height, you can set a default.
// Otherwise we compute offsets with CSS vars and keep it minimal.
$default_bar_h = '0px';
/* ===============================
BODY CLASS (PDP foundation)
=============================== */
add_filter('body_class', function ($classes) {
$classes[] = 'eow-pdp';
return $classes;
});
/* ===============================
CSS: offsets + helper classes
=============================== */
$css = "
:root{
--eow-adminbar-h: 0px;
--eow-topbar-h: {$default_bar_h};
--eow-top-offset: 0px;
}
body.admin-bar{ --eow-adminbar-h: 32px; }
@media screen and (max-width: 782px){
body.admin-bar{ --eow-adminbar-h: 46px; }
}
/* Offset used by some tests when they add a fixed element at the top */
body.eow-pdp{ --eow-top-offset: calc(var(--eow-adminbar-h) + var(--eow-topbar-h)); }
/* Optional: If a test uses a fixed top bar, apply this class to move the header down */
body.eow-pdp.eow-has-topbar {$header_selector}{
top: var(--eow-top-offset) !important;
}
body.eow-pdp.eow-has-topbar.et_fixed_nav {$header_selector}.et-fixed-header{
top: var(--eow-top-offset) !important;
}
/* Utility helpers */
body.eow-pdp .eow-hidden{ display:none !important; }
body.eow-pdp .eow-visually-hidden{
position:absolute !important;
width:1px !important;
height:1px !important;
padding:0 !important;
margin:-1px !important;
overflow:hidden !important;
clip:rect(0,0,0,0) !important;
white-space:nowrap !important;
border:0 !important;
}
";
wp_register_style('eow-pdp-tests-base-inline', false);
wp_enqueue_style('eow-pdp-tests-base-inline');
wp_add_inline_style('eow-pdp-tests-base-inline', $css);
/* ===============================
JS: stable selectors + small API
=============================== */
$js = "
(function(){
if (!document || !document.documentElement) return;
var SELECTORS = {
body: 'body',
header: " . json_encode($header_selector) . ",
// Common WooCommerce PDP parts (best-effort selectors)
productRoot: '.single-product .product, body.single-product',
gallery: '.woocommerce-product-gallery',
thumbs: '.flex-control-nav, .woocommerce-product-gallery__wrapper',
summary: '.summary, .woocommerce-summary',
price: '.summary .price, .woocommerce-Price-amount',
variationsForm: 'form.variations_form',
variations: 'form.variations_form .variations',
atcForm: 'form.cart',
atcButton: 'form.cart button.single_add_to_cart_button',
qty: 'form.cart input.qty',
description: '.woocommerce-Tabs-panel--description, .woocommerce-product-details__short-description',
tabs: '.woocommerce-tabs',
reviewsTab: '#tab-title-reviews, a[href=\"#tab-reviews\"], .woocommerce-review-link',
reviewsPanel: '#tab-reviews, .woocommerce-Tabs-panel--reviews',
additionalInfo: '#tab-additional_information, .woocommerce-Tabs-panel--additional_information'
};
function qs(sel, root){
try { return (root || document).querySelector(sel); } catch(e){ return null; }
}
function qsa(sel, root){
try { return Array.prototype.slice.call((root || document).querySelectorAll(sel)); } catch(e){ return []; }
}
function addBodyClass(cls){
if (!cls) return;
document.body.classList.add(cls);
}
function removeBodyClass(cls){
if (!cls) return;
document.body.classList.remove(cls);
}
function setVar(name, value){
if (!name) return;
document.documentElement.style.setProperty(name, value);
}
function getVar(name){
if (!name) return '';
return getComputedStyle(document.documentElement).getPropertyValue(name) || '';
}
function setTopbarHeight(pxValue){
// Ex: '44px'
setVar('--eow-topbar-h', pxValue);
addBodyClass('eow-has-topbar');
}
function clearTopbarHeight(){
setVar('--eow-topbar-h', '0px');
removeBodyClass('eow-has-topbar');
}
function moveEl(el, target, position){
// position: 'beforebegin' | 'afterbegin' | 'beforeend' | 'afterend'
if (!el || !target || !target.insertAdjacentElement) return false;
var pos = position || 'beforeend';
try {
target.insertAdjacentElement(pos, el);
return true;
} catch(e){
return false;
}
}
function hideEl(el){
if (!el) return;
el.classList.add('eow-hidden');
}
function showEl(el){
if (!el) return;
el.classList.remove('eow-hidden');
}
function triggerChange(el){
if (!el) return;
try {
var evt = new Event('change', { bubbles: true });
el.dispatchEvent(evt);
} catch(e){}
}
function forEachPDP(fn){
// In case of quick view or unusual templates, target the first product root we can find
var root = qs(SELECTORS.productRoot) || document.body;
if (typeof fn === 'function') fn(root);
}
function refresh(){
// Reserved for future: if tests add dynamic elements and need re-measurement.
// Keeping it here so Nelio can call it consistently.
// Example: window.EOWPDPTests.setTopbarHeight('44px'); window.EOWPDPTests.refresh();
return true;
}
// Public API for Nelio JS variants
window.EOWPDPTests = window.EOWPDPTests || {
SELECTORS: SELECTORS,
qs: qs,
qsa: qsa,
addBodyClass: addBodyClass,
removeBodyClass: removeBodyClass,
setVar: setVar,
getVar: getVar,
setTopbarHeight: setTopbarHeight,
clearTopbarHeight: clearTopbarHeight,
moveEl: moveEl,
hideEl: hideEl,
showEl: showEl,
triggerChange: triggerChange,
forEachPDP: forEachPDP,
refresh: refresh
};
// Add a stable root class for PDP-specific styling
document.addEventListener('DOMContentLoaded', function(){
if (document.body) document.body.classList.add('eow-pdp-ready');
});
})();
";
wp_register_script('eow-pdp-tests-base-inline', '', [], null, true);
wp_enqueue_script('eow-pdp-tests-base-inline');
wp_add_inline_script('eow-pdp-tests-base-inline', $js);
}, 20);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment