Make WordPress Core


Ignore:
Timestamp:
05/11/2017 06:54:24 PM (7 years ago)
Author:
westonruter
Message:

Widgets: Extend the Text widget with TinyMCE.

Introduces rich text formatting: bold, italic, lists, links.

Props westonruter, azaozz, timmydcrawford, obenland, melchoyce.
See #35760.
Fixes #35243.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/widgets/class-wp-widget-text.php

    r37489 r40631  
    2929            'customize_selective_refresh' => true,
    3030        );
    31         $control_ops = array( 'width' => 400, 'height' => 350 );
     31        $control_ops = array(
     32            'width' => 400,
     33            'height' => 350,
     34        );
    3235        parent::__construct( 'text', __( 'Text' ), $widget_ops, $control_ops );
     36    }
     37
     38    /**
     39     * Add hooks for enqueueing assets when registering all widget instances of this widget class.
     40     *
     41     * @since 4.8.0
     42     * @access public
     43     */
     44    public function _register() {
     45
     46        // Note that the widgets component in the customizer will also do the 'admin_print_scripts-widgets.php' action in WP_Customize_Widgets::print_scripts().
     47        add_action( 'admin_print_scripts-widgets.php', array( $this, 'enqueue_admin_scripts' ) );
     48
     49        // Note that the widgets component in the customizer will also do the 'admin_footer-widgets.php' action in WP_Customize_Widgets::print_footer_scripts().
     50        add_action( 'admin_footer-widgets.php', array( $this, 'render_control_template_scripts' ) );
     51
     52        parent::_register();
    3353    }
    3454
     
    6282        $text = apply_filters( 'widget_text', $widget_text, $instance, $this );
    6383
     84        if ( isset( $instance['filter'] ) ) {
     85            if ( 'content' === $instance['filter'] ) {
     86
     87                /**
     88                 * Filters the content of the Text widget to apply changes expected from the visual (TinyMCE) editor.
     89                 *
     90                 * By default a subset of the_content filters are applied, including wpautop and wptexturize.
     91                 *
     92                 * @since 4.8.0
     93                 *
     94                 * @param string         $widget_text The widget content.
     95                 * @param array          $instance    Array of settings for the current widget.
     96                 * @param WP_Widget_Text $this        Current Text widget instance.
     97                 */
     98                $text = apply_filters( 'widget_text_content', $widget_text, $instance, $this );
     99
     100            } elseif ( $instance['filter'] ) {
     101                $text = wpautop( $text ); // Back-compat for instances prior to 4.8.
     102            }
     103        }
     104
    64105        echo $args['before_widget'];
    65106        if ( ! empty( $title ) ) {
    66107            echo $args['before_title'] . $title . $args['after_title'];
    67         } ?>
    68             <div class="textwidget"><?php echo !empty( $instance['filter'] ) ? wpautop( $text ) : $text; ?></div>
     108        }
     109
     110        ?>
     111            <div class="textwidget"><?php echo $text; ?></div>
    69112        <?php
    70113        echo $args['after_widget'];
     
    90133            $instance['text'] = wp_kses_post( $new_instance['text'] );
    91134        }
    92         $instance['filter'] = ! empty( $new_instance['filter'] );
     135
     136        /*
     137         * Re-use legacy 'filter' (wpautop) property to now indicate content filters will always apply.
     138         * Prior to 4.8, this is a boolean value used to indicate whether or not wpautop should be
     139         * applied. By re-using this property, downgrading WordPress from 4.8 to 4.7 will ensure
     140         * that the content for Text widgets created with TinyMCE will continue to get wpautop.
     141         */
     142        $instance['filter'] = 'content';
     143
    93144        return $instance;
    94145    }
    95146
    96147    /**
     148     * Loads the required scripts and styles for the widget control.
     149     *
     150     * @since 4.8.0
     151     * @access public
     152     */
     153    public function enqueue_admin_scripts() {
     154        wp_enqueue_editor();
     155        wp_enqueue_script( 'text-widgets' );
     156    }
     157
     158    /**
    97159     * Outputs the Text widget settings form.
    98160     *
    99161     * @since 2.8.0
    100      * @access public
     162     * @since 4.8.0 Form only contains hidden inputs which are synced with JS template.
     163     * @access public
     164     * @see WP_Widget_Visual_Text::render_control_template_scripts()
    101165     *
    102166     * @param array $instance Current settings.
     167     * @return void
    103168     */
    104169    public function form( $instance ) {
    105         $instance = wp_parse_args( (array) $instance, array( 'title' => '', 'text' => '' ) );
    106         $filter = isset( $instance['filter'] ) ? $instance['filter'] : 0;
    107         $title = sanitize_text_field( $instance['title'] );
     170        $instance = wp_parse_args(
     171            (array) $instance,
     172            array(
     173                'title' => '',
     174                'text' => '',
     175            )
     176        );
    108177        ?>
    109         <p><label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title:'); ?></label>
    110         <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo esc_attr($title); ?>" /></p>
    111 
    112         <p><label for="<?php echo $this->get_field_id( 'text' ); ?>"><?php _e( 'Content:' ); ?></label>
    113         <textarea class="widefat" rows="16" cols="20" id="<?php echo $this->get_field_id('text'); ?>" name="<?php echo $this->get_field_name('text'); ?>"><?php echo esc_textarea( $instance['text'] ); ?></textarea></p>
    114 
    115         <p><input id="<?php echo $this->get_field_id('filter'); ?>" name="<?php echo $this->get_field_name('filter'); ?>" type="checkbox"<?php checked( $filter ); ?> />&nbsp;<label for="<?php echo $this->get_field_id('filter'); ?>"><?php _e('Automatically add paragraphs'); ?></label></p>
     178        <input id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" class="title" type="hidden" value="<?php echo esc_attr( $instance['title'] ); ?>">
     179        <input id="<?php echo $this->get_field_id( 'text' ); ?>" name="<?php echo $this->get_field_name( 'text' ); ?>" class="text" type="hidden" value="<?php echo esc_attr( $instance['text'] ); ?>">
    116180        <?php
    117181    }
     182
     183    /**
     184     * Render form template scripts.
     185     *
     186     * @since 4.8.0
     187     * @access public
     188     */
     189    public function render_control_template_scripts() {
     190        ?>
     191        <script type="text/html" id="tmpl-widget-text-control-fields">
     192            <# var elementIdPrefix = 'el' + String( Math.random() ).replace( /\D/g, '' ) + '_' #>
     193            <p>
     194                <label for="{{ elementIdPrefix }}title"><?php esc_html_e( 'Title:' ); ?></label>
     195                <input id="{{ elementIdPrefix }}title" type="text" class="widefat title">
     196            </p>
     197            <p>
     198                <label for="{{ elementIdPrefix }}text" class="screen-reader-text"><?php esc_html_e( 'Content:' ); ?></label>
     199                <textarea id="{{ elementIdPrefix }}text" class="widefat text" style="height: 200px" rows="16" cols="20"></textarea>
     200            </p>
     201        </script>
     202        <?php
     203    }
    118204}
Note: See TracChangeset for help on using the changeset viewer.