For a client's website I'm using Elementor to build up the website. The client wants to show photo's of his projects in a Image Carousel.
For this I've created some code to add a meta box to the posts where the images can be added, also I've added a piece of code to create the dynamic tag which makes it possible to connect it to the Image Carousel.
I add the images, I add the dynamic tag, but no images are showing up. In a var_dump I do see the images added to the post.
My question is, what kind of data does the Image Carousel expect to be able to display the images in the carousel?
<?php
/**
* Theme functions and definitions.
*
* For additional information on potential customization options,
* read the developers' documentation:
*
* @package HelloBizChild
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
define( 'HELLO_BIZ_CHILD_VERSION', '1.0.0' );
/**
* Load child theme scripts & styles.
*
* @return void
*/
function hello_biz_child_scripts_styles() {
wp_enqueue_style(
'hello-biz-child-style',
get_stylesheet_directory_uri() . '/style.css',
[
'theme',
],
HELLO_BIZ_CHILD_VERSION
);
}
add_action( 'wp_enqueue_scripts', 'hello_biz_child_scripts_styles', 20 );
/******************************************************** CUSTOM PHP ******************************************************/
// Voeg een meta box toe alleen aan berichten in de categorie 'project'
add_action('add_meta_boxes', function() {
global $post;
if ($post && has_category('project', $post)) {
add_meta_box(
'project_images_box',
'Project Afbeeldingen',
'project_images_meta_box_callback',
'post',
'normal',
'high'
);
}
});
function project_images_meta_box_callback($post) {
$images = get_post_meta($post->ID, '_project_images', true) ?: [];
wp_nonce_field('save_project_images', 'project_images_nonce');
?>
<div id="project-images-container">
<ul id="project-images-list">
<?php foreach ($images as $image_id): ?>
<li style="margin-bottom:8px;">
<?php echo wp_get_attachment_image($image_id, 'thumbnail'); ?>
<input type="hidden" name="project_images[]" value="<?php echo esc_attr($image_id); ?>">
</li>
<?php endforeach; ?>
</ul>
<button type="button" class="button" id="add-project-image">+ Afbeelding toevoegen</button>
</div>
<script>
jQuery(document).ready(function($){
var frame;
$('#add-project-image').on('click', function(e){
e.preventDefault();
if(frame){ frame.open(); return; }
frame = wp.media({
title: 'Selecteer afbeeldingen',
button: { text: 'Gebruik deze afbeeldingen' },
multiple: true
});
frame.on('select', function(){
var attachments = frame.state().get('selection').toJSON();
attachments.forEach(function(attachment){
$('#project-images-list').append(
'<li style="margin-bottom:8px;">' +
'<img src="'+attachment.sizes.thumbnail.url+'" style="max-width:100px;"/>' +
'<input type="hidden" name="project_images[]" value="'+attachment.id+'">' +
'</li>'
);
});
});
frame.open();
});
});
</script>
<?php
}
// Sla de afbeeldingen op
add_action('save_post', function($post_id){
if (!isset($_POST['project_images_nonce']) || !wp_verify_nonce($_POST['project_images_nonce'], 'save_project_images')) return;
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
$images = isset($_POST['project_images']) ? array_map('intval', $_POST['project_images']) : [];
update_post_meta($post_id, '_project_images', $images);
});
// Elementor Dynamic Tag registreren
add_action('elementor/dynamic_tags/register', function($dynamic_tags) {
$dynamic_tags->register(new \Project_Images_Tag());
});
// Dynamic tag class
/**
* Project images dynamic tag - robust version
* Paste into functions.php
*/
if ( did_action( 'elementor/loaded' ) ) {
add_action('elementor/dynamic_tags/register', function($dynamic_tags) {
$dynamic_tags->register( new Project_Images_Tag() );
});
}
/**
* Dynamic Tag Class
*/
if (!class_exists('Project_Images_Tag')) {
class Project_Images_Tag extends \Elementor\Core\DynamicTags\Tag {
public function get_name() {
return 'project-images';
}
public function get_title() {
return 'Project Afbeeldingen (custom)';
}
public function get_group() {
return 'site';
}
public function get_categories() {
// probeer meerdere constants / fallbacks
if ( defined('\Elementor\Modules\DynamicTags\Module::GALLERY_CATEGORY') ) {
return [ \Elementor\Modules\DynamicTags\Module::GALLERY_CATEGORY ];
} elseif ( defined('\Elementor\Modules\DynamicTags\Module::IMAGE_CATEGORY') ) {
return [ \Elementor\Modules\DynamicTags\Module::IMAGE_CATEGORY ];
} elseif ( defined('\Elementor\Modules\DynamicTags\Module::IMAGE_GALLERY_CATEGORY') ) {
return [ \Elementor\Modules\DynamicTags\Module::IMAGE_GALLERY_CATEGORY ];
} else {
return [ 'image' ];
}
}
protected function register_controls() {}
/**
* Elementor calls get_value() to retrieve data.
* We return multiple possible formats via a single array, but main returned value is an array of associative arrays.
*/
public function get_value( array $options = [] ) {
$post_id = get_the_ID();
if ( ! $post_id ) {
return [];
}
$images = get_post_meta( $post_id, '_project_images', true );
if ( empty( $images ) || ! is_array( $images ) ) {
return [];
}
// Normaliseer IDs
$images = array_map( 'intval', $images );
$gallery_assoc = [];
foreach ( $images as $image_id ) {
$full = wp_get_attachment_image_url( $image_id, 'full' );
$thumb = wp_get_attachment_image_url( $image_id, 'thumbnail' );
$alt = get_post_meta( $image_id, '_wp_attachment_image_alt', true );
$title = get_the_title( $image_id );
$caption = wp_get_attachment_caption( $image_id );
$gallery_assoc[] = [
'id' => $image_id,
'url' => $full ?: $thumb,
'thumb' => $thumb,
'alt' => $alt,
'title' => $title,
'caption' => $caption,
];
}
// Return een array van associative arrays — dit is de meest expliciete vorm
// (sommige Elementor-widgets accepteren ook array van ints of CSV van IDs)
// Maar we geven ook die extra vormen via keys, zodat debuggen makkelijker is.
return $gallery_assoc;
}
/**
* Fallback render: als widget direct render() opvraagt, toon niks (of commentaar)
*/
public function render() {
// geen echo: widget zal get_value() gebruiken.
// Houd render kort als fallback (komt zelden voor).
return;
}
}
}
add_action('wp_footer', function() {
if (is_single()) {
$meta = get_post_meta(get_the_ID(), '_project_images', true);
echo '<pre style="background:#111;color:#0f0;padding:10px;">';
var_dump($meta);
echo '</pre>';
}
});
I've contacted Elementor about this, but nobody wants/is able to answer this question, so I'm hoping someone here can.
Thanks in advance!