WPBakery Multiple Image Element
December 16, 2024 · AI Conversations
### Step 1: Create a Custom WPBakery Shortcode
1. **Add the following code to your theme's `functions.php` file** or create a custom plugin:
function vc_image_content_shortcode($atts, $content = null) {
$atts = shortcode_atts(array(
'images' => '', // A comma-separated list of image IDs
), $atts);
$image_ids = explode(',', $atts['images']);
$output = '<div class="vc-image-content">';
foreach ($image_ids as $id) {
$image_url = wp_get_attachment_image_src(trim($id), 'full');
if ($image_url) {
$output .= '<div class="vc-image-content-item">';
$output .= '<img src="' . esc_url($image_url[0]) . '" alt="" />';
$output .= '<div class="vc-image-content-text">' . do_shortcode($content) . '</div>';
$output .= '</div>';
}
}
$output .= '</div>';
return $output;
}
// Register the shortcode with WPBakery
function vc_image_content_shortcode_vc() {
vc_map(array(
'name' => __('Image and Content', 'text-domain'),
'base' => 'vc_image_content',
'category' => __('Custom Elements', 'text-domain'),
'params' => array(
array(
'type' => 'attach_images',
'heading' => __('Select Images', 'text-domain'),
'param_name' => 'images',
'description' => __('Select multiple images from media library.', 'text-domain'),
'admin_label' => true,
),
array(
'type' => 'textarea_html',
'heading' => __('Content', 'text-domain'),
'param_name' => 'content',
'description' => __('Content to display under each image.', 'text-domain'),
),
),
));
}
add_action('vc_before_init', 'vc_image_content_shortcode_vc');
add_shortcode('vc_image_content', 'vc_image_content_shortcode');
### Step 2: Style the Output (Optional)
You can add some custom CSS to style the output of your images and content. Add the following CSS to your theme's `style.css` or a custom CSS file:
.vc-image-content {
display: flex;
flex-wrap: wrap;
gap: 20px; /* Space between items */
}
.vc-image-content-item {
flex: 1 1 calc(33.333% - 20px); /* Adjust to desired width */
box-sizing: border-box;
}
.vc-image-content-item img {
max-width: 100%;
height: auto;
}
.vc-image-content-text {
margin-top: 10px;
text-align: center; /* Center content below images */
}
### Step 3: Use the Custom Element in WPBakery
1. In your WordPress dashboard, go to a page or post where you want to use this new element.
2. Click on the WPBakery Page Builder button to edit the content.
3. Add the "Image and Content" element to your layout.
4. Select multiple images from the media library and add the content you want to display below each image.
### Step 4: Save and Preview
Save your changes and preview the page to see your new custom element in action.
### Note
– Adjust the CSS styles as needed to fit your theme's design.
– Make sure to replace `'text-domain'` with your theme or plugin's actual text domain.
This setup allows you to add multiple images with accompanying content easily. Let me know if you need further modifications or assistance!
### Step 1: Create a Custom WPBakery Shortcode
1. **Add the following code to your theme's `functions.php` file** or create a custom plugin:
function vc_multiple_images_content_shortcode($atts, $content = null) {
// Extract attributes
$atts = shortcode_atts(array(
'items' => '', // A serialized array of image-content pairs
), $atts);
$items = maybe_unserialize($atts['items']);
$output = '<div class="vc-multiple-images-content">';
if (is_array($items)) {
foreach ($items as $item) {
$image_url = wp_get_attachment_image_src(trim($item['image']), 'full');
if ($image_url) {
$output .= '<div class="vc-multiple-images-content-item">';
$output .= '<img src="' . esc_url($image_url[0]) . '" alt="" />';
$output .= '<div class="vc-multiple-images-content-text">' . wp_kses_post($item['content']) . '</div>';
$output .= '</div>';
}
}
}
$output .= '</div>';
return $output;
}
// Register the shortcode with WPBakery
function vc_multiple_images_content_shortcode_vc() {
vc_map(array(
'name' => __('Multiple Images with Content', 'text-domain'),
'base' => 'vc_multiple_images_content',
'category' => __('Custom Elements', 'text-domain'),
'params' => array(
array(
'type' => 'param_group',
'heading' => __('Image and Content Items', 'text-domain'),
'param_name' => 'items',
'value' => '',
'params' => array(
array(
'type' => 'attach_image',
'heading' => __('Image', 'text-domain'),
'param_name' => 'image',
'description' => __('Select an image from media library.', 'text-domain'),
'admin_label' => true,
),
array(
'type' => 'textarea_html',
'heading' => __('Content', 'text-domain'),
'param_name' => 'content',
'description' => __('Content to display under the image.', 'text-domain'),
),
),
),
),
));
}
add_action('vc_before_init', 'vc_multiple_images_content_shortcode_vc');
add_shortcode('vc_multiple_images_content', 'vc_multiple_images_content_shortcode');
### Step 2: Style the Output (Optional)
Add custom CSS to your theme’s `style.css` or a custom CSS file to style the output of the images and content:
.vc-multiple-images-content {
display: flex;
flex-wrap: wrap;
gap: 20px; /* Space between items */
}
.vc-multiple-images-content-item {
flex: 1 1 calc(33.333% - 20px); /* Adjust width as needed */
box-sizing: border-box;
}
.vc-multiple-images-content-item img {
max-width: 100%;
height: auto;
}
.vc-multiple-images-content-text {
margin-top: 10px;
text-align: center; /* Center content below images */
}
### Step 3: Use the Custom Element in WPBakery
1. In your WordPress dashboard, go to a page or post where you want to use this new element.
2. Click on the WPBakery Page Builder button to edit the content.
3. Add the "Multiple Images with Content" element to your layout.
4. Use the `Add Item` button to add multiple image-content pairs:
– Select an image from the media library.
– Add the content you want to display below each image.
5. Save your changes.
### Step 4: Save and Preview
After saving, preview your page to see your new custom element in action. The element should now display multiple images, each with its associated content.
### Note
– Adjust the CSS styles as needed to fit your theme's design.
– Make sure to replace `'text-domain'` with your theme or plugin's actual text domain.
This setup allows users to easily add multiple images, each with their content, directly through the WPBakery Page Builder interface. Let me know if you need any further adjustments or assistance!
### Step-by-Step Fix
1. **Ensure Proper Data Serialization**: When using `param_group`, the data needs to be serialized properly when passing it to the shortcode. We need to make sure that the data is correctly handled within the shortcode function.
2. **Debugging the Output**: To see if the data is being passed correctly, we can add some debugging output. We’ll also ensure that we properly unserialize the input data.
### Updated Code
Here’s the revised code for your custom WPBakery element:
function vc_multiple_images_content_shortcode($atts, $content = null) {
// Extract attributes
$atts = shortcode_atts(array(
'items' => '', // A serialized array of image-content pairs
), $atts);
// Check if 'items' is set and unserialize it
$items = isset($atts['items']) ? vc_param_group_parse_atts($atts['items']) : array();
$output = '<div class="vc-multiple-images-content">';
if (is_array($items) && !empty($items)) {
foreach ($items as $item) {
if (!empty($item['image'])) {
$image_url = wp_get_attachment_image_src(trim($item['image']), 'full');
if ($image_url) {
$output .= '<div class="vc-multiple-images-content-item">';
$output .= '<img src="' . esc_url($image_url[0]) . '" alt="" />';
$output .= '<div class="vc-multiple-images-content-text">' . wp_kses_post($item['content']) . '</div>';
$output .= '</div>';
}
}
}
}
$output .= '</div>';
return $output;
}
// Register the shortcode with WPBakery
function vc_multiple_images_content_shortcode_vc() {
vc_map(array(
'name' => __('Multiple Images with Content', 'text-domain'),
'base' => 'vc_multiple_images_content',
'category' => __('Custom Elements', 'text-domain'),
'params' => array(
array(
'type' => 'param_group',
'heading' => __('Image and Content Items', 'text-domain'),
'param_name' => 'items',
'value' => '',
'params' => array(
array(
'type' => 'attach_image',
'heading' => __('Image', 'text-domain'),
'param_name' => 'image',
'description' => __('Select an image from media library.', 'text-domain'),
'admin_label' => true,
),
array(
'type' => 'textarea_html',
'heading' => __('Content', 'text-domain'),
'param_name' => 'content',
'description' => __('Content to display under the image.', 'text-domain'),
),
),
),
),
));
}
add_action('vc_before_init', 'vc_multiple_images_content_shortcode_vc');
add_shortcode('vc_multiple_images_content', 'vc_multiple_images_content_shortcode');
### Key Changes Made:
– **Data Parsing**: Used `vc_param_group_parse_atts` to correctly parse the `items` array.
– **Check for Empty Values**: Added checks to ensure that both `image` and `content` are present before generating output.
### Step 3: Test the Changes
1. **Clear Caches**: If you have any caching plugins, clear their caches.
2. **Update the Element**: Edit your WPBakery element on the page where you used it and ensure the images and content are correctly set.
3. **Preview the Page**: Check the front end to see if the custom element displays correctly.
### Debugging
If it still does not work:
– **Inspect the HTML Output**: View the page source and check if the shortcode is outputting any HTML.
– **Check for Errors**: Use the browser's console (F12) to look for JavaScript errors that might prevent the proper rendering of the page.
– **Enable Debugging**: If needed, enable debugging in WordPress by adding the following lines to your `wp-config.php`:
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);
After trying the above steps, let me know if you're still experiencing issues, and I can help troubleshoot further!
To fix this issue, you can follow these steps:
### Step 1: Change the `textarea_html` Field Type
Instead of using `textarea_html`, which is typically used for rich text areas in WPBakery, you can use a simple `textarea` field. If you still want rich text functionality, you will need to handle it differently.
Here’s how you can adjust the code:
### Updated Code
function vc_multiple_images_content_shortcode($atts, $content = null) {
// Extract attributes
$atts = shortcode_atts(array(
'items' => '', // A serialized array of image-content pairs
), $atts);
// Check if 'items' is set and unserialize it
$items = isset($atts['items']) ? vc_param_group_parse_atts($atts['items']) : array();
$output = '<div class="vc-multiple-images-content">';
if (is_array($items) && !empty($items)) {
foreach ($items as $item) {
if (!empty($item['image'])) {
$image_url = wp_get_attachment_image_src(trim($item['image']), 'full');
if ($image_url) {
$output .= '<div class="vc-multiple-images-content-item">';
$output .= '<img src="' . esc_url($image_url[0]) . '" alt="" />';
$output .= '<div class="vc-multiple-images-content-text">' . wp_kses_post($item['content']) . '</div>';
$output .= '</div>';
}
}
}
}
$output .= '</div>';
return $output;
}
// Register the shortcode with WPBakery
function vc_multiple_images_content_shortcode_vc() {
vc_map(array(
'name' => __('Multiple Images with Content', 'text-domain'),
'base' => 'vc_multiple_images_content',
'category' => __('Custom Elements', 'text-domain'),
'params' => array(
array(
'type' => 'param_group',
'heading' => __('Image and Content Items', 'text-domain'),
'param_name' => 'items',
'value' => '',
'params' => array(
array(
'type' => 'attach_image',
'heading' => __('Image', 'text-domain'),
'param_name' => 'image',
'description' => __('Select an image from media library.', 'text-domain'),
'admin_label' => true,
),
array(
'type' => 'textarea',
'heading' => __('Content', 'text-domain'),
'param_name' => 'content',
'description' => __('Content to display under the image.', 'text-domain'),
),
),
),
),
));
}
add_action('vc_before_init', 'vc_multiple_images_content_shortcode_vc');
add_shortcode('vc_multiple_images_content', 'vc_multiple_images_content_shortcode');
### Step 2: Use a Custom TinyMCE Field (Optional)
If you need the rich text editor functionality, you can use a `textarea` but still ensure the editor is initialized. Here's how to do it:
1. Change the `type` from `textarea_html` to `textarea` in the `vc_map` parameters.
2. Add a custom JavaScript file to reinitialize TinyMCE for the newly added text areas.
### Step 3: Enqueue Custom JavaScript
To reinitialize TinyMCE on the textarea when new items are added, you can enqueue a script in your functions.php:
function custom_enqueue_vc_scripts() {
if (is_admin()) {
wp_enqueue_script('custom-vc-tinymce', get_template_directory_uri() . '/path/to/your/custom-vc-tinymce.js', array('jquery'), null, true);
}
}
add_action('admin_enqueue_scripts', 'custom_enqueue_vc_scripts');
### Step 4: Create `custom-vc-tinymce.js`
Create the JavaScript file (`custom-vc-tinymce.js`) and add the following code:
jQuery(document).ready(function($) {
$(document).on('click', '.add-param-group-item', function() {
// Reinitialize TinyMCE for newly added textarea
tinymce.init({
selector: 'textarea',
menubar: false,
toolbar: 'bold italic | alignleft aligncenter alignright | bullist numlist outdent indent | link image',
// Add other TinyMCE settings as needed
});
});
});
### Summary
1. Change the `textarea_html` to `textarea` in the `vc_map`.
2. Optionally, enqueue a custom JavaScript file to reinitialize TinyMCE for dynamically added text areas.
### Step 5: Test Again
After making these changes, test the WPBakery element again:
1. Click "Add Item" and check if the editor toolbar shows up for the new text area.
2. Save and preview the changes to see if everything is working correctly.
Let me know if you have any further questions or if you encounter any issues!