feat: Complete markdown syntax refinement and variable protection

 New cleaner syntax implemented:
- [card:type] instead of [card type='type']
- [button:style](url)Text[/button] instead of [button url='...' style='...']
- Standard markdown images: ![alt](url)

 Variable protection from markdown parsing:
- Variables with underscores (e.g., {order_items_table}) now protected
- HTML comment placeholders prevent italic/bold parsing
- All variables render correctly in preview

 Button rendering fixes:
- Buttons work in Visual mode inside cards
- Buttons work in Preview mode
- Button clicks prevented in visual editor
- Proper styling for solid and outline buttons

 Backward compatibility:
- Old syntax still supported
- No breaking changes

 Bug fixes:
- Fixed order_item_table → order_items_table naming
- Fixed button regex to match across newlines
- Added button/image parsing to parseMarkdownBasics
- Prevented button clicks on .button and .button-outline classes

📚 Documentation:
- NEW_MARKDOWN_SYNTAX.md - Complete user guide
- MARKDOWN_SYNTAX_AND_VARIABLES.md - Technical analysis
This commit is contained in:
dwindown
2025-11-15 20:05:50 +07:00
parent 550b3b69ef
commit 4471cd600f
45 changed files with 9194 additions and 508 deletions

253
FILTER_HOOKS_GUIDE.md Normal file
View File

