Difference between bloginfo('home') and home_url() and site_url()

I have been reading through Codex and other SO and SE posts regarding this. But I am confused.

I used home_url() and site_url() to linking the site’s home and it gave same results.

As I was using qTranslate for bilingual implementation. And had its language switcher.

Found later, when clicked on the home logo (used home_url() and site_url()) the current language didn’t persist. Because, I am using one language as default and which would just produce http://example.com And for other language it would be http://example.com/ar

Later I found that, using bloginfo('home') solves it. The url now carries the language suffix with the home URL.

As these posts say the bloginfo() functions are being deprecated. I am really confused.

Solutions Collecting From Web of "Difference between bloginfo('home') and home_url() and site_url()"

The difference in your case is in filters being applied to output of these functions.

While bloginfo applies one of these filters:

if ( 'display' == $filter ) {
        if ( $url )
            $output = apply_filters('bloginfo_url', $output, $show);
        else
            $output = apply_filters('bloginfo', $output, $show);
    }

Function home_url applies this filter:

return apply_filters( 'home_url', $url, $path, $orig_scheme, $blog_id );

Adn finally site_url applies this filter:

return apply_filters( 'site_url', $url, $path, $scheme, $blog_id );

It is true that bloginfo uses one of mentioned functions (home_url and site_url). It is clear from its source code:

function get_bloginfo( $show = '', $filter = 'raw' ) {

    switch( $show ) {
        case 'home' : // DEPRECATED
        case 'siteurl' : // DEPRECATED
            _deprecated_argument( __FUNCTION__, '2.2', sprintf( __('The <code>%s</code> option is deprecated for the family of <code>bloginfo()</code> functions.' ), $show ) . ' ' . sprintf( __( 'Use the <code>%s</code> option instead.' ), 'url'  ) );
        case 'url' :
            $output = home_url();
            break;
        case 'wpurl' :
            $output = site_url();
            break;
...

From this piece of code, it is clear that when calling bloginfo(‘home_url’) or bloginfo(‘site_url’), all mentioned filters ale applied. When calling home_url or site_url, bloginfo’s filters are not applied.

The thing is, that qTranslate, probably, hooks only bloginfo’s filters.

Open your backend and go to Settings/General. You will see to input fields:

  • WordPress Address (URL)
  • Site Address (URL)

The first one correspond to site_url() and the second one to home_url()

So why is there a difference? Because WordPress is able to start from a different site then your blog posts. For example, create a page called ‘homepage’ and enter in the second input field on Settings/General your domain and the pagename (with pretty permalinks turned on): http://www.example.com/homepage. From now on your blog starts with ‘homepage’ instead of the list with your blog posts. If a user enters ‘http:/www.example.com’ in the browsers adress bar, the ‘homepage’ page will be displayed (a memory hook: home_url() shows you the homepage). In short, this feature is called ‘static frontpage’

The site url is the ‘domain’ of your WordPress install no matter what page or site should be displayed as start page/frontpage/homepage.

bloginfo() is just a wrapper for get_option(). The parameter home is deprecated since version 2.2 in favor of siteurl.

  • wpurl -> site_url()
  • siteurl -> home_url()

Because this is confusing, it is better to use the function calls site_url() and home_url()

To avoid using deprecated call bloginfo('home') added new function to qtranslate_core.php:

function qtrans_convertHomeURL($url, $what) {
    if($what=='/') return qtrans_convertURL($url);
    return $url;
}

and new filter to qtranslate_hooks.php:

add_filter('home_url', 'qtrans_convertHomeURL', 10, 2);

This way no other changes were needed. Not the best solution but worked in my env. Hope qTranslate author won’t get mad for this.

Have to always use home_url('/') this way in themes/plugins to keep localization. Can be improved by using some special parameter instead of '/' which won’t ever be used as real address.

Tested on WordPress 3.5.2 + qTranslate 2.5.35 + Responsive theme 1.9.3.2.