PluginProbe
Easy Elements for Elementor – Addons & Website Templates / 1.5.0
Easy Elements for Elementor – Addons & Website Templates v1.5.0
1.5.3 1.5.2 1.5.1 1.5.0 1.4.9 1.4.6 1.4.7 1.4.8 1.4.5 1.4.4 1.4.3 1.2.7 1.2.8 1.2.9 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 All 47 releases
easy-elements / widgets / post-content / post-content.php

post-content.php in Easy Elements for Elementor – Addons & Website Templates 1.5.0, at widgets/post-content/post-content.php

797 lines 25.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Easyel\EasyElements\Widgets;
3 use Elementor\Controls_Manager;
4 use Elementor\Widget_Base;
5
6 if ( ! defined( 'ABSPATH' ) ) {
7 exit;
8 }
9
10 class Easyel_Free_Post_content_Widget extends \Elementor\Widget_Base {
11
12 public function get_name() {
13 return 'eel-post-content';
14 }
15
16 public function get_title() {
17 return __( 'Post Content', 'easy-elements' );
18 }
19
20 public function get_icon() {
21 return 'easyicon easyelIcon-post-content';
22 }
23
24 public function get_categories() {
25 return [ 'easyelements_category' ];
26 }
27
28 public function get_keywords() {
29 return [ 'post', 'content', 'link', 'click', 'text' ];
30 }
31
32 public function get_style_depends() {
33 // Keep this list minimal: Elementor enqueues these AFTER theme CSS in the
34 // preview iframe, so any heading/typography handle here will override the
35 // active theme (e.g. wp-block-library-theme sets h2/h3 sizes that win and
36 // make Gutenberg headings look tiny in the preview). Block library CSS is
37 // force-enqueued earlier instead — see the wp_enqueue_scripts hook at the
38 // bottom of this file (priority 1, runs before theme at priority 10).
39 return [
40 'eel-post-content',
41 ];
42 }
43
44
45 protected function register_controls() {
46
47 $this->start_controls_section(
48 'content_section',
49 [
50 'label' => esc_html__('Content Style', 'easy-elements'),
51 'tab' => Controls_Manager::TAB_CONTENT,
52 ]
53 );
54
55 $this->add_control(
56 'content_color',
57 [
58 'label' => esc_html__('Color', 'easy-elements'),
59 'type' => Controls_Manager::COLOR,
60 'selectors' => [
61 '{{WRAPPER}} .eel-post-content' => 'color: {{VALUE}};',
62 ],
63 ]
64 );
65
66 $this->add_group_control(
67 \Elementor\Group_Control_Typography::get_type(),
68 [
69 'name' => 'content_typography',
70 'selector' => '{{WRAPPER}} .eel-post-content',
71 ]
72 );
73
74 $this->add_control(
75 'global_heading',
76 [
77 'label' => esc_html__( 'Global Heading', 'easy-elements' ),
78 'type' => \Elementor\Controls_Manager::HEADING,
79 'separator' => 'after',
80 ]
81 );
82
83 $this->add_control(
84 'global_color',
85 [
86 'label' => esc_html__('Color', 'easy-elements'),
87 'type' => Controls_Manager::COLOR,
88 'selectors' => [
89 '{{WRAPPER}} .eel-post-content h1, {{WRAPPER}} .eel-post-content h2, {{WRAPPER}} .eel-post-content h3, {{WRAPPER}} .eel-post-content h4, {{WRAPPER}} .eel-post-content h5, {{WRAPPER}} .eel-post-content h6' => 'color: {{VALUE}};',
90 ],
91 ]
92 );
93
94 $this->add_group_control(
95 \Elementor\Group_Control_Typography::get_type(),
96 [
97 'name' => 'global_typography',
98 'selector' => '{{WRAPPER}} .eel-post-content h1, {{WRAPPER}} .eel-post-content h2, {{WRAPPER}} .eel-post-content h3, {{WRAPPER}} .eel-post-content h4, {{WRAPPER}} .eel-post-content h5, {{WRAPPER}} .eel-post-content h6',
99 ]
100 );
101
102 $this->add_responsive_control(
103 'global_margin',
104 [
105 'label' => __( 'Margin', 'easy-elements' ),
106 'type' => \Elementor\Controls_Manager::DIMENSIONS,
107 'size_units' => [ 'px', 'em', '%' ],
108 'selectors' => [
109 '{{WRAPPER}} .eel-post-content h1, {{WRAPPER}} .eel-post-content h2, {{WRAPPER}} .eel-post-content h3, {{WRAPPER}} .eel-post-content h4, {{WRAPPER}} .eel-post-content h5, {{WRAPPER}} .eel-post-content h6' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
110 ],
111 ]
112 );
113
114 $this->add_control(
115 'strong_heading',
116 [
117 'label' => esc_html__( 'Strong Style', 'easy-elements' ),
118 'type' => \Elementor\Controls_Manager::HEADING,
119 'separator' => 'after',
120 ]
121 );
122
123 $this->add_control(
124 'strong_color',
125 [
126 'label' => esc_html__('Color', 'easy-elements'),
127 'type' => Controls_Manager::COLOR,
128 'selectors' => [
129 '{{WRAPPER}} .eel-post-content strong' => 'color: {{VALUE}};',
130 ],
131 ]
132 );
133
134 $this->add_group_control(
135 \Elementor\Group_Control_Typography::get_type(),
136 [
137 'name' => 'strong_typography',
138 'selector' => '{{WRAPPER}} .eel-post-content strong',
139 ]
140 );
141
142 $this->add_control(
143 'link_heading',
144 [
145 'label' => esc_html__( 'Link Style', 'easy-elements' ),
146 'type' => \Elementor\Controls_Manager::HEADING,
147 'separator' => 'after',
148 ]
149 );
150
151 $this->add_control(
152 'link_color',
153 [
154 'label' => esc_html__('Color', 'easy-elements'),
155 'type' => Controls_Manager::COLOR,
156 'selectors' => [
157 '{{WRAPPER}} .eel-post-content a' => 'color: {{VALUE}};',
158 ],
159 ]
160 );
161
162 $this->add_group_control(
163 \Elementor\Group_Control_Typography::get_type(),
164 [
165 'name' => 'link_typography',
166 'selector' => '{{WRAPPER}} .eel-post-content a',
167 ]
168 );
169
170 $this->end_controls_section();
171
172 $this->start_controls_section(
173 'content_section_heading',
174 [
175 'label' => esc_html__('Heading Style', 'easy-elements'),
176 'tab' => Controls_Manager::TAB_CONTENT,
177 ]
178 );
179
180 $this->add_control(
181 'h1_heading',
182 [
183 'label' => esc_html__( 'H1 Heading', 'easy-elements' ),
184 'type' => \Elementor\Controls_Manager::HEADING,
185 ]
186 );
187
188 $this->add_control(
189 'h1_color',
190 [
191 'label' => esc_html__('Color', 'easy-elements'),
192 'type' => Controls_Manager::COLOR,
193 'selectors' => [
194 '{{WRAPPER}} .eel-post-content h1' => 'color: {{VALUE}};',
195 ],
196 ]
197 );
198
199 $this->add_group_control(
200 \Elementor\Group_Control_Typography::get_type(),
201 [
202 'name' => 'h1_typography',
203 'selector' => '{{WRAPPER}} .eel-post-content h1',
204 ]
205 );
206
207 $this->add_responsive_control(
208 'h1_margin',
209 [
210 'label' => __( 'Margin', 'easy-elements' ),
211 'type' => \Elementor\Controls_Manager::DIMENSIONS,
212 'size_units' => [ 'px', 'em', '%' ],
213 'selectors' => [
214 '{{WRAPPER}} .eel-post-content h1' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
215 ],
216 ]
217 );
218
219 $this->add_control(
220 'h2_heading',
221 [
222 'label' => esc_html__( 'H2 Heading', 'easy-elements' ),
223 'type' => \Elementor\Controls_Manager::HEADING,
224 ]
225 );
226
227 $this->add_control(
228 'h2_color',
229 [
230 'label' => esc_html__('Color', 'easy-elements'),
231 'type' => Controls_Manager::COLOR,
232 'selectors' => [
233 '{{WRAPPER}} .eel-post-content h2' => 'color: {{VALUE}};',
234 ],
235 ]
236 );
237
238 $this->add_group_control(
239 \Elementor\Group_Control_Typography::get_type(),
240 [
241 'name' => 'h2_typography',
242 'selector' => '{{WRAPPER}} .eel-post-content h2',
243 ]
244 );
245
246 $this->add_responsive_control(
247 'h2_margin',
248 [
249 'label' => __( 'Margin', 'easy-elements' ),
250 'type' => \Elementor\Controls_Manager::DIMENSIONS,
251 'size_units' => [ 'px', 'em', '%' ],
252 'selectors' => [
253 '{{WRAPPER}} .eel-post-content h2' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
254 ],
255 ]
256 );
257
258 $this->add_control(
259 'h3_heading',
260 [
261 'label' => esc_html__( 'H3 Heading', 'easy-elements' ),
262 'type' => \Elementor\Controls_Manager::HEADING,
263 ]
264 );
265
266 $this->add_control(
267 'h3_color',
268 [
269 'label' => esc_html__('Color', 'easy-elements'),
270 'type' => Controls_Manager::COLOR,
271 'selectors' => [
272 '{{WRAPPER}} .eel-post-content h3' => 'color: {{VALUE}};',
273 ],
274 ]
275 );
276
277 $this->add_group_control(
278 \Elementor\Group_Control_Typography::get_type(),
279 [
280 'name' => 'h3_typography',
281 'selector' => '{{WRAPPER}} .eel-post-content h3',
282 ]
283 );
284
285 $this->add_responsive_control(
286 'h3_margin',
287 [
288 'label' => __( 'Margin', 'easy-elements' ),
289 'type' => \Elementor\Controls_Manager::DIMENSIONS,
290 'size_units' => [ 'px', 'em', '%' ],
291 'selectors' => [
292 '{{WRAPPER}} .eel-post-content h3' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
293 ],
294 ]
295 );
296
297 $this->add_control(
298 'h4_heading',
299 [
300 'label' => esc_html__( 'H4 Heading', 'easy-elements' ),
301 'type' => \Elementor\Controls_Manager::HEADING,
302 ]
303 );
304
305 $this->add_control(
306 'h4_color',
307 [
308 'label' => esc_html__('Color', 'easy-elements'),
309 'type' => Controls_Manager::COLOR,
310 'selectors' => [
311 '{{WRAPPER}} .eel-post-content h4' => 'color: {{VALUE}};',
312 ],
313 ]
314 );
315
316 $this->add_group_control(
317 \Elementor\Group_Control_Typography::get_type(),
318 [
319 'name' => 'h4_typography',
320 'selector' => '{{WRAPPER}} .eel-post-content h4',
321 ]
322 );
323
324 $this->add_responsive_control(
325 'h4_margin',
326 [
327 'label' => __( 'Margin', 'easy-elements' ),
328 'type' => \Elementor\Controls_Manager::DIMENSIONS,
329 'size_units' => [ 'px', 'em', '%' ],
330 'selectors' => [
331 '{{WRAPPER}} .eel-post-content h4' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
332 ],
333 ]
334 );
335
336 $this->add_control(
337 'h5_heading',
338 [
339 'label' => esc_html__( 'H5 Heading', 'easy-elements' ),
340 'type' => \Elementor\Controls_Manager::HEADING,
341 ]
342 );
343
344 $this->add_control(
345 'h5_color',
346 [
347 'label' => esc_html__('Color', 'easy-elements'),
348 'type' => Controls_Manager::COLOR,
349 'selectors' => [
350 '{{WRAPPER}} .eel-post-content h5' => 'color: {{VALUE}};',
351 ],
352 ]
353 );
354
355 $this->add_group_control(
356 \Elementor\Group_Control_Typography::get_type(),
357 [
358 'name' => 'h5_typography',
359 'selector' => '{{WRAPPER}} .eel-post-content h5',
360 ]
361 );
362
363 $this->add_responsive_control(
364 'h5_margin',
365 [
366 'label' => __( 'Margin', 'easy-elements' ),
367 'type' => \Elementor\Controls_Manager::DIMENSIONS,
368 'size_units' => [ 'px', 'em', '%' ],
369 'selectors' => [
370 '{{WRAPPER}} .eel-post-content h5' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
371 ],
372 ]
373 );
374
375 $this->add_control(
376 'h6_heading',
377 [
378 'label' => esc_html__( 'H6 Heading', 'easy-elements' ),
379 'type' => \Elementor\Controls_Manager::HEADING,
380 'separator' => 'after',
381 ]
382 );
383
384 $this->add_control(
385 'h6_color',
386 [
387 'label' => esc_html__('Color', 'easy-elements'),
388 'type' => Controls_Manager::COLOR,
389 'selectors' => [
390 '{{WRAPPER}} .eel-post-content h6' => 'color: {{VALUE}};',
391 ],
392 ]
393 );
394
395 $this->add_group_control(
396 \Elementor\Group_Control_Typography::get_type(),
397 [
398 'name' => 'h6_typography',
399 'selector' => '{{WRAPPER}} .eel-post-content h6',
400 ]
401 );
402
403 $this->add_responsive_control(
404 'h6_margin',
405 [
406 'label' => __( 'Margin', 'easy-elements' ),
407 'type' => \Elementor\Controls_Manager::DIMENSIONS,
408 'size_units' => [ 'px', 'em', '%' ],
409 'selectors' => [
410 '{{WRAPPER}} .eel-post-content h6' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
411 ],
412 ]
413 );
414
415 $this->end_controls_section();
416
417 $this->start_controls_section(
418 'ul_content_section',
419 [
420 'label' => esc_html__('Others Style', 'easy-elements'),
421 'tab' => Controls_Manager::TAB_CONTENT,
422 ]
423 );
424
425 $this->add_control(
426 'ul_heading',
427 [
428 'label' => esc_html__( 'UL Style', 'easy-elements' ),
429 'type' => \Elementor\Controls_Manager::HEADING,
430 'separator' => 'after',
431 ]
432 );
433 $this->add_control(
434 'ul_color',
435 [
436 'label' => esc_html__('Color', 'easy-elements'),
437 'type' => Controls_Manager::COLOR,
438 'selectors' => [
439 '{{WRAPPER}} .eel-post-content ul' => 'color: {{VALUE}};',
440 ],
441 ]
442 );
443
444 $this->add_group_control(
445 \Elementor\Group_Control_Typography::get_type(),
446 [
447 'name' => 'ul_typography',
448 'selector' => '{{WRAPPER}} .eel-post-content ul',
449 ]
450 );
451
452 $this->add_responsive_control(
453 'ul_margin',
454 [
455 'label' => __( 'Margin', 'easy-elements' ),
456 'type' => \Elementor\Controls_Manager::DIMENSIONS,
457 'size_units' => [ 'px', 'em', '%' ],
458 'selectors' => [
459 '{{WRAPPER}} .eel-post-content ul' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
460 ],
461 ]
462 );
463
464 $this->add_responsive_control(
465 'ul_padding',
466 [
467 'label' => __( 'Padding', 'easy-elements' ),
468 'type' => \Elementor\Controls_Manager::DIMENSIONS,
469 'size_units' => [ 'px', 'em', '%' ],
470 'selectors' => [
471 '{{WRAPPER}} .eel-post-content ul' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
472 ],
473 ]
474 );
475
476 $this->add_control(
477 'li_heading',
478 [
479 'label' => esc_html__( 'LI Style', 'easy-elements' ),
480 'type' => \Elementor\Controls_Manager::HEADING,
481 'separator' => 'after',
482 ]
483 );
484
485 $this->add_responsive_control(
486 'li_margin',
487 [
488 'label' => __( 'Margin', 'easy-elements' ),
489 'type' => \Elementor\Controls_Manager::DIMENSIONS,
490 'size_units' => [ 'px', 'em', '%' ],
491 'selectors' => [
492 '{{WRAPPER}} .eel-post-content ul > li' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
493 ],
494 ]
495 );
496
497 $this->add_responsive_control(
498 'li_padding',
499 [
500 'label' => __( 'Padding', 'easy-elements' ),
501 'type' => \Elementor\Controls_Manager::DIMENSIONS,
502 'size_units' => [ 'px', 'em', '%' ],
503 'selectors' => [
504 '{{WRAPPER}} .eel-post-content ul > li' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
505 ],
506 ]
507 );
508
509 $this->add_control(
510 'p_heading',
511 [
512 'label' => esc_html__( 'Paragraph Style', 'easy-elements' ),
513 'type' => \Elementor\Controls_Manager::HEADING,
514 'separator' => 'after',
515 ]
516 );
517
518 $this->add_responsive_control(
519 'p__margin',
520 [
521 'label' => __( 'Margin', 'easy-elements' ),
522 'type' => \Elementor\Controls_Manager::DIMENSIONS,
523 'size_units' => [ 'px', 'em', '%' ],
524 'selectors' => [
525 '{{WRAPPER}} .eel-post-content p' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
526 ],
527 ]
528 );
529
530 $this->add_control(
531 'p_img_heading',
532 [
533 'label' => esc_html__( 'Paragraph Image Style', 'easy-elements' ),
534 'type' => \Elementor\Controls_Manager::HEADING,
535 'separator' => 'after',
536 ]
537 );
538
539 $this->add_responsive_control(
540 'p_image_margin',
541 [
542 'label' => __( 'Margin', 'easy-elements' ),
543 'type' => \Elementor\Controls_Manager::DIMENSIONS,
544 'size_units' => [ 'px', 'em', '%' ],
545 'selectors' => [
546 '{{WRAPPER}} .eel-post-content img' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
547 ],
548 ]
549 );
550
551 $this->end_controls_section();
552
553 }
554
555 protected function render() {
556
557 $post_id = function_exists( 'easyel_get_prepared_post_id' )
558 ? easyel_get_prepared_post_id()
559 : get_the_ID();
560
561 if ( ! $post_id ) {
562 return;
563 }
564
565 $plugin = \Elementor\Plugin::$instance;
566
567 $is_editor = $plugin->editor->is_edit_mode();
568 $is_preview = $plugin->preview->is_preview_mode();
569 $is_elementor = $is_editor || $is_preview;
570
571 // Prevent recursion
572 static $rendering_post_ids = [];
573 if ( in_array( $post_id, $rendering_post_ids, true ) ) {
574 echo '<div class="easyel-editor-placeholder">' . esc_html__( 'Post content will appear on frontend.', 'easy-elements' ) . '</div>';
575 return;
576 }
577 $rendering_post_ids[] = $post_id;
578
579 $content = '';
580
581 if ( $is_elementor ) {
582 $content = $plugin->frontend->get_builder_content_for_display(
583 $post_id,
584 true
585 );
586 }
587
588 if ( empty( $content ) ) {
589 $raw_content = get_post_field( 'post_content', $post_id );
590
591 if ( $is_editor || $is_preview ) {
592 // Snapshot the global hook callbacks BEFORE render so we can
593 // identify what render_block() adds for dynamic per-block layout
594 // rules (.wp-container-XYZ { grid-template-columns: … } etc.).
595 // In the Elementor preview iframe those rules never reach the
596 // <head> via the usual path, so Gutenberg grid / columns / flex
597 // groups lose their dynamically-generated CSS. We capture from
598 // THREE places (block themes use wp_head, classic themes use
599 // wp_footer, and WP 6.0+ also stores rules in the Style Engine
600 // "block-supports" context) and inline whatever appears.
601 global $wp_filter;
602 $snapshot_head = ( isset( $wp_filter['wp_head'] ) && ! empty( $wp_filter['wp_head']->callbacks ) )
603 ? $wp_filter['wp_head']->callbacks
604 : array();
605 $snapshot_footer = ( isset( $wp_filter['wp_footer'] ) && ! empty( $wp_filter['wp_footer']->callbacks ) )
606 ? $wp_filter['wp_footer']->callbacks
607 : array();
608
609 $blocks = parse_blocks( $raw_content );
610 if ( ! empty( $blocks ) ) {
611 $content = '';
612 foreach ( $blocks as $block ) {
613 $content .= render_block( $block );
614 }
615 }
616
617 $captured = '';
618
619 // Capture closures added during render to wp_head / wp_footer
620 // — these come from wp_enqueue_block_support_styles().
621 foreach ( array( 'wp_head' => $snapshot_head, 'wp_footer' => $snapshot_footer ) as $hook => $snapshot ) {
622 if ( empty( $wp_filter[ $hook ] ) || empty( $wp_filter[ $hook ]->callbacks ) ) {
623 continue;
624 }
625 foreach ( $wp_filter[ $hook ]->callbacks as $priority => $cb_group ) {
626 foreach ( $cb_group as $cb_id => $cb ) {
627 if ( isset( $snapshot[ $priority ][ $cb_id ] ) ) {
628 continue; // existed before render — not ours.
629 }
630 if ( empty( $cb['function'] ) || ! is_callable( $cb['function'] ) ) {
631 continue;
632 }
633 ob_start();
634 call_user_func( $cb['function'] );
635 $captured .= ob_get_clean();
636 // Remove so it doesn't double-output at the real hook.
637 unset( $wp_filter[ $hook ]->callbacks[ $priority ][ $cb_id ] );
638 }
639 }
640 }
641
642 // Capture CSS rules from the WP Style Engine "block-supports"
643 // context (WP 6.0+). This is where modern layout / spacing /
644 // typography block-supports stash their generated CSS.
645 if ( function_exists( '\wp_style_engine_get_stylesheet_from_context' ) ) {
646 $engine_css = \wp_style_engine_get_stylesheet_from_context( 'block-supports', array( 'optimize' => true ) );
647 if ( ! empty( $engine_css ) ) {
648 $captured .= "<style id=\"easyel-post-content-block-supports\">{$engine_css}</style>\n";
649 // Clear the store so wp_enqueue_stored_styles() (which
650 // runs later for the queried-post render) doesn't emit
651 // the same rules again.
652 if ( class_exists( '\WP_Style_Engine' ) && method_exists( '\WP_Style_Engine', 'get_store' ) ) {
653 $store = \WP_Style_Engine::get_store( 'block-supports' );
654 if ( $store && method_exists( $store, 'remove_all_rules' ) ) {
655 $store->remove_all_rules();
656 }
657 }
658 }
659 }
660
661 if ( '' !== $captured ) {
662 // Prepend captured <style> tags so dynamic layout CSS is
663 // in place before the rendered block markup.
664 $content = $captured . $content;
665 }
666 } else {
667
668 // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
669 $content = apply_filters( 'the_content', $raw_content );
670 }
671 }
672
673 if ( empty( $content ) ) {
674 echo '<div class="easyel-editor-placeholder">' . esc_html__( 'Post content will appear here.', 'easy-elements' ) . '</div>';
675 $key = array_search( $post_id, $rendering_post_ids, true );
676 if ( $key !== false ) unset( $rendering_post_ids[ $key ] );
677 return;
678 }
679
680 // phpcs:ignore WordPress.Security.EscapeOutput
681 echo '<div class="eel-post-content eel-gutenberg-content">' . $content . '</div>';
682
683 $key = array_search( $post_id, $rendering_post_ids, true );
684 if ( $key !== false ) unset( $rendering_post_ids[ $key ] );
685 }
686 }
687
688 /**
689 * Detect whether the current request is the Elementor editor or its preview
690 * iframe. Used by the block-asset enqueue helpers below so they only act inside
691 * Elementor and leave the front end alone.
692 *
693 * @return bool
694 */
695 if ( ! function_exists( 'easyel_post_content_is_elementor_preview' ) ) {
696 function easyel_post_content_is_elementor_preview() {
697 if ( ! class_exists( '\Elementor\Plugin' ) || ! \Elementor\Plugin::$instance ) {
698 return false;
699 }
700 $plugin = \Elementor\Plugin::$instance;
701 if ( ! isset( $plugin->preview, $plugin->editor ) ) {
702 return false;
703 }
704 return $plugin->preview->is_preview_mode() || $plugin->editor->is_edit_mode();
705 }
706 }
707
708 /**
709 * Bundle every core block stylesheet into the single wp-block-library handle
710 * when inside Elementor preview/edit. Combined with the enqueue action below,
711 * this guarantees block layout CSS (columns, image, gallery, button group, …)
712 * is present in the preview iframe, where lazy per-block enqueues otherwise
713 * miss the <head>. No effect on the front end.
714 *
715 * @param bool $load_separate Default WP behavior (per-block CSS).
716 * @return bool
717 */
718 if ( ! function_exists( 'easyel_post_content_disable_separate_block_assets' ) ) {
719 function easyel_post_content_disable_separate_block_assets( $load_separate ) {
720 return easyel_post_content_is_elementor_preview() ? false : $load_separate;
721 }
722 // Note: FQN is required because this file is in a namespace; bare string
723 // callbacks would be looked up in the global scope and trigger a fatal.
724 add_filter( 'should_load_separate_core_block_assets', __NAMESPACE__ . '\\easyel_post_content_disable_separate_block_assets' );
725 }
726
727 /**
728 * Force-enqueue every registered block stylesheet inside the Elementor preview
729 * iframe so post content rendered by this widget keeps its Gutenberg layout.
730 *
731 * Background: WP 5.8+ loads per-block CSS only when has_blocks() is true on the
732 * QUERIED post. The Elementor preview iframe queries the Elementor template,
733 * not the post displayed by this widget, so WP skips the enqueues and the
734 * widget's markup renders without layout CSS (side-by-side images stack,
735 * columns collapse, galleries lose grid). On the front end the queried post
736 * is the rendered post, so this issue never appears there.
737 *
738 * This callback walks WP_Block_Type_Registry, enqueues each block type's
739 * declared style handles (style_handles / view_style_handles /
740 * editor_style_handles plus the legacy singular style / editor_style), and
741 * also force-enqueues the comprehensive WP block stylesheets so theme.json
742 * globals and classic-theme layout classes (is-layout-flex, is-layout-flow)
743 * are present. Unregistered handles fail silently in wp_enqueue_style().
744 *
745 * @return void
746 */
747 if ( ! function_exists( 'easyel_post_content_enqueue_block_styles_in_preview' ) ) {
748 function easyel_post_content_enqueue_block_styles_in_preview() {
749 if ( ! easyel_post_content_is_elementor_preview() ) {
750 return;
751 }
752
753 // Core / global block stylesheets. Unregistered handles fail silently.
754 $globals = array(
755 'wp-block-library',
756 'wp-block-library-theme',
757 'global-styles',
758 'classic-theme-styles',
759 'wp-block-editor-content',
760 );
761 foreach ( $globals as $handle ) {
762 if ( wp_style_is( $handle, 'registered' ) ) {
763 wp_enqueue_style( $handle );
764 }
765 }
766
767 if ( ! class_exists( '\WP_Block_Type_Registry' ) ) {
768 return;
769 }
770
771 // Walk every registered block type and enqueue its declared style handles.
772 $registry = \WP_Block_Type_Registry::get_instance();
773 foreach ( $registry->get_all_registered() as $block_type ) {
774 foreach ( array( 'style_handles', 'view_style_handles', 'editor_style_handles' ) as $prop ) {
775 if ( empty( $block_type->{$prop} ) || ! is_array( $block_type->{$prop} ) ) {
776 continue;
777 }
778 foreach ( $block_type->{$prop} as $handle ) {
779 if ( is_string( $handle ) && wp_style_is( $handle, 'registered' ) ) {
780 wp_enqueue_style( $handle );
781 }
782 }
783 }
784 // Older WP versions used singular `style` / `editor_style` properties.
785 foreach ( array( 'style', 'editor_style' ) as $prop ) {
786 $value = isset( $block_type->{$prop} ) ? $block_type->{$prop} : null;
787 if ( is_string( $value ) && wp_style_is( $value, 'registered' ) ) {
788 wp_enqueue_style( $value );
789 }
790 }
791 }
792 }
793 // Priority 1 so our enqueues run BEFORE the active theme (priority 10) —
794 // theme CSS then loads after wp-block-library-theme and wins for heading
795 // sizes etc., keeping Gutenberg content visually consistent with the front.
796 add_action( 'wp_enqueue_scripts', __NAMESPACE__ . '\\easyel_post_content_enqueue_block_styles_in_preview', 1 );
797 }