Cache busting CSS files other than style.css

All right, so we’re probably all familiar with the typical way to ensure that your main CSS file is refreshed when you load the page (busting the browser cache), right?

<link rel="stylesheet" type="text/css" media="all"
  href="<?php echo get_stylesheet_uri();
    echo '?'.filemtime( get_stylesheet_directory() . '/style.css'); ?>" />

I need to do the same thing on another CSS file. Yes, my style.css file has its own set of @import “css/myFile.css” which are working fine, but humor me, if you will.
So, back to header.php, right after that first link, and before the call to wp_head():

Read More
<?php $cssFile = get_stylesheet_directory_uri().'/css/other.css'; ?>
<link rel="stylesheet" type="text/css" media="all"
  href="<?php echo $cssFile; echo '?'.filemtime($cssFile); ?>" />

And this leads to a warning (as part of the href attribute of the link when the browser gets the page):

Warning: filemtime(): stat failed for http://localhost/wordpress/wp-content/themes/my_theme/css/other.css

the path to the file seems to be built correctly (and the other.css file is there), but filemtime (stat, actually) fails on it. How come?

Other recommended ways to include the ‘latest’ version of a CSS file other than style.css?
Should I go with wp_register_style instead? If so… how can I tell wp_register_style to bust the browser cache (ie: get me the latest version of the css file, even if the browser has it cached)?
Thanks in advance

Related posts

Leave a Reply

6 comments

  1. I tend to just enqueue the main stylesheet using wp_enqueue_style, and append something to the version when i want to prevent caching..

    $ver = '';
    wp_enqueue_style( 'theme_style', get_bloginfo('stylesheet_url'), false, $ver );
    

    When i want to stop caching i update $ver to something that will constantly change, such as the time..

    $ver = time();
    

    Or something similar..

  2. Here is the code I have from an unreleased CDN plugin I have. It will automatically replace the ver query_var that the enqueue functions use with the file time:

    class CDN_VersionAssets {
    
        private $default_version = '';
        private $root_url;
    
        public function __construct() {
            $this->root_url = site_url();
        }
    
        public function initialize() {
            add_filter('style_loader_src', array($this, 'replace_version'), 10);
            add_filter('script_loader_src', array($this, 'replace_version'), 10);
            add_filter('stylesheet_uri', array($this, 'replace_version'), 10);
        }
    
        public function on_template_redirect() {
            $this->default_version = @filemtime(get_stylesheet_directory().'/style.css');
        }
    
        private function get_version($url) {
            if(0 === strpos($url, $this->root_url)) {
                $parts = parse_url($url);
                $file_path = str_replace(site_url('/'), ABSPATH, $parts['scheme'].'://'.$parts['host'].$parts['path']);
                if( !($version = @filemtime($file_path)) ) {
                    $version = $this->default_version;
                }
                return $version;
            }
            return false;
        }
    
        public function replace_version($src) {
            if( $new_version = $this->get_version($src) ) {
                return add_query_arg('ver', $new_version, $src);
            }
            return $src;
        }
    }
    add_action('init', array(new CDN_VersionAssets(), 'initialize'));
    
  3. If you’d prefer not to use the standard style.css file for your WordPress theme’s CSS cache-busting technique, here’s a complete working code example:

    <?php
        // Prevent CSS Caching
        $css_link = get_stylesheet_directory_uri() . '/css/screen.css';
        $css_file = get_stylesheet_directory() . '/css/screen.css';
    ?>
    
    <link href="<?php echo $css_link . '?' . filemtime( $css_file ); ?>" />
    

    Would result in the following HTML output:

    <link href="http://example.com/wp-content/themes/theme-name/css/screen.css?1349389530" />
    

    For terseness of this example, I excluded rel="stylesheet" type="text/css" on the <link> element, so be sure to add those attributes to your final markup.

  4. I wrote my own little function as a plugin for jobs like this. It take two paramters, the path that will need to be appended and a date format. Here is a sample usage…

    <?php echo cache_busting_path('/css/reset.css', 'Y-m-d_g:i:s'); ?>
    

    which would result in http://pewsocialtrends.org/wp-content/themes/pew-socialtrends/css/reset.css?2010-11-11_6:47:45

    Here is the code:

        <?php
    /*
            Plugin Name: Cache Busting Path
            Description: Function that returns a path with a cache-busting query string based on the last time the file was updated.
            Version: 1.0
            Author: Russell Heimlich
            Author URI: http://www.russellheimlich.com/blog/
            License: GPL2
        */
    
            function cache_busting_path($path, $time_format = 'U') {
                if( $path[0] != '/' ) { //Checks for the first character in $path is a slash and adds it if it isn't. 
                    $path = '/' . $path;
                }
                return get_bloginfo('template_url') . $path . '?' . date($time_format, filemtime( get_theme_root() . '/' . get_template() . $path ) );
            }
    ?>
    
  5. Simple: use the URl to load the style and the path to get the filemtime():

    wp_register_style(
        'handle',
        get_stylesheet/template_directory_uri().'/path/to/your/stylesheet.css',
        array( 'possible_dependency' ),
        filemtime( plugin_dir_path( __FILE__ ).'path/to/your/stylesheet.css' )
    );
    

    The resulting URl will be something like

    <link href="http://example.com/wp-content/themes/path/to/your/stylesheet.css?1379012967924">