PluginProbe ʕ •ᴥ•ʔ
Elementor Website Builder – more than just a page builder / 3.35.0-beta4
Elementor Website Builder – more than just a page builder v3.35.0-beta4
4.1.1 4.1.0 4.1.0-beta3 4.1.0-dev3 4.0.9 4.1.0-beta2 4.1.0-dev2 4.0.8 4.1.0-beta1 4.1.0-dev1 4.0.7 4.0.6 4.0.5 4.0.4 4.0.3 3.22.0-dev1 4.0.0-beta3 3.22.0-dev2 4.0.0-beta4 3.22.0-dev3 4.0.0-beta5 3.22.0-dev4 4.0.0-dev1 3.22.0-dev5 4.0.0-dev2 3.22.0-dev6 4.0.0-dev3 3.22.1 4.0.0-dev4 3.22.2 4.0.0-dev5 3.22.3 4.0.1 3.23.0 4.0.2 3.23.0-beta1 3.23.0-beta2 3.23.0-beta3 3.23.0-beta4 3.23.0-beta5 3.23.0-beta6 3.23.0-dev1 3.23.0-dev2 3.23.0-dev3 3.23.0-dev4 3.23.0-dev5 3.23.0-dev6 3.23.1 3.23.2 3.23.3 3.23.4 3.24.0 3.24.0-beta1 3.24.0-beta2 3.24.0-beta3 3.24.0-dev1 3.24.0-dev2 3.24.0-dev3 3.24.1 3.24.2 3.24.3 3.24.4 3.24.5 3.24.6 3.24.7 3.24.8 3.25.0 3.25.0-beta1 3.25.0-beta2 3.25.0-beta3 3.25.0-dev1 3.25.0-dev2 3.25.0-dev3 3.25.1 3.25.10 3.25.11 3.25.2 3.25.3 3.25.4 3.25.5 3.25.6 3.25.7 3.25.8 3.25.9 3.26.0 3.26.0-beta1 3.26.0-beta2 3.26.0-beta3 3.26.0-beta4 3.26.0-beta5 3.26.0-dev1 3.26.0-dev2 3.26.0-dev3 3.26.0-dev4 3.26.0-dev5 3.26.1 3.26.2 3.26.3 3.26.4 3.26.5 3.27.0 3.27.0-beta1 3.27.0-beta2 3.27.0-dev1 3.27.0-dev2 3.27.1 3.27.2 3.27.3 3.27.4 3.27.5 3.27.6 3.27.7 3.28.0 3.28.0-beta1 3.28.0-beta2 3.28.0-beta3 3.28.0-dev1 3.28.0-dev2 3.28.0-dev3 3.28.1 3.28.2 3.28.3 3.28.4 3.29.0 3.29.0-beta1 trunk 3.29.0-beta2 3.0.0 3.29.0-beta3 3.0.1 3.29.0-beta4 3.0.10 3.29.0-dev1 3.0.11 3.29.0-dev2 3.0.12 3.29.0-dev3 3.0.13 3.29.0-dev4 3.0.14 3.29.1 3.0.15 3.29.2 3.0.16 3.3.0 3.0.2 3.3.1 3.0.3 3.30.0 3.0.4 3.30.0-beta1 3.0.5 3.30.0-beta2 3.0.6 3.30.0-beta3 3.0.7 3.30.0-dev1 3.0.8 3.30.0-dev2 3.0.8.1 3.30.0-dev3 3.0.9 3.30.1 3.1.0 3.30.2 3.1.0-beta1 3.30.3 3.1.0-beta2 3.30.4 3.1.0-beta3 3.31.0 3.1.0-beta4 3.31.0-beta1 3.1.0-dev1 3.31.0-beta2 3.1.0-dev2 3.31.0-dev1 3.1.0-dev3 3.31.0-dev2 3.1.1 3.31.1 3.1.2 3.31.2 3.1.3 3.31.3 3.1.4 3.31.4 3.10.0 3.31.5 3.10.0-dev1 3.32.0 3.10.1 3.32.0-beta1 3.10.2 3.32.0-beta2 3.11.0 3.32.0-beta3 3.11.0-beta1 3.32.0-dev1 3.11.0-beta2 3.32.0-dev2 3.11.0-beta3 3.32.0-dev3 3.11.0-dev1 3.32.1 3.11.0-dev2 3.32.2 3.11.0-dev3 3.32.3 3.11.1 3.32.4 3.11.2 3.32.5 3.11.3 3.33.0 3.11.4 3.33.0-beta1 3.11.5 3.33.0-beta2 3.12.0 3.33.0-beta3 3.12.1 3.33.0-beta4 3.12.2 3.33.0-dev1 3.13.0 3.33.0-dev2 3.13.0-beta1 3.33.0-dev3 3.13.0-beta2 3.33.0-dev4 3.13.0-beta3 3.33.1 3.13.0-dev3 3.33.2 3.13.0-dev4 3.33.3 3.13.1 3.33.4 3.13.2 3.33.5 3.13.3 3.33.6 3.13.4 3.34.0 3.14.0 3.34.0-beta1 3.14.0-beta1 3.34.0-beta2 3.14.0-beta2 3.34.0-beta3 3.14.0-beta3 3.34.0-dev1 3.14.0-beta4 3.34.0-dev2 3.14.0-beta5 3.34.1 3.14.1 3.34.2 3.15.0 3.34.3 3.15.1 3.34.4 3.15.2 3.35.0 3.15.3 3.35.0-beta1 3.16.0 3.35.0-beta2 3.16.0-beta3 3.35.0-beta3 3.16.0-beta4 3.35.0-beta4 3.16.0-dev1 3.35.0-dev1 3.16.0-dev2 3.35.0-dev2 3.16.1 3.35.0-dev3 3.16.2 3.35.0-dev4 3.16.3 3.35.1 3.16.4 3.35.2 3.16.5 3.35.3 3.16.6 3.35.4 3.17.0 3.35.5 3.17.0-dev2 3.35.6 3.17.0-dev3 3.35.7 3.17.0-dev4 3.35.8 3.17.1 3.35.9 3.17.2 3.4.0 3.17.3 3.4.0-dev7 3.18.0 3.4.0-dev8 3.18.0-beta1 3.4.0-dev9 3.18.0-beta2 3.4.1 3.18.0-beta3 3.4.2 3.18.0-beta4 3.4.3 3.18.0-dev1 3.4.4 3.18.1 3.4.5 3.18.2 3.4.6 3.18.3 3.4.7 3.19.0 3.4.8 3.19.0-beta1 3.5.0 3.19.0-beta2 3.5.0-beta1 3.19.0-beta3 3.5.0-beta2 3.19.0-beta4 3.5.0-beta3 3.19.0-beta5 3.5.0-beta4 3.19.0-beta6 3.5.0-beta5 3.19.0-dev1 3.5.0-beta7 3.19.0-dev2 3.5.0-beta8 3.19.0-dev3 3.5.0-dev8 3.19.0-dev4 3.5.0-dev9 3.19.0-dev5 3.5.1 3.19.0-dev6 3.5.2 3.19.1 3.5.3 3.19.2 3.5.4 3.19.3 3.5.5 3.19.4 3.5.6 3.2.0 3.6.0 3.2.1 3.6.0-beta1 3.2.2 3.6.0-beta2 3.2.3 3.6.0-beta3 3.2.4 3.6.0-beta4 3.2.5 3.6.0-beta5 3.20.0 3.6.0-dev1 3.20.0-beta1 3.6.0-dev10 3.20.0-beta2 3.6.1 3.20.0-beta3 3.6.2 3.20.0-beta4 3.6.3 3.20.0-dev1 3.6.4 3.20.0-dev2 3.6.5 3.20.0-dev3 3.6.6 3.20.0-dev4 3.6.7 3.20.1 3.6.8 3.20.2 3.7.0 3.20.3 3.7.0-beta1 3.20.4 3.7.0-beta2 3.21.0 3.7.0-beta3 3.21.0-beta1 3.7.0-beta4 3.21.0-beta2 3.7.0-dev1 3.21.0-beta3 3.7.1 3.21.0-dev1 3.7.2 3.21.0-dev2 3.7.3 3.21.0-dev3 3.7.4 3.21.1 3.7.5 3.21.2 3.7.6 3.21.3 3.7.7 3.21.4 3.7.8 3.21.5 3.8.0 3.21.6 3.8.0-beta1 3.21.7 3.8.0-beta2 3.21.8 3.8.0-beta3 3.22.0 3.8.1 3.22.0-beta1 3.9.0 3.22.0-beta2 3.9.1 3.22.0-beta3 3.9.2 3.22.0-beta4 4.0.0 3.22.0-beta5 4.0.0-beta1 3.22.0-beta6 4.0.0-beta2
elementor / modules / page-templates / module.php
elementor / modules / page-templates Last commit date
templates 1 year ago module.php 7 months ago
module.php
426 lines
1 <?php
2 namespace Elementor\Modules\PageTemplates;
3
4 use Elementor\Controls_Manager;
5 use Elementor\Core\Base\Document;
6 use Elementor\Core\Base\Module as BaseModule;
7 use Elementor\Core\Kits\Documents\Kit;
8 use Elementor\Plugin;
9 use Elementor\Utils;
10 use Elementor\Core\DocumentTypes\PageBase;
11 use Elementor\Modules\Library\Documents\Page as LibraryPageDocument;
12
13 if ( ! defined( 'ABSPATH' ) ) {
14 exit; // Exit if accessed directly.
15 }
16
17 /**
18 * Elementor page templates module.
19 *
20 * Elementor page templates module handler class is responsible for registering
21 * and managing Elementor page templates modules.
22 *
23 * @since 2.0.0
24 */
25 class Module extends BaseModule {
26
27 /**
28 * The of the theme.
29 */
30 const TEMPLATE_THEME = 'elementor_theme';
31
32 /**
33 * Elementor Canvas template name.
34 */
35 const TEMPLATE_CANVAS = 'elementor_canvas';
36
37 /**
38 * Elementor Header & Footer template name.
39 */
40 const TEMPLATE_HEADER_FOOTER = 'elementor_header_footer';
41
42 /**
43 * Print callback.
44 *
45 * Holds the page template callback content.
46 *
47 * @since 2.0.0
48 * @access protected
49 *
50 * @var callable
51 */
52 protected $print_callback;
53
54 /**
55 * Get module name.
56 *
57 * Retrieve the page templates module name.
58 *
59 * @since 2.0.0
60 * @access public
61 *
62 * @return string Module name.
63 */
64 public function get_name() {
65 return 'page-templates';
66 }
67
68 /**
69 * Template include.
70 *
71 * Update the path for the Elementor Canvas template.
72 *
73 * Fired by `template_include` filter.
74 *
75 * @since 2.0.0
76 * @access public
77 *
78 * @param string $template The path of the template to include.
79 *
80 * @return string The path of the template to include.
81 */
82 public function template_include( $template ) {
83 if ( is_singular() ) {
84 $document = Plugin::$instance->documents->get_doc_for_frontend( get_the_ID() );
85
86 if ( $document && $document::get_property( 'support_wp_page_templates' ) ) {
87 $page_template = $document->get_meta( '_wp_page_template' );
88
89 $template_path = $this->get_template_path( $page_template );
90
91 if ( self::TEMPLATE_THEME !== $page_template && ! $template_path && $document->is_built_with_elementor() ) {
92 $kit_default_template = Plugin::$instance->kits_manager->get_current_settings( 'default_page_template' );
93 $template_path = $this->get_template_path( $kit_default_template );
94 }
95
96 if ( $template_path ) {
97 $template = $template_path;
98
99 Plugin::$instance->inspector->add_log( 'Page Template', Plugin::$instance->inspector->parse_template_path( $template ), $document->get_edit_url() );
100 }
101 }
102 }
103
104 return $template;
105 }
106
107 /**
108 * Add WordPress templates.
109 *
110 * Adds Elementor templates to all the post types that support
111 * Elementor.
112 *
113 * Fired by `init` action.
114 *
115 * @since 2.0.0
116 * @access public
117 */
118 public function add_wp_templates_support() {
119 $post_types = get_post_types_by_support( 'elementor' );
120
121 foreach ( $post_types as $post_type ) {
122 add_filter( "theme_{$post_type}_templates", [ $this, 'add_page_templates' ], 10, 4 );
123 }
124 }
125
126 /**
127 * Add page templates.
128 *
129 * Add the Elementor page templates to the theme templates.
130 *
131 * Fired by `theme_{$post_type}_templates` filter.
132 *
133 * @since 2.0.0
134 * @access public
135 * @static
136 *
137 * @param array $page_templates Array of page templates. Keys are filenames, checks are translated names.
138 * @param \WP_Theme $wp_theme
139 * @param \WP_Post $post
140 *
141 * @return array Page templates.
142 */
143 public function add_page_templates( $page_templates, $wp_theme, $post ) {
144 if ( $post ) {
145 // FIX ME: Gutenberg not send $post as WP_Post object, just the post ID.
146 $post_id = ! empty( $post->ID ) ? $post->ID : $post;
147
148 $document = Plugin::$instance->documents->get( $post_id );
149 if ( $document && ! $document::get_property( 'support_wp_page_templates' ) ) {
150 return $page_templates;
151 }
152 }
153
154 $page_templates = [
155 self::TEMPLATE_CANVAS => esc_html__( 'Elementor Canvas', 'elementor' ),
156 self::TEMPLATE_HEADER_FOOTER => esc_html__( 'Elementor Full Width', 'elementor' ),
157 self::TEMPLATE_THEME => esc_html__( 'Theme', 'elementor' ),
158 ] + $page_templates;
159
160 return $page_templates;
161 }
162
163 /**
164 * Set print callback.
165 *
166 * Set the page template callback.
167 *
168 * @since 2.0.0
169 * @access public
170 *
171 * @param callable $callback
172 */
173 public function set_print_callback( $callback ) {
174 $this->print_callback = $callback;
175 }
176
177 /**
178 * Print callback.
179 *
180 * Prints the page template content using WordPress loop.
181 *
182 * @since 2.0.0
183 * @access public
184 */
185 public function print_callback() {
186 while ( have_posts() ) :
187 the_post();
188 the_content();
189 endwhile;
190 }
191
192 /**
193 * Print content.
194 *
195 * Prints the page template content.
196 *
197 * @since 2.0.0
198 * @access public
199 */
200 public function print_content() {
201 if ( ! $this->print_callback ) {
202 $this->print_callback = [ $this, 'print_callback' ];
203 }
204
205 call_user_func( $this->print_callback );
206 }
207
208 /**
209 * Get page template path.
210 *
211 * Retrieve the path for any given page template.
212 *
213 * @since 2.0.0
214 * @access public
215 *
216 * @param string $page_template The page template name.
217 *
218 * @return string Page template path.
219 */
220 public function get_template_path( $page_template ) {
221 $template_path = '';
222 switch ( $page_template ) {
223 case self::TEMPLATE_CANVAS:
224 $template_path = __DIR__ . '/templates/canvas.php';
225 break;
226 case self::TEMPLATE_HEADER_FOOTER:
227 $template_path = __DIR__ . '/templates/header-footer.php';
228 break;
229 }
230
231 return $template_path;
232 }
233
234 /**
235 * Register template control.
236 *
237 * Adds custom controls to any given document.
238 *
239 * Fired by `update_post_metadata` action.
240 *
241 * @since 2.0.0
242 * @access public
243 *
244 * @param Document $document The document instance.
245 */
246 public function action_register_template_control( $document ) {
247 if (
248 ( $document instanceof PageBase || $document instanceof LibraryPageDocument ) &&
249 $document::get_property( 'support_page_layout' )
250 ) {
251 $this->register_template_control( $document );
252 }
253 }
254
255 /**
256 * Register template control.
257 *
258 * Adds custom controls to any given document.
259 *
260 * @since 2.0.0
261 * @access public
262 *
263 * @param Document $document The document instance.
264 * @param string $control_id Optional. The control ID. Default is `template`.
265 */
266 public function register_template_control( $document, $control_id = 'template' ) {
267 if ( ! Utils::is_cpt_custom_templates_supported() ) {
268 return;
269 }
270
271 require_once ABSPATH . '/wp-admin/includes/template.php';
272
273 $document->start_injection( [
274 'of' => 'post_status',
275 'fallback' => [
276 'of' => 'post_title',
277 ],
278 ] );
279
280 $control_options = [
281 'options' => array_flip( get_page_templates( null, $document->get_main_post()->post_type ) ),
282 ];
283
284 $this->add_template_controls( $document, $control_id, $control_options );
285
286 $document->end_injection();
287 }
288
289 /**
290 * The $options variable is an array of $control_options to overwrite the default.
291 */
292 public function add_template_controls( Document $document, $control_id, $control_options ) {
293 // Default Control Options
294 $default_control_options = [
295 'label' => esc_html__( 'Page Layout', 'elementor' ),
296 'type' => Controls_Manager::SELECT,
297 'default' => 'default',
298 'options' => [
299 'default' => esc_html__( 'Default', 'elementor' ),
300 ],
301 ];
302
303 $control_options = array_replace_recursive( $default_control_options, $control_options );
304
305 $document->add_control(
306 $control_id,
307 $control_options
308 );
309
310 $document->add_control(
311 $control_id . '_default_description',
312 [
313 'type' => Controls_Manager::RAW_HTML,
314 'raw' => '<b>' . esc_html__( 'The default page template as defined in Elementor Panel → Hamburger Menu → Site Settings.', 'elementor' ) . '</b>',
315 'content_classes' => 'elementor-descriptor',
316 'condition' => [
317 $control_id => 'default',
318 ],
319 ]
320 );
321
322 $document->add_control(
323 $control_id . '_theme_description',
324 [
325 'type' => Controls_Manager::RAW_HTML,
326 'raw' => '<b>' . esc_html__( 'Default Page Template from your theme.', 'elementor' ) . '</b>',
327 'content_classes' => 'elementor-descriptor',
328 'condition' => [
329 $control_id => self::TEMPLATE_THEME,
330 ],
331 ]
332 );
333
334 $document->add_control(
335 $control_id . '_canvas_description',
336 [
337 'type' => Controls_Manager::RAW_HTML,
338 'raw' => '<b>' . esc_html__( 'No header, no footer, just Elementor', 'elementor' ) . '</b>',
339 'content_classes' => 'elementor-descriptor',
340 'condition' => [
341 $control_id => self::TEMPLATE_CANVAS,
342 ],
343 ]
344 );
345
346 $document->add_control(
347 $control_id . '_header_footer_description',
348 [
349 'type' => Controls_Manager::RAW_HTML,
350 'raw' => '<b>' . esc_html__( 'This template includes the header, full-width content and footer', 'elementor' ) . '</b>',
351 'content_classes' => 'elementor-descriptor',
352 'condition' => [
353 $control_id => self::TEMPLATE_HEADER_FOOTER,
354 ],
355 ]
356 );
357
358 if ( $document instanceof Kit ) {
359 $document->add_control(
360 'reload_preview_description',
361 [
362 'type' => Controls_Manager::RAW_HTML,
363 'raw' => esc_html__( 'Changes will be reflected in the preview only after the page reloads.', 'elementor' ),
364 'content_classes' => 'elementor-descriptor',
365 ]
366 );
367 }
368 }
369
370 /**
371 * Filter metadata update.
372 *
373 * Filters whether to update metadata of a specific type.
374 *
375 * Elementor don't allow WordPress to update the parent page template
376 * during `wp_update_post`.
377 *
378 * Fired by `update_{$meta_type}_metadata` filter.
379 *
380 * @since 2.0.0
381 * @access public
382 *
383 * @param bool $check Whether to allow updating metadata for the given type.
384 * @param int $object_id Object ID.
385 * @param string $meta_key Meta key.
386 *
387 * @return bool Whether to allow updating metadata of a specific type.
388 */
389 public function filter_update_meta( $check, $object_id, $meta_key ) {
390 if ( '_wp_page_template' === $meta_key && Plugin::$instance->common ) {
391 /** @var \Elementor\Core\Common\Modules\Ajax\Module $ajax */
392 $ajax = Plugin::$instance->common->get_component( 'ajax' );
393
394 $ajax_data = $ajax->get_current_action_data();
395
396 $is_autosave_action = $ajax_data && 'save_builder' === $ajax_data['action'] && Document::STATUS_AUTOSAVE === $ajax_data['data']['status'];
397
398 // Don't allow WP to update the parent page template.
399 // (during `wp_update_post` from page-settings or save_plain_text).
400 if ( $is_autosave_action && ! wp_is_post_autosave( $object_id ) && Document::STATUS_DRAFT !== get_post_status( $object_id ) ) {
401 $check = false;
402 }
403 }
404
405 return $check;
406 }
407
408 /**
409 * Page templates module constructor.
410 *
411 * Initializing Elementor page templates module.
412 *
413 * @since 2.0.0
414 * @access public
415 */
416 public function __construct() {
417 add_action( 'init', [ $this, 'add_wp_templates_support' ] );
418
419 add_filter( 'template_include', [ $this, 'template_include' ], 11 /* After Plugins/WooCommerce */ );
420
421 add_action( 'elementor/documents/register_controls', [ $this, 'action_register_template_control' ] );
422
423 add_filter( 'update_post_metadata', [ $this, 'filter_update_meta' ], 10, 3 );
424 }
425 }
426