You've already forked wc-composable-product
Initial implementation of WooCommerce Composable Products plugin
Implemented custom WooCommerce product type allowing customers to build their own product bundles by selecting from predefined sets of products. Features: - Custom "Composable Product" type with admin interface - Product selection by category, tag, or SKU - Configurable selection limits (global and per-product) - Dual pricing modes: fixed price or sum of selected products - Modern responsive frontend with Twig templates - AJAX add-to-cart functionality - Full internationalization support (.pot file) - WooCommerce settings integration - Comprehensive documentation Technical implementation: - PHP 8.3+ with PSR-4 autoloading - Twig 3.0 templating engine via Composer - Vanilla JavaScript with jQuery for frontend interactions - WordPress and WooCommerce hooks for seamless integration - Security: input sanitization, validation, and output escaping - Translation-ready with text domain 'wc-composable-product' Documentation: - README.md: Project overview and features - INSTALL.md: Installation and usage guide - IMPLEMENTATION.md: Technical architecture - CHANGELOG.md: Version history 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
65
templates/product-selector.twig
Normal file
65
templates/product-selector.twig
Normal file
@@ -0,0 +1,65 @@
|
||||
{# Product Selector Template #}
|
||||
<div class="wc-composable-product-selector" data-product-id="{{ product_id }}" data-selection-limit="{{ selection_limit }}" data-pricing-mode="{{ pricing_mode }}" data-fixed-price="{{ fixed_price }}">
|
||||
|
||||
<div class="composable-header">
|
||||
<h3>{{ __('Select Your Products') }}</h3>
|
||||
<p class="selection-info">
|
||||
{{ __('Choose up to') }} <strong>{{ selection_limit }}</strong> {{ __('items from the selection below.') }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="composable-products-grid">
|
||||
{% for product in products %}
|
||||
<div class="composable-product-item" data-product-id="{{ product.id }}" data-price="{{ product.price }}">
|
||||
<div class="product-item-inner">
|
||||
<label class="product-item-label">
|
||||
<input type="checkbox"
|
||||
name="composable_products[]"
|
||||
value="{{ product.id }}"
|
||||
class="composable-product-checkbox"
|
||||
data-product-id="{{ product.id }}"
|
||||
data-price="{{ product.price }}">
|
||||
|
||||
{% if show_images and product.image_url %}
|
||||
<div class="product-item-image">
|
||||
<img src="{{ product.image_url }}" alt="{{ product.name|esc_attr }}">
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="product-item-details">
|
||||
<h4 class="product-item-name">{{ product.name|esc_html }}</h4>
|
||||
|
||||
{% if show_prices %}
|
||||
<div class="product-item-price">
|
||||
{{ product.price_html|raw }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<span class="product-item-checkmark"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{% if show_total %}
|
||||
<div class="composable-total">
|
||||
<div class="total-label">{{ __('Total Price:') }}</div>
|
||||
<div class="total-price" data-currency="{{ currency_symbol }}">
|
||||
{% if pricing_mode == 'fixed' %}
|
||||
{{ currency_symbol }}{{ fixed_price }}
|
||||
{% else %}
|
||||
<span class="calculated-total">{{ currency_symbol }}0.00</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="composable-actions">
|
||||
<button type="button" class="button alt composable-add-to-cart" data-product-id="{{ product_id }}">
|
||||
{{ __('Add to Cart') }}
|
||||
</button>
|
||||
<div class="composable-messages"></div>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user