Skip to content

Commit 4882c16

Browse files
committed
Update Settings API: add get_allowed_html(), Tom Select clear-button styles, repeater JS, and unminified Tom Select source
1 parent a427c6b commit 4882c16

7 files changed

Lines changed: 5208 additions & 20 deletions

File tree

includes/admin/settings/class-settings-form.php

Lines changed: 114 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,105 @@ protected function get_field_attributes( $args ) {
135135
'field_name' => $field_name,
136136
);
137137
}
138+
139+
/**
140+
* Returns the allowed HTML tags and attributes for settings form output.
141+
*
142+
* Use the `{prefix}_settings_form_allowed_html` filter to add extra tags or
143+
* attributes needed by custom field types or `field_attributes` entries.
144+
*
145+
* @return array<string, array<string, bool>>
146+
*/
147+
protected function get_allowed_html(): array {
148+
$allowed = wp_kses_allowed_html( 'post' );
149+
150+
$form_tags = array(
151+
'input' => array(
152+
'type' => true,
153+
'name' => true,
154+
'id' => true,
155+
'value' => true,
156+
'class' => true,
157+
'style' => true,
158+
'checked' => true,
159+
'disabled' => true,
160+
'readonly' => true,
161+
'required' => true,
162+
'placeholder' => true,
163+
'size' => true,
164+
'min' => true,
165+
'max' => true,
166+
'step' => true,
167+
'multiple' => true,
168+
'autocomplete' => true,
169+
// Tom Select data attributes (built-in Settings API feature).
170+
'data-wp-prefix' => true,
171+
'data-wp-endpoint' => true,
172+
'data-ts-config' => true,
173+
),
174+
'select' => array(
175+
'id' => true,
176+
'name' => true,
177+
'class' => true,
178+
'style' => true,
179+
'disabled' => true,
180+
'multiple' => true,
181+
'size' => true,
182+
'autocomplete' => true,
183+
// Tom Select data attributes (built-in Settings API feature).
184+
'data-wp-prefix' => true,
185+
'data-wp-endpoint' => true,
186+
'data-ts-config' => true,
187+
),
188+
'option' => array(
189+
'value' => true,
190+
'selected' => true,
191+
'disabled' => true,
192+
),
193+
'optgroup' => array(
194+
'label' => true,
195+
'disabled' => true,
196+
),
197+
'textarea' => array(
198+
'id' => true,
199+
'name' => true,
200+
'class' => true,
201+
'style' => true,
202+
'rows' => true,
203+
'cols' => true,
204+
'disabled' => true,
205+
'readonly' => true,
206+
'required' => true,
207+
'placeholder' => true,
208+
'autocomplete' => true,
209+
),
210+
'label' => array(
211+
'for' => true,
212+
'class' => true,
213+
'style' => true,
214+
),
215+
'button' => array(
216+
'type' => true,
217+
'id' => true,
218+
'class' => true,
219+
'style' => true,
220+
'disabled' => true,
221+
),
222+
);
223+
224+
$allowed = array_replace_recursive( $allowed, $form_tags );
225+
226+
/**
227+
* Filters the allowed HTML tags and attributes for settings form output.
228+
*
229+
* Use this filter to add data attributes or custom elements required by
230+
* field_attributes entries in your registered settings.
231+
*
232+
* @param array<string, array<string, bool>> $allowed Allowed HTML tags/attributes.
233+
*/
234+
return apply_filters( $this->prefix . '_settings_form_allowed_html', $allowed ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.DynamicHooknameFound
235+
}
236+
138237
/**
139238
* Miscellaneous callback funcion
140239
*
@@ -163,7 +262,7 @@ public function callback_header( $args ) {
163262
* @param string $html HTML string.
164263
* @param array $args Arguments array.
165264
*/
166-
echo apply_filters( $this->prefix . '_after_setting_output', $html, $args ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.DynamicHooknameFound,WordPress.Security.EscapeOutput.OutputNotEscaped
265+
echo wp_kses( apply_filters( $this->prefix . '_after_setting_output', $html, $args ), $this->get_allowed_html() ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.DynamicHooknameFound
167266
}
168267

169268
/**
@@ -211,7 +310,7 @@ public function callback_text( $args ) {
211310
$html .= $this->get_field_description( $args );
212311

213312
/** This filter has been defined in class-settings-api.php */
214-
echo apply_filters( $this->prefix . '_after_setting_output', $html, $args ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.DynamicHooknameFound,WordPress.Security.EscapeOutput.OutputNotEscaped
313+
echo wp_kses( apply_filters( $this->prefix . '_after_setting_output', $html, $args ), $this->get_allowed_html() ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.DynamicHooknameFound
215314
}
216315

217316
/**
@@ -291,7 +390,7 @@ public function callback_textarea( $args ) {
291390
$html .= $this->get_field_description( $args );
292391

293392
/** This filter has been defined in class-settings-api.php */
294-
echo apply_filters( $this->prefix . '_after_setting_output', $html, $args ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.DynamicHooknameFound,WordPress.Security.EscapeOutput.OutputNotEscaped
393+
echo wp_kses( apply_filters( $this->prefix . '_after_setting_output', $html, $args ), $this->get_allowed_html() ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.DynamicHooknameFound
295394
}
296395

297396
/**
@@ -345,7 +444,7 @@ public function callback_checkbox( $args ) {
345444
$html .= $this->get_field_description( $args );
346445

347446
/** This filter has been defined in class-settings-api.php */
348-
echo apply_filters( $this->prefix . '_after_setting_output', $html, $args ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.DynamicHooknameFound,WordPress.Security.EscapeOutput.OutputNotEscaped
447+
echo wp_kses( apply_filters( $this->prefix . '_after_setting_output', $html, $args ), $this->get_allowed_html() ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.DynamicHooknameFound
349448
}
350449

351450
/**
@@ -399,7 +498,7 @@ public function callback_multicheck( $args ) {
399498
$html .= $this->get_field_description( $args );
400499

401500
/** This filter has been defined in class-settings-api.php */
402-
echo apply_filters( $this->prefix . '_after_setting_output', $html, $args ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.DynamicHooknameFound,WordPress.Security.EscapeOutput.OutputNotEscaped
501+
echo wp_kses( apply_filters( $this->prefix . '_after_setting_output', $html, $args ), $this->get_allowed_html() ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.DynamicHooknameFound
403502
}
404503

405504
/**
@@ -439,7 +538,7 @@ public function callback_radio( $args ) {
439538
$html .= $this->get_field_description( $args );
440539

441540
/** This filter has been defined in class-settings-api.php */
442-
echo apply_filters( $this->prefix . '_after_setting_output', $html, $args ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.DynamicHooknameFound,WordPress.Security.EscapeOutput.OutputNotEscaped
541+
echo wp_kses( apply_filters( $this->prefix . '_after_setting_output', $html, $args ), $this->get_allowed_html() ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.DynamicHooknameFound
443542
}
444543

445544
/**
@@ -482,7 +581,7 @@ public function callback_radiodesc( $args ) {
482581
$html .= $this->get_field_description( $args );
483582

484583
/** This filter has been defined in class-settings-api.php */
485-
echo apply_filters( $this->prefix . '_after_setting_output', $html, $args ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.DynamicHooknameFound,WordPress.Security.EscapeOutput.OutputNotEscaped
584+
echo wp_kses( apply_filters( $this->prefix . '_after_setting_output', $html, $args ), $this->get_allowed_html() ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.DynamicHooknameFound
486585
}
487586

488587
/**
@@ -534,7 +633,7 @@ public function callback_thumbsizes( $args ) {
534633
$html .= $this->get_field_description( $args );
535634

536635
/** This filter has been defined in class-settings-api.php */
537-
echo apply_filters( $this->prefix . '_after_setting_output', $html, $args ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.DynamicHooknameFound,WordPress.Security.EscapeOutput.OutputNotEscaped
636+
echo wp_kses( apply_filters( $this->prefix . '_after_setting_output', $html, $args ), $this->get_allowed_html() ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.DynamicHooknameFound
538637
}
539638

540639
/**
@@ -574,7 +673,7 @@ public function callback_number( $args ) {
574673
$html .= $this->get_field_description( $args );
575674

576675
/** This filter has been defined in class-settings-api.php */
577-
echo apply_filters( $this->prefix . '_after_setting_output', $html, $args ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.DynamicHooknameFound,WordPress.Security.EscapeOutput.OutputNotEscaped
676+
echo wp_kses( apply_filters( $this->prefix . '_after_setting_output', $html, $args ), $this->get_allowed_html() ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.DynamicHooknameFound
578677
}
579678

580679
/**
@@ -618,7 +717,7 @@ public function callback_select( $args ) {
618717
$html .= $this->get_field_description( $args );
619718

620719
/** This filter has been defined in class-settings-api.php */
621-
echo apply_filters( $this->prefix . '_after_setting_output', $html, $args ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.DynamicHooknameFound,WordPress.Security.EscapeOutput.OutputNotEscaped
720+
echo wp_kses( apply_filters( $this->prefix . '_after_setting_output', $html, $args ), $this->get_allowed_html() ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.DynamicHooknameFound
622721
}
623722

624723
/**
@@ -675,7 +774,7 @@ public function callback_posttypes( $args ) {
675774
$html .= $this->get_field_description( $args );
676775

677776
/** This filter has been defined in class-settings-api.php */
678-
echo apply_filters( $this->prefix . '_after_setting_output', $html, $args ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.DynamicHooknameFound,WordPress.Security.EscapeOutput.OutputNotEscaped
777+
echo wp_kses( apply_filters( $this->prefix . '_after_setting_output', $html, $args ), $this->get_allowed_html() ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.DynamicHooknameFound
679778
}
680779

681780

@@ -729,7 +828,7 @@ public function callback_taxonomies( $args ) {
729828
$html .= $this->get_field_description( $args );
730829

731830
/** This filter has been defined in class-settings-api.php */
732-
echo apply_filters( $this->prefix . '_after_setting_output', $html, $args ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.DynamicHooknameFound,WordPress.Security.EscapeOutput.OutputNotEscaped
831+
echo wp_kses( apply_filters( $this->prefix . '_after_setting_output', $html, $args ), $this->get_allowed_html() ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.DynamicHooknameFound
733832
}
734833

735834

@@ -792,7 +891,7 @@ public function callback_file( $args ) {
792891
$html .= $this->get_field_description( $args );
793892

794893
/** This filter has been defined in class-settings-api.php */
795-
echo apply_filters( $this->prefix . '_after_setting_output', $html, $args ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.DynamicHooknameFound,WordPress.Security.EscapeOutput.OutputNotEscaped
894+
echo wp_kses( apply_filters( $this->prefix . '_after_setting_output', $html, $args ), $this->get_allowed_html() ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.DynamicHooknameFound
796895
}
797896

798897
/**
@@ -819,7 +918,7 @@ public function callback_password( $args ) {
819918
$html .= $this->get_field_description( $args );
820919

821920
/** This filter has been defined in class-settings-api.php */
822-
echo apply_filters( $this->prefix . '_after_setting_output', $html, $args ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.DynamicHooknameFound,WordPress.Security.EscapeOutput.OutputNotEscaped
921+
echo wp_kses( apply_filters( $this->prefix . '_after_setting_output', $html, $args ), $this->get_allowed_html() ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.DynamicHooknameFound
823922
}
824923

825924
/**
@@ -867,7 +966,7 @@ public function callback_repeater( $args ) {
867966
$html .= $this->get_field_description( $args );
868967

869968
/** This filter has been defined in class-settings-api.php */
870-
echo apply_filters( $this->prefix . '_after_setting_output', $html, $args ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.DynamicHooknameFound,WordPress.Security.EscapeOutput.OutputNotEscaped
969+
echo apply_filters( $this->prefix . '_after_setting_output', $html, $args ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.DynamicHooknameFound,WordPress.Security.EscapeOutput.OutputNotEscaped -- Contains <script type="text/template"> which wp_kses would strip.
871970
}
872971

873972
/**

includes/admin/settings/css/admin-style-rtl.css

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,3 +267,15 @@
267267
background-color: #2271b1;
268268
color: #fff;
269269
}
270+
271+
.ts-wrapper.single.plugin-clear_button {
272+
position: relative;
273+
}
274+
275+
.ts-wrapper.single .clear-button {
276+
position: absolute;
277+
top: 50%;
278+
left: 8px;
279+
transform: translateY(-50%);
280+
font-size: 2em;
281+
}

includes/admin/settings/css/admin-style-rtl.min.css

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

includes/admin/settings/css/admin-style.css

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,3 +267,15 @@
267267
background-color: #2271b1;
268268
color: #fff;
269269
}
270+
271+
.ts-wrapper.single.plugin-clear_button {
272+
position: relative;
273+
}
274+
275+
.ts-wrapper.single .clear-button {
276+
position: absolute;
277+
top: 50%;
278+
right: 8px;
279+
transform: translateY(-50%);
280+
font-size: 2em;
281+
}

0 commit comments

Comments
 (0)