set_stylesheet() || isset( $_REQUEST['save'] ) ) return; $this->previewing = true; do_action( 'customize_previewing' ); } /** * Init filters to filter theme options. * * @since 3.4.0 */ public function customize_previewing() { global $wp_theme_directories; show_admin_bar( false ); add_filter( 'template', array( $this, 'get_template' ) ); add_filter( 'stylesheet', array( $this, 'get_stylesheet' ) ); add_filter( 'pre_option_current_theme', array( $this, 'current_theme' ) ); // @link: http://core.trac.wordpress.org/ticket/20027 add_filter( 'pre_option_stylesheet', array( $this, 'get_stylesheet' ) ); add_filter( 'pre_option_template', array( $this, 'get_template' ) ); // Handle custom theme roots. if ( count( $wp_theme_directories ) > 1 ) { add_filter( 'pre_option_stylesheet_root', array( $this, 'get_stylesheet_root' ) ); add_filter( 'pre_option_template_root', array( $this, 'get_template_root' ) ); } } /** * Register styles/scripts and initialize the preview of each setting * * @since 3.4.0 */ public function wp_loaded() { do_action( 'customize_register' ); if ( $this->is_preview() ) add_action( 'template_redirect', array( $this, 'customize_preview_init' ) ); } /** * Print javascript settings. * * @since 3.4.0 */ public function customize_preview_init() { $this->prepare_controls(); wp_enqueue_script( 'customize-preview' ); add_action( 'wp_footer', array( $this, 'customize_preview_settings' ), 20 ); foreach ( $this->settings as $setting ) { $setting->preview(); } do_action( 'customize_preview_init' ); } /** * Print javascript settings. * * @since 3.4.0 */ public function customize_preview_settings() { $settings = array( // @todo: Perhaps grab the URL via $_POST? 'parent' => esc_url( admin_url( 'themes.php' ) ), 'values' => array(), ); foreach ( $this->settings as $id => $setting ) { $settings['values'][ $id ] = $setting->value(); } ?> previewing; } /** * Set the template name of the previewed theme. * * @since 3.4.0 * * @return bool|string Template name. */ public function set_template() { if ( ! empty( $this->template ) ) return $this->template; $template = preg_replace('|[^a-z0-9_./-]|i', '', $_REQUEST['template'] ); if ( validate_file( $template ) ) return false; return $this->template = $template; } /** * Set the stylesheet name of the previewed theme. * * @since 3.4.0 * * @return bool|string Stylesheet name. */ public function set_stylesheet() { if ( ! empty( $this->stylesheet ) ) return $this->stylesheet; $this->set_template(); if ( empty( $this->template ) ) return false; if ( empty( $_REQUEST['stylesheet'] ) ) { $stylesheet = $this->template; } else { $stylesheet = preg_replace( '|[^a-z0-9_./-]|i', '', $_REQUEST['stylesheet'] ); if ( $stylesheet != $this->template && validate_file( $stylesheet ) ) return false; } return $this->stylesheet = $stylesheet; } /** * Retrieve the template name of the previewed theme. * * @since 3.4.0 * * @return string Template name. */ public function get_template() { return $this->template; } /** * Retrieve the stylesheet name of the previewed theme. * * @since 3.4.0 * * @return string Stylesheet name. */ public function get_stylesheet() { return $this->stylesheet; } /** * Retrieve the template root of the previewed theme. * * @since 3.4.0 * * @return string Theme root. */ public function get_template_root() { return get_raw_theme_root( $this->template, true ); } /** * Retrieve the stylesheet root of the previewed theme. * * @since 3.4.0 * * @return string Theme root. */ public function get_stylesheet_root() { return get_raw_theme_root( $this->stylesheet, true ); } /** * Filter the current theme and return the name of the previewed theme. * * @since 3.4.0 * * @return string Theme name. */ public function current_theme( $current_theme ) { return wp_get_theme( $this->stylesheet )->get('Name'); } /** * Trigger save action and load customize controls. * * @since 3.4.0 */ public function admin_init() { if ( isset( $_REQUEST['save'] ) ) $this->save(); wp_enqueue_script( 'customize-loader' ); if ( ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) return; if ( ! isset( $_GET['customize'] ) || 'on' != $_GET['customize'] ) return; if ( ! $this->is_preview() ) return; if ( ! current_user_can( 'edit_theme_options' ) ) return; include( ABSPATH . WPINC . '/customize-controls.php' ); die; } /** * Print the customize template. * * @since 3.4.0 */ public function admin_footer() { ?>
is_preview() ) return; check_admin_referer( 'customize_controls' ); if ( ! $this->set_stylesheet() ) return; $active_template = get_template(); $active_stylesheet = get_stylesheet(); // Do we have to switch themes? if ( $this->get_template() != $active_template || $this->get_stylesheet() != $active_stylesheet ) { if ( ! current_user_can( 'switch_themes' ) ) return; switch_theme( $this->get_template(), $this->get_stylesheet() ); } do_action( 'customize_save' ); foreach ( $this->settings as $setting ) { $setting->save(); } add_action( 'admin_notices', array( $this, '_save_feedback' ) ); } /** * Show an admin notice after settings are saved. * * @since 3.4.0 */ public function _save_feedback() { ?>

