Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions solution/INTEGRATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Clerk.io Elementor Integration Guide

This guide explains how to integrate Clerk.io sliders with Elementor pages, ensuring that all slider types work correctly, including those that require product or category data.

## Method 1: Using Shortcodes in Elementor HTML Widget

The most reliable way to add Clerk.io sliders to Elementor pages is using the HTML widget with shortcodes:

1. Add an HTML widget to your Elementor page
2. Insert the following code:

```html
<span class="clerk"
data-template="@popular-products"
data-products="[clerk_product_id]">
</span>
```

The `[clerk_product_id]` shortcode will be automatically replaced with the current product ID.

For category pages, use:

```html
<span class="clerk"
data-template="@category-products"
data-categories="[clerk_category_id]">
</span>
```

## Method 2: Using Embed Code

If you're copying embed code from my.clerk.io, make sure to replace any PHP code with the appropriate shortcodes:

Instead of:
```html
<span class="clerk"
data-template="@popular-products"
data-products="<?php echo $product->get_id(); ?>">
</span>
```

Use:
```html
<span class="clerk"
data-template="@popular-products"
data-products="[clerk_product_id]">
</span>
```

## Method 3: Using the Clerk.io Widget (Coming Soon)

We're working on a dedicated Elementor widget for Clerk.io that will make integration even easier. This will allow you to:

1. Add a Clerk.io widget directly to your Elementor page
2. Select the template from a dropdown
3. Configure all options through the Elementor interface
4. Product and category data will be automatically handled

## Troubleshooting

If your sliders still don't work after implementing these solutions:

1. **Check Browser Console**: Look for any JavaScript errors related to Clerk.io
2. **Verify Shortcodes**: Make sure you're using the correct shortcodes (`[clerk_product_id]`, `[clerk_category_id]`, or `[clerk_cart_ids]`)
3. **Clear Cache**: Clear your Elementor cache and any caching plugins
4. **Check Template ID**: Verify that the template ID in the `data-template` attribute is correct
5. **Inspect Element**: Use browser developer tools to check if the data attributes have been properly populated with actual values

## Support

If you encounter any issues with this integration, please contact Clerk.io support at [email protected] or through the chat on your my.clerk.io dashboard.

65 changes: 65 additions & 0 deletions solution/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Clerk.io Elementor Compatibility Fix

This solution addresses the issue with Clerk.io sliders not working in Elementor when using embed code with product/category data.

## Problem

When using Clerk.io sliders in Elementor pages, sliders that require product or category data (via `data-products` or `data-categories` attributes) do not work properly. This happens because:

1. Elementor doesn't properly process PHP shortcodes within HTML attributes
2. The shortcodes in the data attributes are not evaluated before Clerk.js initializes
3. This results in the slider not having the necessary product/category data to function

## Solution

The solution consists of two parts:

### 1. JavaScript Fix (`clerk-elementor-fix.js`)

This script:
- Waits for the DOM to be fully loaded
- Finds all Clerk elements with PHP shortcodes in data attributes
- Evaluates these shortcodes via AJAX
- Updates the data attributes with the actual values
- Re-initializes Clerk.js to process the updated elements

### 2. PHP Integration (`clerk-elementor-compatibility.php`)

This PHP file:
- Adds an AJAX handler for evaluating shortcodes
- Enqueues the compatibility script when Elementor is active
- Adds filters to process shortcodes in Elementor widgets
- Provides helper methods for getting product and category IDs

## Implementation

To implement this solution:

1. Add the `clerk-elementor-compatibility.php` file to the `includes` directory of the Clerk WooCommerce plugin
2. Add the `clerk-elementor-fix.js` file to the `assets/js` directory of the plugin
3. Include the compatibility file in the main plugin file:

```php
// In the main plugin file (clerk.php)
include_once 'includes/clerk-elementor-compatibility.php';
```

## How It Works

1. When a page is loaded with Elementor, the compatibility script is enqueued
2. The script finds all Clerk elements with shortcodes in their data attributes
3. It sends these shortcodes to the server via AJAX to be evaluated
4. The server evaluates the shortcodes and returns the actual values
5. The script updates the data attributes with these values
6. Clerk.js is re-initialized to process the updated elements

This ensures that the sliders have the correct product/category data before they are initialized, allowing them to function properly in Elementor pages.

## Benefits

- Works with both embed code and plugin-inserted sliders
- No need to modify existing templates or shortcodes
- Compatible with all Elementor widgets
- Minimal performance impact
- No changes required to Clerk.js core functionality

197 changes: 197 additions & 0 deletions solution/clerk-elementor-compatibility.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
<?php
/**
* Clerk.io Elementor Compatibility
*
* This file adds compatibility between Clerk.io and Elementor by ensuring
* that shortcodes in data attributes are properly processed.
*
* @package clerk-woocommerce
*/

