Need help linking a button to a function in wordpr

2019-08-27 10:59发布

I have created a custom control for the theme customizer which is a simple button and label. I am going to be using it as a theme reset button that will clear the theme mod settings to their original state. Now that I have added the control and have it showing up on the customizer, I am not sure where I am supposed to add the code to reset the settings.

So far I have only created customizer settings for css and text changes. To remove the settings I will be using the remove theme mods function.

 <?php remove_theme_mods() ?>

So my question is do is how exactly do I use this button to execute the remove_mods function as seen above? The documentation on that function is very minimal.

If there is another way to reset the theme mod settings to default and this is not the right approach than please chime in.

Here is the code I have created my custom button with.

function newtheme_customize_reset_control($wp_customize) {
    /**
     * Reset Control
     *
     */
    class newtheme_Customize_reset_Control extends WP_Customize_Control {
        public $type = 'button';

        public function render_content() {
    ?>
        <label>
                        <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
                                <div>
                                    <a href="#" class="button-secondary upload"><?php _e( 'Reset Settings' ); ?></a>

                            </div>
                    </label>
    <?php
        }
    } 
}
add_action( 'customize_register', 'newtheme_customize_reset_control', 1, 1 );

2条回答
霸刀☆藐视天下
2楼-- · 2019-08-27 11:43

In theme customizer you can register your custom javascript to wordpress theme customizer

add_action('customize_preview_init', 'your_live_preview_function');

public static function your_live_preview_function() {
        wp_enqueue_script(
                'your-theme_customizer', //Give the script an ID
                get_template_directory_uri() . '/js/your-customizer-javascript-file.js', //Define it's JS file
                array('jquery', 'customize-preview'), //Define dependencies
                rand(1, 1000), //Define a version (optional) (but I use it for development as random so don't have to worry about cache etc.
                true //Specify whether to put in footer (leave this true)
        );

}

and inside your javascript file you can do something like this

( function( $ ) {
wp.customize(
        'your_reset_button_control_id',
        function( value ) {
            value.bind(
                function( to ) {
                    jQuery.post( ajax_url, 
                    { 
                        action: 'your_ajax_action_for_calling_reset',
                        reset_value: to
                    },
                    function( response ) {
                        jQuery( '.reset-info' ).html( response );
                    }
                    );
                }
                );
        }
        );
} )( jQuery );

and inside ajax you can do something like this

add_action('wp_ajax_your_ajax_action_for_calling_reset', 'your_ajax_action_for_calling_reset_callback_function');

function your_ajax_action_for_calling_reset_callback_function(){
$reset_value = esc_attr($_POST['reset_value']);

if($reset_value){
remove_theme_mods() ;
}
}

Haaaaaa hope it helps.

查看更多
老娘就宠你
3楼-- · 2019-08-27 11:53

The problem with using remove_theme_mods for showing defaults in the Customizer is

  • the Customizer is a preview which you can exit without saving,
  • the individual theme_mods are filtered, but not the entire theme_mod array
  • theme_mods includes menus and widgets.

I also wanted a reset button, but I chose instead to create a Preset control, and one of the presets is "defaults". This way uses a select, so there is no problem with the button not working (because bind is for value changes and buttons don't change their values).

The trick is to use ajax to retrieve the chosen preset, and then loop over the values in javascript, assigning them to the settings so that those changes will trigger the refresh of the preview. My code includes filters so that child themes can add in more options and presets. And the presets can be subsets of the options available.

Here is PHP for the Preset control (just a normal select, but a settingless control):

$wp_customize->add_control( 'option_presets', array(
    'label'    => __( 'Use preset theme options', 'mytheme' ),
    'description' => __( 'Theme options will be set to the preset values.', 'mytheme' ),
    'section'  => 'mytheme_section',
    'settings' => array(),
    'type'     => 'select',
    'capability' => 'edit_theme_options',
    'choices'  => mytheme_option_presets_choices(),
) );

Here is the rest of the PHP functions.

/**
 * Supply list of choices for option presets.
 */
function mytheme_option_presets_choices() {
    return apply_filters( 'mytheme_option_presets_choices', array(
        'none' => __( 'Select preset', 'mytheme' ),
        'defaults' => __( 'Defaults', 'mytheme' ),
        'dark' => __( 'Dark', 'mytheme' ),
    ) );
}

/**
 * Sanitize an option preset choice.
 */
function mytheme_sanitize_option_presets_choice( $input ) {
    $valid = mytheme_option_presets_choices();
    return array_key_exists( $input, $valid ) ? $input : 'none';
}

/**
 * Get the preset values for the chosen option preset.
 */
function mytheme_option_preset( $which ) {
    $values = array();
    if ( 'defaults' === $which ) {
        $values = mytheme_default_values();
    }
    if ( 'dark' === $which ) {
        $values = array(
            'body_textcolor' => '#f9f7f7',
            'background_color' => '#444244',
            'header_textcolor' => '#bf9a07',
            'area_classes' => array(
                'sidebar' => 'semi-black',
                'widgets' => 'box',
                ),
        );
    }
    return apply_filters( 'mytheme_option_preset', $values, $which );
}

/**
 * Add a nonce for Customizer for option presets.
 */
function mytheme_refresh_nonces( $nonces ) {
    $nonces['mytheme-customize-presets'] = wp_create_nonce( 'mytheme-customize-presets' );
    return $nonces;
}
add_filter( 'customize_refresh_nonces', 'mytheme_refresh_nonces' );

/**
 * Ajax handler for supplying option preset values.
 */
function mytheme_ajax_option_preset_values() {
    check_ajax_referer( 'mytheme-customize-presets', 'option_presets_nonce' );
    if ( ! current_user_can( 'edit_theme_options' ) ) {
        wp_die( -1 );
    }

    if ( empty( $_POST['option_preset'] ) ) {
        wp_send_json_error( 'mytheme_missing_preset_parameter' );
    }
    $preset = sanitize_text_field( wp_unslash( $_POST['option_preset'] ) );
    $values = mytheme_option_preset( $preset );
    if ( empty( $values ) ) {
        wp_send_json_error( array( 'message' => __( 'No preset found.', 'mytheme' ) ) );
    }
    else {   // Flatten the array.
        foreach ($values as $key => $avalue) {
            if ( is_array( $avalue ) ) {
                unset( $values[$key] );
                foreach ($avalue as $subkey => $subvalue) {
                    $values[$key . '[' . $subkey . ']'] = $subvalue;
                }
            }
        }
        wp_send_json_success( array( 'values' => $values ) );
    }
}
add_action( 'wp_ajax_mytheme_option_preset', 'mytheme_ajax_option_preset_values' );

And then just a little bit of Javascript to make the ajax request. This is queued on the 'customize_controls_enqueue_scripts' action. (I left out the display of the error message.)

wp.customize.control( 'option_presets', function( control ) {
    control.element = new wp.customize.Element( control.container.find( 'select' ) );
    control.element.bind( function( preset ) {
        var request = wp.ajax.post( 'mytheme_option_preset', {
            option_presets_nonce: wp.customize.settings.nonce['mytheme-customize-presets'],
            wp_customize: 'on',
            customize_theme: wp.customize.settings.theme.stylesheet,
            option_preset: preset
        } );
        request.done( function( response ) {
            _.each( response.values, function( value, id ) {
                var setting = wp.customize( id );
                if ( setting ) {
                    setting.set( value );
                }
            } );
        } );
    } );
} );
查看更多
登录 后发表回答