Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

Enqueuing Google Web Fonts the usual way, i.e., using the wp_enqueue_style function like so...

function wpse_google_webfonts() {
    wp_enqueue_style( 'google-webfonts', 'http://fonts.googleapis.com/css?family=Ubuntu+Condensed|Open+Sans:400italic,700italic,400,700' );
}
add_action( 'wp_enqueue_scripts', 'wpse_google_webfonts' );

...results in a link tag placed in the header like so:

<link rel='stylesheet' id='google-webfonts-css'  href='http://fonts.googleapis.com/css?family=Ubuntu+Condensed%7COpen+Sans%3A400italic%2C700italic%2C400%2C700&#038;ver=3.5' type='text/css' media='all' />

As you can see, the resultant URL is encoded.

I am pretty sure it poses no problems, but to keep things clean and clear, I would like to go ahead and ask -- Is there a way to enqueue Google Web Fonts (via functions.php and not a plugin) in a way that the URL output is not encoded?

That's like so:

<link rel='stylesheet' id='google-webfonts-css'  href='http://fonts.googleapis.com/css?family=Ubuntu+Condensed|Open+Sans:400italic,700italic,400,700?ver=3.5' type='text/css' media='all' />

Reason For Bounty

@webaware's answer is near perfect, especially because it's similar to the method employed in enqueuing 'Open Sans' Google Web Font in the Twenty Twelve theme.

The only problem in the output is that it's like this:

<link rel='stylesheet' id='twentytwelve-fonts-css'  href='http://fonts.googleapis.com/css?family=Ubuntu+Condensed|Open+Sans:400italic,700italic,400,700&#038;subset=latin,latin-ext' type='text/css' media='all' />

Notice the &#038;? It should be &, otherwise the font-files served only have the latin glyphs (i.e. the subset parameter in the URL is neglected unless you use & and NOT its HTML entity).

Anyone who can help modify @webaware's answer so that the output's looks like this...

<link rel='stylesheet' id='twentytwelve-fonts-css'  href='http://fonts.googleapis.com/css?family=Ubuntu+Condensed|Open+Sans:400italic,700italic,400,700&subset=latin,latin-ext' type='text/css' media='all' />

...wins the bounty.

share|improve this question
    
Not quite sure what you're wanting here; do you want to have latin + latin-ext subsets (which this does), or do you want it not to subset (which can be achieved by removing the 'subset' element from the array)? –  webaware Dec 30 '12 at 7:22
    
@webaware Ah, okay. Thanks! –  its_me Dec 30 '12 at 7:53
add comment

4 Answers

up vote 21 down vote accepted
+50

WordPress knows what it is doing here. Honest.

When rendering an ampersand in HTML, you should always use &amp; or &#038;. The browser then converts it to & before actually firing the HTTP request. See for yourself by inspecting the network calls in a web inspector tool. You're not actually losing your non-latin subsets.

Notice the &#038;? It should be &, otherwise the font-files served only have the latin glyphs (i.e. the subset parameter in the URL is neglected unless you use & and NOT its HTML entity).

This tells me you have inspected the source to see that there is an escaped ampersand, without actually verifying the resulting behavior. Yes, it occurs when you paste a URL with an escaped ampersand in an address bar. But not when you have a properly encoded and escaped URL in an HTML src or href attribute.

You should look over http://www.blooberry.com/indexdot/html/topics/urlencoding.htm for additional unsafe and reserved characters. Both groups should always be encoded.

share|improve this answer
1  
A very fine explanation, thanks for taking the time Andrew! –  webaware Dec 30 '12 at 7:23
    