if (!defined('ABSPATH')) {
exit; // Exit if accessed directly.
}

/**
* Clerk_Elementor_Compatibility Class
*/
class Clerk_Elementor_Compatibility {

/**
* Error and Warning Logger
*
* @var $logger Clerk_Logger
*/
protected $logger;

/**
* Constructor
*/
public function __construct() {
$this->init_hooks();
include_once __DIR__ . '/class-clerk-logger.php';
$this->logger = new Clerk_Logger();
}

/**
* Initialize hooks
*/
private function init_hooks() {
// Add AJAX handler for evaluating shortcodes
add_action('wp_ajax_clerk_evaluate_shortcode', array($this, 'evaluate_shortcode'));
add_action('wp_ajax_nopriv_clerk_evaluate_shortcode', array($this, 'evaluate_shortcode'));

// Enqueue the compatibility script
add_action('wp_enqueue_scripts', array($this, 'enqueue_compatibility_script'));

// Add support for Elementor widgets
add_action('elementor/frontend/after_enqueue_scripts', array($this, 'enqueue_compatibility_script'));

// Add filter to process shortcodes in Elementor HTML widget
add_filter('elementor/widget/render_content', array($this, 'process_elementor_widget_content'), 10, 2);
}

/**
* Enqueue the compatibility script
*/
public function enqueue_compatibility_script() {
// Only enqueue if Elementor is active
if (!did_action('elementor/loaded')) {
return;
}

$options = clerk_get_options();

// Only enqueue if Clerk.io is enabled
if (!isset($options['public_key']) || !$options['public_key']) {
return;
}

// Enqueue the script
wp_enqueue_script(
'clerk-elementor-compatibility',
plugins_url('assets/js/clerk-elementor-fix.js', dirname(__FILE__)),
array('jquery'),
'1.0.0',
true
);

// Localize the script with the AJAX URL
wp_localize_script(
'clerk-elementor-compatibility',
'clerk_elementor_compat',
array(
'ajax_url' => admin_url('admin-ajax.php'),
)
);
}

/**
* AJAX handler for evaluating shortcodes
*/
public function evaluate_shortcode() {
try {
// Get the shortcode from the request
$shortcode = isset($_POST['shortcode']) ? sanitize_text_field(wp_unslash($_POST['shortcode'])) : '';

if (empty($shortcode)) {
wp_send_json_error('No shortcode provided');
return;
}

// Process the shortcode
$result = do_shortcode($shortcode);

// Send the result
wp_send_json_success($result);
} catch (Exception $e) {
$this->logger->error('ERROR evaluate_shortcode', array('error' => $e->getMessage()));
wp_send_json_error($e->getMessage());
}

wp_die();
}

/**
* Process Elementor widget content to handle Clerk.io shortcodes
*
* @param string $widget_content The widget content.
* @param object $widget The widget instance.
* @return string The processed widget content.
*/
public function process_elementor_widget_content($widget_content, $widget) {
// Only process HTML widgets
if ('html' !== $widget->get_name()) {
return $widget_content;
}

// Process shortcodes in the widget content
$widget_content = do_shortcode($widget_content);

// Process data attributes with PHP code
$widget_content = $this->process_php_in_attributes($widget_content);

return $widget_content;
}

/**
* Process PHP code in HTML attributes
*
* @param string $content The HTML content.
* @return string The processed HTML content.
*/
private function process_php_in_attributes($content) {
// Use a regular expression to find data attributes with PHP code
$pattern = '/data-(products|categories)=["\'](.*?)\[\s*clerk_(?:product|category)_id\s*\](.*?)["\']/i';

// Replace the PHP code with the evaluated result
$content = preg_replace_callback($pattern, function($matches) {
$attribute = $matches[1];
$prefix = $matches[2];
$suffix = $matches[3];

// Get the appropriate ID based on the attribute
if ($attribute === 'products') {
$id = $this->get_product_id();
} else {
$id = $this->get_category_id();
}

// Return the attribute with the evaluated ID
return 'data-' . $attribute . '="' . $prefix . $id . $suffix . '"';
}, $content);

return $content;
}

/**
* Get the current product ID
*
* @return int|null The product ID or null if not on a product page.
*/
private function get_product_id() {
if (is_product()) {
return get_the_ID();
}

return null;
}

/**
* Get the current category ID
*
* @return int|null The category ID or null if not on a category page.
*/
private function get_category_id() {
if (is_product_category()) {
$category = get_queried_object();
return $category->term_id;
}

return null;
}
}

// Initialize the compatibility class
new Clerk_Elementor_Compatibility();

Loading