ÿØÿà JFIF ÿÛ „ ( %!1!%*+...983,7(-.- class-wp-widget-pages.php 0000644 00000013130 15234243711 0011364 0 ustar 00 'widget_pages', 'description' => __( 'A list of your site’s Pages.' ), 'customize_selective_refresh' => true, 'show_instance_in_rest' => true, ); parent::__construct( 'pages', __( 'Pages' ), $widget_ops ); } /** * Outputs the content for the current Pages widget instance. * * @since 2.8.0 * * @param array $args Display arguments including 'before_title', 'after_title', * 'before_widget', and 'after_widget'. * @param array $instance Settings for the current Pages widget instance. */ public function widget( $args, $instance ) { $default_title = __( 'Pages' ); $title = ! empty( $instance['title'] ) ? $instance['title'] : $default_title; /** * Filters the widget title. * * @since 2.6.0 * * @param string $title The widget title. Default 'Pages'. * @param array $instance Array of settings for the current widget. * @param mixed $id_base The widget ID. */ $title = apply_filters( 'widget_title', $title, $instance, $this->id_base ); $sortby = empty( $instance['sortby'] ) ? 'menu_order' : $instance['sortby']; $exclude = empty( $instance['exclude'] ) ? '' : $instance['exclude']; if ( 'menu_order' === $sortby ) { $sortby = 'menu_order, post_title'; } $output = wp_list_pages( /** * Filters the arguments for the Pages widget. * * @since 2.8.0 * @since 4.9.0 Added the `$instance` parameter. * * @see wp_list_pages() * * @param array $args An array of arguments to retrieve the pages list. * @param array $instance Array of settings for the current widget. */ apply_filters( 'widget_pages_args', array( 'title_li' => '', 'echo' => 0, 'sort_column' => $sortby, 'exclude' => $exclude, ), $instance ) ); if ( ! empty( $output ) ) { echo $args['before_widget']; if ( $title ) { echo $args['before_title'] . $title . $args['after_title']; } $format = current_theme_supports( 'html5', 'navigation-widgets' ) ? 'html5' : 'xhtml'; /** This filter is documented in wp-includes/widgets/class-wp-nav-menu-widget.php */ $format = apply_filters( 'navigation_widgets_format', $format ); if ( 'html5' === $format ) { // The title may be filtered: Strip out HTML and make sure the aria-label is never empty. $title = trim( strip_tags( $title ) ); $aria_label = $title ? $title : $default_title; echo '
__( 'A cloud of your most used tags.' ), 'customize_selective_refresh' => true, 'show_instance_in_rest' => true, ); parent::__construct( 'tag_cloud', __( 'Tag Cloud' ), $widget_ops ); } /** * Outputs the content for the current Tag Cloud widget instance. * * @since 2.8.0 * * @param array $args Display arguments including 'before_title', 'after_title', * 'before_widget', and 'after_widget'. * @param array $instance Settings for the current Tag Cloud widget instance. */ public function widget( $args, $instance ) { $current_taxonomy = $this->_get_current_taxonomy( $instance ); if ( ! empty( $instance['title'] ) ) { $title = $instance['title']; } else { if ( 'post_tag' === $current_taxonomy ) { $title = __( 'Tags' ); } else { $tax = get_taxonomy( $current_taxonomy ); $title = $tax->labels->name; } } $default_title = $title; $show_count = ! empty( $instance['count'] ); $tag_cloud = wp_tag_cloud( /** * Filters the taxonomy used in the Tag Cloud widget. * * @since 2.8.0 * @since 3.0.0 Added taxonomy drop-down. * @since 4.9.0 Added the `$instance` parameter. * * @see wp_tag_cloud() * * @param array $args Args used for the tag cloud widget. * @param array $instance Array of settings for the current widget. */ apply_filters( 'widget_tag_cloud_args', array( 'taxonomy' => $current_taxonomy, 'echo' => false, 'show_count' => $show_count, ), $instance ) ); if ( empty( $tag_cloud ) ) { return; } /** This filter is documented in wp-includes/widgets/class-wp-widget-pages.php */ $title = apply_filters( 'widget_title', $title, $instance, $this->id_base ); echo $args['before_widget']; if ( $title ) { echo $args['before_title'] . $title . $args['after_title']; } $format = current_theme_supports( 'html5', 'navigation-widgets' ) ? 'html5' : 'xhtml'; /** This filter is documented in wp-includes/widgets/class-wp-nav-menu-widget.php */ $format = apply_filters( 'navigation_widgets_format', $format ); if ( 'html5' === $format ) { // The title may be filtered: Strip out HTML and make sure the aria-label is never empty. $title = trim( strip_tags( $title ) ); $aria_label = $title ? $title : $default_title; echo ''; } echo $args['after_widget']; } /** * Handles updating settings for the current Tag Cloud widget instance. * * @since 2.8.0 * * @param array $new_instance New settings for this instance as input by the user via * WP_Widget::form(). * @param array $old_instance Old settings for this instance. * @return array Settings to save or bool false to cancel saving. */ public function update( $new_instance, $old_instance ) { $instance = array(); $instance['title'] = sanitize_text_field( $new_instance['title'] ); $instance['count'] = ! empty( $new_instance['count'] ) ? 1 : 0; $instance['taxonomy'] = stripslashes( $new_instance['taxonomy'] ); return $instance; } /** * Outputs the Tag Cloud widget settings form. * * @since 2.8.0 * * @param array $instance Current settings. */ public function form( $instance ) { $title = ! empty( $instance['title'] ) ? $instance['title'] : ''; $count = isset( $instance['count'] ) ? (bool) $instance['count'] : false; ?>true ), 'object' ); $current_taxonomy = $this->_get_current_taxonomy( $instance ); switch ( count( $taxonomies ) ) { // No tag cloud supporting taxonomies found, display error message. case 0: ?>
0 ) { ?>
/>
'widget_recent_comments', 'description' => __( 'Your site’s most recent comments.' ), 'customize_selective_refresh' => true, 'show_instance_in_rest' => true, ); parent::__construct( 'recent-comments', __( 'Recent Comments' ), $widget_ops ); $this->alt_option_name = 'widget_recent_comments'; if ( is_active_widget( false, false, $this->id_base ) || is_customize_preview() ) { add_action( 'wp_head', array( $this, 'recent_comments_style' ) ); } } /** * Outputs the default styles for the Recent Comments widget. * * @since 2.8.0 */ public function recent_comments_style() { /** * Filters the Recent Comments default widget styles. * * @since 3.1.0 * * @param bool $active Whether the widget is active. Default true. * @param string $id_base The widget ID. */ if ( ! current_theme_supports( 'widgets' ) // Temp hack #14876. || ! apply_filters( 'show_recent_comments_widget_style', true, $this->id_base ) ) { return; } echo ''; } /** * Outputs the content for the current Recent Comments widget instance. * * @since 2.8.0 * @since 5.4.0 Creates a unique HTML ID for the `
'widget_calendar', 'description' => __( 'A calendar of your site’s posts.' ), 'customize_selective_refresh' => true, 'show_instance_in_rest' => true, ); parent::__construct( 'calendar', __( 'Calendar' ), $widget_ops ); } /** * Outputs the content for the current Calendar widget instance. * * @since 2.8.0 * * @param array $args Display arguments including 'before_title', 'after_title', * 'before_widget', and 'after_widget'. * @param array $instance The settings for the particular instance of the widget. */ public function widget( $args, $instance ) { $title = ! empty( $instance['title'] ) ? $instance['title'] : ''; /** This filter is documented in wp-includes/widgets/class-wp-widget-pages.php */ $title = apply_filters( 'widget_title', $title, $instance, $this->id_base ); echo $args['before_widget']; if ( $title ) { echo $args['before_title'] . $title . $args['after_title']; } if ( 0 === self::$instance ) { echo '
'', 'content' => '', ); /** * Sets up a new Custom HTML widget instance. * * @since 4.8.1 */ public function __construct() { $widget_ops = array( 'classname' => 'widget_custom_html', 'description' => __( 'Arbitrary HTML code.' ), 'customize_selective_refresh' => true, 'show_instance_in_rest' => true, ); $control_ops = array( 'width' => 400, 'height' => 350, ); parent::__construct( 'custom_html', __( 'Custom HTML' ), $widget_ops, $control_ops ); } /** * Add hooks for enqueueing assets when registering all widget instances of this widget class. * * @since 4.9.0 * * @param int $number Optional. The unique order number of this widget instance * compared to other instances of the same class. Default -1. */ public function _register_one( $number = -1 ) { parent::_register_one( $number ); if ( $this->registered ) { return; } $this->registered = true; /* * Note that the widgets component in the customizer will also do * the 'admin_print_scripts-widgets.php' action in WP_Customize_Widgets::print_scripts(). */ add_action( 'admin_print_scripts-widgets.php', array( $this, 'enqueue_admin_scripts' ) ); /* * Note that the widgets component in the customizer will also do * the 'admin_footer-widgets.php' action in WP_Customize_Widgets::print_footer_scripts(). */ add_action( 'admin_footer-widgets.php', array( 'WP_Widget_Custom_HTML', 'render_control_template_scripts' ) ); // Note this action is used to ensure the help text is added to the end. add_action( 'admin_head-widgets.php', array( 'WP_Widget_Custom_HTML', 'add_help_text' ) ); } /** * Filters gallery shortcode attributes. * * Prevents all of a site's attachments from being shown in a gallery displayed on a * non-singular template where a $post context is not available. * * @since 4.9.0 * * @param array $attrs Attributes. * @return array Attributes. */ public function _filter_gallery_shortcode_attrs( $attrs ) { if ( ! is_singular() && empty( $attrs['id'] ) && empty( $attrs['include'] ) ) { $attrs['id'] = -1; } return $attrs; } /** * Outputs the content for the current Custom HTML widget instance. * * @since 4.8.1 * * @global WP_Post $post Global post object. * * @param array $args Display arguments including 'before_title', 'after_title', * 'before_widget', and 'after_widget'. * @param array $instance Settings for the current Custom HTML widget instance. */ public function widget( $args, $instance ) { global $post; // Override global $post so filters (and shortcodes) apply in a consistent context. $original_post = $post; if ( is_singular() ) { // Make sure post is always the queried object on singular queries (not from another sub-query that failed to clean up the global $post). $post = get_queried_object(); } else { // Nullify the $post global during widget rendering to prevent shortcodes from running with the unexpected context on archive queries. $post = null; } // Prevent dumping out all attachments from the media library. add_filter( 'shortcode_atts_gallery', array( $this, '_filter_gallery_shortcode_attrs' ) ); $instance = array_merge( $this->default_instance, $instance ); /** This filter is documented in wp-includes/widgets/class-wp-widget-pages.php */ $title = apply_filters( 'widget_title', $instance['title'], $instance, $this->id_base ); // Prepare instance data that looks like a normal Text widget. $simulated_text_widget_instance = array_merge( $instance, array( 'text' => $instance['content'] ?? '', 'filter' => false, // Because wpautop is not applied. 'visual' => false, // Because it wasn't created in TinyMCE. ) ); unset( $simulated_text_widget_instance['content'] ); // Was moved to 'text' prop. /** This filter is documented in wp-includes/widgets/class-wp-widget-text.php */ $content = apply_filters( 'widget_text', $instance['content'], $simulated_text_widget_instance, $this ); /** * Filters the content of the Custom HTML widget. * * @since 4.8.1 * * @param string $content The widget content. * @param array $instance Array of settings for the current widget. * @param WP_Widget_Custom_HTML $widget Current Custom HTML widget instance. */ $content = apply_filters( 'widget_custom_html_content', $content, $instance, $this ); // Restore post global. $post = $original_post; remove_filter( 'shortcode_atts_gallery', array( $this, '_filter_gallery_shortcode_attrs' ) ); // Inject the Text widget's container class name alongside this widget's class name for theme styling compatibility. $args['before_widget'] = preg_replace( '/(?<=\sclass=["\'])/', 'widget_text ', $args['before_widget'] ); echo $args['before_widget']; if ( ! empty( $title ) ) { echo $args['before_title'] . $title . $args['after_title']; } echo ''; echo $args['after_widget']; } /** * Handles updating settings for the current Custom HTML widget instance. * * @since 4.8.1 * * @param array $new_instance New settings for this instance as input by the user via * WP_Widget::form(). * @param array $old_instance Old settings for this instance. * @return array Settings to save or bool false to cancel saving. */ public function update( $new_instance, $old_instance ) { $instance = array_merge( $this->default_instance, $old_instance ); $instance['title'] = sanitize_text_field( $new_instance['title'] ); if ( current_user_can( 'unfiltered_html' ) ) { $instance['content'] = $new_instance['content']; } else { $instance['content'] = wp_kses_post( $new_instance['content'] ); } return $instance; } /** * Loads the required scripts and styles for the widget control. * * @since 4.9.0 */ public function enqueue_admin_scripts() { $settings = wp_enqueue_code_editor( array( 'type' => 'text/html', 'codemirror' => array( 'indentUnit' => 2, 'tabSize' => 2, ), ) ); wp_enqueue_script( 'custom-html-widgets' ); wp_add_inline_script( 'custom-html-widgets', sprintf( 'wp.customHtmlWidgets.idBases.push( %s );', wp_json_encode( $this->id_base, JSON_HEX_TAG | JSON_UNESCAPED_SLASHES ) ) ); if ( empty( $settings ) ) { $settings = array( 'disabled' => true, ); } wp_add_inline_script( 'custom-html-widgets', sprintf( 'wp.customHtmlWidgets.init( %s );', wp_json_encode( $settings, JSON_HEX_TAG | JSON_UNESCAPED_SLASHES ) ), 'after' ); $l10n = array( 'errorNotice' => array( /* translators: %d: Error count. */ 'singular' => _n( 'There is %d error which must be fixed before you can save.', 'There are %d errors which must be fixed before you can save.', 1 ), /* translators: %d: Error count. */ 'plural' => _n( 'There is %d error which must be fixed before you can save.', 'There are %d errors which must be fixed before you can save.', 2 ), // @todo This is lacking, as some languages have a dedicated dual form. For proper handling of plurals in JS, see #20491. ), ); wp_add_inline_script( 'custom-html-widgets', sprintf( 'jQuery.extend( wp.customHtmlWidgets.l10n, %s );', wp_json_encode( $l10n, JSON_HEX_TAG | JSON_UNESCAPED_SLASHES ) ), 'after' ); } /** * Outputs the Custom HTML widget settings form. * * @since 4.8.1 * @since 4.9.0 The form contains only hidden sync inputs. For the control UI, see `WP_Widget_Custom_HTML::render_control_template_scripts()`. * * @see WP_Widget_Custom_HTML::render_control_template_scripts() * * @param array $instance Current instance. */ public function form( $instance ) { $instance = wp_parse_args( (array) $instance, $this->default_instance ); ?> '; $content .= __( 'Use the Custom HTML widget to add arbitrary HTML code to your widget areas.' ); $content .= ''; if ( 'false' !== wp_get_current_user()->syntax_highlighting ) { $content .= '
'; $content .= sprintf( /* translators: 1: Link to user profile, 2: Additional link attributes, 3: Accessibility text. */ __( 'The edit field automatically highlights code syntax. You can disable this in your user profile%3$s to work in plain text mode.' ), esc_url( get_edit_profile_url() ), 'class="external-link" target="_blank"', sprintf( ' %s', /* translators: Hidden accessibility text. */ __( '(opens in a new tab)' ) ) ); $content .= '
'; $content .= '' . __( 'When using a keyboard to navigate:' ) . '
'; $content .= '
id="get_field_id( 'images' ); ?>" name="get_field_name( 'images' ); ?>" />
id="get_field_id( 'name' ); ?>" name="get_field_name( 'name' ); ?>" />
id="get_field_id( 'description' ); ?>" name="get_field_name( 'description' ); ?>" />
id="get_field_id( 'rating' ); ?>" name="get_field_name( 'rating' ); ?>" />
'widget_search', 'description' => __( 'A search form for your site.' ), 'customize_selective_refresh' => true, 'show_instance_in_rest' => true, ); parent::__construct( 'search', _x( 'Search', 'Search widget' ), $widget_ops ); } /** * Outputs the content for the current Search widget instance. * * @since 2.8.0 * * @param array $args Display arguments including 'before_title', 'after_title', * 'before_widget', and 'after_widget'. * @param array $instance Settings for the current Search widget instance. */ public function widget( $args, $instance ) { $title = ! empty( $instance['title'] ) ? $instance['title'] : ''; /** This filter is documented in wp-includes/widgets/class-wp-widget-pages.php */ $title = apply_filters( 'widget_title', $title, $instance, $this->id_base ); echo $args['before_widget']; if ( $title ) { echo $args['before_title'] . $title . $args['after_title']; } // Use active theme search form if it exists. get_search_form(); echo $args['after_widget']; } /** * Outputs the settings form for the Search widget. * * @since 2.8.0 * * @param array $instance Current settings. */ public function form( $instance ) { $instance = wp_parse_args( (array) $instance, array( 'title' => '' ) ); $title = $instance['title']; ?>
'' ) ); $instance['title'] = sanitize_text_field( $new_instance['title'] ); return $instance; } } class-wp-widget-recent-posts.php 0000644 00000013421 15234243711 0012716 0 ustar 00 'widget_recent_entries', 'description' => __( 'Your site’s most recent Posts.' ), 'customize_selective_refresh' => true, 'show_instance_in_rest' => true, ); parent::__construct( 'recent-posts', __( 'Recent Posts' ), $widget_ops ); $this->alt_option_name = 'widget_recent_entries'; } /** * Outputs the content for the current Recent Posts widget instance. * * @since 2.8.0 * * @param array $args Display arguments including 'before_title', 'after_title', * 'before_widget', and 'after_widget'. * @param array $instance Settings for the current Recent Posts widget instance. */ public function widget( $args, $instance ) { if ( ! isset( $args['widget_id'] ) ) { $args['widget_id'] = $this->id; } $default_title = __( 'Recent Posts' ); $title = ( ! empty( $instance['title'] ) ) ? $instance['title'] : $default_title; /** This filter is documented in wp-includes/widgets/class-wp-widget-pages.php */ $title = apply_filters( 'widget_title', $title, $instance, $this->id_base ); $number = ( ! empty( $instance['number'] ) ) ? absint( $instance['number'] ) : 5; if ( ! $number ) { $number = 5; } $show_date = $instance['show_date'] ?? false; $r = new WP_Query( /** * Filters the arguments for the Recent Posts widget. * * @since 3.4.0 * @since 4.9.0 Added the `$instance` parameter. * * @see WP_Query::get_posts() * * @param array $args An array of arguments used to retrieve the recent posts. * @param array $instance Array of settings for the current widget. */ apply_filters( 'widget_posts_args', array( 'posts_per_page' => $number, 'no_found_rows' => true, 'post_status' => 'publish', 'ignore_sticky_posts' => true, ), $instance ) ); if ( ! $r->have_posts() ) { return; } ?> '; } ?>
id="get_field_id( 'show_date' ); ?>" name="get_field_name( 'show_date' ); ?>" />
__( 'Displays a video from the media library or from YouTube, Vimeo, or another provider.' ), 'mime_type' => 'video', ) ); $this->l10n = array_merge( $this->l10n, array( 'no_media_selected' => __( 'No video selected' ), 'add_media' => _x( 'Add Video', 'label for button in the video widget' ), 'replace_media' => _x( 'Replace Video', 'label for button in the video widget; should preferably not be longer than ~13 characters long' ), 'edit_media' => _x( 'Edit Video', 'label for button in the video widget; should preferably not be longer than ~13 characters long' ), 'missing_attachment' => sprintf( /* translators: %s: URL to media library. */ __( 'That video cannot be found. Check your media library and make sure it was not deleted.' ), esc_url( admin_url( 'upload.php' ) ) ), /* translators: %d: Widget count. */ 'media_library_state_multi' => _n_noop( 'Video Widget (%d)', 'Video Widget (%d)' ), 'media_library_state_single' => __( 'Video Widget' ), /* translators: %s: A list of valid video file extensions. */ 'unsupported_file_type' => sprintf( __( 'Sorry, the video at the supplied URL cannot be loaded. Please check that the URL is for a supported video file (%s) or stream (e.g. YouTube and Vimeo).' ), '.' . implode( ', .', wp_get_video_extensions() ) . '' ),
)
);
}
/**
* Get schema for properties of a widget instance (item).
*
* @since 4.8.0
*
* @see WP_REST_Controller::get_item_schema()
* @see WP_REST_Controller::get_additional_fields()
* @link https://core.trac.wordpress.org/ticket/35574
*
* @return array Schema for properties.
*/
public function get_instance_schema() {
$schema = array(
'preload' => array(
'type' => 'string',
'enum' => array( 'none', 'auto', 'metadata' ),
'default' => 'metadata',
'description' => __( 'Preload' ),
'should_preview_update' => false,
),
'loop' => array(
'type' => 'boolean',
'default' => false,
'description' => __( 'Loop' ),
'should_preview_update' => false,
),
'content' => array(
'type' => 'string',
'default' => '',
'sanitize_callback' => 'wp_kses_post',
'description' => __( 'Tracks (subtitles, captions, descriptions, chapters, or metadata)' ),
'should_preview_update' => false,
),
);
foreach ( wp_get_video_extensions() as $video_extension ) {
$schema[ $video_extension ] = array(
'type' => 'string',
'default' => '',
'format' => 'uri',
/* translators: %s: Video extension. */
'description' => sprintf( __( 'URL to the %s video source file' ), $video_extension ),
);
}
return array_merge( $schema, parent::get_instance_schema() );
}
/**
* Render the media on the frontend.
*
* @since 4.8.0
*
* @param array $instance Widget instance props.
*/
public function render_media( $instance ) {
$instance = array_merge( wp_list_pluck( $this->get_instance_schema(), 'default' ), $instance );
$attachment = null;
if ( $this->is_attachment_with_mime_type( $instance['attachment_id'], $this->widget_options['mime_type'] ) ) {
$attachment = get_post( $instance['attachment_id'] );
}
$src = $instance['url'];
if ( $attachment ) {
$src = wp_get_attachment_url( $attachment->ID );
}
if ( empty( $src ) ) {
return;
}
$youtube_pattern = '#^https?://(?:www\.)?(?:youtube\.com/watch|youtu\.be/)#';
$vimeo_pattern = '#^https?://(.+\.)?vimeo\.com/.*#';
if ( $attachment || preg_match( $youtube_pattern, $src ) || preg_match( $vimeo_pattern, $src ) ) {
add_filter( 'wp_video_shortcode', array( $this, 'inject_video_max_width_style' ) );
echo wp_video_shortcode(
array_merge(
$instance,
compact( 'src' )
),
$instance['content']
);
remove_filter( 'wp_video_shortcode', array( $this, 'inject_video_max_width_style' ) );
} else {
echo $this->inject_video_max_width_style( wp_oembed_get( $src ) );
}
}
/**
* Inject max-width and remove height for videos too constrained to fit inside sidebars on frontend.
*
* @since 4.8.0
*
* @param string $html Video shortcode HTML output.
* @return string HTML Output.
*/
public function inject_video_max_width_style( $html ) {
$html = preg_replace( '/\sheight="\d+"/', '', $html );
$html = preg_replace( '/\swidth="\d+"/', '', $html );
$html = preg_replace( '/(?<=width:)\s*\d+px(?=;?)/', '100%', $html );
return $html;
}
/**
* Enqueue preview scripts.
*
* These scripts normally are enqueued just-in-time when a video shortcode is used.
* In the customizer, however, widgets can be dynamically added and rendered via
* selective refresh, and so it is important to unconditionally enqueue them in
* case a widget does get added.
*
* @since 4.8.0
*/
public function enqueue_preview_scripts() {
/** This filter is documented in wp-includes/media.php */
if ( 'mediaelement' === apply_filters( 'wp_video_shortcode_library', 'mediaelement' ) ) {
wp_enqueue_style( 'wp-mediaelement' );
wp_enqueue_script( 'mediaelement-vimeo' );
wp_enqueue_script( 'wp-mediaelement' );
}
}
/**
* Loads the required scripts and styles for the widget control.
*
* @since 4.8.0
*/
public function enqueue_admin_scripts() {
parent::enqueue_admin_scripts();
$handle = 'media-video-widget';
wp_enqueue_script( $handle );
$exported_schema = array();
foreach ( $this->get_instance_schema() as $field => $field_schema ) {
$exported_schema[ $field ] = wp_array_slice_assoc( $field_schema, array( 'type', 'default', 'enum', 'minimum', 'format', 'media_prop', 'should_preview_update' ) );
}
wp_add_inline_script(
$handle,
sprintf(
'wp.mediaWidgets.modelConstructors[ %s ].prototype.schema = %s;',
wp_json_encode( $this->id_base, JSON_HEX_TAG | JSON_UNESCAPED_SLASHES ),
wp_json_encode( $exported_schema, JSON_HEX_TAG | JSON_UNESCAPED_SLASHES )
)
);
wp_add_inline_script(
$handle,
sprintf(
'
wp.mediaWidgets.controlConstructors[ %1$s ].prototype.mime_type = %2$s;
wp.mediaWidgets.controlConstructors[ %1$s ].prototype.l10n = _.extend( {}, wp.mediaWidgets.controlConstructors[ %1$s ].prototype.l10n, %3$s );
',
wp_json_encode( $this->id_base, JSON_HEX_TAG | JSON_UNESCAPED_SLASHES ),
wp_json_encode( $this->widget_options['mime_type'], JSON_HEX_TAG | JSON_UNESCAPED_SLASHES ),
wp_json_encode( $this->l10n, JSON_HEX_TAG | JSON_UNESCAPED_SLASHES )
)
);
}
/**
* Render form template scripts.
*
* @since 4.8.0
*/
public function render_control_template_scripts() {
parent::render_control_template_scripts()
?>
'widget_categories',
'description' => __( 'A list or dropdown of categories.' ),
'customize_selective_refresh' => true,
'show_instance_in_rest' => true,
);
parent::__construct( 'categories', __( 'Categories' ), $widget_ops );
}
/**
* Outputs the content for the current Categories widget instance.
*
* @since 2.8.0
* @since 4.2.0 Creates a unique HTML ID for the `