Visit site.' ), home_url( '/' ) ); ?>

settings[ $setting->id ] = $setting; } /** * Retrieve a customize setting. * * @since 3.4.0 * * @param string $id An specific ID of the setting. * @return object The settings object. */ public function get_setting( $id ) { if ( isset( $this->settings[ $id ] ) ) return $this->settings[ $id ]; } /** * Remove a customize setting. * * @since 3.4.0 * * @param string $id An specific ID of the setting. */ public function remove_setting( $id ) { unset( $this->settings[ $id ] ); } /** * Add a customize section. * * @since 3.4.0 * * @param string $id An specific ID of the section. * @param array $args Section arguments. */ public function add_section( $id, $args = array() ) { $section = new WP_Customize_Section( $this, $id, $args ); $this->sections[ $section->id ] = $section; } /** * Retrieve a customize section. * * @since 3.4.0 * * @param string $id An specific ID of the section. * @return object The section object. */ public function get_section( $id ) { if ( isset( $this->sections[ $id ] ) ) return $this->sections[ $id ]; } /** * Remove a customize section. * * @since 3.4.0 * * @param string $id An specific ID of the section. */ public function remove_section( $id ) { unset( $this->sections[ $id ] ); } /** * Helper function to compare two objects by priority. * * @since 3.4.0 * * @param object $a Object A. * @param object $b Object B. */ protected final function _cmp_priority( $a, $b ) { $ap = $a->priority; $bp = $b->priority; if ( $ap == $bp ) return 0; return ( $ap > $bp ) ? 1 : -1; } /** * Prepare settings and sections. * * @since 3.4.0 */ public function prepare_controls() { // Prepare settings // Reversing makes uasort sort by time added when conflicts occur. $this->settings = array_reverse( $this->settings ); $settings = array(); foreach ( $this->settings as $id => $setting ) { if ( ! isset( $this->sections[ $setting->section ] ) || ! $setting->check_capabilities() ) continue; $this->sections[ $setting->section ]->settings[] = $setting; $settings[ $id ] = $setting; } $this->settings = $settings; // Prepare sections $this->sections = array_reverse( $this->sections ); uasort( $this->sections, array( $this, '_cmp_priority' ) ); $sections = array(); foreach ( $this->sections as $section ) { if ( ! $section->check_capabilities() || ! $section->settings ) continue; usort( $section->settings, array( $this, '_cmp_priority' ) ); $sections[] = $section; } $this->sections = $sections; } /** * Enqueue scripts for customize controls. * * @since 3.4.0 */ public function enqueue_control_scripts() { foreach ( $this->settings as $setting ) { $setting->enqueue(); } } /** * Register some default controls. * * @since 3.4.0 */ public function register_controls() { /* Custom Header */ $this->add_section( 'header', array( 'title' => __( 'Header' ), 'theme_supports' => 'custom-header', ) ); $this->add_setting( 'header_textcolor', array( 'label' => 'Text Color', 'section' => 'header', 'sanitize_callback' => 'sanitize_hexcolor', 'control' => 'color', 'theme_supports' => array( 'custom-header', 'header-text' ), 'default' => get_theme_support( 'custom-header', 'default-text-color' ), ) ); /* $this->add_setting( 'display_header', array( 'label' => 'Display Text', 'section' => 'header', 'type' => 'radio', 'choices' => array( 'show' => 'Yes', 'hide' => 'No' ), // Showing header text is actually done by setting header_textcolor to 'blank'. // @todo: Do some JS magic to make this work (since we'll be hiding the textcolor input). 'theme_mod' => false, ) ); */ // Input type: checkbox // With custom value $this->add_setting( 'header_image', array( 'label' => 'Random Image', 'section' => 'header', 'control' => 'checkbox', // @todo // not the default, it's the value. // value is saved in get_theme_support( 'custom-header', 'random-default' ) 'default' => 'random-default-image' ) ); /* Custom Background */ $this->add_section( 'background', array( 'title' => __( 'Background' ), 'theme_supports' => 'custom-background', ) ); // Input type: Color // With sanitize_callback $this->add_setting( 'background_color', array( 'label' => 'Background Color', 'section' => 'background', 'control' => 'color', 'default' => get_theme_support( 'custom-background', 'default-color' ), 'sanitize_callback' => 'sanitize_hexcolor', ) ); $this->add_setting( 'background_image', array( 'label' => 'Background Image', 'section' => 'background', 'control' => 'upload', 'default' => get_theme_support( 'custom-background', 'default-image' ), ) ); $this->add_setting( 'background_repeat', array( 'label' => 'Background Repeat', 'section' => 'background', 'visibility' => 'background_image', 'control' => 'radio', 'choices' => array( 'no-repeat' => __('No Repeat'), 'repeat' => __('Tile'), 'repeat-x' => __('Tile Horizontally'), 'repeat-y' => __('Tile Vertically'), ), 'default' => 'repeat', ) ); $this->add_setting( 'background_position_x', array( 'label' => 'Background Position', 'section' => 'background', 'visibility' => 'background_image', 'control' => 'radio', 'choices' => array( 'left' => __('Left'), 'center' => __('Center'), 'right' => __('Right'), ), 'default' => 'left', ) ); $this->add_setting( 'background_attachment', array( 'label' => 'Background Attachment', 'section' => 'background', 'visibility' => 'background_image', 'control' => 'radio', 'choices' => array( 'fixed' => __('Fixed'), 'scroll' => __('Scroll'), ), 'default' => 'fixed', ) ); /* Nav Menus */ $locations = get_registered_nav_menus(); $menus = wp_get_nav_menus(); $menu_locations = get_nav_menu_locations(); $num_locations = count( array_keys( $locations ) ); $this->add_section( 'nav', array( 'title' => __( 'Navigation' ), 'theme_supports' => 'menus', 'description' => sprintf( _n('Your theme supports %s menu. Select which menu you would like to use.', 'Your theme supports %s menus. Select which menu appears in each location.', $num_locations ), number_format_i18n( $num_locations ) ), ) ); foreach ( $locations as $location => $description ) { $choices = array( 0 => '' ); foreach ( $menus as $menu ) { $truncated_name = wp_html_excerpt( $menu->name, 40 ); $truncated_name == $menu->name ? $menu->name : trim( $truncated_name ) . '…'; $choices[ $menu->term_id ] = $truncated_name; } $this->add_setting( "nav_menu_locations[{$location}]", array( 'label' => $description, 'theme_supports' => 'menus', // Todo: Needs also widgets -- array( 'menus', 'widgets' ) 'section' => 'nav', 'control' => 'select', 'choices' => $choices, 'sanitize_callback' => 'absint', ) ); } /* Static Front Page */ // #WP19627 $this->add_section( 'static_front_page', array( 'title' => __( 'Static Front Page' ), // 'theme_supports' => 'static-front-page', 'description' => __( 'Your theme supports a static front page.' ), ) ); $choices = array(); $choices['posts'] = __( 'Your latest posts' ); $choices['page'] = __( 'A static page (select below)' ); $this->add_setting( 'show_on_front', array( 'label' => __( 'Front page displays' ), // 'theme_supports' => 'static-front-page', 'section' => 'static_front_page', 'control' => 'radio', 'choices' => $choices, 'default' => get_option( 'show_on_front' ), 'type' => 'option', 'capability' => 'manage_options', ) ); $this->add_setting( 'page_on_front', array( 'label' => __( 'Front page' ), // 'theme_supports' => 'static-front-page', 'section' => 'static_front_page', 'control' => 'dropdown-pages', 'type' => 'option', 'capability' => 'manage_options', 'visibility' => array( 'show_on_front', 'page' ), ) ); $this->add_setting( 'page_for_posts', array( 'label' => __( 'Posts page' ), // 'theme_supports' => 'static-front-page', 'section' => 'static_front_page', 'control' => 'dropdown-pages', 'type' => 'option', 'capability' => 'manage_options', 'visibility' => array( 'show_on_front', 'page' ), ) ); /* Site Title & Tagline */ $this->add_section( 'strings', array( 'title' => __( 'Site Title & Tagline' ), ) ); $this->add_setting( 'blogname', array( 'label' => __( 'Site Title' ), 'section' => 'strings', 'default' => get_option( 'blogname' ), 'type' => 'option', 'capability' => 'manage_options', ) ); $this->add_setting( 'blogdescription', array( 'label' => __( 'Tagline' ), 'section' => 'strings', 'default' => get_option( 'blogdescription' ), 'type' => 'option', 'capability' => 'manage_options', ) ); } }; // Callback function for sanitizing a hex color function sanitize_hexcolor( $color ) { $color = preg_replace( '/[^0-9a-fA-F]/', '', $color ); if ( preg_match('|[A-Fa-f0-9]{3,6}|', $color ) ) return $color; return $color; }