So, you are saying... when you have a properly encoded URL in an HTML src or href attribute (i.e. http://fonts.googleapis.com/css?family=Ubuntu+Condensed&#038;subset=latin,latin‌​-ext), the way the browser treats it is equivalent to the user entering http://fonts.googleapis.com/css?family=Ubuntu+Condensed&subset=latin,latin-ext (i.e. with the actual & and not the HTML entity) in the address bar. Is that correct? If so, thanks for the clear explanation. :) –  its_me Dec 30 '12 at 7:58
2  
Correct. I edited my answer slightly to make it a bit more clear. In this case, the ampersand is an escaped HTML entity, not URL encoded. It should not be encoded (which would be %38) because it is being used in its special URL role. URL encoding a reserved or unsafe character like |, :, or spaces are separate, and also encouraged. –  Andrew Nacin Dec 30 '12 at 8:16
    
@AndrewNacin: just a nitput, but: that URL to blooberry.com is actually about URL-encoding characters, not HTML-encoding characters. The issue you are addressing is the latter, not the former. –  webaware Dec 30 '12 at 8:47
    
I spoke about both in my answer, and comment. You were worried about both in your original question. –  Andrew Nacin Dec 30 '12 at 21:47
add comment

Based on this answer you could try something like this untested code:

add_filter( 'clean_url', 'wpse_77227_decode_googlefont_url' );

function wpse_77227_decode_googlefont_url( $url )
{
    $host = parse_url ($url, PHP_URL_HOST );

    if ( 'fonts.googleapis.com' === $host )
        return urldecode( $url );

    return $url;
}
share|improve this answer
    
Yes, it kinda works, except the way versioning is done (wrongly?). Output looks like: <link rel='stylesheet' id='google-webfonts-css' href='http://fonts.googleapis.com/css?family=Ubuntu Condensed|Open Sans:400italic,700italic,400,700&#038;ver=3.5' type='text/css' media='all' /> -- notice &#038;ver=3.5? It should rather be ?ver=3.5. Any fix in mind? Thanks for the answer. :) –  its_me Dec 25 '12 at 16:53
    
You cannot use a second ?. That would result in an invalid URL for Google. –  toscho Dec 25 '12 at 16:57
    
http://fonts.googleapis.com/css?family=Ubuntu%20Condensed|Open%20Sans:400italic‌​,700italic,400,700?ver=3.5 is loading up just fine. Or am I missing your point? –  its_me Dec 25 '12 at 17:00
    
The argument separator is &, not ?. You cannot rely on Google’s generosity. –  toscho Dec 25 '12 at 21:25
    
This function has been deprecated "clean_url" -> codex.wordpress.org/Function_Reference/clean_url, you should use other one. –  Ed T. Dec 25 '12 at 23:14
show 3 more comments

Try this (will also handle HTTP vs HTTPS):

function wpse_google_webfonts() {
    $protocol = is_ssl() ? 'https' : 'http';
    $query_args = array(
        'family' => 'Ubuntu+Condensed|Open+Sans:400italic,700italic,400,700',
        'subset' => 'latin,latin-ext',
    );

    wp_enqueue_style('google-webfonts',
        add_query_arg($query_args, "$protocol://fonts.googleapis.com/css" ),
        array(), null);
}

add_action( 'wp_enqueue_scripts', 'wpse_google_webfonts' );
share|improve this answer
    
By chance, is this based on Twenty Twelve theme? :P –  its_me Dec 26 '12 at 14:30
    
Very likely where I saw it :) but It's all just part of the kit now. –  webaware Dec 26 '12 at 14:31
1  
Actually, they are the same. The browser sees &#038; as & and loads exactly the same URI. To test, I loaded simple HTML pages with both, and cleared cache before loading; both loaded the same font files (same size). Try it. –  webaware Dec 30 '12 at 7:19
add comment

Actually, it's as simple as this:

wp_enqueue_style( 'google-webfonts', 'http://fonts.googleapis.com/css?family=Ubuntu+Condensed|Open+Sans:400italic,700italic,400,700&subset=latin,latin-ext', array(), null );

And that should output:

<link rel='stylesheet' id='google-webfonts-css'  href='http://fonts.googleapis.com/css?family=Ubuntu+Condensed|Open+Sans:400italic,700italic,400,700&#038;subset=latin,latin-ext' type='text/css' media='all' />

That's pretty close to what I'd wanted (only regret being that & becomes &#038; in output). But then I realized it doesn't matter, really, largely thanks to Andrew Nacin's answer.

But I must thank everyone for their efforts.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.