Case:
I got a set of classes that build form fields based on data from an input array. The class can build the following types of form fields:
- input (basic, hidden, password)
- textarea
- radio
- checkbox
- select
- colorpicker
- datepicker
- file upload
EDIT: The class uses wp_register_script/_style
& wp_enqueue_script/_style
to load the scripts & styles. The functions containing the actions are hooked inside the class like this: add_action( 'admin_enqueue_scripts', array( &$this, 'enqueue' ) );
.
Example:
(Inside functions.php
)
// meta box callback function
function test_meta_box_cb()
{
$input_args = array(
'type' => 'color'
,'id' => 'color-id'
,'label' => 'Input Colorpicker Label'
,'opt_name' => 'abc_xyz'
,'value' => '009ee0'
);
new FormClass( $input_args, true );
}
// add the meta box
function add_test_meta_box()
{
add_meta_box( 'test_box', __('TestBox'), 'test_meta_box_cb', 'post', 'advanced', 'high' );
}
add_action( 'add_meta_boxes', 'add_test_meta_box' );
Problem:
This way, my call for wp_enqueue_script
& wp_enqueue_style
doesn’t work. I get the form fields rendered, but no scripts or styles.
Situation & Backtracing of the problem:
So far I could track down the problem to the wordpress core architecture:
- WP doesn’t question what happens inside the callback function until
do_action('add_meta_boxes', $post_type, $post)
get’s called (inside edit-form-advanced.php). - That call happens long after admin-header.php was called (which contains
do_action('admin_enqueue_scripts', $hook_suffix);
). - Therefore the script & style can’t get loaded (if I’m not wrong).
Question:
- How could i load styles before the meta box form fields get called?
- How could i avoid repeating the same stylesheet over and over again – i want to use
wp_enqueue_style
&wp_register_style
?
I’m open to any answers including those who force me to rewrite my class architecture.
Note: I need to use this class in a lot of different szenarios, so bundling it to close together with the add_meta_box
function is not good. I’m close to making an abstraction layer that divides the call for the meta box and the style/script part, but why would I want to add another layer above a core function?
3 Answers
Your problem is adding the scripts, styles inside the class, and because the class instance is created when the hook add_meta_box
is fired, at that time the wp_enqueue_script/style
are already finished.
A solution for you is adding the scripts, styles outside the function and the class. And because meta boxes are used only at editing pages, you can do as the following:
// the editing pages are actually post.php and post-new.php
add_action('admin_print_styles-post.php', 'custom_js_css');
add_action('admin_print_styles-post-new.php', 'custom_js_css');
function custom_js_css() {
wp_enqueue_style('your-meta-box', $base_url . '/meta-box.css');
wp_enqueue_script('your-meta-box', $base_url . '/meta-box.js', array('jquery'), null, true);
}
Actually, I wrote a meta box class for WP, that uses another approach. Instead of writing form class for form fields like you did, my class is a wrapper for meta boxes. If you interested in, it’s worth to take a look.