JavaScript Plugins
Contents of this page:
The Guppy Theme extends the Shopware frontend through specialized JavaScript plugins that provide modern functionalities and improved user interactions.
Plugin Architecture
The Guppy Theme uses the Shopware plugin system and extends it with custom components:
Registration
javascript
// New plugins
PluginManager.register('SplideSliderPlugin', SplideSliderPlugin);
PluginManager.register('UspBannerPlugin', UspBannerPlugin);
PluginManager.register('ProductBoxClickPlugin', ProductBoxClickPlugin);
// Plugin overrides
PluginManager.override('QuantitySelector', () => import('./js/quantity-selector.plugin'));Plugin Initialization
javascript
// Automatic initialization via data attributes
<div data-splide-slider-plugin="true" data-splide-slider-plugin-options='{...}'>Splide Slider Plugin
Description
Modern slider based on the Splide.js library that replaces the standard Tiny Slider.
Features
- Better Performance: Optimized for modern browsers
- Accessibility: Full keyboard navigation and screen reader support
- Responsive Design: Automatic adaptation to different screen sizes
- Touch Support: Native touch gestures for mobile devices
Implementation
javascript
export default class SplideSliderPlugin extends Plugin {
static options = {
splideSnippets: ""
}
init() {
this._mountSlider(this.el, this.options.splideSnippets);
}
_mountSlider(element, options) {
var splideSlider = new Splide(element, {
i18n: options
}).mount();
// Autoplay handling
const splideOptions = Object.getPrototypeOf(splideSlider.options);
if (splideOptions.autoplay === "pause") {
splideSlider.Components.Autoplay.play();
}
}
}Usage
html
<div class="splide" data-splide-slider-plugin="true">
<div class="splide__track">
<ul class="splide__list">
<li class="splide__slide">Slide 1</li>
<li class="splide__slide">Slide 2</li>
<li class="splide__slide">Slide 3</li>
</ul>
</div>
</div>USP Banner Plugin
Description
Interactive banner system for Unique Selling Points with tooltip functionality and responsive behavior.
Features
- Tooltip System: Automatic tooltips for longer content
- Responsive Display: Different number of USPs depending on screen size
- Slider Integration: Automatic slider behavior on mobile devices
- Configurable Layouts: Standard and benefit layout available
Configuration
javascript
// Theme configuration
{
"guppy-usp-active": true,
"guppy-usp-layout": "benefits",
"guppy-usp-layout-benefit1": "Free Shipping",
"guppy-usp-layout-benefit2": "30 Day Returns",
"guppy-usp-layout-benefit3": "Fast Delivery"
}Responsive Behavior
- Desktop: 1-4 USPs (static)
- Tablet: 1-2 USPs (slider with infinite loop)
- Mobile: 1 USP (slider with infinite loop)
Product Box Click Plugin
Description
Extends product box functionality with improved click interactions and accessibility.
Features
- Entire Box Clickable: Not just the product name
- Keyboard Navigation: Full keyboard support
- Focus Management: Correct focus handling
- Event Delegation: Efficient event handling
Implementation
javascript
// Enhanced product box interaction
document.addEventListener('click', (event) => {
const productBox = event.target.closest('.product-box');
if (productBox && !event.target.closest('.btn, .product-action')) {
const link = productBox.querySelector('.product-name a');
if (link) {
link.click();
}
}
});Custom Checkout Plugin
Description
Optimizes the checkout experience through improved user guidance and form handling.
Features
- Form Validation: Extended client-side validation
- Progress Tracking: Visual progress through checkout steps
- Auto-Save: Automatic saving of form data
- Error Handling: Improved error handling
Usage
javascript
// Automatic activation on checkout pages
<div class="checkout-main" data-custom-checkout-plugin="true">Quantity Selector Plugin (Override)
Description
Extends the standard Quantity Selector with improved user interaction and validation.
Features
- Input Validation: Prevents invalid inputs
- Keyboard Support: Arrow key navigation
- Accessibility: ARIA labels and screen reader support
- Animation: Smooth transitions on changes
Extended Functionality
javascript
// Enhanced quantity selection
PluginManager.override('QuantitySelector', QuantitySelectorPlugin, '[data-quantity-selector]');Additional Plugins
Remove Extra H1 Plugin
- Purpose: SEO optimization by removing redundant H1 tags
- Automatic: Runs after DOM load
- SEO Compliant: Prevents multiple H1 tags per page
Delivery Information Margin Plugin
- Purpose: Dynamic margin adjustment for delivery information
- Responsive: Adapts to different screen sizes
- Layout Optimization: Improved visual hierarchy
Splide Slider Gallery Plugin
- Purpose: Extended gallery functionality
- Thumbnail Navigation: Synchronized thumbnail view
- Zoom Integration: Seamless zoom functionality
- Touch Gestures: Extended touch interactions
Collapse Footer Columns Plugin (Override)
- Purpose: Responsive footer behavior
- Mobile First: Accordion behavior on mobile devices
- Accessibility: Correct ARIA attributes
- Animation: Smooth collapse animations
Detailed Plugin Configuration
Splide Slider Options
The Splide Slider supports all Splide.js options:
javascript
// Via data attributes
<div class="splide"
data-splide-slider-plugin="true"
data-splide-slider-plugin-options='{
"type": "loop",
"perPage": 4,
"perMove": 1,
"gap": "1rem",
"pagination": false,
"arrows": true,
"autoplay": true,
"interval": 5000,
"pauseOnHover": true,
"breakpoints": {
"1024": { "perPage": 3 },
"768": { "perPage": 2 },
"576": { "perPage": 1 }
}
}'>| Option | Type | Default | Description |
|---|---|---|---|
type | string | slide | Slider type: slide, loop, fade |
perPage | number | 1 | Visible slides |
perMove | number | 1 | Slides per movement |
gap | string | 0 | Gap between slides |
arrows | boolean | true | Show navigation arrows |
pagination | boolean | true | Show pagination dots |
autoplay | boolean | false | Automatic playback |
interval | number | 5000 | Autoplay interval (ms) |
pauseOnHover | boolean | true | Pause on hover |
rewind | boolean | false | Rewind to beginning |
speed | number | 400 | Animation speed (ms) |
easing | string | cubic-bezier(0.25, 1, 0.5, 1) | Easing function |
Splide Events
javascript
// Add event listeners
document.addEventListener('DOMContentLoaded', () => {
const splideEl = document.querySelector('.splide');
const splide = splideEl._splide; // Access Splide instance
if (splide) {
// Slide changed
splide.on('move', (newIndex, prevIndex) => {
console.log(`Moved from ${prevIndex} to ${newIndex}`);
});
// Slider initialized
splide.on('mounted', () => {
console.log('Slider mounted');
});
// Autoplay started/stopped
splide.on('autoplay:play', () => console.log('Autoplay started'));
splide.on('autoplay:pause', () => console.log('Autoplay paused'));
}
});USP Banner Plugin Options
javascript
// Theme configuration (theme.json)
{
"guppy-usp-active": true,
"guppy-usp-layout": "benefits", // "benefits" or "standard"
// Benefits Layout (up to 4 USPs)
"guppy-usp-layout-benefit1": "Free shipping over $50",
"guppy-usp-layout-benefit2": "30-day return policy",
"guppy-usp-layout-benefit3": "Fast delivery",
"guppy-usp-layout-benefit4": "Secure payment",
// Standard Layout
"guppy-usp-layout-text": "Get 10% off now!",
"guppy-usp-layout-link": "/promotions",
"guppy-usp-layout-newTab": false,
// Colors
"guppy-usp-text-color": "#2b3136",
"guppy-usp-hover-color": "#0042a0",
"guppy-usp-background-color": "#EEEEEE"
}Product Box Click Plugin
javascript
// Customize plugin behavior
export default class ProductBoxClickPlugin extends Plugin {
static options = {
// Elements excluded from click
excludeSelectors: '.btn, .product-action, .wishlist-button, input, select',
// Link selector for product page
linkSelector: '.product-name a, .product-image-link'
}
init() {
this.el.addEventListener('click', this._onClick.bind(this));
this.el.addEventListener('keydown', this._onKeydown.bind(this));
}
_onClick(event) {
if (event.target.closest(this.options.excludeSelectors)) {
return;
}
const link = this.el.querySelector(this.options.linkSelector);
if (link) {
link.click();
}
}
_onKeydown(event) {
if (event.key === 'Enter' || event.key === ' ') {
this._onClick(event);
}
}
}Plugin Debugging
DevTools Integration
javascript
// Get plugin instance
const element = document.querySelector('[data-splide-slider-plugin]');
const pluginInstance = window.PluginManager.getPluginInstanceFromElement(element, 'SplideSliderPlugin');
// Show plugin options
console.log(pluginInstance.options);
// List all registered plugins
console.log(window.PluginManager.getPluginList());Common Issues
| Issue | Cause | Solution |
|---|---|---|
| Plugin not loading | JavaScript error | Check browser console |
| Slider shows no slides | Wrong HTML structure | Check Splide classes |
| Events not firing | Plugin not initialized | Wait for DOMContentLoaded |
| Autoplay not working | autoplay: "pause" set | Change to true |
Creating Custom Plugins
Plugin Template
javascript
import Plugin from 'src/plugin-system/plugin.class';
export default class MyCustomPlugin extends Plugin {
static options = {
// Default options
myOption: 'default-value',
anotherOption: true
};
init() {
// Plugin initialization
this._registerEvents();
}
_registerEvents() {
this.el.addEventListener('click', this._onClick.bind(this));
}
_onClick(event) {
// Event handler
console.log('Clicked!', this.options.myOption);
}
// Lifecycle: Plugin is removed
destroy() {
// Cleanup
}
}Register Plugin
javascript
// main.js
import MyCustomPlugin from './plugins/my-custom-plugin';
window.PluginManager.register('MyCustomPlugin', MyCustomPlugin, '[data-my-custom-plugin]');Use Plugin
html
<div data-my-custom-plugin="true"
data-my-custom-plugin-options='{"myOption": "custom-value"}'>
<!-- Content -->
</div>