Hello. I am trying to write some Customizer JS that will change a background image URL via the "transport = postMessage" method.
The name of my setting is "color_scheme" which is changed via a dropdown control. A unique header image is associated with each of my five different color schemes.
My frontend function (which works fine) looks like this:
function mytheme_custom_css_output() {
$template = get_template_directory_uri();
$industry = get_option( 'industry', 'tourism' );
$filename = get_theme_mod( 'color_scheme', 'default' );
echo '<style type="text/css" id="custom-theme-css">';
echo '.site-header { background-image: url("' . $template . '/skins/' . $industry . '/header-' . $filename . '.jpg") }';
echo '</style>';
}
add_action( 'wp_head', 'mytheme_custom_css_output');
The path to my background image is generated via three variables, $template, $industry & $filename as demonstrated above.
$filename contains the theme_mod value I am trying to update live via JS.
My current live preview JS (that does not work) is:
wp.customize( 'color_scheme', function( value ) {
value.bind( function( to ) {
$( '#custom-theme-css' ).html( to );
} );
} );
Please can someone suggest some new JS to replace my current code.
Thank you.
Reigel Gallarde answers:
If your doing for a background, then the code should have been like this?
wp.customize( 'color_scheme', function( value ) {
value.bind( function( to ) {
$( '#custom-theme-css' ).css( 'background', to );
} );
} );
Reigel Gallarde comments:
also... try adding console.log(to); before $( '#custom-theme-css' ).css( 'background', to ); and look at your console (ctrl+shift+j on chrome) to see what value you're getting...
Reigel Gallarde comments:
be sure also that there are no javascript error for wp.customize to work... your console will display the error if it does have one...
designbuildtest comments:
Didn't work sorry Reigel. See additional notes in response to your two further comments below ...
designbuildtest comments:
The value I am getting is seemingly correct ... "tourism_red", "tourism_blue" etc
designbuildtest comments:
No JS errors reported via console.log(to)
Reigel Gallarde comments:
so wp.customize is working fine...
the problem is, that output value is not what you need.... you need a hex like #00f for blue... #fff for white.. etc...
designbuildtest comments:
Hi Riegel, I am trying to change a background image URL, not a background color hex value.
Reigel Gallarde comments:
sorry, I was lost with `color_scheme`..
hmm....
so what you need is `$( '#custom-theme-css' ).css( 'background-image', 'url(' + to + ')');`
but now the problem is you only have `"tourism_red", "tourism_blue"` as values... we need an image link...
can you let me show your full code? paste it on pastebin.com perhaps...
Reigel Gallarde comments:
I mean can you let me see your full code?
designbuildtest comments:
Hi Reigel, I've adapted your code and got the following to work...
$( '.site-header' ).css( 'background-image', 'url(http://localhost/mysubsite/wp-content/themes/mytheme/skins/tourism/header-' + to + '.jpg)' );
My issue now is how to introduce variables for the template directory (http://localhost/mysubsite/wp-content/themes/mytheme) and industry (tourism). I can't hard code the URL as I'm working on a multisite install and the industry selection (in this case tourism) determines which folder to grab the image from.
Take another look at my original post and you'll see how I'm currently constructing my wp_head() action function.
Thanks
Reigel Gallarde comments:
can you post your control please...
designbuildtest comments:
Here you go...
$wp_customize->add_control( 'color_scheme', array(
'label' => __( 'Select a Color' ),
'section' => 'color_scheme',
'type' => 'select',
'choices' => array(
'tourism_red' => 'Red',
'tourism_green' => 'Green',
'tourism_blue' => 'Blue',
'tourism_black' => 'Black',
'tourism_brown' => 'Brown',
),
) );
Reigel Gallarde comments:
try this...
$wp_customize->add_setting(
'rei_background_image',
array(
'default' => 'tourism_red',
'sanitize_callback' => 'rei_sanitize_background_image',
'transport' => 'postMessage'
)
);
if you have something like that, put 'sanitize_callback' => 'rei_sanitize_background_image'
then somewhere in your code define the callback...
function rei_sanitize_background_image($filename) {
$template = get_template_directory_uri();
$industry = get_option( 'industry', 'tourism' );
return 'url("' . $template . '/skins/' . $industry . '/header-' . $filename . '.jpg")';
}
then javascript as follows
$( '#custom-theme-css' ).css( 'background-image', 'url(' + to + ')');
Reigel Gallarde comments:
I mean javascript as follows...
$( '#custom-theme-css' ).css( 'background-image', to );
Reigel Gallarde comments:
ahhh then this, take note of `color_scheme`
<blockquote>$wp_customize->add_setting(
'color_scheme',
array(
'default' => 'tourism_red',
'sanitize_callback' => 'rei_sanitize_background_image',
'transport' => 'postMessage'
)
);
</blockquote>
function should be define somewhere...
function rei_sanitize_background_image($filename) {
$template = get_template_directory_uri();
$industry = get_option( 'industry', 'tourism' );
return 'url("' . $template . '/skins/' . $industry . '/header-' . $filename . '.jpg")';
}
then javascript,
$( '#custom-theme-css' ).css( 'background-image', to );
Reigel Gallarde comments:
this also will have to change
function mytheme_custom_css_output() {
$url= get_theme_mod( 'color_scheme', 'default' );
echo '<style type="text/css" id="custom-theme-css">';
echo '.site-header { background-image: ' . $url . ' }';
echo '</style>';
}
add_action( 'wp_head', 'mytheme_custom_css_output');
designbuildtest comments:
Hi Reigel, technically I suspect your suggestions above will work, but I do not want to save a full url as my settings value. I'm also adding the color_scheme value (e.g. tourism_red) as a body class value via a body_class filter.
Reigel Gallarde comments:
hmm... you can still get the value as something like tourism_red..
like in php,
$url= get_theme_mod( 'color_scheme', 'default' );
$color_scheme = basename($url, ".jpg");
Reigel Gallarde comments:
add_filter('body_class', 'body_classes');
function body_classes($classes) {
$url= get_theme_mod( 'color_scheme', 'default' );
$color_scheme = basename($url, ".jpg");
$classes[] = $color_scheme;
return $classes;
}
designbuildtest comments:
Sorry Reigel, I'm not sure I follow you.
The "color_scheme" setting value I would like saved in the database is something like "tourism_red".
I do not want to save a full url such as "http://localhost/mysubsite/wp-content/themes/mytheme/skins/tourism/header-tourism_red.jpg" as the value of my color_scheme variable.
Reigel Gallarde comments:
ahh... I was demonstrating how to get "tourism_red" if we are saving a full url...
that way, while saving "http://localhost/mysubsite/wp-content/themes/mytheme/skins/tourism/header-tourism_red.jpg", you can still have a way to get "tourism_red"...
if we can't save full url, it will be hard to get it on the javascript part...
designbuildtest comments:
Okay, thanks for your efforts Reigel.
I'd really like to avoid saving a URL as my color_scheme value if possible. Perhaps someone else will be able to suggest another approach?
Could a JS value be used to live edit my body_class filter for instance?
function mytheme_body_class( $classes ) {
$industry = get_option( 'industry', 'tourism' );
$get_color_scheme = get_theme_mod( 'color_scheme', 'default' );
$color_scheme = $industry . '-' . $get_color_scheme;
$classes[] = esc_attr( $color_scheme );
return $classes;
}
add_filter( 'body_class', 'mytheme_body_class' );
Then I could just reference all the possible site-header images in my main stylesheet I guess ...
.tourism_red .site-header {
background-image: url('skins/tourism/header-tourism_red.jpg' );
}
.tourism_blue .site-header {
background-image: url('skins/tourism/header-tourism_blue.jpg' );
}
etc
Reigel Gallarde comments:
okay.. we're out on that saving full url... after searching google, cause I was curious too... I've found out that we can add a setting that doesn't do anything but hold a value...
sample code...
$wp_customize->add_setting(
'template_scheme',
array(
'default' => get_template_directory_uri(),
'transport' => 'postMessage'
)
);
$wp_customize->add_setting(
'industry_scheme',
array(
'default' => get_option( 'industry', 'tourism' ),
'transport' => 'postMessage'
)
);
then on your js we could do
wp.customize( 'color_scheme', function( value ) {
value.bind( function( to ) {
var template_scheme = wp.customize( 'template_scheme' )();
var industry_scheme = wp.customize( 'industry_scheme' )();
var url = template_scheme + '/skins/' + industry_scheme + '/header-' + to + '.jpg';
$( '#custom-theme-css' ).css( 'background', 'url(' +url+')' );
} );
} );
does this make sense?
designbuildtest comments:
Wonderful!!! That worked perfectly ... many thanks for your perseverance Reigel :-)
Even though there is no actual Customizer Control to update the 'template_scheme' and 'industry_scheme' Settings, do I still need to include 'sanitize_callback' functions for both values?
Many thanks again.
Reigel Gallarde comments:
no need for control cause we don't need a user to interact with these values... no need to sanitize, cause anyway it's already in the database, so that should be clean already.
glad I could help.
designbuildtest comments:
Thinking more about my sanitization question above ... I'm guessing no sanitization is actually required as the 'template_scheme' and 'industry_scheme' values are never saved to the database.
If my thinking is wrong, please can someone correct me.
Thanks again Reigel.
Reigel Gallarde comments:
[[LINK href="http://codex.wordpress.org/Function_Reference/get_template_directory_uri"]]get_template_directory_uri[[/LINK]] is a function that will retrieve template directory URI for the current theme.
You don't need to worry about that.. unless you really really need to...
[[LINK href="http://codex.wordpress.org/Function_Reference/get_option"]]get_option[[/LINK]] - A safe way of getting values for a named option from the options database table.
so, that's that....
designbuildtest comments:
Thanks Reigel. Closing the question and voting you the prize now ... Cheers