PluginProbe
Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! / 3.6.8
Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! v3.6.8
3.7.5 3.7.4 3.7.3 3.7.2 1-final 3.7.1 3.7.0 3.6.8 3.6.7 3.6.6 3.6.5 3.6.4 3.6.3 3.6.2 3.6.1 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 3.1.10 All 111 releases
← All changes | includes/Core/Platform/Elementor.php +100 -9 3.0.53.6.8 View file →
@@ -15,8 +15,9 @@
15 15 use Elementor\Plugin;
16 16 use Elementor\Core\Kits\Documents\Kit;
17 17 use Elementor\Core\Settings\Manager as SettingsManager;
18 18 use Templately\Core\Importer\Elementor as ElementorImporter;
19 +use Templately\Core\Importer\Utils\Utils;
19 20 use Elementor\TemplateLibrary\Source_Local as ElementorLocal;
20 21
21 22 class Elementor extends Platform {
22 23 private $id = 'elementor';
@@ -47,8 +48,9 @@
47 48 * @return void
48 49 */
49 50 public function styles() {
50 51 templately()->assets->enqueue( 'templately-elementor-preview', 'css/elementor.css' );
52 + templately()->assets->enqueue( 'templately-tailwind', 'css/tailwind.css', ['templately-elementor-preview'] );
51 53 }
52 54
53 55 /**
54 56 * Assets Enqueueing
@@ -55,8 +57,9 @@
55 57 * @return void
56 58 */
57 59 public function scripts() {
58 60 templately()->assets->enqueue( 'templately-elementor', 'css/elementor.css' );
61 + templately()->assets->enqueue( 'templately-tailwind', 'css/tailwind.css', ['templately-elementor'] );
59 62 templately()->assets->enqueue( 'templately-elementor', 'js/elementor.js', [ 'jquery' ], true );
60 63 templately()->admin->scripts( 'elementor' );
61 64 }
62 65
@@ -74,9 +77,9 @@
74 77 * Checking the template eligibility for import.
75 78 *
76 79 * @return WP_Error|void
77 80 */
78 - protected function is_eligible( $template, $types = [ 'page', 'section' ] ) {
81 + protected function is_eligible( $template, $types = [ 'page', 'section', 'block' ] ) {
79 82 if ( ! Helper::is_plugin_active( 'elementor-pro/elementor-pro.php' ) &&
80 83 isset( $template['type'] ) &&
81 84 ! in_array( $template['type'], $types, true )
82 85 ) {
@@ -94,8 +97,12 @@
94 97 }
95 98 }
96 99
97 100 public function get_saved_templates( $params = [] ) {
101 + if ( ! function_exists( 'is_plugin_active' ) ){
102 + require_once( ABSPATH . '/wp-admin/includes/plugin.php' );
103 + }
104 +
98 105 $_page_number = isset( $params['page'] ) ? intval( $params['page'] ) : 1;
99 106
100 107 $args = [
101 108 'post_type' => 'elementor_library',
@@ -128,11 +135,13 @@
128 135 wp_reset_postdata();
129 136 wp_reset_query();
130 137
131 138 return array(
132 - 'current_page' => $templates->query_vars['paged'],
133 - 'total_page' => $templates->max_num_pages,
134 - 'items' => $templateList,
139 + 'current_page' => $templates->query_vars['paged'],
140 + 'total_page' => $templates->max_num_pages,
141 + 'items' => $templateList,
142 + 'has_elementor' => rest_sanitize_boolean( \is_plugin_active( 'elementor/elementor.php' ) ),
143 + 'has_elementor_pro' => rest_sanitize_boolean( \is_plugin_active( 'elementor-pro/elementor-pro.php' ) ),
135 144 );
136 145 }
137 146
138 147 private function get_export_link( $template_id ) {
@@ -234,9 +243,9 @@
234 243 * @since 2.0.0
235 244 *
236 245 * @return array|WP_Error array on success, WP_Error on failure.
237 246 */
238 - public function create_page( $id, $title, $importer = null ) {
247 + public function create_page( $id, $title, $importer = null, $settings = [] ) {
239 248 $template_data = $importer->get_content( $id );
240 249
241 250 if ( is_wp_error( $template_data ) ) {
242 251 return $template_data;
@@ -241,8 +250,12 @@
241 250 if ( is_wp_error( $template_data ) ) {
242 251 return $template_data;
243 252 }
244 253
254 + if ( ! empty( $settings ) && ! empty( $template_data['content'] ) && is_array( $template_data['content'] ) ) {
255 + $template_data['content'] = \Templately\Core\Importer\Utils\ElementorSettingsMerger::merge( $template_data['content'], $settings );
256 + }
257 +
245 258 $importer = new ElementorImporter;
246 259 $template_data = $importer->get_data( $template_data );
247 260
248 261 if ( ! empty( $title ) ) {
@@ -275,9 +288,9 @@
275 288 'visit' => get_permalink( $inserted_ID )
276 289 ];
277 290 }
278 291
279 - public function import_in_library( $id, $importer = null ) {
292 + public function import_in_library( $id, $importer = null, $settings = [], $template_type = '', $type = '' ) {
280 293 $template_data = $importer->get_content( $id, 'elementor', 'remote' );
281 294
282 295 if ( is_wp_error( $template_data ) ) {
283 296 return $template_data;
@@ -282,8 +295,25 @@
282 295 if ( is_wp_error( $template_data ) ) {
283 296 return $template_data;
284 297 }
285 298
299 + if ( ! empty( $settings ) && ! empty( $template_data['content'] ) && is_array( $template_data['content'] ) ) {
300 + $template_data['content'] = \Templately\Core\Importer\Utils\ElementorSettingsMerger::merge( $template_data['content'], $settings );
301 + }
302 +
303 + // Frontend-provided template_type (from item details API) takes precedence over
304 + // whatever the fetched content JSON reports.
305 + if ( ! empty( $template_type ) ) {
306 + $template_data['template_type'] = $template_type;
307 + }
308 +
309 + // Resolve the correct Builder Type using template_type before passing to the importer.
310 + try {
311 + $template_data['type'] = static::resolve_library_type( $template_data );
312 + } catch ( \InvalidArgumentException $e ) {
313 + return Helper::error( 'unsupported_template_type', $e->getMessage(), 'import', 400 );
314 + }
315 +
286 316 $importer = new ElementorImporter;
287 317 $imported_template = $importer->import_in_library( $template_data );
288 318
289 319 if( is_wp_error( $imported_template ) ) {
@@ -289,12 +319,25 @@
289 319 if( is_wp_error( $imported_template ) ) {
290 320 return $imported_template;
291 321 }
292 322
323 + $post_id = $imported_template['template_id'];
324 +
325 + // Companion content for archive/fluent types — same side effects (Shop page,
326 + // page_for_posts, LearnDash courses slug, fluent single-page template) the FSI
327 + // Templates runner performs when importing these template types.
328 + Utils::create_companion_content( $template_data['type'], $template_data['title'] ?? '', 'elementor' );
329 +
330 + // Mark user as having imported a template
331 + \Templately\Utils\Options::get_instance()->set( 'has_imported_template', true );
332 +
333 + $document = Plugin::$instance->documents->get( $post_id );
334 + $elementor_edit_link = $document ? $document->get_edit_url() : admin_url( 'post.php?post=' . $post_id . '&action=elementor' );
335 +
293 336 return [
294 - 'post_id' => $imported_template['template_id'],
295 - 'edit_link' => get_edit_post_link( $imported_template['template_id'], 'internal' ),
296 - 'elementor_edit_link' => Plugin::$instance->documents->get( $imported_template['template_id'] )->get_edit_url(),
337 + 'post_id' => $post_id,
338 + 'edit_link' => get_edit_post_link( $post_id, 'internal' ),
339 + 'elementor_edit_link' => $elementor_edit_link,
297 340 'visit' => $imported_template['url']
298 341 ];
299 342 }
300 343
@@ -322,6 +365,54 @@
322 365 public function insert( $data ) {
323 366 $importer = new ElementorImporter();
324 367
325 368 return $importer->get_data( $data );
369 + }
370 +
371 + /**
372 + * Register the Pro-promotion child-type fix once per request.
373 + *
374 + * Templates can reference Elementor Pro widgets (e.g. nested-carousel) that aren't
375 + * installed. Elementor substitutes a Pro_Widget_Promotion placeholder, but its
376 + * get_child_type() can't resolve the original nested children — so saving such a
377 + * template fatals with "get_default_args() on array". filter_child_type() restores
378 + * the correct child type. FSI registers this in FullSiteImport; single-template
379 + * imports go through Importer\Elementor::get_data(), which calls this so the filter
380 + * is active for every import path.
381 + */
382 + public static function register_child_type_filter() {
383 + static $registered = false;
384 + if ( $registered ) {
385 + return;
386 + }
387 + $registered = true;
388 + add_filter( 'elementor/element/get_child_type', [ __CLASS__, 'filter_child_type' ], 10, 3 );
389 + }
390 +
391 + /**
392 + * Filter Child Type
393 + *
394 + * @param $child_type
395 + * @param $element_data
396 + * @param $element
397 + *
398 + * @return mixed
399 + */
400 + public static function filter_child_type( $child_type, $element_data, $element ) {
401 + // Fix for Elementor Pro Promotion Widget
402 + if ( is_a( $element, 'Elementor\Modules\Promotions\Widgets\Pro_Widget_Promotion' ) || ( is_object( $element ) && 'pro-promotion' === $element->get_name() ) ) {
403 + $el_types = array_keys( Plugin::$instance->elements_manager->get_element_types() );
404 +
405 + if ( isset( $element_data['elType'] ) && in_array( $element_data['elType'], $el_types, true ) ) {
406 + return Plugin::$instance->elements_manager->get_element_types( $element_data['elType'] );
407 + }
408 +
409 + if ( ! isset( $element_data['widgetType'] ) ) {
410 + return null;
411 + }
412 +
413 + return Plugin::$instance->widgets_manager->get_widget_types( $element_data['widgetType'] );
414 + }
415 +
416 + return $child_type;
326 417 }
327 418 }