PluginProbe
Elementor Website Builder – more than just a page builder / 3.0.6
Elementor Website Builder – more than just a page builder v3.0.6
4.3.0-beta3 4.3.0-beta2 4.3.0-beta1 4.2.4 4.2.3 4.2.2 4.2.1 4.2.0 4.1.5 4.2.0-beta2 4.2.0-dev2 4.2.0-beta1 4.1.4 4.1.3 4.1.2 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 All 452 releases
← All changes | core/kits/documents/tabs/settings-layout.php +70 -247 4.2.23.0.6 View file →
@@ -1,51 +1,34 @@
1 1 <?php
2 2 namespace Elementor\Core\Kits\Documents\Tabs;
3 3
4 -use Elementor\Core\Breakpoints\Breakpoint;
5 -use Elementor\Core\Breakpoints\Manager as Breakpoints_Manager;
4 +use Elementor\DB;
6 5 use Elementor\Plugin;
7 6 use Elementor\Controls_Manager;
8 -use Elementor\Core\Base\Document;
7 +use Elementor\Core\Responsive\Responsive;
9 8 use Elementor\Modules\PageTemplates\Module as PageTemplatesModule;
10 9
11 10 if ( ! defined( 'ABSPATH' ) ) {
12 - exit; // Exit if accessed directly.
11 + exit; // Exit if accessed directly
13 12 }
14 13
15 14 class Settings_Layout extends Tab_Base {
16 15
17 - const ACTIVE_BREAKPOINTS_CONTROL_ID = 'active_breakpoints';
18 -
19 16 public function get_id() {
20 17 return 'settings-layout';
21 18 }
22 19
23 20 public function get_title() {
24 - return esc_html__( 'Layout', 'elementor' );
21 + return __( 'Layout', 'elementor' );
25 22 }
26 23
27 - public function get_group() {
28 - return 'settings';
29 - }
30 -
31 - public function get_icon() {
32 - return 'eicon-layout-settings';
33 - }
34 -
35 - public function get_help_url() {
36 - return 'https://go.elementor.com/global-layout/';
37 - }
38 -
39 24 protected function register_tab_controls() {
40 - $breakpoints_default_config = Breakpoints_Manager::get_default_config();
41 - $breakpoint_key_mobile = Breakpoints_Manager::BREAKPOINT_KEY_MOBILE;
42 - $breakpoint_key_tablet = Breakpoints_Manager::BREAKPOINT_KEY_TABLET;
25 + $default_breakpoints = Responsive::get_default_breakpoints();
43 26
44 27 $this->start_controls_section(
45 28 'section_' . $this->get_id(),
46 29 [
47 - 'label' => esc_html__( 'Layout Settings', 'elementor' ),
30 + 'label' => __( 'Layout Settings', 'elementor' ),
48 31 'tab' => $this->get_id(),
49 32 ]
50 33 );
51 34
@@ -51,19 +34,18 @@
51 34
52 35 $this->add_responsive_control(
53 36 'container_width',
54 37 [
55 - 'label' => esc_html__( 'Content Width', 'elementor' ),
38 + 'label' => __( 'Content Width', 'elementor' ) . ' (px)',
56 39 'type' => Controls_Manager::SLIDER,
57 - 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
58 40 'default' => [
59 - 'size' => 1140,
41 + 'size' => '1140',
60 42 ],
61 43 'tablet_default' => [
62 - 'size' => $breakpoints_default_config[ $breakpoint_key_tablet ]['default_value'],
44 + 'size' => $default_breakpoints['lg'],
63 45 ],
64 46 'mobile_default' => [
65 - 'size' => $breakpoints_default_config[ $breakpoint_key_mobile ]['default_value'],
47 + 'size' => $default_breakpoints['md'],
66 48 ],
67 49 'range' => [
68 50 'px' => [
69 51 'min' => 300,
@@ -70,67 +52,34 @@
70 52 'max' => 1500,
71 53 'step' => 10,
72 54 ],
73 55 ],
74 - 'description' => esc_html__( 'Sets the default width of the content area (Default: 1140px)', 'elementor' ),
56 + 'description' => __( 'Sets the default width of the content area (Default: 1140)', 'elementor' ),
75 57 'selectors' => [
76 58 '.elementor-section.elementor-section-boxed > .elementor-container' => 'max-width: {{SIZE}}{{UNIT}}',
77 - '.e-con' => '--container-max-width: {{SIZE}}{{UNIT}}',
78 59 ],
79 60 ]
80 61 );
81 62
82 - $is_container_active = Plugin::instance()->experiments->is_feature_active( 'container' );
83 -
84 - if ( $is_container_active ) {
85 - $this->add_responsive_control(
86 - 'container_padding',
87 - [
88 - 'label' => esc_html__( 'Container Padding', 'elementor' ),
89 - 'type' => Controls_Manager::DIMENSIONS,
90 - 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
91 - 'description' => esc_html__( 'Sets the default space inside the container (Default is 10px)', 'elementor' ),
92 - 'selectors' => [
93 - '.e-con' => '--container-default-padding-top: {{TOP}}{{UNIT}}; --container-default-padding-right: {{RIGHT}}{{UNIT}}; --container-default-padding-bottom: {{BOTTOM}}{{UNIT}}; --container-default-padding-left: {{LEFT}}{{UNIT}};',
94 - ],
95 - ]
96 - );
97 - }
98 -
99 - $widgets_space_label = $is_container_active
100 - ? esc_html__( 'Gaps', 'elementor' )
101 - : esc_html__( 'Widgets Space', 'elementor' );
102 -
103 63 $this->add_control(
104 64 'space_between_widgets',
105 65 [
106 - 'label' => $widgets_space_label,
107 - 'type' => Controls_Manager::GAPS,
66 + 'label' => __( 'Widgets Space', 'elementor' ) . ' (px)',
67 + 'type' => Controls_Manager::SLIDER,
108 68 'default' => [
109 - 'row' => '20',
110 - 'column' => '20',
111 - 'unit' => 'px',
69 + 'size' => 20,
112 70 ],
113 - 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
114 - 'placeholder' => [
115 - 'row' => '20',
116 - 'column' => '20',
117 - ],
118 - 'description' => esc_html__( 'Sets the default space between widgets (Default: 20px)', 'elementor' ),
119 - 'selectors' => $this->get_spacing_selectors(),
120 - 'conversion_map' => [
121 - 'old_key' => 'size',
122 - 'new_key' => 'column',
123 - ],
124 - 'upgrade_conversion_map' => [
125 - 'old_key' => 'size',
126 - 'new_keys' => [ 'column', 'row' ],
127 - ],
128 - 'validators' => [
129 - 'Number' => [
71 + 'range' => [
72 + 'px' => [
130 73 'min' => 0,
74 + 'max' => 40,
131 75 ],
132 76 ],
77 + 'placeholder' => '20',
78 + 'description' => __( 'Sets the default space between widgets (Default: 20)', 'elementor' ),
79 + 'selectors' => [
80 + '.elementor-widget:not(:last-child)' => 'margin-bottom: {{SIZE}}{{UNIT}}',
81 + ],
133 82 ]
134 83 );
135 84
136 85 $this->add_control(
@@ -135,17 +84,14 @@
135 84
136 85 $this->add_control(
137 86 'page_title_selector',
138 87 [
139 - 'label' => esc_html__( 'Page Title Selector', 'elementor' ),
88 + 'label' => __( 'Page Title Selector', 'elementor' ),
140 89 'type' => Controls_Manager::TEXT,
141 90 'default' => 'h1.entry-title',
142 91 'placeholder' => 'h1.entry-title',
143 - 'description' => esc_html__( 'Elementor lets you hide the page title. This works for themes that have "h1.entry-title" selector. If your theme\'s selector is different, please enter it above.', 'elementor' ),
92 + 'description' => __( 'Elementor lets you hide the page title. This works for themes that have "h1.entry-title" selector. If your theme\'s selector is different, please enter it above.', 'elementor' ),
144 93 'label_block' => true,
145 - 'ai' => [
146 - 'active' => false,
147 - ],
148 94 'selectors' => [
149 95 // Hack to convert the value into a CSS selector.
150 96 '' => '}{{VALUE}}{display: var(--page-title-display)',
151 97 ],
@@ -154,17 +100,14 @@
154 100
155 101 $this->add_control(
156 102 'stretched_section_container',
157 103 [
158 - 'label' => esc_html__( 'Stretched Section Fit To', 'elementor' ),
104 + 'label' => __( 'Stretched Section Fit To', 'elementor' ),
159 105 'type' => Controls_Manager::TEXT,
160 106 'placeholder' => 'body',
161 - 'description' => esc_html__( 'Enter parent element selector to which stretched sections will fit to (e.g. #primary / .wrapper / main etc). Leave blank to fit to page width.', 'elementor' ),
107 + 'description' => __( 'Enter parent element selector to which stretched sections will fit to (e.g. #primary / .wrapper / main etc). Leave blank to fit to page width.', 'elementor' ),
162 108 'label_block' => true,
163 109 'frontend_available' => true,
164 - 'ai' => [
165 - 'active' => false,
166 - ],
167 110 ]
168 111 );
169 112
170 113 /**
@@ -172,16 +115,13 @@
172 115 */
173 116 $page_templates_module = Plugin::$instance->modules_manager->get_modules( 'page-templates' );
174 117 $page_templates = $page_templates_module->add_page_templates( [], null, null );
175 118
176 - // Removes the Theme option from the templates because 'default' is already handled.
177 - unset( $page_templates[ PageTemplatesModule::TEMPLATE_THEME ] );
178 -
179 119 $page_template_control_options = [
180 - 'label' => esc_html__( 'Default Page Layout', 'elementor' ),
120 + 'label' => __( 'Default Page Layout', 'elementor' ),
181 121 'options' => [
182 122 // This is here because the "Theme" string is different than the default option's string.
183 - 'default' => esc_html__( 'Theme', 'elementor' ),
123 + 'default' => __( 'Theme', 'elementor' ),
184 124 ] + $page_templates,
185 125 ];
186 126
187 127 $page_templates_module->add_template_controls( $this->parent, 'default_page_template', $page_template_control_options );
@@ -190,192 +130,75 @@
190 130
191 131 $this->start_controls_section(
192 132 'section_breakpoints',
193 133 [
194 - 'label' => esc_html__( 'Breakpoints', 'elementor' ),
134 + 'label' => __( 'Breakpoints', 'elementor' ),
195 135 'tab' => $this->get_id(),
196 136 ]
197 137 );
198 138
199 - $prefix = Breakpoints_Manager::BREAKPOINT_SETTING_PREFIX;
200 - $options = [];
139 + $this->add_control(
140 + 'breakpoint_md_heading',
141 + [
142 + 'label' => __( 'Mobile', 'elementor' ),
143 + 'type' => Controls_Manager::HEADING,
144 + ]
145 + );
201 146
202 - foreach ( $breakpoints_default_config as $breakpoint_key => $breakpoint ) {
203 - $options[ $prefix . $breakpoint_key ] = $breakpoint['label'];
204 - }
147 + $this->add_control(
148 + Responsive::BREAKPOINT_OPTION_PREFIX . 'md',
149 + [
150 + 'label' => __( 'Breakpoint', 'elementor' ) . ' (px)',
151 + 'type' => Controls_Manager::NUMBER,
152 + 'min' => $default_breakpoints['sm'] + 1,
153 + 'max' => $default_breakpoints['lg'] - 1,
154 + 'default' => $default_breakpoints['md'],
155 + 'placeholder' => $default_breakpoints['md'],
156 + /* translators: %d: Breakpoint value */
157 + 'desc' => sprintf( __( 'Sets the breakpoint between tablet and mobile devices. Below this breakpoint mobile layout will appear (Default: %dpx).', 'elementor' ), $default_breakpoints['md'] ),
158 + ]
159 + );
205 160
206 - if ( Plugin::$instance->experiments->is_feature_active( 'additional_custom_breakpoints' ) ) {
207 - $active_breakpoints_control_type = Controls_Manager::SELECT2;
208 - } else {
209 - $active_breakpoints_control_type = Controls_Manager::HIDDEN;
210 - }
161 + $this->add_control(
162 + 'breakpoint_lg_heading',
163 + [
164 + 'label' => __( 'Tablet', 'elementor' ),
165 + 'type' => Controls_Manager::HEADING,
166 + ]
167 + );
211 168
212 169 $this->add_control(
213 - self::ACTIVE_BREAKPOINTS_CONTROL_ID,
170 + Responsive::BREAKPOINT_OPTION_PREFIX . 'lg',
214 171 [
215 - 'label' => esc_html__( 'Active Breakpoints', 'elementor' ),
216 - 'type' => $active_breakpoints_control_type,
217 - 'description' => esc_html__( 'Mobile and Tablet options cannot be deleted.', 'elementor' ),
218 - 'options' => $options,
219 - 'default' => [
220 - $prefix . $breakpoint_key_mobile,
221 - $prefix . $breakpoint_key_tablet,
222 - ],
223 - 'select2options' => [
224 - 'allowClear' => false,
225 - ],
226 - 'lockedOptions' => [
227 - $prefix . $breakpoint_key_mobile,
228 - $prefix . $breakpoint_key_tablet,
229 - ],
230 - 'label_block' => true,
231 - 'render_type' => 'none',
232 - 'frontend_available' => true,
233 - 'multiple' => true,
172 + 'label' => __( 'Breakpoint', 'elementor' ) . ' (px)',
173 + 'type' => Controls_Manager::NUMBER,
174 + 'min' => $default_breakpoints['md'] + 1,
175 + 'max' => $default_breakpoints['xl'] - 1,
176 + 'default' => $default_breakpoints['lg'],
177 + 'placeholder' => $default_breakpoints['lg'],
178 + /* translators: %d: Breakpoint value */
179 + 'desc' => sprintf( __( 'Sets the breakpoint between desktop and tablet devices. Below this breakpoint tablet layout will appear (Default: %dpx).', 'elementor' ), $default_breakpoints['lg'] ),
234 180 ]
235 181 );
236 182
237 - $this->add_breakpoints_controls();
238 -
239 - // Include the old mobile and tablet breakpoint controls as hidden for backwards compatibility.
240 - $this->add_control( 'viewport_md', [ 'type' => Controls_Manager::HIDDEN ] );
241 - $this->add_control( 'viewport_lg', [ 'type' => Controls_Manager::HIDDEN ] );
242 -
243 183 $this->end_controls_section();
244 184 }
245 185
246 - private function get_spacing_selectors(): array {
247 - $optimized_markup = Plugin::$instance->experiments->is_feature_active( 'e_optimized_markup' );
248 - $sections_widget_spacing = $optimized_markup
249 - ? '--kit-widget-spacing: {{ROW}}{{UNIT}}'
250 - : 'margin-block-end: {{ROW}}{{UNIT}}';
251 -
252 - return [
253 - '.elementor-widget:not(:last-child)' => $sections_widget_spacing,
254 - '.elementor-element' => '--widgets-spacing: {{ROW}}{{UNIT}} {{COLUMN}}{{UNIT}};--widgets-spacing-row: {{ROW}}{{UNIT}};--widgets-spacing-column: {{COLUMN}}{{UNIT}};',
255 - ];
256 - }
257 -
258 - /**
259 - * Before Save
260 - *
261 - * Runs Before the Kit document is saved.
262 - *
263 - * For backwards compatibility, when the mobile and tablet breakpoints are updated, we also update the
264 - * old breakpoint settings ('viewport_md', 'viewport_lg' ) with the saved values + 1px. The reason 1px
265 - * is added is because the old breakpoints system was min-width based, and the new system introduced in
266 - * Elementor v3.2.0 is max-width based.
267 - *
268 - * @since 3.2.0
269 - *
270 - * @param array $data
271 - * @return array $data
272 - */
273 - public function before_save( array $data ) {
274 - // When creating a default kit, $data['settings'] is empty and should remain empty, so settings.
275 - if ( empty( $data['settings'] ) ) {
276 - return $data;
277 - }
278 -
279 - $prefix = Breakpoints_Manager::BREAKPOINT_SETTING_PREFIX;
280 - $mobile_breakpoint_key = $prefix . Breakpoints_Manager::BREAKPOINT_KEY_MOBILE;
281 - $tablet_breakpoint_key = $prefix . Breakpoints_Manager::BREAKPOINT_KEY_TABLET;
282 -
283 - $default_breakpoint_config = Breakpoints_Manager::get_default_config();
284 -
285 - // Update the old mobile breakpoint. If the setting is empty, use the default value.
286 - $data['settings'][ $prefix . 'md' ] = empty( $data['settings'][ $mobile_breakpoint_key ] )
287 - ? $default_breakpoint_config[ Breakpoints_Manager::BREAKPOINT_KEY_MOBILE ]['default_value'] + 1
288 - : $data['settings'][ $mobile_breakpoint_key ] + 1;
289 -
290 - // Update the old tablet breakpoint. If the setting is empty, use the default value.
291 - $data['settings'][ $prefix . 'lg' ] = empty( $data['settings'][ $tablet_breakpoint_key ] )
292 - ? $default_breakpoint_config[ Breakpoints_Manager::BREAKPOINT_KEY_TABLET ]['default_value'] + 1
293 - : $data['settings'][ $tablet_breakpoint_key ] + 1;
294 -
295 - return $data;
296 - }
297 -
298 186 public function on_save( $data ) {
299 - if ( ! isset( $data['settings'] ) || ( isset( $data['settings']['post_status'] ) && Document::STATUS_PUBLISH !== $data['settings']['post_status'] ) ) {
187 + if ( ! isset( $data['settings'] ) || DB::STATUS_PUBLISH !== $data['settings']['post_status'] ) {
300 188 return;
301 189 }
302 190
303 191 $should_compile_css = false;
304 192
305 - $breakpoints_default_config = Breakpoints_Manager::get_default_config();
306 -
307 - foreach ( $breakpoints_default_config as $breakpoint_key => $default_config ) {
308 - $breakpoint_setting_key = Breakpoints_Manager::BREAKPOINT_SETTING_PREFIX . $breakpoint_key;
309 -
310 - if ( isset( $data['settings'][ $breakpoint_setting_key ] ) ) {
193 + foreach ( Responsive::get_editable_breakpoints() as $breakpoint_key => $breakpoint ) {
194 + $setting_key = "viewport_{$breakpoint_key}";
195 + if ( isset( $data['settings'][ $setting_key ] ) ) {
311 196 $should_compile_css = true;
312 197 }
313 198 }
314 199
315 200 if ( $should_compile_css ) {
316 - Breakpoints_Manager::compile_stylesheet_templates();
317 - }
318 - }
319 -
320 - private function add_breakpoints_controls() {
321 - $default_breakpoints_config = Breakpoints_Manager::get_default_config();
322 - $prefix = Breakpoints_Manager::BREAKPOINT_SETTING_PREFIX;
323 -
324 - // If the ACB experiment is inactive, only add the mobile and tablet controls.
325 - if ( ! Plugin::$instance->experiments->is_feature_active( 'additional_custom_breakpoints' ) ) {
326 - $default_breakpoints_config = array_intersect_key( $default_breakpoints_config, array_flip( [ Breakpoints_Manager::BREAKPOINT_KEY_MOBILE, Breakpoints_Manager::BREAKPOINT_KEY_TABLET ] ) );
327 - }
328 -
329 - // Add a control for each of the **default** breakpoints.
330 - foreach ( $default_breakpoints_config as $breakpoint_key => $default_breakpoint_config ) {
331 - $this->add_control(
332 - 'breakpoint_' . $breakpoint_key . '_heading',
333 - [
334 - 'label' => $default_breakpoint_config['label'],
335 - 'type' => Controls_Manager::HEADING,
336 - 'separator' => 'before',
337 - 'conditions' => [
338 - 'terms' => [
339 - [
340 - 'name' => 'active_breakpoints',
341 - 'operator' => 'contains',
342 - 'value' => $prefix . $breakpoint_key,
343 - ],
344 - ],
345 - ],
346 - ]
347 - );
348 -
349 - $control_config = [
350 - 'label' => esc_html__( 'Breakpoint', 'elementor' ) . ' (px)',
351 - 'type' => Controls_Manager::NUMBER,
352 - 'placeholder' => $default_breakpoint_config['default_value'],
353 - 'frontend_available' => true,
354 - 'validators' => [
355 - 'Breakpoint' => [
356 - 'breakpointName' => $breakpoint_key,
357 - ],
358 - ],
359 - 'conditions' => [
360 - 'terms' => [
361 - [
362 - 'name' => 'active_breakpoints',
363 - 'operator' => 'contains',
364 - 'value' => $prefix . $breakpoint_key,
365 - ],
366 - ],
367 - ],
368 - ];
369 -
370 - if ( Breakpoints_Manager::BREAKPOINT_KEY_WIDESCREEN === $breakpoint_key ) {
371 - $control_config['description'] = esc_html__(
372 - 'Widescreen breakpoint settings will apply from the selected value and up.',
373 - 'elementor'
374 - );
375 - }
376 -
377 - // Add the breakpoint Control itself.
378 - $this->add_control( $prefix . $breakpoint_key, $control_config );
201 + Responsive::compile_stylesheet_templates();
379 202 }
380 203 }
381 204 }