PluginProbe
Gutenberg / 12.1.0
Gutenberg v12.1.0
23.9.1 23.9.0 23.8.0 23.7.2 23.7.1 23.7.0 23.6.1 23.6.2 23.6.0 23.5.3 23.5.2 23.5.1 23.5.0 23.4.0 23.3.2 23.3.1 23.3.0 23.2.0 23.2.1 23.2.2 23.1.1 23.1.0 23.0.1 12.6.0 7.4.0 All 402 releases
gutenberg / build / block-library / blocks / search.php

search.php in Gutenberg 12.1.0, at build/block-library/blocks/search.php

353 lines 12.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Server-side rendering of the `core/search` block.
4 *
5 * @package WordPress
6 */
7
8 /**
9 * Dynamically renders the `core/search` block.
10 *
11 * @param array $attributes The block attributes.
12 *
13 * @return string The search block markup.
14 */
15 function gutenberg_render_block_core_search( $attributes ) {
16 static $instance_id = 0;
17
18 // Older versions of the Search block defaulted the label and buttonText
19 // attributes to `__( 'Search' )` meaning that many posts contain `<!--
20 // wp:search /-->`. Support these by defaulting an undefined label and
21 // buttonText to `__( 'Search' )`.
22 $attributes = wp_parse_args(
23 $attributes,
24 array(
25 'label' => __( 'Search' ),
26 'buttonText' => __( 'Search' ),
27 )
28 );
29
30 $input_id = 'wp-block-search__input-' . ++$instance_id;
31 $classnames = gutenberg_classnames_for_block_core_search( $attributes );
32 $show_label = ( ! empty( $attributes['showLabel'] ) ) ? true : false;
33 $use_icon_button = ( ! empty( $attributes['buttonUseIcon'] ) ) ? true : false;
34 $show_input = ( ! empty( $attributes['buttonPosition'] ) && 'button-only' === $attributes['buttonPosition'] ) ? false : true;
35 $show_button = ( ! empty( $attributes['buttonPosition'] ) && 'no-button' === $attributes['buttonPosition'] ) ? false : true;
36 $label_markup = '';
37 $input_markup = '';
38 $button_markup = '';
39 $inline_styles = gutenberg_styles_for_block_core_search( $attributes );
40 $color_classes = gutenberg_get_color_classes_for_block_core_search( $attributes );
41 $is_button_inside = ! empty( $attributes['buttonPosition'] ) &&
42 'button-inside' === $attributes['buttonPosition'];
43 // Border color classes need to be applied to the elements that have a border color.
44 $border_color_classes = gutenberg_get_border_color_classes_for_block_core_search( $attributes );
45
46 $label_markup = sprintf(
47 '<label for="%1$s" class="wp-block-search__label screen-reader-text">%2$s</label>',
48 $input_id,
49 empty( $attributes['label'] ) ? __( 'Search' ) : $attributes['label']
50 );
51 if ( $show_label && ! empty( $attributes['label'] ) ) {
52 $label_markup = sprintf(
53 '<label for="%1$s" class="wp-block-search__label">%2$s</label>',
54 $input_id,
55 $attributes['label']
56 );
57 }
58
59 if ( $show_input ) {
60 $input_classes = ! $is_button_inside ? $border_color_classes : '';
61 $input_markup = sprintf(
62 '<input type="search" id="%s" class="wp-block-search__input %s" name="s" value="%s" placeholder="%s" %s required />',
63 $input_id,
64 $input_classes,
65 esc_attr( get_search_query() ),
66 esc_attr( $attributes['placeholder'] ),
67 $inline_styles['input']
68 );
69 }
70
71 if ( $show_button ) {
72 $button_internal_markup = '';
73 $button_classes = $color_classes;
74
75 if ( ! $is_button_inside ) {
76 $button_classes .= ' ' . $border_color_classes;
77 }
78 if ( ! $use_icon_button ) {
79 if ( ! empty( $attributes['buttonText'] ) ) {
80 $button_internal_markup = $attributes['buttonText'];
81 }
82 } else {
83 $button_classes .= ' has-icon';
84 $button_internal_markup =
85 '<svg id="search-icon" class="search-icon" viewBox="0 0 24 24" width="24" height="24">
86 <path d="M13.5 6C10.5 6 8 8.5 8 11.5c0 1.1.3 2.1.9 3l-3.4 3 1 1.1 3.4-2.9c1 .9 2.2 1.4 3.6 1.4 3 0 5.5-2.5 5.5-5.5C19 8.5 16.5 6 13.5 6zm0 9.5c-2.2 0-4-1.8-4-4s1.8-4 4-4 4 1.8 4 4-1.8 4-4 4z"></path>
87 </svg>';
88 }
89
90 $button_markup = sprintf(
91 '<button type="submit" class="wp-block-search__button %s" %s>%s</button>',
92 $button_classes,
93 $inline_styles['button'],
94 $button_internal_markup
95 );
96 }
97
98 $field_markup_classes = $is_button_inside ? $border_color_classes : '';
99 $field_markup = sprintf(
100 '<div class="wp-block-search__inside-wrapper %s" %s>%s</div>',
101 $field_markup_classes,
102 $inline_styles['wrapper'],
103 $input_markup . $button_markup
104 );
105 $wrapper_attributes = get_block_wrapper_attributes( array( 'class' => $classnames ) );
106
107 return sprintf(
108 '<form role="search" method="get" action="%s" %s>%s</form>',
109 esc_url( home_url( '/' ) ),
110 $wrapper_attributes,
111 $label_markup . $field_markup
112 );
113 }
114
115 /**
116 * Registers the `core/search` block on the server.
117 */
118 function gutenberg_register_block_core_search() {
119 register_block_type_from_metadata(
120 __DIR__ . '/search',
121 array(
122 'render_callback' => 'gutenberg_render_block_core_search',
123 )
124 );
125 }
126 add_action( 'init', 'gutenberg_register_block_core_search', 20 );
127
128 /**
129 * Builds the correct top level classnames for the 'core/search' block.
130 *
131 * @param array $attributes The block attributes.
132 *
133 * @return string The classnames used in the block.
134 */
135 function gutenberg_classnames_for_block_core_search( $attributes ) {
136 $classnames = array();
137
138 if ( ! empty( $attributes['buttonPosition'] ) ) {
139 if ( 'button-inside' === $attributes['buttonPosition'] ) {
140 $classnames[] = 'wp-block-search__button-inside';
141 }
142
143 if ( 'button-outside' === $attributes['buttonPosition'] ) {
144 $classnames[] = 'wp-block-search__button-outside';
145 }
146
147 if ( 'no-button' === $attributes['buttonPosition'] ) {
148 $classnames[] = 'wp-block-search__no-button';
149 }
150
151 if ( 'button-only' === $attributes['buttonPosition'] ) {
152 $classnames[] = 'wp-block-search__button-only';
153 }
154 }
155
156 if ( isset( $attributes['buttonUseIcon'] ) ) {
157 if ( ! empty( $attributes['buttonPosition'] ) && 'no-button' !== $attributes['buttonPosition'] ) {
158 if ( $attributes['buttonUseIcon'] ) {
159 $classnames[] = 'wp-block-search__icon-button';
160 } else {
161 $classnames[] = 'wp-block-search__text-button';
162 }
163 }
164 }
165
166 return implode( ' ', $classnames );
167 }
168
169 /**
170 * Builds an array of inline styles for the search block.
171 *
172 * The result will contain one entry for shared styles such as those for the
173 * inner input or button and a second for the inner wrapper should the block
174 * be positioning the button "inside".
175 *
176 * @param array $attributes The block attributes.
177 *
178 * @return array Style HTML attribute.
179 */
180 function gutenberg_styles_for_block_core_search( $attributes ) {
181 $wrapper_styles = array();
182 $button_styles = array();
183 $input_styles = array();
184
185 // Add width styles.
186 $has_width = ! empty( $attributes['width'] ) && ! empty( $attributes['widthUnit'] );
187 $button_only = ! empty( $attributes['buttonPosition'] ) && 'button-only' === $attributes['buttonPosition'];
188
189 if ( $has_width && ! $button_only ) {
190 $wrapper_styles[] = sprintf(
191 'width: %d%s;',
192 esc_attr( $attributes['width'] ),
193 esc_attr( $attributes['widthUnit'] )
194 );
195 }
196
197 // Add border radius styles.
198 $has_border_radius = ! empty( $attributes['style']['border']['radius'] );
199
200 if ( $has_border_radius ) {
201 $default_padding = '4px';
202 $border_radius = $attributes['style']['border']['radius'];
203 // Apply wrapper border radius if button placed inside.
204 $is_button_inside = ! empty( $attributes['buttonPosition'] ) &&
205 'button-inside' === $attributes['buttonPosition'];
206
207 if ( is_array( $border_radius ) ) {
208 // Apply styles for individual corner border radii.
209 foreach ( $border_radius as $key => $value ) {
210 if ( null !== $value ) {
211 // Convert camelCase key to kebab-case.
212 $name = strtolower( preg_replace( '/(?<!^)[A-Z]/', '-$0', $key ) );
213
214 // Add shared styles for individual border radii for input & button.
215 $border_style = sprintf(
216 'border-%s-radius: %s;',
217 esc_attr( $name ),
218 esc_attr( $value )
219 );
220 $input_styles[] = $border_style;
221 $button_styles[] = $border_style;
222
223 // Add adjusted border radius styles for the wrapper element
224 // if button is positioned inside.
225 if ( $is_button_inside && intval( $value ) !== 0 ) {
226 $wrapper_styles[] = sprintf(
227 'border-%s-radius: calc(%s + %s);',
228 esc_attr( $name ),
229 esc_attr( $value ),
230 $default_padding
231 );
232 }
233 }
234 }
235 } else {
236 // Numeric check is for backwards compatibility purposes.
237 $border_radius = is_numeric( $border_radius ) ? $border_radius . 'px' : $border_radius;
238 $border_style = sprintf( 'border-radius: %s;', esc_attr( $border_radius ) );
239 $input_styles[] = $border_style;
240 $button_styles[] = $border_style;
241
242 if ( $is_button_inside && intval( $border_radius ) !== 0 ) {
243 // Adjust wrapper border radii to maintain visual consistency
244 // with inner elements when button is positioned inside.
245 $wrapper_styles[] = sprintf(
246 'border-radius: calc(%s + %s);',
247 esc_attr( $border_radius ),
248 $default_padding
249 );
250 }
251 }
252 }
253
254 // Add border color styles.
255 $has_border_color = ! empty( $attributes['style']['border']['color'] );
256
257 if ( $has_border_color ) {
258 $border_color = $attributes['style']['border']['color'];
259 $is_button_inside = ! empty( $attributes['buttonPosition'] ) &&
260 'button-inside' === $attributes['buttonPosition'];
261
262 // Apply wrapper border color if button placed inside.
263 if ( $is_button_inside ) {
264 $wrapper_styles[] = sprintf( 'border-color: %s;', esc_attr( $border_color ) );
265 } else {
266 $button_styles[] = sprintf( 'border-color: %s;', esc_attr( $border_color ) );
267 $input_styles[] = sprintf( 'border-color: %s;', esc_attr( $border_color ) );
268 }
269 }
270
271 // Add color styles.
272 $has_text_color = ! empty( $attributes['style']['color']['text'] );
273 if ( $has_text_color ) {
274 $button_styles[] = sprintf( 'color: %s;', esc_attr( $attributes['style']['color']['text'] ) );
275 }
276
277 $has_background_color = ! empty( $attributes['style']['color']['background'] );
278 if ( $has_background_color ) {
279 $button_styles[] = sprintf( 'background-color: %s;', esc_attr( $attributes['style']['color']['background'] ) );
280 }
281
282 $has_custom_gradient = ! empty( $attributes['style']['color']['gradient'] );
283 if ( $has_custom_gradient ) {
284 $button_styles[] = sprintf( 'background: %s;', $attributes['style']['color']['gradient'] );
285 }
286
287 return array(
288 'input' => ! empty( $input_styles ) ? sprintf( ' style="%s"', implode( ' ', $input_styles ) ) : '',
289 'button' => ! empty( $button_styles ) ? sprintf( ' style="%s"', implode( ' ', $button_styles ) ) : '',
290 'wrapper' => ! empty( $wrapper_styles ) ? sprintf( ' style="%s"', implode( ' ', $wrapper_styles ) ) : '',
291 );
292 }
293
294 /**
295 * Returns border color classnames depending on whether there are named or custom border colors.
296 *
297 * @param array $attributes The block attributes.
298 *
299 * @return string The border color classnames to be applied to the block elements.
300 */
301 function gutenberg_get_border_color_classes_for_block_core_search( $attributes ) {
302 $has_custom_border_color = ! empty( $attributes['style']['border']['color'] );
303 $border_color_classes = ! empty( $attributes['borderColor'] ) ? sprintf( 'has-border-color has-%s-border-color', $attributes['borderColor'] ) : '';
304 // If there's a border color style and no `borderColor` text string, we still want to add the generic `has-border-color` class name to the element.
305 if ( $has_custom_border_color && empty( $attributes['borderColor'] ) ) {
306 $border_color_classes = 'has-border-color';
307 }
308 return $border_color_classes;
309 }
310
311 /**
312 * Returns color classnames depending on whether there are named or custom text and background colors.
313 *
314 * @param array $attributes The block attributes.
315 *
316 * @return string The color classnames to be applied to the block elements.
317 */
318 function gutenberg_get_color_classes_for_block_core_search( $attributes ) {
319 $classnames = array();
320
321 // Text color.
322 $has_named_text_color = ! empty( $attributes['textColor'] );
323 $has_custom_text_color = ! empty( $attributes['style']['color']['text'] );
324 if ( $has_named_text_color ) {
325 $classnames[] = sprintf( 'has-text-color has-%s-color', $attributes['textColor'] );
326 } elseif ( $has_custom_text_color ) {
327 // If a custom 'textColor' was selected instead of a preset, still add the generic `has-text-color` class.
328 $classnames[] = 'has-text-color';
329 }
330
331 // Background color.
332 $has_named_background_color = ! empty( $attributes['backgroundColor'] );
333 $has_custom_background_color = ! empty( $attributes['style']['color']['background'] );
334 $has_named_gradient = ! empty( $attributes['gradient'] );
335 $has_custom_gradient = ! empty( $attributes['style']['color']['gradient'] );
336 if (
337 $has_named_background_color ||
338 $has_custom_background_color ||
339 $has_named_gradient ||
340 $has_custom_gradient
341 ) {
342 $classnames[] = 'has-background';
343 }
344 if ( $has_named_background_color ) {
345 $classnames[] = sprintf( 'has-%s-background-color', $attributes['backgroundColor'] );
346 }
347 if ( $has_named_gradient ) {
348 $classnames[] = sprintf( 'has-%s-gradient-background', $attributes['gradient'] );
349 }
350
351 return implode( ' ', $classnames );
352 }
353