From c832f904ae2af615ce40ebb878138fefe80c7902 Mon Sep 17 00:00:00 2001 From: koopersmith Date: Sat, 25 Feb 2012 04:12:43 +0000 Subject: [PATCH] Introduce new theme customizer to replace theme preview. Rough first pass. props koopersmith, ocean90. see #19910. Merges in http://plugins.svn.wordpress.org/gandalf/branches/dev/ rev 510148. git-svn-id: http://svn.automattic.com/wordpress/trunk@19995 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-includes/class-wp-customize-section.php | 83 +++ wp-includes/class-wp-customize-setting.php | 489 +++++++++++++++ wp-includes/class-wp-customize.php | 660 +++++++++++++++++++++ wp-includes/css/customize-controls.css | 0 wp-includes/css/customize-controls.dev.css | 216 +++++++ wp-includes/css/customize-loader.css | 0 wp-includes/css/customize-loader.dev.css | 90 +++ wp-includes/customize-controls.php | 108 ++++ wp-includes/js/customize-base.dev.js | 496 ++++++++++++++++ wp-includes/js/customize-base.js | 0 wp-includes/js/customize-controls.dev.js | 101 ++++ wp-includes/js/customize-controls.js | 0 wp-includes/js/customize-loader.dev.js | 75 +++ wp-includes/js/customize-loader.js | 0 wp-includes/js/customize-preview.dev.js | 59 ++ wp-includes/js/customize-preview.js | 0 wp-includes/script-loader.php | 7 + wp-includes/theme.php | 12 + 18 files changed, 2396 insertions(+) create mode 100644 wp-includes/class-wp-customize-section.php create mode 100644 wp-includes/class-wp-customize-setting.php create mode 100644 wp-includes/class-wp-customize.php create mode 100644 wp-includes/css/customize-controls.css create mode 100644 wp-includes/css/customize-controls.dev.css create mode 100644 wp-includes/css/customize-loader.css create mode 100644 wp-includes/css/customize-loader.dev.css create mode 100644 wp-includes/customize-controls.php create mode 100644 wp-includes/js/customize-base.dev.js create mode 100644 wp-includes/js/customize-base.js create mode 100644 wp-includes/js/customize-controls.dev.js create mode 100644 wp-includes/js/customize-controls.js create mode 100644 wp-includes/js/customize-loader.dev.js create mode 100644 wp-includes/js/customize-loader.js create mode 100644 wp-includes/js/customize-preview.dev.js create mode 100644 wp-includes/js/customize-preview.js diff --git a/wp-includes/class-wp-customize-section.php b/wp-includes/class-wp-customize-section.php new file mode 100644 index 000000000..ca8f1da62 --- /dev/null +++ b/wp-includes/class-wp-customize-section.php @@ -0,0 +1,83 @@ +id = $id; + + $keys = array_keys( get_class_vars( __CLASS__ ) ); + foreach ( $keys as $key ) { + if ( isset( $args[ $key ] ) ) + $this->$key = $args[ $key ]; + } + + $this->settings = array(); // Users cannot customize the $settings array. + + return $this; + } + + /** + * Check if the theme supports the section and check user capabilities. + * + * @since 3.4.0 + * + * @return bool False if theme doesn't support the section or user doesn't have the capability. + */ + function check_capabilities() { + if ( ! $this->capability || ! current_user_can( $this->capability ) ) + return false; + + if ( $this->theme_supports && ! current_theme_supports( $this->theme_supports ) ) + return false; + + return true; + } + + /** + * Render the section. + * + * @since 3.4.0 + */ + function render() { + if ( ! $this->check_capabilities() ) + return; + ?> +
  • +

    title ); ?>

    + +
  • + $key = $args[ $key ]; + } + + $this->id = $id; + + // Parse the ID for array keys. + $this->id_data[ 'keys' ] = preg_split( '/\[/', str_replace( ']', '', $this->id ) ); + $this->id_data[ 'base' ] = array_shift( $this->id_data[ 'keys' ] ); + + // Rebuild the ID. + $this->id = $this->id_data[ 'base' ]; + if ( ! empty( $this->id_data[ 'keys' ] ) ) + $this->id .= '[' . implode( '][', $this->id_data[ 'keys' ] ) . ']'; + + if ( $this->sanitize_callback != '' ) + add_filter( "customize_sanitize_{$this->id}", $this->sanitize_callback ); + + return $this; + } + + /** + * Enqueue setting related scripts/styles. + * + * @since 3.4.0 + */ + public function enqueue() { + switch( $this->control ) { + case 'color': + wp_enqueue_script( 'farbtastic' ); + wp_enqueue_style( 'farbtastic' ); + break; + } + } + + /** + * Handle previewing the setting. + * + * @since 3.4.0 + */ + public function preview() { + switch( $this->type ) { + case 'theme_mod' : + add_filter( 'theme_mod_' . $this->id_data[ 'base' ], array( $this, '_preview_filter' ) ); + break; + case 'option' : + if ( empty( $this->id_data[ 'keys' ] ) ) + add_filter( 'pre_option_' . $this->id_data[ 'base' ], array( $this, '_preview_filter' ) ); + else + add_filter( 'option_' . $this->id_data[ 'base' ], array( $this, '_preview_filter' ) ); + break; + default : + do_action( 'customize_preview_' . $this->id ); + } + } + + /** + * Callback function to filter the theme mods and options. + * + * @since 3.4.0 + * + * @param mixed Old value. + * @return mixed New or old value. + */ + public function _preview_filter( $original ) { + return $this->multidimensional_replace( $original, $this->id_data[ 'keys' ], $this->post_value() ); + } + + /** + * Set the value of the parameter for a specific theme. + * + * @since 3.4.0 + * + * @return bool False if cap check fails or value isn't set. + */ + public final function save() { + $value = $this->post_value(); + + if ( ! $this->check_capabilities() || ! isset( $value ) ) + return false; + + do_action( 'customize_save_' . $this->id_data[ 'base' ] ); + + $this->update( $value ); + } + + /** + * Fetches, validates, and sanitizes the $_POST value. + * + * @since 3.4.0 + * + * @param $default mixed A default value which is used as a fallback. Default is null. + * @return mixed Either the default value on failure or sanitized value. + */ + public final function post_value( $default = null ) { + if ( isset( $this->_post_value ) ) + return $this->_post_value; + + $base = self::name_prefix . $this->id_data[ 'base' ]; + + if ( ! isset( $_POST[ $base ] ) ) + return $default; + + $result = $this->multidimensional_get( $_POST[ $base ], $this->id_data[ 'keys' ] ); + if ( ! isset( $result ) ) + return $default; + + $result = $this->sanitize( $result ); + if ( isset( $result ) ) + return $this->_post_value = $result; + else + return $default; + } + + /** + * Sanitize an input. + * + * @since 3.4.0 + * + * @param $value mixed The value to sanitize. + * @return mixed Null if an input isn't valid, otherwise the sanitized value. + */ + public function sanitize( $value ) { + return apply_filters( "customize_sanitize_{$this->id}", $value ); + } + + /** + * Set the value of the parameter for a specific theme. + * + * @since 3.4.0 + * + * @param $value mixed The value to update. + * @return mixed The result of saving the value. + */ + protected function update( $value ) { + switch( $this->type ) { + case 'theme_mod' : + return $this->_update_theme_mod( $value ); + break; + case 'option' : + return $this->_update_option( $value ); + break; + default : + return do_action( 'customize_update_' . $this->type, $value ); + } + } + + /** + * Update the theme mod from the value of the parameter. + * + * @since 3.4.0 + * + * @param $value mixed The value to update. + * @return mixed The result of saving the value. + */ + protected function _update_theme_mod( $value ) { + // Handle non-array theme mod. + if ( empty( $this->id_data[ 'keys' ] ) ) + return set_theme_mod( $this->id_data[ 'base' ], $value ); + + // Handle array-based theme mod. + $mods = get_theme_mod( $this->id_data[ 'base' ] ); + $mods = $this->multidimensional_replace( $mods, $this->id_data[ 'keys' ], $value ); + if ( isset( $mods ) ) + return set_theme_mod( $this->id_data[ 'base' ], $mods ); + } + + /** + * Update the theme mod from the value of the parameter. + * + * @since 3.4.0 + * + * @param $value mixed The value to update. + * @return mixed The result of saving the value. + */ + protected function _update_option( $value ) { + // Handle non-array option. + if ( empty( $this->id_data[ 'keys' ] ) ) + return update_option( $this->id_data[ 'base' ], $value ); + + // Handle array-based options. + $options = get_option( $this->id_data[ 'base' ] ); + $options = $this->multidimensional_replace( $options, $this->id_data[ 'keys' ], $value ); + if ( isset( $options ) ) + return update_option( $this->id_data[ 'base' ], $options ); + } + + /** + * Fetch the value of the parameter for a specific theme. + * + * @since 3.4.0 + * + * @return mixed The requested value. + */ + public function value() { + switch( $this->type ) { + case 'theme_mod' : + $function = 'get_theme_mod'; + break; + case 'option' : + $function = 'get_option'; + break; + default : + return apply_filters( 'customize_value_' . $this->id_data[ 'base' ], $this->default ); + } + + // Handle non-array value + if ( empty( $this->id_data[ 'keys' ] ) ) + return $function( $this->id_data[ 'base' ], $this->default ); + + // Handle array-based value + $values = $function( $this->id_data[ 'base' ] ); + return $this->multidimensional_get( $values, $this->id_data[ 'keys' ], $this->default ); + } + + /** + * Check if the theme supports the setting and check user capabilities. + * + * @since 3.4.0 + * + * @return bool False if theme doesn't support the setting or user can't change setting, otherwise true. + */ + public final function check_capabilities() { + global $customize; + + if ( ! $this->capability || ! current_user_can( $this->capability ) ) + return false; + + if ( $this->theme_supports && ! current_theme_supports( $this->theme_supports ) ) + return false; + + $section = $customize->get_section( $this->section ); + if ( isset( $section ) && ! $section->check_capabilities() ) + return false; + + return true; + } + + /** + * Render the control. + * + * @since 3.4.0 + */ + public final function _render() { + if ( ! $this->check_capabilities() ) + return; + + do_action( 'customize_render_' . $this->id ); + + $this->render(); + } + + /** + * Render the control. + * + * @since 3.4.0 + */ + protected function render() { + $this->_render_type(); + } + + /** + * Retrieve the name attribute for an input. + * + * @since 3.4.0 + * + * @return string The name. + */ + public final function get_name() { + return self::name_prefix . esc_attr( $this->id ); + } + + /** + * Echo the HTML name attribute for an input. + * + * @since 3.4.0 + * + * @return string The HTML name attribute. + */ + public final function name() { + echo 'name="' . $this->get_name() . '"'; + } + + /** + * Render the control type. + * + * @todo Improve value and checked attributes. + * + * @since 3.4.0 + */ + public final function _render_type() { + switch( $this->control ) { + case 'text': + ?> + + + + + + choices ) ) + return; + + echo esc_html( $this->label ) . '
    '; + foreach ( $this->choices as $value => $label ) : + ?> + + choices ) ) + return; + + ?> +