@@ -0,0 +1,253 @@
# Filter Hooks Guide - Events & Templates
## Single Source of Truth: ✅ Verified
**EventRegistry.php** is the single source of truth for all events.
**DefaultTemplates.php** provides templates for all events.
All components use EventRegistry:
- ✅ NotificationsController.php (Events API)
- ✅ TemplateProvider.php (Templates API)
- ✅ No hardcoded event lists anywhere
## Adding Custom Events & Templates
### 1. Add Custom Event
```php
add_filter('woonoow_notification_events_registry', function($events) {
// Add custom event
$events['vip_milestone'] = [
'id' => 'vip_milestone',
'label' => __('VIP Milestone Reached', 'my-plugin'),
'description' => __('When customer reaches VIP milestone', 'my-plugin'),
'category' => 'customers',
'recipient_type' => 'customer',
'wc_email' => '',
'enabled' => true,
];
return $events;
});
```
### 2. Add Default Template for Custom Event
```php
add_filter('woonoow_email_default_templates', function($templates) {
// Add template for custom event
$templates['customer']['vip_milestone'] = '[card type="success"]
## Congratulations, {customer_name}!
You\'ve reached VIP status! Enjoy exclusive benefits.
[/card]
[card]
**Your VIP Benefits:**
- Free shipping on all orders
- 20% discount on premium items
- Early access to new products
- Priority customer support
[button url="{vip_dashboard_url}"]View VIP Dashboard[/button]
[/card]';
return $templates;
}, 10, 1);
```
### 3. Add Subject for Custom Event
```php
add_filter('woonoow_email_default_subject', function($subject, $recipient, $event) {
if ($event === 'vip_milestone' && $recipient === 'customer') {
return '🎉 Welcome to VIP Status, {customer_name}!';
}
return $subject;
}, 10, 3);
```
### 4. Replace Existing Template
```php
add_filter('woonoow_email_default_templates', function($templates) {
// Replace order_placed template for staff
$templates['staff']['order_placed'] = '[card type="hero"]
# 🎉 New Order Alert!
Order #{order_number} just came in from {customer_name}
[button url="{order_url}"]Process Order Now[/button]
[/card]';
return $templates;
}, 20, 1); // Priority 20 to override default
```
## Complete Example: Subscription Plugin
```php
<?php
/**
* Plugin Name: WooNooW Subscriptions Addon
*/
// Add subscription events
add_filter('woonoow_notification_events_registry', function($events) {
$events['subscription_created'] = [
'id' => 'subscription_created',
'label' => __('Subscription Created', 'woonoow-subscriptions'),
'description' => __('When new subscription is created', 'woonoow-subscriptions'),
'category' => 'subscriptions',
'recipient_type' => 'customer',
'wc_email' => 'customer_new_subscription',
'enabled' => true,
];
$events['subscription_renewal'] = [
'id' => 'subscription_renewal',
'label' => __('Subscription Renewal', 'woonoow-subscriptions'),
'description' => __('When subscription renews', 'woonoow-subscriptions'),
'category' => 'subscriptions',
'recipient_type' => 'customer',
'wc_email' => 'customer_renewal_subscription',
'enabled' => true,
];
$events['subscription_cancelled'] = [
'id' => 'subscription_cancelled',
'label' => __('Subscription Cancelled', 'woonoow-subscriptions'),
'description' => __('When subscription is cancelled', 'woonoow-subscriptions'),
'category' => 'subscriptions',
'recipient_type' => 'customer',
'wc_email' => 'customer_cancelled_subscription',
'enabled' => true,
];
return $events;
});
// Add templates
add_filter('woonoow_email_default_templates', function($templates) {
$templates['customer']['subscription_created'] = '[card type="success"]
## Welcome to Your Subscription!
Your subscription is now active. We\'ll charge you {subscription_amount} every {billing_period}.
[/card]
[card]
**Subscription Details:**
**Product:** {subscription_product}
**Amount:** {subscription_amount}
**Billing Period:** {billing_period}
**Next Payment:** {next_payment_date}
[button url="{subscription_url}"]Manage Subscription[/button]
[/card]';
$templates['customer']['subscription_renewal'] = '[card]
## Subscription Renewed
Your subscription for {subscription_product} has been renewed.
**Amount Charged:** {subscription_amount}
**Next Renewal:** {next_payment_date}
[button url="{subscription_url}"]View Subscription[/button]
[/card]';
$templates['customer']['subscription_cancelled'] = '[card type="warning"]
## Subscription Cancelled
Your subscription for {subscription_product} has been cancelled.
You\'ll continue to have access until {expiry_date}.
[/card]
[card]
Changed your mind? You can reactivate anytime.
[button url="{subscription_url}"]Reactivate Subscription[/button]
[/card]';
return $templates;
});
// Add subjects
add_filter('woonoow_email_default_subject', function($subject, $recipient, $event) {
$subjects = [
'subscription_created' => 'Your subscription is active!',
'subscription_renewal' => 'Subscription renewed - {subscription_product}',
'subscription_cancelled' => 'Subscription cancelled - {subscription_product}',
];
if (isset($subjects[$event]) && $recipient === 'customer') {
return $subjects[$event];
}
return $subject;
}, 10, 3);
```
## Available Filter Hooks
### 1. `woonoow_notification_events_registry`
**Location:** `EventRegistry::get_all_events()`
**Purpose:** Add/modify notification events
**Parameters:** `$events` (array)
**Return:** Modified events array
### 2. `woonoow_email_default_templates`
**Location:** `DefaultTemplates::get_all_templates()`
**Purpose:** Add/modify email templates
**Parameters:** `$templates` (array)
**Return:** Modified templates array
### 3. `woonoow_email_default_subject`
**Location:** `DefaultTemplates::get_default_subject()`
**Purpose:** Add/modify email subjects
**Parameters:** `$subject` (string), `$recipient` (string), `$event` (string)
**Return:** Modified subject string
## Testing Your Custom Event
After adding filters:
1. **Refresh WordPress** - Clear any caches
2. **Check Events API:** `/wp-json/woonoow/v1/notifications/events`
3. **Check Templates API:** `/wp-json/woonoow/v1/notifications/templates`
4. **UI:** Your event should appear in Staff/Customer Notifications
5. **Template:** Should be editable in the template editor
## Best Practices
**DO:**
- Use unique event IDs
- Provide clear labels and descriptions
- Include all required fields
- Test thoroughly
- Use appropriate priority for filters
**DON'T:**
- Hardcode events anywhere
- Skip required fields
- Use conflicting event IDs
- Forget to add templates for events