The solution is basically from this SO post:
When wordpress "localizes" a script, what it does is has php print out <script></script>
tags with javascript objects in them that are then accessible within the DOM to the scripts you are "sending" the parameters to.
If I understand correctly, the extension of WP_Scripts
simple adds a filter, referenced by the (arbitrary) handle, script_l10n
, then sends that filtered variable, $110n
through to the parent method, localize
, which is where WPs array of arrays to "localize" gets sent.
class Filterable_Scripts extends WP_Scripts
{
function localize( $handle, $object_name, $l10n )
{
$l10n = apply_filters( 'script_l10n', $l10n, $handle, $object_name );
return parent::localize($handle, $object_name, $l10n);
}
}
Then we replace $GLOBALS['wp_scripts']
with our new filterable one.
function my_filter_script_intlization() {
$GLOBALS['wp_scripts'] = new Filterable_Scripts;
}
add_action( 'init', 'my_filter_script_intlization');
And now we can hook into the filter to modify the l10n
string from the plugin (once we've used print_r()
or something to figure out what it is).
function se108362_example_filter($l10n, $handle, $object_name ) {
if('simple-locator' == $handle && 'wpsl_locator' == $object_name) {
$phyt_i10n_settings = array(
'mapTypeId' => 'roadmap',
'mapTypeControl' => false,
'zoom' => 8,
'panControl' => false,
'zoomControlOptions' => array('style' => '') // was google.maps.ZoomControlStyle.SMALL
);
$l10n['l10n_print_after'] = 'wpsl_locator.map_options = ' . json_encode($phyt_i10n_settings);
return $l10n;
}
return $l10n;
}
add_filter('script_l10n', 'se108362_example_filter', 10 , 3);
Then in the js I replace the l10n
variables with my hard-coded ones:
wpsl_locator.map_options.zoomControlOptions.style = google.maps.ZoomControlStyle.SMALL;
wpsl_locator.map_options.styles = wpsl_locator.mapstyles;
For some reason the Filterable_Scripts
sub-class seems to break the Advanced Custom Fields script loading:
public function my_filter_script_intlization() {
//These exist here:
var_dump($GLOBALS['wp_scripts']->registered['acf-field-group']);
var_dump($GLOBALS['wp_scripts']->registered['acf-input']);
$GLOBALS['wp_scripts'] = new \PhytJobs\FilterableScripts;
// But now they are gone
print_r(isset($GLOBALS['wp_scripts']->registered['acf-field-group']));
}
My workaround is to do this:
public function my_filter_script_intlization() {
$acf_field_group = $GLOBALS['wp_scripts']->registered['acf-field-group'];
$acf_input = $GLOBALS['wp_scripts']->registered['acf-input'];
$GLOBALS['wp_scripts'] = new \PhytJobs\FilterableScripts;
$GLOBALS['wp_scripts']->registered['acf-field-group'] = $acf_field_group;
$GLOBALS['wp_scripts']->registered['acf-input'] = $acf_input;
}
But I'm wondering why the sub-classing is breaking it in the first place.
Someone suggested that the issue is caused by hooking the my_filter_script_intlization
action too late, after $WP_Scripts
has already been partly populated. I'm still a little unclear on how that works or why ACF would be the problem.
UPDATE, ACF only loads its scripts in Admin and the other plugin only l10n
in the front end so I just wrapped the action
and filter
hook in a !is_admin
test and ACF has nothing to complain about.