I am working on a plugin for custom fields throughout the admin and I am trying to create as many locations for fields as possible. So far I am successfully doing this for quite a few of those locations:
- Post types
- Taxonomies
- Comments
- Users
- Options (pages)
- Widgets
- Menu items
- Attachments
- Shortcodes
- The customizer (sort of)
Naturally, for each of the locations I have, I am trying to use the appropriate WordPress API – *_post_meta, *_term_meta, etc. and things are working quite nicely.
For the locations, which are associated with an item that has a URL (mainly the first 4, even though attachments also have URLs), I have front-end forms, which would allow users to edit the current item and save its custom fields. I do this through a single function/template tag, which does not require any arguments – all groups of fields, which are associated with the item, are automatically displayed.
The last element I wish to have, before I consider my (proof of) concept successful, is support for the customizer. Using the default API allows me to work with options/theme mods quite easily and I got to a point, where the “customizer” location is quite functional. The only downside of my implementation seems to be that I am displaying the whole group with fields as a single control. This allows me to have tabs, conditional logic and proper validation (which depends on the conditional logic). Still, I am using different settings (as in WP_Customize_Setting
), so postMessage and everything else are pretty much working correctly without having to hack anything else.
What I want though, is to allow the same locations, which have URLs and can have front-end forms, to be easily added to the customizer too. A developer can create a post meta group, which will appear as a normal post box on the edit screen and my goal is to allow the him to call something like ->show_in_customizer() in order to let that group be used there too.
I know that many people would advise against editing posts in the customizer and for many occasions I would agree with them. However, if there is a per-post layout setting, some color options or even something as simple as the featured image, I would like to keep that door open.
To cut to the chase, this seems to be quite a hard task, because it requires at least the following:
- Determining whether to display the responsible section in the customizer. That’s easy enough through the “active_callback” property of sections.
- Feeding data into the customizer: This one is slightly tricky. Even if you click the “Customize” button while previewing a page, the customizer is loaded from within the context of the admin and I don’t have direct access to the thing, which is being displayed. What I am doing, is to gather all data which I need in the footer of the page and send it to the customizer through
parent.someFunction
when the page is loaded. This is not ideal, but works well enough – I am not retrieving/sending any value more than once so I am happy. In the perfect world, this functionality, combined with theactive_callback
, would let users edit a page, click a link to another page an immediately edit the newly loaded page. However, when this is done, the new page receives neither request parameters nor headers include so it’s pretty much acting if it was not in the customizer at all, so this is not working for me. - Overwriting the result of
get_*_meta
with the values from the customizer on normal (non-postMessage) request. This part is very straight-forward. - Saving the data: Here is where my implementation fails 🙁
When the “Save & Publish” button is clicked, the customizer performs a wp_ajax request. The request still includes the normal customized
JSON, as a refresh when a value is changed, but because the script is using admin-ajax, I cannot know what is really getting saved.
The only idea I have right now is to overwrite the wp.customize.previewer.query
JavaScript function with something in the lines of:
var query = wp.customize.previewer.query;
wp.customize.previewer.query = function( options ) {
args = query.call( wp.customize.previewer, options );
args.my_plugin_name_current_object="post_10";
return args;
}
At this point though, I need to be very careful when I’m adding the parameter though and in overall, the implementation is starting to become too dirty.
Finally, my question:
Has anyone managed to successfully achieve similar functionality in the customizer? Could you advise me on a proper approach to finish this thing up?
So far I have not tried developing anything custom for the customzer and (while not intending to offend anybody), I am surprised how over-complicated/over-engineered some parts of the customizer seem, while some quite basic aspects seem to be extremely half-baked.
I know I am not including any particular code snippets, but the question seems to be general enough, at least for me.
Thanks in advance!
1 Answer
Please see the Customize Posts plugin. It has a WP_Customize_Post_Setting
and WP_Customize_Postmeta_Setting
for representing posts and postmeta in the customizer, respectively.