向WP Customizer

时间:2016-05-23 19:28:56

标签: php jquery wordpress jquery-ui wordpress-theming

这是什么

我发现@scottfennell this post关于向WP Customizer添加可排序/可拖动的多重复选框控件。 他的帖子受到@JustinTadlock的previous work的启发,这是为多重复选框添加定制器控件。

我想在我的自定义程序中使用可排序/可拖动的多重复选框控件,但我在实现它时遇到了问题。非常欢迎您的帮助,非常感谢。我认为这个插件对其他人也有用,所以我希望这会遇到一些积极的兴趣。

编辑:查找以下示例代码

到目前为止我做了什么

  1. 使用类的代码(myclass.php)
  2. 创建一个文件
  3. 使用jquery插件的代码创建一个文件(customizer-drag-boxes.js)
  4. 在我的主题中加入文件“customizer.php”并添加以下代码:

    function customizer_setup( $wp_customize ) {
    // Include the class
    require_once( get_template_directory() . '/inc/functions/admin/myclass.php' );
    
    // Add a section
    $wp_customize->add_section( 'example_section', array(
    'title'          => __( 'Example Section', 'mytheme' ),
    'priority'       => 35,
    ) );
    
    // Add settings
    $wp_customize->add_setting(
        'example_settings',
        array(
            'default'           => array( 'apple', 'orange' )
        )
    );
    // Add control  
    $wp_customize->add_control(
        new LXB_AF_Checkbox(
            $wp_customize,
            'example_settings',
            array(
                'section'   => 'example_section',
                'label'     => __( 'My new Control', 'mytheme' ),
                'choices' => array(
                    'apple'      => __( 'Apple',      'mytheme' ),
                    'banana'     => __( 'Banana',     'mytheme' ),
                    'date'       => __( 'Date',       'mytheme' ),
                    'orange'     => __( 'Orange',     'mytheme' ),
                    'watermelon' => __( 'Watermelon', 'mytheme' )
                )
            )
        )
    );
    }
    add_action( 'customize_register', 'customizer_setup' );
    
  5. public $type = 'checkbox_group';

    之后将其添加到myclass.php
    public function enqueue() {
    wp_enqueue_script( 'customizer-drag-boxes-control', get_template_directory_uri() . '/inc/js/customizer-drag-boxes.js', array( 'jquery' ) );
    }
    

    我这样做是因为我认为jquery文件尚未入队。

  6. 我改变了myclass.php $class = LXB_AF . '-checkbox_group-hidden';$class = 'LXB_AF' . '-checkbox_group-hidden';。由于缺少'',我这样做是因为错误。

  7. 结果

    自定义程序屏幕显示我的部分和测试字段,其中包含默认值。可拖动列表没有出现,我没有wordpress错误。在我的控制台中,我收到以下错误消息:

      

    Uncaught SyntaxError:位于0的JSON中的意外标记u

         
        
    • create @ customizer-drag-boxes.js?ver = 4.5.2:197
    •   
    • (匿名函数)@ customizer-drag-boxes.js?ver = 4.5.2:327

    •   
    • n.extend.each @ load-scripts.php?c = 0& load [] = jquery-core,jquery-migrate,jquery-ui-core,jquery-ui-widget,jquery-ui-莫...:2

    •   
    • n.fn.n.each @ load-scripts.php?c = 0& load [] = jquery-core,jquery-migrate,jquery-ui-core,jquery-ui-widget,jquery- UI谟...:2

    •   
    • $。fn.lxbAfCheckboxGroup @ customizer-drag-boxes.js?ver = 4.5.2:316

    •   
    • (匿名函数)@ customizer-drag-boxes.js?ver = 4.5.2:9

    •   
    • n.event.dispatch @ load-scripts.php?c = 0& load [] = jquery-core,jquery-migrate,jquery-ui-core,jquery-ui-widget,jquery-ui-莫...:3

    •   
    • r.handle @ load-scripts.php?c = 0&amp; load [] = jquery-core,jquery-migrate,jquery-ui-core,jquery-ui-widget,jquery-ui-mo ...:3 < / LI>   

    你能帮我实施吗?你看到代码中有任何缺陷吗?提前致谢! :)

    示例代码

    课程

    class LXB_AF_Checkbox extends WP_Customize_Control {
    
        // I'm not sure where this gets used but it's in the codex.
        public $type = 'checkbox_group';
    
        /**
         * This method must be named, exactly, 'render_content', as that's
         * expected by the WP core cusotmization class, which it extends.  It
         * outputs the HTML for our custom input.
         * 
         * In this case, all it does is output a hidden input with some
         * important data attributes.  Our JS reads the data attributes and
         * creates the markup. The reason for this is because the customizer 
         * only updates via JS, so we might as well create it via JS, since the 
         * logic for creating and updating is very similar.
         */
        public function render_content() {
    
            $out = '';
    
            $class = LXB_AF . '-checkbox_group-hidden';
            $class = " class='$class' ";
            $id    = esc_attr( $this -> id );
            $name  = " name='$id' ";
            $label = esc_html( $this -> label );
    
            $value = '';
            if( isset( $this -> value ) ) {
                $value = $this -> value;
            }
    
            // WP uses this to create the value of the input.
            $link = 'data-customize-setting-link="' . $id . '"';
    
            /**
             * Store the choices for this setting in a data attr. In our JS,
             * we'll use these to make the checkboxes.
             */
            $choices      = $this -> choices;
            $choices_data = esc_attr( json_encode( $choices ) );
            $choices_data = " data-choices='$choices_data' ";
    
            // The type of input.  Text for debugging purposes.  Switch to hidden for production.
            $type = " 'type='text' ";
    
            $out .= "<span class='customize-control-title'>$label</span>";
            $out .= "<input $choices_data $link $type $name $class>";
    
            echo $out;
    
        }
    
    }
    

    jQuery插件

    /**
     * A jQuery plugin for making a sortable/draggable multi-checkbox.
     */
    jQuery( window ).load(function() {
    
        // The li that wraps this whole section of the customizer. Sort of like a fieldset.
        var el = jQuery( '.customize-control-checkbox_group' );
    
        jQuery( el ).lxbAfCheckboxGroup();
    
    });
    
    (function ( $ ) {
    
        $.fn.lxbAfCheckboxGroup = function( options ) {
    
            /**
             * Create an HTML <select> menu for choosing some value related to this checkbox.
             * 
             * @param  {string}  type         What type of options we want: linkCategories, customMenu, etc...
             * @param  {boolean} visible      Should the menu be visible?  If the checkbox is not checked, the select menu should not be visible.
             * @param  {string}  hiddenValArr The JSON currently being stored for this fieldset.
             * @return {string}  The HTML for a <select> menu.
             */
            function dropdown( type, visible, hiddenValArr ) {
    
                // Create a select menu.
                var select = jQuery( '<select>' ).addClass( 'lxbAfCheckboxGroup-select' ).attr( 'data-type', type );
    
                // Maybe hide it.
                if( ! visible ) {
                    jQuery( select ).hide();
                }
    
                // Start it with an empty option.
                var emptyOpt = jQuery( '<option>' ).val( '' ).appendTo( select );
    
                // Grab our php variables.
                var localize = lxbAfCustomizeLocalize;
    
                // Grab the current value for this menu.
                var current = '';
                if( hiddenValArr != null ) {
    
                    //Is the checkbox for this item checked?
                    if( hiddenValArr[ '###' + type + '###' ] != null ) {
    
                        // If so, determine which option is selected.
                        var current = hiddenValArr[ '###' + type + '###' ];
                    }
                }
    
                // Get a list of <option>'s for the <select>.
                var choices = localize[type];
    
                // For each <option>...
                jQuery( choices ).each( function( index, value ) {
    
                    // The value.
                    var slug = value.slug;
    
                    // The label.
                    var name = value.name;
    
                    // Build the <option>.
                    var option = jQuery( '<option/>', {
                        html: name,
                        'value' : slug
                    });
    
                    // Maybe make it sticky.
                    if( slug == current ) {
                        jQuery( option ).attr( 'selected', 'selected' );
                    }
    
                    // Add it to the select menu.
                    jQuery( option ).appendTo( select );
    
                });
    
                var out = jQuery( select );
    
                return out;
    
            }
    
            /**
             * A function to make a draggable checkbox input.
             * 
             * @param  {string}   key          The name of the option controlled by this checkbox.
             * @param  {string}   hiddenValArr The JSON currently being stored in this fieldset.
             * @param  {string}   fieldsetID   The HTML ID for this fieldset.
             * @param  {boolean}  checked      Whether or not this checkbox hould be checked.
             * @return {string}   The HTML for a draggable checkbox input.
             */
            function checkboxListItem( key, hiddenValArr, fieldsetID,  checked ) {
    
                var out = '';
    
                // If the key is empty, skip it.
                if( key === '' ) { return out; }
    
                // If we are doing an empty checkbox, make sure it's not already on the list.
                if( ! checked ) {
    
                    // If there is actually some value in the hidden input...
                    if( hiddenValArr !== null ) {
    
                        // If the checkbox for this item is already checked, skip it.
                        if( hiddenValArr[key] == true ) {
                            return out;
    
                        // Else, if it's a non empty string, skip it.
                        } else if( ( typeof hiddenValArr[key] == 'string' ) && hiddenValArr[key] != '' ){
                            return out;
                        }
                    }
                }
    
                // This might end up holding an HTML <select> menu.
                var select = '';
    
                // The might hold the current value of the select menu.
                var selected = false;
    
                // Does this key contain a magic hash code?
                if( key.indexOf( '###' ) != -1 ) {
    
                    // If so, remove the magic hash codes in order to arrive at what type of <select> it is.
                    var type = key.replace( new RegExp( '#', 'g' ), '' );
    
                    // Grab the select menu. We'll append it later.
                    select = dropdown( type, checked, hiddenValArr );
    
                    // Grab the current value of the select menu.
                    selected = jQuery( select ).val();
    
                }
    
                // Create the checkbox.
                var input = jQuery( '<input/>', {
                    'id'    : fieldsetID + key,
                    'name'  : key,
                    'type'  : 'checkbox',
                    'value' : key
                });
    
                // If the checkbox is checked and has a select menu, record the value of the select menu in a data attribute.
                if( checked && selected ) {
                    jQuery( input ).attr( 'data-which', selected );
                }
    
                // Wrap a label around the input.
                var label = jQuery( '<label/>', {
                    html  : key,
                    'for' : fieldsetID + key
                });
                jQuery( input ).prependTo( label );
    
                // Make a list item to wrap the whole darn thing.
                var out = jQuery( '<li/>' );
    
                // Add the label to the list item.
                jQuery( label ).appendTo( out );
    
                // Add the select menu to the list item.
                jQuery( select ).appendTo( out );
    
                return out;
    
            }
    
            /**
             * Create the list of checkboxes.
             * 
             * @param  {string}   fieldsetID       The ID for this fieldset.
             * @param  {object}   hidden           The input that stores the value of the checkboxes.
             */
            function create( fieldsetID, hidden ) {
    
                // The JSON string in the hidden value.
                var hiddenVal = hidden.val();
    
                // Grab the hidden value as an object.
                if( typeof hiddenVal !== 'object' ) {
                    var hiddenValArr = jQuery.parseJSON( hiddenVal );
                } else {
                    var hiddenValArr = hiddenVal;
                }
    
                /**
                 * The availabe options for this fieldset, stored in the DOM as a
                 * data attribute on the input that stores the JSON.
                 */ 
                var choices    = hidden.data( 'choices' );
                choices        = JSON.stringify( choices );
                var choicesArr = JSON.parse( choices );
    
                // Start a list to hold the checkboxes, which we'll draw shortly.
                var sortable = jQuery( '<ul>' ).addClass( 'ui-sortable' ).insertBefore( hidden );   
    
                // Make the checkboxes sortable.
                jQuery( sortable ).sortable({
    
                    // Once an item is dragged and sorted, update the preview and save the JSON.
                    stop: function( event, ui ) {
                        update( hidden  );
                    }
                });
    
                // Loop through the current values and output checked checkboxes.
                if( ! jQuery.isEmptyObject( hiddenValArr ) ) {
    
                    // For each of the current values...
                    jQuery.each( hiddenValArr, function( key, value ) {
    
                        // Draw a checkbox with the dropdown menu visible.
                        var listItem = checkboxListItem( key, hiddenValArr, fieldsetID,  true );
    
                        // Add it to the DOM and check the box.
                        jQuery( listItem ).appendTo( sortable ).find( 'input' ).prop( 'checked', true );
    
                    });
    
    
                }
    
                // For all the available choices on this fieldset...
                jQuery.each( choicesArr, function( key, value ) {
    
                    // Draw a checkbox with the dropdown menu hidden.
                    var listItem = checkboxListItem( key, hiddenValArr, fieldsetID,  false );
    
                    // Add it to the DOM.
                    jQuery( listItem ).appendTo( sortable ).find( 'input' );
    
                });
    
            }
    
            /**
             * Update the value for this fieldset, perhaps when a checkbox is checked or sorted.
             * 
             * @param  {object} hidden The hidden form field that stores the values for this fieldset.
             */
            function update( hidden ) {
    
                var out = {};
    
                // Grab the name of the hidden field.
                var hiddenName = jQuery( hidden ).attr( 'name' );
    
                // Grab all the checkboxes in this fieldset.
                var checkboxes = jQuery( hidden ).closest( 'li' ).find( '[type="checkbox"]:checked' );
    
                // Grab all the select menus in this fieldset.
                var selects = jQuery( hidden ).closest( 'li' ).find( 'select' );
    
                // For each checkbox...
                jQuery( checkboxes ).each( function( index, value ) {
    
                    // Grab the value.
                    var val = jQuery( value ).val();
    
                    // Let's see if this checkbox carries a select menu as well.
                    var which = jQuery( value ).attr( 'data-which' );
    
                    // If it has a select menu, that acts as the value for the checkbox.
                    if( typeof which != 'undefined' ) {
                        out[val] = which;
    
                    // If not, the checkbox is just boolean true.
                    } else {
                        out[val] = true;
    
                    }
    
                });
    
                // Turn the output into JSON.
                var outStr  = JSON.stringify( out );
                var outJSON = JSON.parse( outStr );
    
                // Update the hidden field.
                jQuery( hidden ).val( outStr );
    
                // Grab the core WP customization object and update it.
                var api = wp.customize;
                api.instance( hiddenName ).set( outStr );
    
                // Show or hide the select menus based on whether the parent menu item is checked.
                jQuery( selects ).each( function( index, value ) {
    
                    // Find out if the checkbox is checked.  If so, reveal the select menu.
                    var checkbox = jQuery( value ).closest( 'li' ).find( '[type="checkbox"]' );
                    if( jQuery( checkbox ).is( ':checked' ) ) {
    
                        jQuery( value ).slideDown();
    
                    // Else, hide the select menu.
                    } else {
    
                        jQuery( value ).slideUp();
    
                    }
    
                });
    
            }
    
            /**
             * The main part of the jQuery plugin that actually returns the selected items.
             * 
             * @return {object} The items that this plugin applies to.
             */
            return this.each(function() {
    
                var that = this;
    
                // The ID for this section of the customizer.
                var fieldsetID = jQuery( that ).attr( 'id' );
    
                // The input that stores JSON as the checkboxes toggle and move.
                var hidden = jQuery( that ).find( '[type="text"]' );
    
                // Okay! Create the list of checkboxes!
                create( fieldsetID, hidden );
    
                // Whenever the checkboxes are checked, update the json and redraw the preview.
                jQuery( that ).on( 'change', '[type="checkbox"]', function( event ) { 
                    update( hidden );
                });
    
                /**
                 * Whenever the dropdowns are selected, trigger a change on the
                 * corresponding checkbox.
                 */ 
                jQuery( that ).on( 'change', 'select', function( event ) { 
    
                    /**
                     * What type of dropdown is this?  Maybe to get links by category, or get a custom menu?
                     */
                    var type = jQuery( this ).attr( 'data-type' );
    
                    // Find the corresponding checkbox.
                    var checkbox = jQuery( this ).closest( 'li' ).find( '[type="checkbox"]:checked' );
    
                    // Find out which <option> is selected.
                    var selected = jQuery( this ).val();
    
                    // Trigger a change on that checkbox.
                    jQuery( checkbox ).attr( 'data-which', selected ).trigger( 'change' );
    
                });
    
                return that;
    
            });
    
        }
    
    }( jQuery ));
    

0 个答案:

没有答案