The Wayback Machine - https://web-wp.archive.org/web/20150402225351/https://make.wordpress.org/core/author/celloexpressions/

WordPress.org

Make WordPress Core

Updates from Nick Halsey Toggle Comment Threads | Keyboard Shortcuts

  • Nick Halsey 11:00 pm on February 11, 2015 Permalink |
    Tags: , , ,   

    Customizer Theme Switcher Feature Plugin Merge Proposal 

    Ticket: #31303

    Customizer Theme Switcher brings theme-browsing and theme-switching functionality into the Customizer. By integrating themes directly into the Customizer, live-previewing workflows are greatly simplified, and the relationship between themes and theme/site options is clarified for the user.

    This plugin represents a significant step in moving all “Appearance” functionality into the Customizer, following Widgets. The future roadmap includes Menus, Theme-Install, and iterations on widgets that would allow the Customizer to entirely replace those admin screens for most users. Because the Customizer Theme Switcher plugin does not address theme-install, the admin page (themes.php) is fully intended to remain in use for now. We are proposing to redirect the front-end “Themes” link (in the admin bar) to the Customizer, as was done for widgets in 4.1.

    Technical Overview

    Customizer Theme Switcher is primarily about adding new UI for existing functionality using existing APIs, rather than introducing new functionality. The plugin operates entirely off of the WordPress 4.1 Customizer API, leveraging the new JavaScript API in particular. Themes is a custom section (that acts kind of like a panel). Each theme is a custom Customizer control.

    The code is heavily Backbone.js-inspired, leveraging JS-heavy portions of the Customizer API to do things like underscore JS templates for rendering theme data. Most of the code is directly adapted from the Backbone-driven themes.php system (and the theme data is retrieved with existing functions), but things like the search/filter are written from the ground up to leverage the Customizer API (in that case, conditionally activating/deactivating controls).

    In keeping with the goal to avoid back-end functionality changes, theme-switches are accomplished simply by leveraging the existing ability to pass a theme as a URL query arg when loading the Customizer; ie, the Customizer is simply reloaded to preview a different theme. Loading overlays are leveraged to make this process seem more instant. Unrelated 4.2 core work around Customizer Transactions could potentially improve how this works.

    Core Changes & Merge Implementation Details

    As outlined in the plugin’s readme there are several proposed technical and user-oriented changes that are best done as core patches (mostly in the merge patch):

    UX

    • Remove #customize-info for theme previews.
    • Change front-end admin bar Themes link to point to themes in the Customizer (deep-linked).
    • When a new theme is activated, go to the home page (front end), not the themes admin.
    • If user doesn’t confirm that they want to leave unsaved changes, remove the customize-loading body class (requires core patch).

    Code

    • Move custom section and control to class-wp-customize-control|section.php in wp-includes.
    • Merge all CSS into customize-controls.css, scope to .wp-customizer.
    • Move .themes-panel-back to the Customizer header, adjust JS accordingly.
    • Merge JS into customizer-controls.js, after the respective object types.
    • Merge customize_themes_template() into wp-admin/includes/theme.php, at the very end. Make sure that this file is included at the appropriate time as needed when adding the Customizer controls.
    • Merge remaining PHP (all in Customize Register callback) into register_controls() in class-wp-customize-manager.php.

    User Testing

    @designsimply has run four usertesting.com tests (see links in #core-customize), and we haven’t really seen any ongoing issues with the actual theme switcher. It has been difficult to get users to follow our instructions, but when they have used the themes-in-Customizer UI, the interactions have been fairly seamless and as-intended. Further testing could be beneficial after merge, but we think that in-person testing and feedback is generally going to be more effective for this particular plugin.

    Outstanding Issues

    The exact handling of the themes header display still needs some work – the backwards-sliding works well but the arrows to indicate it don’t. @folletto opened a ticket on core trac to work through some alternative options. Most of the accessibility issues have been fixed as well (@afercia please let me know if I’ve missed any), with the exception of the Themes section header, which will happen along with the UI changes there for everyone.

    Future Plans

    A future phase of this project will explore integrating theme-install in the Customizer and minimizing the distinction between installed and available themes. Due to the larger UI and UX changes proposed with that effort, we’ve decided to hold off on theme-install for now so that the basic theme-switching functionality could be built on a reasonable timeline for 4.2. This is similar to the manner in which the “THX” feature plugin team re-did themes in 3.8 and theme-install in 3.9.

     
    • bellfalasch 9:31 am on February 12, 2015 Permalink | Log in to Reply

      Looks good =) I personally would love something like a top positioned overlay with short text “You are previewing Theme X – [activate theme] – [cancel]”. Or wouldn’t that make sense in the customizer?

    • Andrea Fercia 1:52 pm on February 12, 2015 Permalink | Log in to Reply

      Thanks very much Nick and great job :) will review all your feedback on the accessibility issues list and will let you know.

    • codeinwp 9:10 pm on February 12, 2015 Permalink | Log in to Reply

      Looks really cool!

  • Nick Halsey 12:46 am on February 3, 2015 Permalink |
    Tags: ,   

    Customizer Theme Switcher Update – 2/2 

    We’ve made lots of progress in the past week and will be holding another meeting tomorrow, Tuesday February 3 2015 16:00 UTC, in #core-customize Slack. The accessibility team did an extensive review and we’ve addressed nearly all of the issues that can be fixed in the plugin (big props to @afercia especially for reviewing and patching some of the issues). I made several core tickets (some with patches, some good-first-bugs) for some of the other issues that came up during the review.

    @designsimply and @vizkr have been working on formal and informal user tests as well. It’s been a little tricky to try to nudge users in the direction of the Theme Switcher in the Customizer without explicitly asking them to change the theme, but they haven’t had any negative feedback or expressed that having themes in the Customizer felt at all out of place. We’ve made a couple of minor adjustments both to the plugin (improving the filter to search for tags without hyphens) and the prompts, and additional tests are in-progress. We’d like to encourage anyone that can to do informal in-person testing, asking for feedback on the workflows and/or comparing the themes admin screen to themes in the Customizer.

    Our biggest remaining decision is whether to change the title of the “themes” section in the Customizer. Currently, it’s “Theme: Current Theme”. Open to suggestions here; we’ll tweak it for screen readers regardless if it works for everyone else as-is, but I’m not convinced that it’s the most discoverable option currently.

    Here’s an agenda for the meeting:

    • Usertesting.com testing update – @designsimply
    • Theme section heading title discussion
    • Informal testing/feedback updates – anyone
    • Accessibility updates: ready for (or do we need) another round of testing for the plugin? – @afercia
    • Outstanding issues – anyone
    • Final proposal and core patch/merge plan and timing – @MarkJaquith, me, @DrewAPicture
     
  • Nick Halsey 8:11 am on January 26, 2015 Permalink |
    Tags: ,   

    Customizer Theme Switcher Update 

    The Customizer Theme Switcher feature-plugin brings theme switching into the Customizer. This project aims to clarify the relationship between themes and theme options by introducing a themes “panel” (it’s actually a custom section since it contains controls, not a multi-level hierarchy of sections and controls) to the Customizer. The themes panel slides in from the left instead of the right, implying a hierarchy of:

    1. Themes – change the entire layout of the site
    2. Theme/site options – tweak various options (default view)
    3. Panels – edit larger groups of site appearance options, such as Widgets and Menus

    Essentially, the phase of the project proposed for WordPress 4.2 (and that exists in the plugin currently) brings the “THX38″ theme browsing experience into the Customizer. Installed themes are browse-able directly in the Customizer controls panel, and have a details modal like the admin page. Functionally, theme-switching is accomplished by reloading the Customizer to live-preview a different theme. @westonruter is working on several related improvements that could further streamlining the experience from a technical perspective, but this feature plugin is focusing on the switching UI, with other improvements considered “nice to have”. @folletto and I have also started planning a second phase of the project for a future release that would also address installing new themes, and simplifying the distinction between installed and available themes. @designsimply is currently in the process of user-testing the plugin.

    Get Involved

    We’ll hold a meeting in #core-customize Slack to discuss the progress of the plugin this Tuesday, January 27, 2015 16:00 UTC, and continue at that time weekly as needed at that time. Development is happening directly in the WordPress.org plugins repo – I’ll give commit access to anyone interested in contributing code. Outstanding issues are noted below, but the plugin is generally ready for review of code, inline-docs, design, and accessibility (with each of those being theoretically good-to-go in the plugin). Note that the plugin can’t really work on mobile because the Customizer doesn’t really work on mobile, see #28784 (great 4.2 candidate if it gets a patch).

    Known issues (see also a list of core merge notes in the plugin’s readme):

     
    • Weston Ruter 9:53 pm on January 29, 2015 Permalink | Log in to Reply

      PostMessage setting transport may not be working immediately after switching themes, cause unknown

      I can’t reproduce this. See Slack conversation.

    • Rian Rietveld 7:40 am on January 31, 2015 Permalink | Log in to Reply

    • Devin Price 12:04 am on February 5, 2015 Permalink | Log in to Reply

      Hi Nick. Great work on this. A couple thoughts:

      I might recommend is that the theme panel stays open (retains focus) after switching. If someone is testing the look of a few different themes, it might be annoying to have to open that panel again each time and lose context.

      I’m not sure if the theme switcher should have such a high priority (in terms of order). I feel like switching themes has a lot of ramifications, and perhaps shouldn’t be the first option. I’d probably hook it in below the “widgets” (just a personal feeling though).

      Also, looks like the open/close arrows for the panel are pointing the wrong way.

      Maybe you’re already working through some of those. Just wanted to add my 2 cents.

  • Nick Halsey 7:07 pm on December 19, 2014 Permalink |
    Tags: ,   

    Menu Customizer: Call for Contributors 

    After a few months off from working on the Menu Customizer to focus on improving the Customizer API in core, I’m starting to pick up development on the feature-plugin. Now that it’s approaching a reasonably usable state, and is compatible with the latest major release of WordPress (4.1), I’d like to begin efforts to see if we can propose merging it into core for WordPress 4.2.

    But there is a lot of work to be done. When Menu Customizer was my GSoC project, it was closed to contributors per GSoC rules. But development is now open to everyone, and I could use a lot of help with both development and non-development tasks. Here’s a list of items that need work:

    •  Development
      • Build-out the core API for adding Customizer sections and controls entirely with JavaScript, #30741 and its related tickets (PHP, JS)
      • Drag & Drop menu item reordering needs to do sub-menus (code imported from nav-menus.php is commented out in menu-customizer.js currently) (JS)
      • Fix problems with previewing updates to menu items, and with previewing newly-added menus once items are added (JS)
      • Eliminate the PHP closure that currently facilitates menu previewing, for PHP 5.2 compatibility (PHP)
      • Redo the add-menu-items “panel” to lazy-load its contents & utilize Backbone sub-views (PHP, JS)
      • Improve the core Customizer on mobile, then make Menu Customizer work on mobile (CSS)
      • Think about an API or otherwise action hooks to allow plugins to add menu item fields, #27066, #21898, #18584, etc. (PHP)
      • Inline docs audit, once we’re mostly done (PHP, JS)
      • Comprehensive code review by people like @westonruter, @ocean90, or @nacin, once we’re mostly “done”, preferably before a core merge proposal. Initial code review/cleanup from anyone can start now
    • Design
      • Overall UI audit/review, propose changes
      • Consider things like #29158 in relation to how the menus UI looks
      • Discuss approach to screen options (currently an icon in the Menus panel header)
      • UX audit, propose changes
      • Evaluate user flows & menus use-cases
      • Conduct user tests
    • Other
      • General user feedback – getting the word out about the plugin and collecting feedback (reviews & support forms on the .org repo would be a good place for feedback). Anyone reading this can try the plugin and provide feedback too :)
      • Accessibility audit
      • Backwards-compatibility audit; in particular, assessing whether Menu Customizer could replace the Menus admin screen, and what further features or use-cases would need to be addressed to do so
      • Research the history of the Menus UI in core and document how Menu Customizer addresses ongoing concerns; also consider open tickets in the Menus component (for merge proposal)

    Development is happening on the WordPress.org plugins repo the a GitHub repo. Some helpful links: create a ticket, Menu Customizer tickets, development log. It’ll probably also be possible to contribute via Github if that’s your preference – talk to @westonruter about how he does it.

    This project will primarily take place over the next month, when core development is largely on hold for the holidays and between releases, and when I’m in between semesters at school. The goal is to be merge-ready before the 4.2 feature-plugin merge consideration happens in January. If you’re interested in helping out, please comment on this post or ping me in WordPress Slack in #core (@celloexpressions).

    Due to the timing of this project around the holidays, we’ll probably do mostly asynchronous communication, but I would like to try a kick-off meeting in #core Slack on Monday, December 22, 2014 18:00 UTC; please come by if you’re interested!

     
    • diddledan 9:11 pm on December 19, 2014 Permalink | Log in to Reply

      Hi Nick,

      you may find my plugin https://wordpress.org/plugins/custom-menu-fields/ useful as it provides an api for menu fields to be added by plugins. I’ve not updated it in a while, but you’re welcome to have a look and reuse anything you like the look of (we are all GPL afterall :-p) – I might be able to have a look at your code over the weekend or holiday period and see if I can develop and send you any patches I think you might find useful.

    • Nick Halsey 7:51 pm on December 22, 2014 Permalink | Log in to Reply

      Had our first meeting today. Ongoing discussion will happen in the new #core-customize channel on Slack, so stop by if you have any feedback or want to help out!

  • Nick Halsey 3:48 pm on November 17, 2014 Permalink
    Tags: , ,   

    JS/Underscore-template-rendered Custom Customizer Controls in WordPress 4.1 

    The Customizer is a JavaScript-driven feature of WordPress core, but until recently, most of the APIs for extending it in themes and plugins were PHP-oriented. In WordPress 4.1, we’re introducing more complete JS models for the different UI objects that comprise the Customizer. In the process, all controls are now placed into the DOM with JavaScript, rather than being output directly in PHP.

    At the same time, we’ve been working on issues of scalability and performance. In particular, bringing the navigation menu management experience into the Customizer has highlighted several areas with room for improvement. With menus, each menu item is a Customizer control with several fields, so a site with hundreds of menu items across different menus will end up sending a lot of repetitive HTML down from PHP, and we currently have to send the full markup for a menu item control down from the server when adding menu items in an Ajax call.

    #29572 offered a solution to these challenges: an optional API that allows Customizer controls to be written as JavaScript templates. Rather than populating a control’s container with markup rendered on the server and obtained via an Ajax call, we can now use JS templates to render these controls on the client without any server-side call. In the future, new controls could be added dynamically (lazy-loaded, #28580) by leveraging the control-type templates already loaded in the Customizer.

    In the remainder of this post, I’ll walk through how to use this API, its benefits, and example use-cases that are already benefiting WordPress core in 4.1.

    Registered Control Types

    In order to introduce a concept of having one template for multiple Customizer controls of the same type, we needed to introduce a way to register a type of control with the Customize Manager. Previously, custom control objects were only encountered when custom controls were added using WP_Customize_Manager::add_control(). But detecting added control types to render one template per type wouldn’t allow new controls to be created dynamically if no other instances of that type were loaded. So we’ve introduced WP_Customize_Manager::register_control_type(). Usage is simple:

    add_action( 'customize_register', '29527_customize_register' );
    function 29527_customize_register( $wp_customize ) {
    	// Define a custom control class, WP_Customize_Custom_Control.
    	// Register the class so that it's JS template is available in the Customizer.
    	$wp_customize->register_control_type( 'WP_Customize_Custom_Control' );
    }
    

    All registered control types will have their templates printed to the Customizer by WP_Customize_Manager::print_control_templates().

    Sending PHP Control Data to JavaScript

    While Customizer control data has always been passed to the control JS models, and this has always been able to be extended, you’re much more likely to need to send data down when working with JS templates. Anything that you would want access to in render_content() in PHP will need to be exported to JavaScript to be accessible in your control template. WP_Customize_Control exports the following control class variables by default:

    • type
    • label
    • description
    • active (boolean state)

    You can add additional parameters specific to your custom control by overriding WP_Customize_Control::to_json() in your custom control subclass. In most cases, you’ll want to call the parent class’ to_json method also, to ensure that all core variables are exported as well. Here’s an example from the core color control:

    public function to_json() {
    	parent::to_json();
    	$this->json['statuses'] = $this->statuses;
    	$this->json['defaultValue'] = $this->setting->default;
    }
    

    JS/Underscore Templating, + examples

    Once you’ve registered your custom control class as a control type and exported any custom class variables, you can create the template that will render the control UI. You’ll override WP_Customize_Control::content_template() (empty by default) as a replacement for WP_Customize_Control::render_content(). Render content is still called, so be sure to override it with an empty function in your subclass as well.

    Underscore-style custom control templates are very similar to PHP. As more and more of WordPress core becomes JavaScript-driven, these templates are becoming increasingly more common. Some sample template code in core can be found in media, revisions, the theme browser, and even in the Twenty Fifteen theme, where a JS template is used to both save the color scheme data and instantly preview color scheme changes in the Customizer. The best way to learn how these templates work is to study similar code in core and, accordingly, I’ll briefly explain an example here now.

    class WP_Customize_Color_Control extends WP_Customize_Control {
    	public $type = 'color';
    // ...
    	/**
    	 * Render a JS template for the content of the color picker control.
    	 */
    	public function content_template() {
    		?>
    		<# var defaultValue = '';
    		if ( data.defaultValue ) {
    			if ( '#' !== data.defaultValue.substring( 0, 1 ) ) {
    				defaultValue = '#' + data.defaultValue;
    			} else {
    				defaultValue = data.defaultValue;
    			}
    			defaultValue = ' data-default-color=' + defaultValue; // Quotes added automatically.
    		} #>
    		<label>
    			<# if ( data.label ) { #>
    				<span class="customize-control-title">{{{ data.label }}}</span>
    			<# } #>
    			<# if ( data.description ) { #>
    				<span class="description customize-control-description">{{{ data.description }}}</span>
    			<# } #>
    			<div class="customize-control-content">
    				<input class="color-picker-hex" type="text" maxlength="7" placeholder="<?php esc_attr_e( 'Hex Value' ); ?>" {{ defaultValue }} />
    			</div>
    		</label>
    		<?php
    	}
    }
    

    In the above template for the core custom color control, you can see that after the closing PHP tag, we have a JS template. <# #> notation is used around statements to be evaluated – in most cases, this is used for conditionals. All of the control instance data that we exported to JS is stored in the `data` object, and we can print a variable using double or triple brace notation {{ }}. As I said before, the best way to get the hang of writing controls like this is to read through existing examples. WP_Customize_Upload_Control was recently updated to leverage this API as well, integrating nicely with the way the media manager is implemented, and squeezing a ton of functionality out of a minimal amount of code. If you want some really good practice, try converting some of the other core controls to use this API – and submit patches to core too, of course!

    Working with Controls in JavaScript

    The Customizer has always had an API for working with controls in JavaScript. Now that the Customizer supports JS-rendered controls, this API will be even more useful, as you can do things like re-rendering the entire control if its data changes significantly (think media attachment previewing, for example), rather than doing direct DOM manipulation. Again, the core code is the best place to start getting a feel for this API, but it essentially works like subclasses do in PHP. See @westonruter‘s post for details on how this side of the API has evolved in 4.1, and take a look at the control-related models in wp-admin/js/customize-controls.js.

    Putting the pieces together

    Here’s a summary of what’s needed to leverage the new API in a custom Customizer control subclass:

    1. Make your render_content() function empty (but it does need to exist to override the default one).
    2. Create a new function, content_template(), and put the old contents of render_content() there.
    3. Add any custom class variables that are needed for the control to be exported to the JavaScript in the browser (the JSON data) by modifying the to_json() function (see WP_Customize_Color_Control for an example).
    4. Convert the PHP from render_content() into a JS template, using <# #> around JS statements to evaluate and {{ }} around variables to print. PHP class variables are available in the data object; for example, the label can be printed with {{ data.label }}.
    5. Register the custom control class/type. This critical step tells the Customizer to print the template for this control. This is distinct from just printing templates for all controls that were added because the ideas are that many instances of this control type could be rendered from one template, and that any registered control types would be available for dynamic control-creation in the future. Just do something like $wp_customize->register_control_type( 'WP_Customize_Color_Control' );.

    The PHP-only parts of the API are still fully supported and perfectly fine to use. But, with WordPress 4.0’s decreased need for custom controls, and given our long term goals for making the Customizer more flexible for doing things like switching themes in the Customizer without a pageload, I strongly encourage using this new API for all custom Customizer controls where feasible.

     
    • Jon Brown 10:51 am on November 18, 2014 Permalink | Log in to Reply

      Nick – Thank you! Seriously impressed by the work you’re doing to the customizer. Please keep it up!

    • Fabien Quatravaux 4:24 pm on December 15, 2014 Permalink | Log in to Reply

      Thanks for your hard work on this topic Nick.

      I’m currently trying to implement a custom control with the new API on 4.1-RC1, and I hit some roadblock : if I use the `$wp_customize->register_control_type` method, the input inside my Control becomes inhert. When I change the value of this control, the “Save” button on the top stays disabed showing that my changes are not taken into account.

      I’m missing the link, that was done automatically in the previous API version, between the actual HTML control and the setting that it is bound to. I thought this link was done thanks to the `data-customize-setting-link` attribute, but I had no luck using it. Any suggestions ?

      • bduclos 6:11 pm on February 6, 2015 Permalink | Log in to Reply

        Hi Fabien,

        Did you manage to do it?
        I’m triing to implement in in WP 4.1 but I have the same issue that you’ve described.

  • Nick Halsey 12:20 am on August 8, 2014 Permalink
    Tags: , ,   

    GSoC Menu Customizer Update: Live-previewing Menus 

    I’ve finished implementing menu-previewing in the Menu Customizer plugin, building on the scalable approach to saving menus that I discussed in my last update. The entire Menus experience is now consolidated into a Menus panel in the Customizer, where you can preview your menus as you make changes. It’s really nice to have Menus easily accessible alongside the rest of the site-appearance-management tools in the Customizer.

    I only have about a week and a half left in my GSoC project, and I’m hoping to focus on improving the add-new-menu-item panel in my remaining time, making it scale and implementing the search functionality. I’m also planning on cleaning up the codebase and implementing the ability to manage menu hierarchy (submenus).

    If you’re interested in testing the Menu Customizer, and live-previewing changes to your menus, you can get the plugin here. Please note that it currently requires PHP 5.3+, but it’s getting less and less alpha by the day.

    Post-GSoC Plans

    After the GSoC coding period is over, I’m planning on transitioning Menu Customizer development to the feature-plugin format, gathering a group of interested contributors and holding weekly meetings to coordinate our efforts. While it won’t be ready for core consideration by 4.1, and requires some more core Customizer infrastructure to really work well, we’ll continue working on the plugin until menus in the Customizer really shine, and are ready for core.

     
  • Nick Halsey 3:15 pm on July 15, 2014 Permalink
    Tags: , ,   

    GSoC Menu Customizer Update: Scalable Menus 

    Since my last GSoC update, I’ve spent a fair amount of time helping prepare the Customizer for 4.0 beta 1. But I’ve also continued working on the Menu Customizer and have a lot of progress to report.

    Add & Delete Menus

    You can now add new menus, via the “+ New Menu” section. Added menus currently have some issues, though; you’ll probably need to reload the page before adding items works. The problems stem from the lack of a proper JS API for adding, deleting, and managing Sections and Settings (and Panels), and the incompleteness of the existing Control JS API. This will probably need to be resolved in core before the Menu Customizer can be considered for core integration, see #28709.

    I’ve also implemented a menu-deletion mode, which can be toggled from the add-menu section. It’s too easy to delete menus otherwise, even with an AYS confirming the delete, because deleted menus cannot be restored, and are not “previewed” before being published to the db (added menus aren’t either). It’s probably worth augmenting the AYS to state the menu name being deleted, and to add an extra warning if it’s active in a theme location or a widget.

    Saving Menus and Menu Item Data in a Scalable Way

    In core, menus do not scale well at all. You don’t have to look very deep into the code to see why – massive amounts of data for each item are hidden on the admin screens (much of which never changes) and then must be updated every time a change is made.

    Since one of the goals of this project is to experiment with new approaches, I’ve begun implementing a new approach for saving menu data, which is currently in use in the plugin. Thanks to my mentors @ethitter and @obenland for guiding me on the best approach to take here, and @westonruter for the way he implemented the Widget Customizer UI, which inspired this exact approach. Here’s how it works:

    • Each menu has a nav_menu Customizer control that contains an ordered array of numerical menu item ids (known throughout the core menus codebase as their db ids).
    • When an item is added, it is created as an orphaned draft via ajax, and its id is added to the nav_menu setting’s array.
    • When an item is deleted, its id is removed from the nav_menu setting’s array.
    • When menu items are reordered, the order of ids in the nav_menu id is updated to match.
    • When menu items are moved into and out of sub-menus, the parent menu item id is updated in the individual item’s data (not yet implemented).
    • When a menu item field is changed (by default, this would mean changing the label or, for custom items, url fileds; there are screen options for several others), the original item is cloned and the copy is updated with the new data, using a wrapper for wp_update_nav_menu_item() that doesn’t require passing all existing (unchanged) menu item data. The cloned item’s id is returned and replaces the original id in the nav_menu setting (thereby marking the original item for deletion). Additional changes are saved to the cloned item until the settings are saved, at which point all items are marked for a new clone to be created if changes are made (not yet implemented).
    • When the user saves their changes from the Customizer (via the customize_update_nav_menu action), the array of ids is compared to the currently-published menu’s items. If there are items that are no longer present, those are marked for deletion. For each of the new ids, the corresponding menu item (which already exists) is updated to be published, assigned to the corresponding menu (for the new items created as orphaned drafts), and the item’s menu_order is set to the id’s position in the nav_menus setting array. Finally, all of the removed items are deleted.

    While menu previewing in the customizer is not yet implemented, it will also be able to use the nav_menu setting’s array of ids to display an augmented set of menu items. I’m also still working on ensuring that menu item data is not posted during the customize-save ajax, but the data isn’t needed so we’re most of the way there already.

    UI Aside

    customize-header-bigflat-buttons-close

    Quick aside: @DrewAPicture pointed out in IRC that the new Customizer close and panel-back icons don’t really match the save button. I’ve done some rough explorations of potential alternatives; if anyone’s interested in discussing them and possibly implementing a change here, feel free to ping me in IRC (@celloexpressions) and/or create a ticket and/or comment here.

    Finally, I’m hoping to finish implementing menu previewing by the end of this week, fully utilizing the Customizer. Once this is done, I’ll essentially be at feature-complete stage (other than some little details and several known bugs) and ready to iterate (I’m already planning on working on the add-menu-items backend, as it currently doesn’t scale).

     
    • michalzuber 5:30 pm on July 17, 2014 Permalink | Log in to Reply

      I’m figuring out why is `@todo: Remove choices` in the `wp-includes/class-wp-customize-control.php` ? Couldn’t get it.

      • Nick Halsey 5:43 pm on July 17, 2014 Permalink | Log in to Reply

        That’s more related to the Customizer post, but I think that’s leftover from the initial customizer development in 3.4. We can remove the todo, since removing $choices is no longer an option due to back-compat.

    • Weston Ruter 8:26 pm on July 22, 2014 Permalink | Log in to Reply

      When an item is added, it is created as an orphaned draft via ajax, and its id is added to the nav_menu setting’s array.

      Something that I’ve been exploring with Customize Posts is the addition and deletion of postmeta. Instead of actually mutating the database, when creating new meta I’m creating faux post meta IDs and then referring to them in the preview filter. When saving the Customizer settings, these posts meta are then inserted at that time. It’s not quite done yet, as I need to now gather the post meta IDs that were inserted at the time of saving, and update the setting to refer to them.

      Generating a virtual post meta ID: https://github.com/x-team/wp-customize-posts/blob/85dc4e562ea806c17480899f5d94f93d42297de1/js/customize-posts.js#L611-L618

      Sanitizing a setting that includes virtual post meta ID: https://github.com/x-team/wp-customize-posts/blob/develop/php/class-wp-customize-posts.php#L303-L310

      It would be ideal if Menu Customizer could add new menu items virtually without touching the DB.

      • Nick Halsey 10:12 pm on July 22, 2014 Permalink | Log in to Reply

        I’m not sure if it would be possible to add items without touching the DB in a scalable way. The primary reason for doing that is so that menu item data doesn’t need to be sent to the server all at once when saving, which causes scaling problems currently (for example, imagine if 100+ menu items were added to several different menus upon initial setup of a site – that data would all go up together).

        In the existing menus system, items are similarly added to the db via ajax before being made available for manipulation in the UI. So, the concept of orphaned draft menu item posts is existing and currently being leveraged here.

  • Nick Halsey 1:58 am on July 8, 2014 Permalink
    Tags: , , ,   

    Customizer Improvements in 4.0 

    Building on the addition of Widgets to the Customizer in 3.9, and alongside my GSoC Menu Customizer project, @westonruter, @ocean90 and I have been working on a series of Customizer improvements for 4.0. In this post, I’ll summarize the changes and proposed changes that we’d like to get in before beta. Anything with an asterisk (*) still needs to be committed but has a patch. Keep in mind that everything here is liable to change before 4.0 is released.

    We currently have eight enhancements and feature requests that need to be completed before beta, but half of them are already marked for commit and all have patches. If you’re interested in helping out with these changes, we could still use help reviewing and testing many of them (especially for UI/UX). Huge thanks to everyone who’s helped out so far this cycle.

    Terminology Notes

    We recently renamed the Appearance trac component to Customize. I’d like to clarify a few things regarding terminology used to describe the Customizer:

    • We’re shifting toward using “Customizer” rather than “Theme Customizer”, as it isn’t necessarily theme-specific (though most of its uses currently are).
    • “Customize” is the action, “Customizer” is the thing. Most UI elements use “Customize” or “customizing”, but most documentation should probably use “Customizer”. If you’re questioning which to use, consider whether you’re looking for a noun or a verb and pick accordingly. Feel free to conjugate the verb form (eg. “customizing”).
    • “Customize” could refer to anything. That’s the point; it could be used to customize any part of a site. The Customizer can be used for anything, and we’d like to encourage more experimentation with different uses of the Customizer.

    UI Changes

    In 4.0, most of the Customizer UI changes are for the Customizer itself; the user experience inside the Customizer. I’m expecting a focus on the experience of accessing and navigating through the Customizer in future releases. In 4.0:

    • Widget areas are all grouped into a “Widgets” context, implemented via the new “Panels” API. Panels are a way to group Customizer sections, just like sections are a way to group controls. Panels slide over to the side, rather than expanding down, and contain vertically-expanding sub-sections. This could use some more work on the UI/UX side, see #27406 for details.
    • Only show “You are previewing / [theme name]” and the theme details & screenshot section when the Customizer is previewing an inactive theme. Otherwise, show “You are customizing / [site title]”, with a short description of the customizer. This matches panel headings, which are displayed as “You are customizing / [panel title]”, with the panel description as that heading section’s contents. #28550.
    • Replace Customizer close button with an “X” icon. This fits better with the arrow icon used to exit panels and makes the Customizer controls feel more like a modal/panel that is contextual to the front-end of the site, rather than a confusing mix between the admin and the front-end. We’d also replace the mess of buttons in the theme-install previewer (which looks like the Customizer) with icons and move them around. #28655.
    • Prevent loss of unsaved changes in the Customizer by warning users with an AYS if they try to close the customizer and there are unsaved changes. #25439.
    • Always return to the screen that the Customizer was opened from in the admin, like on the front-end. Look for more work here in the future. #25457.
    • All core customizer controls now support descriptions (#27981), complementing the ability to add descriptions to sections and panels. We could potentially add descriptions to some core controls if they seem needed, might want to do a UI/UX audit of the core Customizer controls and/or user testing.

    Here’s a screencast demonstrating some of these UI changes:

    API Additions & Improvements

    Customizer Panels

    The Customizer now includes a new way to group options together: panels. Just like a section is a container for controls, a panel is a container for sections. This was implemented in #27406. The Panels API is easy-to-use and works almost identically to the existing customizer section API. Add a panel with the following, within the customize_register action:

    $wp_customize->add_panel( 'panel_id', array(
    	'priority'       => 10,
    	'capability'     => 'edit_theme_options',
    	'theme_supports' => '',
    	'title'          => '',
    	'description'    => '',
    ) );

    As always, only use the arguments where you aren’t using the default values. Note that the panel will not be displayed unless sections are assigned to it. To add a section to a panel, just use the panel id for the new panel argument:

    $wp_customize->add_section( 'section_id', array(
    	'priority'       => 10,
    	'capability'     => 'edit_theme_options',
    	'theme_supports' => '',
    	'title'          => '',
    	'description'    => '',
    	'panel'  => 'panel_id',
    ) );

    You may notice that $wp_customize->add_panel and $wp_customize->add_section have the same arguments (other than panel, of course). This is because panels are a special type of section; technically speaking, WP_Customize_Panel extends WP_Customize_Section. Your sections are backwards-compatible: you can add the panel argument to existing sections without issues. However, you do need to check for the existence of WP_Customize_Manager->add_panel() if you’re maintaining pre-4.0 compatibility. As with Customizer Sections, you can access and modify Panels via:

    • $wp_customize->get_panel( $id );
    • $wp_customize->remove_panel( $id );

    New Built-in Customizer Controls

    WordPress core now provides support for a much wider array of Customizer controls. Implemented in #28477, these changes eliminate the need to create custom controls for most common use cases. The textarea type is now supported in core. For any type of input that uses an input element, you can simply specify the type attribute using the type parameter of $wp_customize->add_control().
    Here’s an example:

    $wp_customize->add_control( 'setting_id', array(
    	'type'     => 'url',
    	'priority' => 10,
    	'section'  => 'title_tagline',
    	'label'    => 'URL Field',
    ) );
    

    Which results in the following markup in the Customizer:

    <li id="customize-control-setting_id" class="customize-control customize-control-url">
    	<label>
    		<span class="customize-control-title">URL Field</span>
    		<input type="url" value="" data-customize-setting-link="setting_id">
    	</label>
    </li>
    

    This is pretty powerful, as you can now use the built-in WP_Customize_Control for most common use-cases rather than creating a custom control. But what about input types like number and range that require additional attributes like min, max, and step?

    New Built-in Customizer Control Parameters

    First of all, all of the built-in Customizer controls (including the custom controls such as WP_Customizer_Color_Control) now support descriptions, just like Customizer sections have descriptions (see #27981). This was much-needed and allows for inline help text at the control level.

    More interestingly, to complement the new support for arbitrary input types, a new input_attrs parameter allows you to add attributes to the input element (also implemented in #28477). This extends beyond just using min, max, and step for number and range, to the ability to add custom classes, placeholders, the pattern attribute, and anything else you need to the input element. Here’s an example:

    $wp_customize->add_control( 'setting_id', array(
    	'type'        => 'range',
    	'priority'    => 10,
    	'section'     => 'title_tagline',
    	'label'       => 'Range',
    	'description' => 'This is the range control description.',
    	'input_attrs' => array(
    		'min'   => 0,
    		'max'   => 10,
    		'step'  => 2,
    		'class' => 'test-class test',
    		'style' => 'color: #0a0',
    	),
    ) );

    Which results in the following markup in the Customizer:

    <li id="customize-control-setting_id" class="customize-control customize-control-range">
    	<label>
    		<span class="customize-control-title">Range</span>
    		<strong><span class="description customize-control-description">This is the range control description.</span></strong>
    		<input type="range" min="0" max="10" step="2" class="test-class test" style="color: #0a0;" value="" data-customize-setting-link="setting_id">
    	</label>
    </li>
    

    Which displays as follows (in Chrome 35):

    customizer-4.0-range-control

    The ability to add classes is particularly useful if you need to target specific controls with CSS or JS, but you don’t need any special markup. I’m using this in the Menu Customizer for the Menu Name field, which is just an ordinary text control with a special setting type.

    Contextual Controls

    Customizer controls can now be displayed or hidden based on the Customizer’s preview context. For example, options that are only relevant to the front page can be shown only when the user is previewing their front page in the Customizer (see #27993). This is already implemented in core for Widgets; Widgets have always been contextually faded and shown/hidden based on their visibility in the preview, but this functionality is now built off of the core active_callback API in both PHP and JS. There are three different ways to specify whether a given control should only be displayed in a certain context. The first, and most straightforward, is to use the active_callback argument in $wp_customize->add_control().

    $wp_customize->add_control( 'front_page_greeting', array(
    	'label'           => __( 'Greeting' ),
    	'section'         => 'title_tagline',
    	'active_callback' => 'is_front_page',
    ) );

    Note that you may use either built-in conditional functions or a custom function. If you have a custom control (via a subclass of WP_Customize_Control) and a custom callback function, you can skip the active_callback argument and override the active_callback method instead:

    class WP_Greeting_Control extends WP_Customize_Control {
    	// ...
    
    	function active_callback() {
    		return is_front_page();
    	}
    }

    Finally, the customize_control_active filter will override all of the other active callback options and may be a better solution in certain cases (note that this particular example will be avoidable with future work on expanding the Customizer’s JS API, and does not hide the title_tagline section, only the controls in it):

    function title_tagline_control_filter( $active, $control ) {
    	if ( 'title_tagline' === $control->section ) {
    		$active = is_front_page();
    	}
    	return $active;
    }
    add_filter( 'customize_control_active', 'title_tagline_control_filter', 10, 2 );
    

    In addition to the PHP API for contextual controls, you can override the control-visibility-toggle function on the JS side. By default, controls will slideUp and slideDown as they become visible or hidden when the Customizer preview is navigated. If you’re familiar with the Customizer control JS API (see wp-admin/js/customize-controls.js, and wp.customize.Control), the Widgets implementation of a custom toggle function is a good example:

    api.Widgets.WidgetControl = api.Control.extend({
    // ...
    	/**
    	* Update widget control to indicate whether it is currently rendered.
    	*
    	* Overrides api.Control.toggle()
    	*
    	* @param {Boolean} active
    	*/
    	toggle: function ( active ) {
    		this.container.toggleClass( 'widget-rendered', active );
    	},
    // ...
    ) };
    
    /**
     * Extends wp.customize.controlConstructor with control constructor for widget_form.
     */
    $.extend( api.controlConstructor, {
    	widget_form: api.Widgets.WidgetControl,
    } );
    

    Changes to the customize_update_ and customize_preview_ Actions

    You probably already know that the Customizer supports both option and theme_mod types for settings. But did you know that you can register arbitrary types? Since this is generally undocumented, I’ll show how it works (this has been in place since 3.4):

    $wp_customize->add_setting( 'setting_id', array(
    	'type'                 => 'custom_type',
    	'capability'           => 'edit_theme_options',
    	'theme_supports'       => '',
    	'default'              => '',
    	'transport'            => 'refresh',
    	'sanitize_callback'    => '',
    	'sanitize_js_callback' => '',
    ) );

    There are a few actions that you can use to handle saving and previewing of custom types (option and theme_mod are handled automatically). Namely, customize_update_$type and customize_preview_$type are useful here. Previously, the value of the setting was passed to these actions, but there was no context. In 4.0, via #27979, the WP_Customize_Setting instance is passed to these actions, allowing more advanced saving and previewing operations. Here’s an example from my Menu Customizer project:

    function menu_customizer_update_menu_name( $value, $setting ) {
    ...
    	// Update the menu name with the new $value.
    	wp_update_nav_menu_object( $setting->menu_id, array( 'menu-name' => trim( esc_html( $value ) ) ) );
    }
    add_action( 'customize_update_menu_name', 'menu_customizer_update_menu_name' );
    

    This part of the Customizer API is a bit too complex to fully explain here, as most of it already existed, but suffice it to say that the addition of the setting instance to these actions greatly expands the possibilities of working with custom setting types in the Customizer.

    New “customize” Meta Capability

    The Customizer has been essentially decoupled from edit_theme_options in favor of a customize meta capability (mapped to edit_theme_options by default), which is assigned only to administrators by default. This allows for wider use of the Customizer’s extensive capability-access options, which are built into panels, sections, and settings. Additionally, this makes it possible to allow non-administrators to use the customizer for, for example, customizing posts. This change is an important step toward expanding the scope of the Customizer beyond themes. See #28605.

    function allow_users_who_can_edit_posts_to_customize( $caps, $cap, $user_id ) {
            $required_cap = 'edit_posts';
            if ( 'customize' === $cap && user_can( $user_id, $required_cap ) ) {
                    $caps = array( $required_cap );
            }
            return $caps;
    }
    add_filter( 'map_meta_cap', 'allow_users_who_can_edit_posts_to_customize', 10, 3 );

    Customizer Conditional Function

    The new is_customize_preview() conditional function can be used to check whether the front-end is being displayed in the Customizer. The naming derives from the fact that the term “preview” applies to both theme previews and previewing changes before saving them. See #23509 for some sample use-cases from WordPress.com.

    Future Work

    Most of the changes in 4.0 focus on the Customizer’s PHP API and the user experience within the Customizer. In the next few releases, we’ll probably shift focus to building out the Customizer JS API (#28709) and work on the user experience of accessing and navigating through the customizer (potentially with something like #28602 and related), as well as improving the experience on mobile (#28784). The Customizer can be very slow currently but we’re exploring ways to improve performance; for example, controls could be dynamically loaded on an as-needed basis once a more complete JS API is in place (#28580). We’ll work on improving custom background images and potentially add menus and/or theme-switching to the Customizer eventually. We’ll also want to address what to do with screens that the Customizer effectively replaces (headers and backgrounds, maybe eventually widgets, menus, and themes).  Check out the future release Customize component tickets for more ideas.

    Thanks again to everyone who’s helped out with the Customizer in 4.0. If any of the outstanding items here pique your interest, feel free to jump in on trac!

     

    Update: all UI changes have been committed. Additional work to improve focus styling will happen during beta, see #28267.

    Update 2: everything here is in WordPress 4.0 beta 1, with the exception of the customize capability. The capability will most likely be implemented as a meta capability, not a primitive one, see #28605 for details.

    Update 3: customize meta capability is now in trunk, will be in 4.0 beta 2. Added usage example.

     
    • prionkor 2:10 am on July 8, 2014 Permalink | Log in to Reply

      >We’re shifting toward using “Customizer” rather than “Theme Customizer”, as it isn’t necessarily theme-specific (though most of its uses currently are).

      Correct me if I am wrong. We are still on “Theme Customizer” stage as customizer settings (on save) only affects theme options.

      Is there any plan for implementing Customizer with post meta in addition to the options? That is when we might truly customize things with the customizer.

      • Nick Halsey 2:31 am on July 8, 2014 Permalink | Log in to Reply

        The short answer is that it depends on what plugins you’re using. You’d probably be interested in the Post Customizer plugin (also linked above).

        However, note that many core (and plugin) options in the customizer are not theme-specific; for example, site title and tagline. That is, the settings are saved as options, not theme_mods, so they persist when switching themes. They’re just contextualized to being directly related to the theme in the customize context.

    • JakePT 3:50 am on July 8, 2014 Permalink | Log in to Reply

      I’ve been digging into the customizer a lot lately, and I’m really loving it. It’s a great way to open up parts of a theme so low-tech clients can make certain changes without an extra options page or awkward single-purpose widget areas. I’m happy to see most of the limitations I ran into being addressed here.

      The one thing that is apparently still missing that I really want is a proper Media control. The current one uploads files to the Media Library, but there’s no way to recover them in the customizer. If you upload 2 images, change your mind and want to go back to the first one, you have to upload it again and end up with duplicates in the media library. From a developer perspective, I’d also like it if it returned the attachment ID so I could do more with the file than just spit out the URL.

      • Weston Ruter 3:59 am on July 8, 2014 Permalink | Log in to Reply

        JakePT: Yeah, that’s being worked on. Have you seen the new Header Image control? You can select any image from the Media Library via the Media Manager. This same ability is being worked on for background images.

        • JakePT 10:12 am on July 8, 2014 Permalink | Log in to Reply

          No I haven’t. Thanks for pointing that out, I’ll take a look.

          Honestly, the reason that I hadn’t is that I generally avoid the Custom Header because I find it kind of ambiguous. Maybe it’s just the sites my company and I develop, but the images near the top couldn’t really be described as being in the ‘Header’, which makes it confusing. What is in the header is usually a logo (these are generally business sites), and the Custom Header functionality doesn’t work perfectly for that since, again, ‘Header Image’ isn’t how I would describe it, and if I want to allow uploading of a High Res logo for Retina, I can’t easily create a second Header control (last time I tried, anyway).

          But I’m glad to hear that it’s being enhanced in this way nonetheless, however I do hope that this enhancement eventually comes down to WP_Customize_Image_Control.

      • Nick Halsey 4:09 am on July 8, 2014 Permalink | Log in to Reply

        The media thing really bugs me too. In fact, I almost worked up a patch to try to get into 4.0 this past weekend, but I didn’t have enough time to get very far with it.

        What should (and probably eventually will) happen is that WP_Customize_Upload_Control should invoke the media library, and then the image and background controls would build off of it with slightly more specialized functionality. It should then be easy to create a custom control that extends this behavior to do all sorts of custom things with JS (like using other attachment metadata). Patches welcome on #21483.

    • Aristeides Stathopoulos 8:25 am on July 8, 2014 Permalink | Log in to Reply

      This is really exciting!
      It was about time this happened…

      The thing that bugs me the most in the Customizer is the fact that it’s almost impossible to save an array as an option… It’s easy to create new controls, but it’s almost impossible to create a control like for example a multi-select control and save it as an array. Instead we have to do some voodoo to convert the array as csv and save it that way.
      Any plans to change that soon?

    • Graham Armfield 10:21 am on July 8, 2014 Permalink | Log in to Reply

      When you’re building your changes to the Customizer as proposed here, please ensure that everything is keyboard accessible and is also providing enough information for screen reader users – not everyone will be using a mouse.

      The Customizer is currently pretty good from an accessibility perspective, and we wouldn’t want to see the Customize take a backward step with these changes.

      Keyboard only testing you’ll be able to do yourself, but feel free to post on the Make WordPress Accessible blog if you need help and guidance with anything else.

      • Nick Halsey 2:30 pm on July 8, 2014 Permalink | Log in to Reply

        Maintaining and improving accessibility is definitely a goal here. All of the new proposed icons (exiting panels, customizer close, etc.) have strong focus styling and use .screen-reader-text. I believe the focus indicators are sufficient even though the change is only color because the colors are inverted, with the darker color moving to the background and the lighter color for the icon. There is also an outstanding patch on #27406 that ensures that only visible elements are focus-able.

        It would be great if the Accessibility team could do an audit of the Customizer’s accessibility, particularly for screen readers, once these changes are committed. We could also maybe fix #27591 in 4.0 if it gets a patch soon.

        • Graham Armfield 1:56 pm on July 10, 2014 Permalink | Log in to Reply

          Nick, I’d like to have a look at the changes with a screen reader. Which ticket patches do I need to install to get the complete picture of the changes?

          • Nick Halsey 4:28 pm on July 10, 2014 Permalink | Log in to Reply

            Excellent!

            All of the user-facing changes are in WordPress 4.0 beta 1, so you should be able to test with that and won’t need any patches at the moment. The remaining known issue with accessibility is insufficient focus styling for Customizer sections and panel headings, which will be addressed in #28267. We’re definitely ready for an in-dept audit, keeping that in mind.

    • simplethemes 3:35 am on July 11, 2014 Permalink | Log in to Reply

      Very nice!

      Has anyone else noticed width issues with panels in Chrome (Testing in Version 35.0.1916.153)?

      http://d.pr/i/j93I

      No problems in latest Firefox.

    • nikeo 1:53 pm on July 15, 2014 Permalink | Log in to Reply

      Panels => just what I needed
      I also love the custom type and the context handling possibilities it creates with customize_update_$type, which I was ignorant of.

      Looking forward to see the JS API enhancements!
      Thanks for this overview @celloexpressions

    • Aniruddh 12:25 am on August 26, 2014 Permalink | Log in to Reply

      I don’t know if I’m missing something here but do we have contextual sections, too?

      • Nick Halsey 12:56 am on August 31, 2014 Permalink | Log in to Reply

        Not yet. There is currently no JS API for sections or panels, so there’s no good way to implement contextual sections. But this feature will be available in the future, once that’s in place. See #28709.

        You might look at what Widgets do in core to make sections contextual by doing special handling with a contextual control within the section.

    • Scott Smith 12:33 am on August 31, 2014 Permalink | Log in to Reply

      So is it possible to use the new ability to specify ‘type’ => ‘url’ in a way that’s compatible with WordPress 3.9 and lower?

      • Nick Halsey 1:07 am on August 31, 2014 Permalink | Log in to Reply

        Unfortunately, no. But you can check for the existence of `$wp_customize->add_panel()` for a 4.0 check and then act accordingly (just use text instead of url as the type). And it won’t cause any critical issues, the control just wouldn’t be displayed.

        It is forward compatible – if core implements something special for a specific html5 input type in the future, it will work with the current fallback input type handling back to 4.0.

    • kmavrov 11:43 am on September 5, 2014 Permalink | Log in to Reply

      Hi there, is it possible to have an indicator next to the range slider, which shows the current value, like when you set min = 1, max = 5, step = 0.25, and to be able to see that the current value of the range slider is 3.75 ?

      • Nick Halsey 7:14 pm on September 5, 2014 Permalink | Log in to Reply

        If you really want to do that, you could add some javascript that does that. But if you want the value to be displayed, you should really be using a `number` input (still with min, max, and step – which most browsers now support). The specs for the range input type specifically state that range should be used for inputs where the exact value is unimportant, and accordingly it wouldn’t make sense to display it. See also #28849. Core is unlikely to adopt this for the reasons above and because `range` doesn’t have to represent something numeric from a user’s perspective.

    • AxisThemes 5:04 pm on September 5, 2014 Permalink | Log in to Reply

      Hi Nick, how could we make theme customizer panel support in 3.9 or 3.8 are there any core plugins. Please adapt changes for customizer how the MP6 was done and later release. If the customizer core WP plugin was started for adapting changes let me know.

      • Nick Halsey 8:46 pm on September 5, 2014 Permalink | Log in to Reply

        Because the panel API is deeply integrated with core, it was developed directly in core instead of in a plugin. In fact, it was developed as part of my GSoC project to integrate Menus into the Customizer in a plugin, which required this functionality.

        New features that can act as standalone plugins are developed as plugins (for example, the Widget Customizer and the Menu Customizer). Iterative enhancements to the central APIs in the Customizer are better developed directly in core. And any smaller feature or API change is best developed in core, only sweeping changes should happen via plugins first.

        There’s pretty much no reason to be worried about supporting 3.8 and 3.9, because there’s pretty much no reason NOT to update to 4.0, since WordPress is backwards-compatible. If you need to use things that have been added in 4.0, simply require your users to update.

    • AxisThemes 10:40 pm on September 6, 2014 Permalink | Log in to Reply

      Hello Nick, Could you please help me with this type of setting. I have gone through almost everything in this post but truly I could solve. So some bit of example for this will be great solution.

      http://d.pr/i/xOBH

      Tip: Until the users select the “Custom” from the ‘Header Size’ select option that range control should be hidden.

      • Nick Halsey 6:16 pm on September 9, 2014 Permalink | Log in to Reply

        You can actually accomplish controls that are conditionally displayed based on the values of other controls with the new active_callback argument for controls. Pass in a custom callback function that checks the value of the other setting (with get_option or get_theme_mod) and return true or false whether to show the conditional control. See an example.

    • steven_gardner 8:10 pm on September 17, 2014 Permalink | Log in to Reply

      Hi, Thanks for the post its helped me a lot.

      One question though, You mentioned “check for the existence of WP_Customize_Manager->add_panel()”, How would I write that in PHP?

      Just learning PHP as I’m going and everything I’ve tried has failed.

      Thanks
      Steven

      • steven_gardner 8:28 pm on September 17, 2014 Permalink | Log in to Reply

        I managed to work this out, I think:

        if(method_exists('WP_Customize_Manager', 'add_panel')):
        $wp_customize->add_panel('themename_homepage_panel', array(
        'title' => __('Homepage Settings', 'themename'),
        'priority' => 12,
        ));
        endif;

        If this is wrong please let me know. Thanks

    • jakilevy 7:07 pm on October 27, 2014 Permalink | Log in to Reply

      Hi All – not sure if this is the best place to post – we just put together a plugin that allows users to import/export the settings in the WordPress Customizer – https://github.com/ArrowRootMedia/Theme-Customizations-Cloner – would be happy to work on a better integration and maintain this kind of functionality ongoingly…

  • Nick Halsey 2:44 am on June 28, 2014 Permalink
    Tags: ,   

    GSoC Menu Customizer Update 

    Since this is my first post here, a quick introduction. I’m a student at the University of Southern California studying Civil Engineering, Architecture, and Music Composition. I’ve been contributing to WordPress Core for just over a year and this summer I’m pleased to be working on WordPress full-time for my Google Summer of Code project.

    Overview

    The goal of the Menu Customizer project is to add Custom Menu management to the Customizer. Ideally, the project should be able to replace the existing Menus screen, with full feature parity, but that’s obviously a bigger discussion that would take place later. For more details, check out my initial proposal.

    Current Status

    I started six weeks ago and have built out most of the plugin’s UI and structure. However, I still need to build the menu-item previewing and saving components of the project. The UI closely resembles the Widgets-in-customizer UI, with sections for each menu and controls for each item. New menu items are added via a slide-out panel, where they’re currently grouped by post type/taxonomy, custom links, and a global search feature. The existing “Navigation” Customizer section has been re-branded to “Theme Locations,” and emphasizes the ability to add menus to widgets. Development is being done on the plugin repo, and you can download and play with it from there, but note that adding items creates orphaned draft menu items that are never published currently. Here’s a demo of the current plugin:

    (If the embedded video doesn’t play for you, try this link: https://cloudup.com/cVJbk3u32QV)

    The add-menu-item UI and implementation will be getting a lot of attention throughout the rest of my project. Items are added immediately, rather than the existing two-step checkboxes and adding several at once process, and menu items can now be deleted without having to open their settings, making deletion and addition more streamlined.

    When editing menu items, changing the navigation label of an item instantly updates its drag-and-drop handle, and updating a menu name updates the corresponding Customizer section. Items can be reordered or moved into sub-menus via either drag-and-drop or a reordering mode similar to that of the Widget Customizer.

    To minimalize the UI, given the limited space in the customizer, the “Title Attribute” field has been turned off by default, and all of the existing menu-item-field screen options are available, syncing with the existing Menus screen. I might look into building a core API for customizer screen options now that #27406 is in trunk, time permitting.

    A good amount of my time in the past couple weeks has been dedicated to #27406, which is a prerequisite for the Menu Customizer to be realistic given the need to allow users to create new menus (and in turn, new Customizer sections). Committed to trunk yesterday, it introduces a “Panels” API to the Customizer. Panels are a way to group sections, adding a new layer of hierarchy to the Customizer. In the Widget Customizer, all widget areas are added to the Widgets panel, allowing widgets to take over the entire Customizer as needed. The Menu Customizer plugin does the same thing with Menus, and requires trunk accordingly.

    Upcoming Work

    My next steps are to implement menu-adding and deleting, to implement reorderability/sortability, and then to spend quite a bit of time developing a saving/previewing system that scales well (see #14134  and related). This will most likely involve creating clones of changed menu items (posts) and menus (taxonomy terms). Once all of that’s finished, the plugin should be feature-complete, and ready for iteration.

    Core Patches

    I’ve also taken the opportunity to spend a fair amount of time working on core patches related to either Menus or the Customizer, as this project is widely expanding my knowledge of both areas. A couple of examples that have made it into core include #27406 – Customizer Panels, and #23076 – which adds live menu-item label-updating to the existing Menu screen. I’m planning on continuing to work on Menus and the Customizer via tickets/patches throughout my project as time allows.

     
    • helgatheviking 3:00 am on June 28, 2014 Permalink | Log in to Reply

      The video is pretty sweet!, great work! I’m definitely interested in seeing #14134 get fixed because it has been holding up the addition of an [18584: action hook for custom menu item meta](https://core.trac.wordpress.org/ticket/18584), which is causing all menu modifying plugins (and themes) to not be compatible with each other.

      • Nick Halsey 3:21 am on June 28, 2014 Permalink | Log in to Reply

        Thanks! I’m hoping to both fix the scaling issues and add some hooks in the new interface. The addition of a hook would really open up the possibilities for what menus can do, as your plugin and others already demonstrate.

        That being said I’m thinking that an API for custom menu fields might be even better than a hook, as that would make it easier to work with and match other core patterns for this type of structure. We’re essentially looking at custom post fields here given the way menus work. I’ll definitely look into this more once I get to the initial feature-completion stage. The ongoing Metadata UI API project might be able to be integrated here in some form, too.

    • nikeo 8:28 am on June 28, 2014 Permalink | Log in to Reply

      Great work! The plugin’s code is really clean and well commented.
      Thanks for sharing

    • Rami Yushuvaev 5:05 pm on June 28, 2014 Permalink | Log in to Reply

      Have you tested this in RTL mode?

      • Nick Halsey 5:54 pm on June 29, 2014 Permalink | Log in to Reply

        Not yet, that’ll come once we’re ready to test on different devices & environments after the basic functionality is complete. That being said, I’m guessing that the core build process will handle most of it automatically.

    • Graham Armfield 10:24 am on July 8, 2014 Permalink | Log in to Reply

      I think some accessibility testing needs to be done on this to ensure that anyone not using a mouse, and screen reader users are catered for here.

c
compose new post
j
next post/next comment
k
previous post/previous comment
r
reply
e
edit
o
show/hide comments
t
go to top
l
go to login
h
show/hide help
shift + esc
cancel
Skip to toolbar