ioCombinerPlugin - 0.1.1

Symfony plugin that minifies and combines css and js files

You are currently browsing
the website for symfony 1

Visit the Symfony2 website


« Back to the Plugins Home

Signin


Forgot your password?
Create an account

Tools

Stats

advanced search
Information Readme Releases Changelog Contribute
This plugin is deprecated and is not maintained anymore. Please use either the npAssetsOptimizerPlugin (http://www.symfony-project.org/plugins/npAssetsOptimizerPlugin) or swCombinePlugin instead (http://www.symfony-project.org/plugins/swCombinePlugin)
Show source

ioCombinerPlugin (for symfony 1.3/1.4)

The ioCombinerPlugin is a symfony plugin that allows you to:

  • Effortlessly combine and minify all css and js files into one file each, which are cached.

  • Dynamically add to or filter your css and js inside your project

  • Quickly use the plugin as-is or completely customize it

For example:

    BEFORE
    <link rel="stylesheet" type="text/css" media="screen" href="/css/jquery.fancybox.css" />
    <link rel="stylesheet" type="text/css" media="screen" href="/css/structure.css" />
    <link rel="stylesheet" type="text/css" media="screen" href="/css/main.css" />
    <script type="text/javascript" src="/js/jquery.min.js"></script>
    <script type="text/javascript" src="/js/jquery.fancybox.js"></script>

    AFTER
    <link rel="stylesheet" type="text/css" media="screen" href="/css/combine.css" />
    <script type="text/javascript" src="/js/combine.js"></script>

To learn more about combining and minifying assets, read Yahoo's Best Practices for Speeding Up Your Web Site.

Installation

  • Install the plugin (via a package)

    symfony plugin:install ioCombinerPlugin --stability=beta
    
  • Install the plugin (via a Subversion checkout)

    svn co http//svn.symfony-project.com/plugins/ioCombinerPlugin/trunk plugins/ioCombinerPlugin
    
  • Activate the plugin in the config/ProjectConfiguration.class.php

    class ProjectConfiguration extends sfProjectConfiguration
    {
      public function setup()
      {
        $this->enablePlugins(array(
          'ioCombinerPlugin',
          '...'
        ));
      }
    }
    
  • Enable the ioCombiner module in settings.yml for your application

    all:
      settings:
        enabled_modules:  [default, ioCombiner]
    
  • Add the following to your web/.htaccess file. Don't include the first and last lines below - they're just there so you can see where the combiner code needs to be added. An example .htaccess file is available in the data directory of the plugin.

    ...
    #RewriteRule .* - [L]
    
    # start combiner code
    RewriteRule ^css\/combine[_*](.*)\.css$ $1.php/css/combine.css [L]
    RewriteRule ^js\/combine[_*](.*)\.js$ $1.php/js/combine.js [L]
    # end combiner code
    
    # we check if the .html version is here (caching)
    ...
    

Configuration

An example of all the configuration options is in the config/app.yml file in the plugin.

    all:
      io_combiner_plugin:
        enabled:      true      # enable or disable the combiner
        stylesheets:  []        # an array of the stylesheets to combine
        javascripts:  []        # an array of the javascript to combine

        # the class that adds the combine.css/js file to the response and removes
        # all of the css/js file that are essentially replaced by the combine file
        response_class: ioCombinerResponse

        # the class that actually combines a group of css/js files and returns
        # the minified, combined string
        combiner_class: ioCombiner

        # the HTTP header Expires length, in days, to set on the combined
        # css/js file. Set to false to not automatically set this header
        expires_days: 30

How to Use

  • Start by configuring your view.yml with all of the stylesheets and javascripts that you will need:

    # apps/%APPNAME%/config/view.yml
    all:
      stylesheets:  [grid_960.css, main.css, print.css: { media: print }]
      javascripts:  [jquery.js, main.js]
    
  • Choose which stylesheets and javascripts you'd like to combine and add them to the app.yml file for your application. Be sure to use the same filename in both files (don't say "jquery" in view.yml and "jquery.js" in app.yml):

    # apps/%APPNAME%/config/app.yml
    all:
      io_combiner_plugin:
        stylesheets:       [grid_960.css, main.css]
        javascripts:       [jquery.js, main.js]
    

