What is it?

Rosemary is a PHP wrapper for executing CSS files. It is a filter-based system that allows you to combine and write custom filters to create different outputs. The filter system is completely free of restrictions so you can create anything from modifiers, to functions, to caching systems. Some packaged filters, for example, include: Variables, Yahoo! Reset, White Space Compressor, and more.

What's the setup like?

There are two key components to setup: .htaccess and .rosemary files.

The .htaccess is to redirect your CSS requests to the PHP filters. You do this by including the supplied .htaccess file in your CSS directory. Below we'll have a look at the code inside the .htaccess and what it means so you can edit it later if necessary.

#### Possible trouble shooting #### # ## Requires `mod_rewrite` to be enabled. # - Check phpinfo(); function to see if yours is on # ## Requires Apache `Allow Override` to be enabled # This may cause a problem if your .htaccess file isn't # working. # Turn the engine on RewriteEngine On RewriteOptions MaxRedirects=1 # Rewrites our CSS files RewriteCond %{THE_REQUEST} ^.*\.css.*$ # This should be the directory path of the Rosemary # controller file. RewriteRule . ../../Rosemary/core/Controller.php

If you have any experience with .htaccess, some of this should look familiar to you. The most important part is the line to note in this example is:
RewriteRule . ../../Rosemary/core/Controller.php. This means, match any file (matching .css) and redirect it to (../../Rosemary/...). The Rosemary folder mentioned is where you installed the library on your server. You can use an absolute path to this if you like, but this example shows a relative path two directories down.

The second part of the setup is even more simple; it is about setting up a .rosemary file. A .rosemary file simply contains a list of the filters you want to apply to a CSS file. The filename of the CSS and .rosemary file should match, so for example: Main.css uses Main.rosemary. Let's have a look at what a Main.rosemary file could be:

<?php /** * Setup modifiers per file */ $modifiers = array( 'Reset', // applied first 'Variables', // applied second 'Include', // applied third ... 'Inheritance' ); /*@ end file */

What's a filter and how does it work?

Filters are just PHP files with code in them. There is no special structure to follow, there are no real guidelines, or anything to restrict you. It flows like this: CSS content is passed into a filter, filter executes code, output is then passed on to the next filter.

Using this cascading effect allows you to organize complex systems by setting the right order and the right filters. Rosemary can be used simply to allow for variables, but it could also allow for dynamic variables by changing the order of filters.

As for writing a filter... You are supplied with the variable $output. Change that variable and let the filters cascade. Here's an example using the Variables filter:

/** * Change Our Output */ preg_match_all("/define (.*?)\:(.*?)\;/im", $output, $variableBlock); $defines = array_reverse($variableBlock[0]); $search = array_reverse($variableBlock[1]); $replace = array_reverse($variableBlock[2]); $tmpOutput = $output; // set var keys foreach( $search as $k => $v ){ $var = '@'. $v; if(substr(trim($replace[$k]), 0, 1) == '$') eval('$replace[$k] = ' . "{$replace[$k]};"); $offsetA = strpos( $output, $defines[$k] ); $tmpOutput = str_replace( $var, $replace[$k], $output ); $offsetB = strpos( $tmpOutput, $defines[$k] ); $replaced = substr( $tmpOutput, $offsetB , strlen( $tmpOutput) ); $output = substr( $output, 0, $offsetA ) . $replaced; } // remove vars $output = str_replace( $defines, '', $output );

What filters are available?

Since a filter can do so many different things and is very customizable, in order to understand how to use it, you'll have to check the individual filter's documentation. Below is a list of some of the pre-packaged filters.

  • Yahoo! Reset

    Includes similar reset functionality as the Yahoo! Reset CSS file described here. Usually best to include first if you want it.
  • Variables

    Allows ability to define variables to use across your CSS. Great for defining a styleguide or swappable theme.

    Usage /*@ Start CSS */ define blue: #0000FF; define fonts: Georgia, "Times New Roman", serif; div { color: @blue; font: 12px/1.5 @fonts; }
  • Browser

    Provides capability of targeting certain browsers for CSS. This can be good for testing, but perhaps not the most efficient method for a production level environment.

    Usage ~ie6 div { /* IE 6 gets this */ } ~gecko div { /* Gecko browsers only receive this */ } ~!gecko div { /* NON-Gecko browsers only receive this */ } div { ~ie height: 100%; ~!ie height: 500px; } /** More usage examples soon **/
  • Inheritance

    ... description soon
  • Strip Comments

    Removes all single line and block level comments from your CSS. This is best included last (or at least after an includes filter).
  • Compressor

    Removes all whitespace (tabs, spaces, and line breaks).
  • Mixins

    ... description soon
  • Includes

    Ability to include other CSS files into another. They can be processed like the current one or included completely raw. Paths are relative.

    Usage /*@ Start CSS file */ body, html { margin: 0; padding: 0; } include ./themes/theme_01.css; /* takes on filters */ include ./styleguide.css -raw; /* do not process this file. */