Minimize, combine & cache your CSS and JS files. Minify your HTML. Because size (still) DOES matter.
Version 2.1.13 — 5 September 2014
"Minimee combines and compresses JavaScript and CSS files, thereby reducing file sizes and HTTP requests, and turning your puddle of online molasses into a digital fire hose." Stephen Lewis, founder, Experience Internet
Minimee watches your filesystem for changes to your CSS & JS assets, and automatically combines, minifies & caches these assets whenever changes are detected. It can also detect changes to stylesheet templates (whether saved as files or not).
Version 2's substantial re-write has ushered in a host of changes big and small. It is the same Minimee you've come to rely on, with more power, intelligence, and fun-ness.
Minimee is inspired and influenced by SL Combinator from Experience Internet, and Carabiner Asset Management Library from Tony Dewan.
The architecture of Minimee(2) has given me the opportunity to build other add-ons that extend Minimee's capabilities. So if you're curious, have a look at:
exp:minimee
tag allows for quick caching, plus access to a powerful API "interface"priority=""
parameter allows you to queue assets into a specific ordercleanup=""
setting for automatically deleting expired caches{stylesheet=""}
{stylesheet=}
or external URLsfile_get_contents()
, PHP must be compiled with support for fopen wrappers (allow_url_fopen must be set to true in PHP.ini)file_get_contents()
and combining/minifying files over https
, PHP must be compiled with OpenSSL supportDespite Minimee2's significant changes, it has been built to ensure full backwards-compatibility with Minimee 1.x. So if you're a cow(boy|girl) and like to upgrade add-ons before reading upgrade notes, then we've got you covered. But to get the most out of Minimee's new abilities and performance, be sure to make it past Step 1.
It's obvious, and it just works. Replace your old system/ee/third_party/minimee
folder with the new, and you're in business.
If you have Minimee's Extension installed, you will want to visit the Extensions page so that Minimee can upgrade its settings the new architecture.
In lieu of Minimee's Extension, you may have Minimee configured via EE's config option, or via EE's Global Variables. If so, please note:
Additionally, when configuring via EE's $config
, setting keys have changed to be a single array. See the Configuration section below for more.
Two files' names have changed case, which may go unrecognised with versioning systems such as SVN/Git, and may cause trouble on case-sensitive filesystems. While a check is in place to account for this, it is recommended that you double-check that the names have been properly maintained, as subsequent versions of Minimee may drop this check to save time. The files are:
// correct: /system/expressionengine/third_party/minimee/libraries/JSMin.php // incorrect: /system/expressionengine/third_party/minimee/libraries/jsmin.php // and // correct: /system/expressionengine/third_party/minimee/libraries/CSSmin.php // incorrect: /system/expressionengine/third_party/minimee/libraries/CSSMin.php
Minimee 2.x's naming convention differs from 1.x, and therefore upon first run will create new cache files. If you'd like to tidy up your cache folder, now would be a good time. Also see Minimee's new cleanup=
setting to automatically delete expired caches.
Out-of-the-box and left un-configured, Minimee 2.x will look for a 'cache' folder at the root of your site, e.g. http://yoursite.com/cache
.
To get the most out of Minimee's performance offering, configure via EE's $config
variable; use the Extension for simplicity and convenience, but at the cost of an extra database call.
Each field of Minimee's Extension screen contains helpful hints and instructions. Screenshots of the page follow:
The first panel allows for basic configuration of Minimee, including whether to combine and/or minify each asset type.
If no values are supplied for Cache Path or Cache URL, Minimee will automatically look for a `cache` folder at your root.
You may specify relative paths by ommitting a leading slash (e.g. `cache/path`).
Configuring Minimee via EE's $config
has the advantage of not requiring any DB calls to initialise or run, saving precious time on your page loads. Going this route requires editing your /system/expressionengine/config/config.php file; alternatively you are encouraged to adopt any of the community-developed "bootstrap" methods, such as:
$config['minimee'] = array( /** * ============================================== * BASIC PREFERENCES (REQUIRED) * ============================================== */ /** * The path to the cache folder. * Defaults to site's FCPATH + '/cache' */ 'cache_path' => '/path/to/site.com/cache', /** * The URL to the cache folder. * Defaults to $EE->config->item('base_url') + '/cache' */ 'cache_url' => 'http://site.com/cache', /** * ============================================== * BASIC PREFERENCES (OPTIONAL) * ============================================== */ /** * Turn on or off combining of CSS assets only. 'yes' or 'no'. * Values: 'yes' or 'no' * Default: yes */ 'combine_css' => 'yes', /** * Turn on or off combining of JS assets only. 'yes' or 'no'. * Values: 'yes' or 'no' * Default: yes */ 'combine_js' => 'yes', /** * Turn on or off minifying of CSS assets. 'yes' or 'no'. * Values: 'yes' or 'no' * Default: yes */ 'minify_css' => 'yes', /** * Turn on or off minifying of the template HTML. * Values: 'yes' or 'no' * Default: no */ 'minify_html' => 'no', /** * Turn on or off minifying of JS assets. * Values: 'yes' or 'no' * Default: yes */ 'minify_js' => 'yes', /** * ============================================== * DISABLING MINIMEE * ============================================== */ /** * Disable Minimee entirely; aborts all activity * and returns all tags untouched. * Values: 'yes' or 'no' * Default: no */ 'disable' => 'no', /** * ============================================== * ADVANCED PREFERENCES * It is recommended to not specify these unless * you are intending to override their default values. * ============================================== */ /** * The base path of your local source assets. * Defaults to site's FCPATH */ 'base_path' => '/path/to/site.com', /** * The base URL of your local source assets. * Defaults to $EE->config->item('base_url') */ 'base_url' => 'http://site.com', /** * An optional unique 'cachebusting' string to force * Minimee to generate a new cache whenever updated. */ 'cachebust' => '', /** * When 'yes', Minimee will attempt to delete caches * it has determined to have expired. * Values: 'yes' or 'no' * Default: no */ 'cleanup' => 'no', /** * Specify which minification library to use for your CSS. * Values: 'minify' or 'cssmin' * Default: minify */ 'css_library' => 'minify', /** * Whether or not to prepend the base URL to relative * @import and image paths in CSS. 'yes' or 'no'. * Values: 'yes' or 'no' * Default: yes */ 'css_prepend_mode' => 'yes', /** * Override the URL used when prepending URL to relative * @import and image paths in CSS. * Defaults to Base URL. */ 'css_prepend_url' => 'http://site.com', /** * Specify what algorithm to use when creating cache filenames. * 'sanitize' enforces a 200 character limit, and is * only recommended during development. * Values: 'md5', 'sha1', or 'sanitize'/'sanitise' * Default: sha1 */ 'hash_method' => 'sha1', /** * Specify which minification library to use for your JS. * Please note that JSMinPlus is VERY memory-intensive. Not recommended * unless you really know what you're doing. Seriously. * * Values: 'jsmin' or 'jsminplus' * Default: jsmin */ 'js_library' => 'jsmin', /** * Specify the method with which Minimee should fetch external & {stylesheet=} assets. * Values: 'auto', 'fgc', or 'curl' * Default: auto */ 'remote_mode' => 'auto' );
Heads up! All Configuration values mentioned above can also be specified as tag parameters. Refer to the EE $config code sample for key/value combinations.
Parameter | Required? | Default | Values | Description |
---|---|---|---|---|
attribute:name="value" |
no | none | String |
By default Minimee uses the first tag it encounters as a template for the cache tag output (e.g. |
combine= |
no | none | yes | no |
Shorthand, runtime override of the combine_(css|js) config option |
delimiter= |
no | , | String |
When not combining, this is the string to place between cache output |
display= |
no | tag | tag |
Specify which format to display as the cache results; the default is "tag", returning the appropriate asset tag (e.g. |
url |
This option will only return the URL to the cache, e.g. |
|||
contents |
Instruct Minimee to return the contents of the cache, for embedding inline in your template. By default, only the contents are returned; specify one or more |
|||
minify= |
no | none | yes | no |
Shorthand, runtime override of the minify_(css|js) config option |
priority= |
no | 0 | Numeric |
For use with |
queue= |
no | none | String |
To "queue" assets for output; receives a "key" value (e.g. "head_css"), which is used later to lookup and retrieve the queue'd cache Note: see the section below about Queue'ing incompatibility with EE's Advanced Conditionals. |
Parameter | Required? | Default | Values | Description |
---|---|---|---|---|
attribute:name="value" |
no | none | String |
By default Minimee uses the first tag it encounters as a template for the cache tag output (e.g. |
combine= |
no | none | yes | no |
Shorthand, runtime override of the combine_(css|js) config option |
css= OR js= |
yes | none | String |
The "key" value of the queue, to fetch and return |
delimiter= |
no | , | String |
When not combining, this is the string to place between cache output |
display= |
no | tag | tag |
Specify which format to display as the cache results; the default is "tag", returning the appropriate asset tag (e.g. |
url |
This option will only return the URL to the cache, e.g. |
|||
contents |
Instruct Minimee to return the contents of the cache, for embedding inline in your template. By default, only the contents are returned; specify one or more |
|||
minify= |
no | none | yes | no |
Shorthand, runtime override of the minify_(css|js) config option |
Parameter | Required? | Default | Values | Description |
---|---|---|---|---|
attribute:name="value" |
no | none | String |
Override the tag output; useful if changing |
combine= |
no | none | yes | no |
Shorthand, runtime override of the combine_(css|js) config option |
css= OR js= |
yes | none | String |
filename(s) of assets to cache. Cannot specify both in same call. |
delimiter= |
no | , | String |
When not combining, this is the string to place between cache output |
display= |
no | tag | tag |
Specify which format to display as the cache results; the default is "tag", returning the appropriate asset tag (e.g. |
url |
This option will only return the URL to the cache, e.g. |
|||
contents |
Instruct Minimee to return the contents of the cache, for embedding inline in your template. By default, only the contents are returned; specify one or more |
|||
minify= |
no | none | yes | no |
Shorthand, runtime override of the minify_(css|js) config option |
priority= |
no | 0 | Numeric |
For use with |
queue= |
no | none | String |
To "queue" assets for output; receives a "key" value (e.g. "head_css"), which is used later to lookup and retrieve the queue'd cache Note: see the section below about Queue'ing incompatibility with EE's Advanced Conditionals. |
Description |
---|
This tag is required only when all are true:
When the above are all true, then Minimee needs to be called once during template parsing to know to minify your HTML. Placing this tag somewhere in your template will do just that. |
Once configured, basic use of Minimee is as simple and beautiful as:
{exp:minimee:css} <link rel="stylesheet" href="css/reset.css"> <link rel="stylesheet" href="{stylesheet='css/webfonts'}"> <link rel="stylesheet" href="http://site.com/css/global.css"> <link rel="stylesheet" href="css/forms.css"> {/exp:minimee:css} {!-- will render something like: --} <link rel="stylesheet" href="http://site.com/cache/b488f65d0085dcc6b8f536f533b5f2da.1345797433.css">
{exp:minimee:js} <script type="text/javascript" src="/js/mylibs/jquery.easing.js"></script> <script type="text/javascript" src="/js/mylibs/jquery.cycle.js"></script> <script type="text/javascript" src="/js/mylibs/jquery.forms.js"></script> <script type="text/javascript" src="/js/scripts.js"></script> <script type="text/javascript" src="/js/plugins.js"></script> {/exp:minimee:js} {!- will render something like: --} <script type="text/javascript" src="http://site.com/cache/16b6345ae6f4b24dd2b1cba102cbf2fa.1298784512.js"></script>
There is a wealth of power and flexibility at your fingertips should you choose to go beyond Minimee's basic setup. This section will continue to grow with more examples as time goes on.
Since Minimee 1.x there has been the ability to "queue" assets and then display the final cache later in your EE template. It's a simple two-step process:
queue=
parameter to your exp:minimee:css
or exp:minimee:js
opening tag:{exp:minimee:css queue="head_css"} <link rel="stylesheet" href="css/reset.css"> {/exp:minimee:css}
For subsequent queue'ing, continue to use the same parameter value:
{exp:minimee:css queue="head_css"} <link rel="stylesheet" href="{stylesheet='css/webfonts'}"> {/exp:minimee:css} ... {exp:minimee:css queue="head_css"} <link rel="stylesheet" href="http://site.com/css/global.css"> <link rel="stylesheet" href="css/forms.css"> {/exp:minimee:css}
exp:minimee:display
tag; use css=
or js=
as your tag parameter depending on the type of asset, and specify the name of the queue:{exp:minimee:display css="head_css"} {!-- will render something like: --} <link rel="stylesheet" href="http://site.com/cache/b488f65d0085dcc6b8f536f533b5f2da.1345797433.css">
If you are attempting to conditionally queue an asset, be warned that Queue'ing is incompatible with EE's Advanced Conditionals. This is due to the EE's parse order, where the evaluation of any Advanced Conditionals happens after the Minimee queue tags have already been parsed and processed.
You have a few options to work around this parse order conflict:
Mark Croxton submitted this feature request to delay the processing of exp:minimee:display
until all other template parsing has been completed, by way of leveraging EE2.4's new template_post_parse
hook. It was a brilliant idea and indication of his mad scientist skills. In his wise words:
"Then you would never need worry about parse order when injecting assets into the header or footer of your page using queues."
This, combined with the new priority=""
parameter, means you can do something like:
{exp:minimee:display css="header_css"} {!-- sometime LATER in EE's parse order --} {exp:minimee:css queue="header_css" priority="10"} <link href="css/forms.css" rel="stylesheet" type="text/css" /> {/exp:minimee:css} {!-- and even later in parse order, also note the priority --} {exp:minimee:css queue="header_css" priority="0"} <link href="css/reset.css" rel="stylesheet" type="text/css" /> {/exp:minimee:css}
And then what ends up happening is that exp:minimee:display
outputs a cached css that contains, in this order:
There are now multiple approaches to "embedding" the contents of your cache inline with the rest of your HTML content. Let's cover 2 basic options:
Begin with Step 1 above under Queueing + Display. This will queue one or more assets for display.
As a Step 2, specify a display output of contents
. Just as with Minimee 1.x, be sure to wrap it within the appropriate HTML tag:
<style type="text/css"> {exp:minimee:display css="head_css" display="contents"} </style>
However, by also specifying one or more attribute:name="value"
parameters to exp:minimee:display
, Minimee will automatically wrap the contents of the cache in the appropriate HTML tag for you, using the attributes you specified:
{exp:minimee:display css="head_css" display="contents" attribute:type="text/css"} {!-- Will output something like: --} <style type="text/css"> /* your CSS here */ </style>
The return mode of exp:minimee:js
and exp:minimee:css
tags can now be altered in a single call, by specifying the display
value at the same time. When doing so, it is recommended to also provide the appropriate attribute:name="value"
parameters as well, so that the contents are automatically wrapped in tags:
{exp:minimee:css display="contents" attribute:type="text/css"} <link rel="stylesheet" href="css/reset.css"> <link rel="stylesheet" href="{stylesheet='css/webfonts'}"> <link rel="stylesheet" href="http://site.com/css/global.css"> <link rel="stylesheet" href="css/forms.css"> {/exp:minimee:css} {!-- Will output something like: --} <style type="text/css"> /* your CSS here */ </style>
If using the LABjs script loading library, you can use the exp:minimee
API tag to seamlessly integrate with your application:
<script> $LAB .script("{exp:minimee js='framework.js'}").wait() .script("{exp:minimee js='plugin.framework.js'}") .script("{exp:minimee js='myplugin.framework.js'}").wait() .script("{exp:minimee js='init.js'}").wait(); </script>
What's more, you can still combine & cache JS assets using a similar syntax. When doing so, consider setting it up so that should Minimee encounter an error - or be disabled manually - the resulting output can still work with LABjs.
Consider the follwing example from LABjs:
<script> $LAB .script("script1.js", "script2.js", "script3.js") .wait(function(){ // wait for all scripts to execute first }); </script>
By modifying the delimiter which Minimee uses to parse assets, we can do the following:
<script> $LAB .script("{exp:minimee js='script1.js", "script2.js", "script3.js' delimiter='", "'}") .wait(function(){ // wait for all scripts to execute first }); </script>
If all goes well, $LAB.script() will receive a single cache file; if not - or if Minimee has been temporarily disabled - it receives the original example's equivalent.
Start by turning on EE's Template Debugging, and visiting the front end of your site. Minimee's debugging messages are each prefixed with one of three labels:
For official support please head over to the @devot-ee forum. When posting, please specify what version of EE and Minimee you are running: Minimee Support Forums on @devot-ee.
As a general rule, Minimee creates a new cache if it can detect that an asset's modification date is later than the cache's creation date, OR if the list of assets to cache has been changed in some way.
More specifically, note:
{stylesheet=}
template, Minimee first checks the database modification date (and if that template is saved as a file, also checks the file’s modification date){path=}
template (see below for more), then Minimee does not compare anything and only fetches the contents at the time of creating a cache.A cache filename begins with a configurable hash option (see Configuration section above), created from the list of assets being cached together. Minimee then appends the last modified timestamp, and if an optional cachebusting string has been specified, comes next. The result format is:
// md5.timestamp.[cachebust].ext 03b5614606d3e8d2f28d0b07f802fbbb.1332460675.v2.5.css
This approach means that:
Sometimes Minimee runs into trouble; a file cannot be found, or perhaps the base path has been incorrectly set. When this happens, Minimee does its best to return your template content ontouched.
This is the same behaviour Minimee follows when it has been disabled (either via config or parameter).
With that in mind, be careful when you set display=
to a format other than the input (e.g., original tag data contains <link>
tags, but displaying just cache url). Disabling or encountering an error may have unintended consequences if, for example, your site expects a URL but receives a list of <link>
tags.
The new "cleanup" setting will delete any cache files it has determined have expired. This is done by looking at the timestamp segment of the filename (see above).
Minimee will not attempt to clean up files that are simply older than some unspecified time. Nor will it know to delete caches that are now obsolete, e.g. were created out of a combination of files that is no longer used any more.
When you specify a cachebust value, such as v1.0
, this value is appended toward the end of the cache filename (see above). In most situations this is not necessary, since Minimee will continue to look at file timestamps and create new cache files as required.
One useful scenario for this feature is when you have a requirement to run your assets through EE's parsing engine and therefore must use the {path=}
global variable. Since Minimee cannot check for updates on {path=}
assets (see below), you might use cachebust
to prompt Minimee to create a new cache.
You may also prefer to simply use the cachebust string as part of tracking your website "revisions". You can create a global variable {gv_cachebust}
, and pass this as a parameter to each of minimee's opening tags like so:
{exp:minimee:css cachebust="{gv_cachebust}"} ... {/exp:minimee:css}
The astute Minimee'er may have noticed that old Minimee 1.x tags such as exp:minimee:embed
continue to work on 2.x. This is because in 2.x, all "display" methods run through our master exp:minimee:display tag. This ensures we can maintain compatibility with our term aliases ("embed" is synonymous with "contents"). What's more, there's some syntax sugary goodness tossed in there for fun.
embed
== contents
url
== link
tag
== display
(since the default display
behaviour is to output tags)exp:minimee:embed
== exp:minimee:display display="contents"
exp:minimee:contents
== exp:minimee:display display="contents"
exp:minimee:url
== exp:minimee:display display="url"
exp:minimee:link
== exp:minimee:display display="url"
exp:minimee:tag
== exp:minimee:display display="tag"
== exp:minimee:display
If you append a 4th segment to your tag pair, you can invoke the display mode automatically. Check it out:
exp:minimee:display:embed
== exp:minimee:display display="contents"
exp:minimee:display:contents
== exp:minimee:display display="contents"
exp:minimee:display:url
== exp:minimee:display display="url"
exp:minimee:display:link
== exp:minimee:display display="url"
exp:minimee:display:tag
== exp:minimee:display display="tag"
== exp:minimee:display
OK, so that might not be too exciting, but the tag pair modifer also works on our standard exp:minimee:css
and exp:minimee:js
tags:
exp:minimee:css:embed
== exp:minimee:css display="contents"
exp:minimee:css:contents
== exp:minimee:css display="contents"
exp:minimee:css:url
== exp:minimee:css display="url"
exp:minimee:css:link
== exp:minimee:css display="url"
exp:minimee:css:tag
== exp:minimee:css display="tag"
== exp:minimee:css
and
exp:minimee:js:embed
== exp:minimee:js display="contents"
exp:minimee:js:contents
== exp:minimee:js display="contents"
exp:minimee:js:url
== exp:minimee:js display="url"
exp:minimee:js:link
== exp:minimee:js display="url"
exp:minimee:js:tag
== exp:minimee:js display="tag"
== exp:minimee:js
Yes, and no - If you have CSS/JS in a template that must be run through EE's parsing engine, you may use the {path=}
global and Minimee will fetch the file's contents, BUT it will not attempt to detect changes to the template's contents. This is because there's no reliable way for Minimee to "know" when a change has been made. So consider a {path=}
asset as the same as any other external asset (e.g. http://static.jquery.com/ui/css/base2.css).
When you need Minimee to support a mix of http
& https
, you can specify a Protocol Relative URL in Minimee's Cache URL and Base URL:
$config['minimee'] = array( ... // Note the two leading slashes 'cache_url' => '//site.com/cache', 'base_url' => '//site.com', ... );
Take note that if you are also changing the URL that is prepended to CSS assets (css_prepend_url
), you will want to be sure this too is protocol 'agnostic'.
To specify unique settings for each asset, you must use the queue
+ display
tags. Take for example you are using a theme from jQuery UI, and would like to cache & combine a copy of the theme CSS. To do so, any url()
properties must have a different URL prepended to them than your site. Here's how you would accomplish this:
// Our first tag will specify an external URL to prepend to all url() paths {exp:minimee:css queue="css_head" css_prepend_url="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/" } <link rel="stylesheet" href="http://static.jquery.com/ui/css/base2.css" /> {/exp:minimee:css} // Our second tag does not specify a special prepend URL, so the default (base URL) will be used {exp:minimee:css queue="css_head"} <link rel="stylesheet" href="/css/styles.css" /> {/exp:minimee:css} // Finally we display our combined output {exp:minimee:display css="css_head"}
No. There are performance implications, error handling gotchas, and it over-complicates what should remain a simple utility.
If you need to "queue" your inline content to appear after other Minimee'd assets, I suggest you consider Croxton's Stash, which is an incredibly powerful, fast, and free tool.
No, but the @import
rule will remain in the cached file, and the path to the imported CSS file will be adjusted so that the file can still be included by the browser.
Minimee is already MSM-compatible as long as each Site's cache folder is located in the same relative location. For example:
To ensure compatibility in these situations, either configure Minimee via config.php using a bootstrap method (examples mentioned above), or config Minimee via the extension but use relative path and url values, e.g. 'cache'
, instead of /cache
.
If your setup does not match the above, and you need per-site configuration, check out MSMinimee.
There are currently two alternative add-ons that help you compress your CSS & JS (for EE2). These are:
AutoMin - By Jesse Bunch, this has been recently re-written shares many similarities with Minimee. Syntax is nearly identical, plus it has built-in support of LESS. Setup requirements differ slightly from Minimee.
NSM Minify - By Leevi Graham, this too only works on local files, but actually runs very different from Minimee & AutoMin. The setup is more similar to SL Combinator, and in fact it's possible to use without any EE tags whatsoever. So if you're after the ultimate in lightweight compression of your assets, NSM Minify might suit your tastes.
hash_method
with ability to sanitize, rather than hash, cache filenames. Useful for debugging, not recommended during development.