use Elementor\Element_Base;
use Elementor\Controls_Manager;
use Elementor\Plugin;
+use Elementor\Utils;
class Setup {
// Register widgets with Elementor
add_action('elementor/widgets/widgets_registered', [$this, 'register_widgets']);
+
+ $this->register_customisations();
}
public function register_widgets() {
$manager->add_category('cube', ['title' => 'Cubedesigners']);
}
+ public function register_customisations() {
+ $this->customise_sections();
+ }
+
+ public function customise_sections() {
+
+ // Layered Backgrounds - PHP (Frontend)
+ add_action('elementor/frontend/section/before_render', function (Element_Base $element) {
+ echo '<div class="layered-backgrounds-wrapper relative">';
+
+ $settings = $element->get_settings();
+
+ echo '<div class="layered-backgrounds absolute top-0 left-0 w-full h-full">';
+
+ foreach ($settings['layers'] as $index => $layer) {
+
+ $style = 'position: absolute;';
+
+ // Common styles
+ $keys = ['width', 'height', 'top', 'right', 'bottom', 'left']; // Which fields to use for styles
+ foreach ($keys as $key) {
+ if (empty($layer[$key])) continue; // Skip
+ $style .= "$key: {$layer[$key]};";
+ }
+
+ $z_index = 0 - $index - 1; // make z-index so layers stack based on original order
+ $style .= "z-index: $z_index;";
+
+ switch($layer['type']) {
+ case 'color':
+ $style .= "background-color: {$layer['color']};";
+ break;
+ case 'image':
+ $style .= "background:url('{$layer['image']['url']}') no-repeat;";
+ break;
+ }
+
+ echo '<div style="'. $style .'"></div>';
+
+ }
+
+ echo '</div>'; // .layered-backgrounds
+
+ });
+
+ // Layered Backgrounds - closing tag on frontend wrapper
+ add_action('elementor/frontend/section/after_render', function (Element_Base $element) {
+ echo '</div>'; // .layered-bg-wrapper
+ });
+
+ //-----------
+
+ // Layered Backgrounds - JS (Elementor Editor Template)
+ // NOTE: This should match the PHP template above as closely as possible but because Elementor
+ // doesn't support this properly, the structures are slightly different.
+ // Ref: https://github.com/elementor/elementor/issues/4092
+ add_action( 'elementor/section/print_template', function($template, $widget) {
+
+ // Unlike in the PHP version, we have to make a separate DIV here that doesn't wrap
+ // the .elementor-container (doing so causes JS errors in the editor due to overly
+ // specific CSS selectors for getting the element in the editor)
+ // The visual result should be the same as long as the background layer divs are just
+ // inside the highest section wrapper...
+
+ $res = '<div class="layered-backgrounds absolute top-0 left-0 w-full h-full">';
+
+ $res .= '<# _.each( settings.layers, function(layer, index) {
+
+ // Prepare style attribute, skipping any empty fields
+ let style = "position: absolute;";
+
+ _.each(["width", "height", "top", "right", "bottom", "left"], function(property) {
+ if (layer[property] == "") return;
+ style += `${property}: ${layer[property]};`;
+ });
+
+ let zIndex = 0 - index - 1;
+ style += `z-index: ${zIndex};`;
+
+ switch(layer.type) {
+ case "color":
+ style += `background-color: ${layer.color};`;
+ break;
+ case "image":
+ style += `background:url(${layer.image.url}) no-repeat;`;
+ break;
+ }
+ #>';
+
+ $res .= '<div style="{{ style }}"></div>';
+ $res .= '<# }); #>';
+
+ $res .= '</div>'; // .layered-backgrounds
+
+ return $res . $template;
+ }, 10, 2 );
+
+ // Add controls to Section element in Elementor editor
+ add_action('elementor/element/section/section_background/before_section_start', function(Element_Base $element, $args) {
+
+ // Background Overlay
+ $element->start_controls_section(
+ 'section_background_layers',
+ [
+ 'label' => __('Background Layers', 'cube'),
+ 'tab' => Controls_Manager::TAB_STYLE,
+ ]
+ );
+
+ $element->add_control(
+ 'layers',
+ [
+ 'label' => __( 'Background Layers', 'cube' ),
+ 'type' => Controls_Manager::REPEATER,
+ 'fields' => [
+ [
+ 'name' => 'type',
+ 'label' => __( 'Background Type', 'cube' ),
+ 'type' => Controls_Manager::SELECT,
+ 'options' => [
+ 'image' => __( 'Image', 'cube' ),
+ 'color' => __( 'Solid Colour', 'cube' ),
+ ],
+ 'default' => 'image',
+ ],
+ [
+ 'name' => 'image',
+ 'label' => __('Image', 'cube'),
+ 'label_block' => true,
+ 'type' => Controls_Manager::MEDIA,
+ 'default' => [
+ 'url' => Utils::get_placeholder_image_src(),
+ ],
+ 'condition' => [
+ 'type' => 'image',
+ ],
+ ],
+ [
+ 'name' => 'color',
+ 'label' => __('Colour', 'cube'),
+ 'type' => Controls_Manager::COLOR,
+ 'default' => '',
+ 'condition' => [
+ 'type' => 'color',
+ ],
+ ],
+ [
+ 'name' => 'width',
+ 'label' => __('Width', 'cube'),
+ 'type' => Controls_Manager::TEXT,
+ 'default' => '100%',
+ ],
+ [
+ 'name' => 'height',
+ 'label' => __('height', 'cube'),
+ 'type' => Controls_Manager::TEXT,
+ 'default' => '100%',
+ ],
+ [
+ 'name' => 'top',
+ 'label' => __('Top Offset', 'cube'),
+ 'type' => Controls_Manager::TEXT,
+ 'default' => '0',
+ ],
+ [
+ 'name' => 'left',
+ 'label' => __('Left Offset', 'cube'),
+ 'type' => Controls_Manager::TEXT,
+ 'default' => '0',
+ ],
+ [
+ 'name' => 'right',
+ 'label' => __('Right Offset', 'cube'),
+ 'type' => Controls_Manager::TEXT,
+ 'default' => '',
+ ],
+ [
+ 'name' => 'bottom',
+ 'label' => __('Bottom Offset', 'cube'),
+ 'type' => Controls_Manager::TEXT,
+ 'default' => '',
+ ],
+ ],
+ 'title_field' => '<# var title = (type == "image") ? "IMAGE: " + image.url.split("/").pop().split(".").shift() : "COLOUR: " + color; #>{{{ title }}}',
+ ]
+ );
+
+ $element->end_controls_section();
+
+ }, 10, 2);
+ }
+
}