Creating a Module
This guide walks you through creating a custom module for the Flavor Starter Theme.
Step 1: Create the Module Directory
In your child theme (recommended) or plugin:
flavor-starter-child/
└── modules/
└── my-custom-module/
└── module.php
Step 2: Module Entry Point
Create module.php with the required structure:
<?php
/**
* Module: My Custom Module
* Description: Adds custom functionality to the store
* Version: 1.0.0
* Author: Your Name
*/
defined('ABSPATH') || exit;
/**
* Initialize the module.
* Called when the module is active and loaded.
*/
function my_custom_module_init(): void
{
// Add your hooks, filters, and initialization here
add_action('wp_enqueue_scripts', 'my_custom_module_assets');
add_filter('wpec_product_price', 'my_custom_module_price_modifier', 10, 2);
}
/**
* Enqueue module assets.
*/
function my_custom_module_assets(): void
{
$module_url = get_stylesheet_directory_uri() . '/modules/my-custom-module';
wp_enqueue_style(
'my-custom-module',
$module_url . '/assets/style.css',
[],
'1.0.0'
);
}
/**
* Example: modify product prices.
*/
function my_custom_module_price_modifier(float $price, $product): float
{
// Your custom pricing logic
return $price;
}
// Boot the module
my_custom_module_init();
Step 3: Register the Module
In your child theme's functions.php:
add_action('flavor_register_modules', function ($moduleManager) {
$moduleManager->registerModule([
'id' => 'my-custom-module',
'name' => 'My Custom Module',
'description' => 'Adds custom functionality to the store',
'version' => '1.0.0',
'path' => get_stylesheet_directory() . '/modules/my-custom-module/',
'external' => true,
'author' => 'Your Name',
]);
});
Step 4: Test
- Go to Appearance → Flavor Options → Modules
- Your module should appear in the list
- Enable it and verify it works
- Check for JavaScript console errors and PHP warnings
Module Registration Fields
| Field | Required | Description |
|---|---|---|
id | Yes | Unique identifier (kebab-case) |
name | Yes | Display name |
description | Yes | Short description |
version | Yes | Semantic version |
path | Yes | Absolute path to module directory |
external | Yes | Must be true for non-built-in modules |
author | No | Module author name |
requires_license | No | Minimum license tier ('starter', 'business') |
depends_on | No | Array of module IDs this module requires |
Example: Complete Module
Here's a more complete module example with settings:
<?php
// modules/sale-banner/module.php
defined('ABSPATH') || exit;
function sale_banner_init(): void
{
$enabled = flavor_get_option('sale_banner_enabled', 'true', 'flavor_module_sale_banner');
if ($enabled !== 'true') return;
add_action('flavor_before_header', 'sale_banner_render');
}
function sale_banner_render(): void
{
$message = flavor_get_option('sale_banner_message', 'Sale! 20% off everything!', 'flavor_module_sale_banner');
$bg_color = flavor_get_option('sale_banner_color', '#ef4444', 'flavor_module_sale_banner');
echo '<div style="background:' . esc_attr($bg_color) . ';color:#fff;text-align:center;padding:10px;font-weight:600;">';
echo esc_html($message);
echo '</div>';
}
sale_banner_init();
tip
Always prefix your functions and classes with your module name to avoid naming conflicts with other modules.