That's it! The plugin will automatically remove grid_960.css and main.css and replace them with combine.css, which will contain the minified contents of both of those css files. Similarly, jquery.js and main.js will be removed and replaced with combine.js, which will contain the minified contents of both of those js files.

    BEFORE:
    <link rel="stylesheet" type="text/css" media="screen" href="/css/grid_960.css" />
    <link rel="stylesheet" type="text/css" media="screen" href="/css/main.css" />
    <link rel="stylesheet" type="text/css" media="print" href="/css/print.css" />
    <script type="text/javascript" src="/js/jquery.min.js"></script>
    <script type="text/javascript" src="/js/main.js"></script>

    AFTER:
    <link rel="stylesheet" type="text/css" media="screen" href="/css/combine.css" />
    <link rel="stylesheet" type="text/css" media="print" href="/css/print.css" />
    <script type="text/javascript" src="/js/combine.js"></script>

Notice that we chose not to include the print.css file in the combiner. As such, it's not included in the combiner and is output normally. Since the combine.css file will always have a media="screen", print css cannot be included in it.

Dynamically Modifying your stylesheets and javascripts

An additional feature of this plugin is the ability to dynamically add or modify the contents that are output in the combine.css or combine.js files. This means that you can easily add dynamic css or js to your application!

This plugin exposes two filter events that can be used to make changes to the combine.css or combine.js files just before they are output.

  • iocombiner.filter_stylesheets
  • iocombiner.filter_javascripts

For information on how to use symfony events, please refer to chapter 17 of the Definitive Guide to symfony. Here's a quick example of how it might be used:

    // config/ProjectConfiguration.class.php
    class ProjectConfiguration extends sfProjectConfiguration
    {
      public function setup()
      {
        // ...
        $this->getEventDispatcher()->connect('iocombiner.filter_stylesheets', array($this, 'filterStylesheets'));
      }

      public function filterStylesheets(sfEvent $event, $result)
      {
        // add some css to the beginning of the combiner
        $result = 'body { background: #fff; }' . $result;

        // add some css to the end of the combiner
        $result .= 'a.footer { color: #333; }';

        // map all  "url(/some/path.jpg)" to a different domain (e.g. a media server)
        $pattern = "#url\('*\/(.+?)'*\)#s";
        $replacement = "url('http://media.yourdomain.com/$1')";
        $result = preg_replace($pattern, $replacement, $result);

        return $result;
      }
    }

Things to watch out for

Clear your cache in production

As the combine.css and combine.js files are cached, you'll need to clear your symfony cache after making changes to combined css or js files in your production environment.

    php symfony cc

One combiner file per site

A combiner file is meant to house the css/js that you need to include on every single page. This means that the combiner files themselves don't change from page to page - it's always the same block of css/js. On many pages, you may need to include additional stylesheets or javascripts. This should be done, as normally, with the use_stylesheet() and use_javascript() helper functions. Anything specified in this way won't be included in the combiner, but will be output like normal - as another stylesheet/javascript that is included next to the combiner.

The ordering of files is important

When using the combiner, all of your css and js files are combined into one big file. The order in which files are combined follows the order in which you specify the files in app.yml. However, when using the use_stylesheet() or use_javascript() methods, the ordering with respect to your combined files may be slightly different as the included file will be output either completely before or completely after your combined files. As you'll usually want these files to be included after some core, combined files, you may need to add special instructions to include these files last.

    <?php use_stylesheet('specific.css', 'last')[ ?>
    <?php use_javascript('specific.js', 'last')[ ?>

List stylesheets & javascripts in two places

This plugin is meant perform as little "magic" as possible so that the developer is always aware and can explicitly control which files are and are not combined. As such, this plugin is setup so that stylesheets and javascripts that should be combined are listed both in view.yml for normal functionality and in app.yml for the combiner. Keep this in mind while developing:

  • If you add a file to view.yml but not app.yml, that file will be included, but won't be combined. This probably won't cause problems, but will change the order in which the files are included (since the uncombined file will be included outside of the combiner file).

  • If you add a file to app.yml but not view.yml, that file will be included in the combiner but not when the combiner is turned off. So, if the combiner is enabled for your prod environment but disabled for your dev environment, prod will include the file while dev will not.

Extending the Plugin

The majority of the work in this plugin is done by two different classes: ioCombiner and ioCombinerResponse. Either of these classes can be replaced by a class of your own via the combiner_class and response_class keys in the app.yml configuration seen above. For example:

    all:
      io_combiner_plugin:
        response_class: myCombinerResponse

    class myCombinerResponse extends ioCombinerResponse
    {
      // do something here
    }

Future

A web debug panel to monitor which files are being combined, the number of requests being saved, and the file size difference with the combiner will be added.