Trying the SUIT CSS Naming Convention

I’m in the process of redeveloping this site. The site will still use WordPress but I’ll be adding a custom skin.

I’ve been wanting to try Pattern Lab for a while, so the first step is to create a pattern library. It’s early days, today’s task it to set up a reset and base styles.

Additionally, I’ll be sampling a CSS naming convention I’ve been meaning to try for a little while. A personal project is the perfect opportunity.

WordPress Theme Elements

A client asked us to put together a list of every design element required in a WordPress theme but it’s the sort of thing we think we should share.

When producing a theme, we try not to limit the website owner’s options within the WordPress Dashboard. The owner may wish to enable an option down the track and be disappointed if they can’t.

The downside for the designer and developer is they may put in work for elements that are never used. The upside is happy clients and return business.

Like most things web, the site’s purpose will dictate that some things just aren’t feasible. Consider this as a series of guidelines that you can adapt for your purposes.

Published
Categorized as Code Tagged

Big Red Framework

We’ve updated the base WordPress theme we use at Soupgiant for WordPress 3.1+ and to make more use of the WordPress API.

Along with the standard features you would expect in a WordPress framework, it includes

Never use the framework proper to set up a theme, set up a child theme instead.

  • Copy the files from the starter directory into the base folder of your child theme
  • Create the sub-directory assets in your child theme
  • Copy the framework’s assets/child/ directory into the assets directory of your child theme

See the WordPress codex page on child themes for more information.

More documentation to come!

Soupgiant WordPress themes on Github

Update: We’ve released our updated framework and renamed it the Big Red Framework.

The Soupgiant base WordPress themes are now available on GitHub. There’s no documentation at this stage, I’ll write up a blog post with details in the coming weeks.

There are two parts to the theme

  • Soupgiant Parent Theme
    We use this as the parent theme across multiple projects. Any bug fixes or new features applied to this theme will be available to all child themes.
  • Soupgiant Child Theme
    Starting point for each project. Once duplicated for the project, CSS styling and per project PHP customisations are applied/overridden in the child theme. Most projects require a custom header.php & footer.php.

As I say, documentation to come.

 

JavaScript Localisation in WordPress

Recently on Twitter @iamcracks asked

Attention WordPress Wizards & Gurus. Is it possible to “get WordPress to write a custom field into a javascript variable”?

source

While I wouldn’t be so bold as to claim I’m either a wizard or a guru, I happen to know the answer to @iamcracks question.

A while back I wrote a two part tutorial on using JavaScript the WordPress way, the code below builds on that. The first step is to load the JavaScript in functions.php using wp_enqueue_script() as detailed in the earlier tutorial:

<?php
function brt_load_scripts() {
  if (!is_admin()) {
    wp_enqueue_script(
      'brt-sample-script', //handle
      '/path/2/script.js', //source
      null, //no dependancies
      '1.0.1', //version
      true //load in html footer
    );
  }
}

add_action('wp_print_scripts', 'brt_load_scripts');
?>

This outputs the html required for the JavaScript when wp_footer() is called in footer.php

Localising the script is done using the function wp_localize_script() it takes three variables:

  • $handle – (string) the handle defined when registering the script with wp_enqueue_script
  • $javascriptObject – (string) name of the JavaScript object that contains the passed variables.
  • $variables – (array) the variables to be passed

To pass the site’s home page and the theme directory, we’d add this function call below the wp_enqueue_script call above:

<?php
...
wp_localize_script('brt-sample-script', 'brtSampleVars', array(
  'url' => get_bloginfo('url'),
  'theme_dir' => get_bloginfo('stylesheet_directory')
  )
);
...
?>

The output html would be:

<script type='text/javascript'>
/* <![CDATA[ */
var brtSampleVars = {
  url: "http://bigredtin.com",
  theme_dir: "http://bigredtin.com/wp-content/themes/bigredtin"
};
/* ]]> */
</script>
<script type='text/javascript' src='/path/2/script.js?ver=1.0.1'></script>

Accessing the variables within JavaScript is done using the standard dot notation, for example brtSampleVars.theme_dir to access the theme directory.

Using a post’s custom fields is slightly more complicated so I’ll write out the code in full:

<?php
function brt_load_scripts() {
  if (is_singular()) {
    wp_enqueue_script(
      'brt-sample-script', //handle
      '/path/2/script.js', //source
      null, //no dependancies
      '1.0.1', //version
      true //load in html footer
    );

    the_post();
    $allPostMeta = get_post_custom();
    wp_localize_script('brt-sample-script', 'brtSampleVars',
    array(
      'petersTwitter' => $allPostMeta['myTwitter'][0],
      'joshsTwitter' => $allPostMeta['joshsTwitter'][0]
      )
    );
    rewind_posts();
  }
}

add_action('wp_print_scripts', 'brt_load_scripts');
?>

Only pages and posts have custom fields so the check at the start of the function has become is_singlular() to check the user is on either a post or a page, earlier we were testing if the user was anywhere on the front end. The arguments for wp_enqueue_script have not changed.

the_post() needs to be called to start the loop and initiate the $post object so the associated custom fields can be accessed in the following line and put in an array.

With the custom fields easily available, the information can then be passed to wp_localize_script() as earlier demonstrated. The final step is to rewind the loop so next time the_post() is called, from either single.php or page.php, the post data is available.

The html output from the sample above would be:

<script type='text/javascript'>
/* <![CDATA[ */
var brtSampleVars = {
  petersTwitter: "@pwcc",
  joshsTwitter: "@sealfur"
};
/* ]]> */
</script>
<script type='text/javascript' src='/path/2/script.js?ver=1.0.1'></script>

Delay Print Stylesheets Plugin

A few weeks ago I wrote a post in which I adapted an idea from a zOompf article to delay the loading of print stylesheets until after a web page has fully rendered. I finished that post with the following point/question:

Another question to ask is whether all this is actually worth the effort – even when reduced through automation. On Big Red Tin, the print.css is 595 bytes, the delay in rendering is negligible.

Chris and Jeff at Digging into WordPress picked up the article and posted it on their site. In turn it was picked up elsewhere and became the surprise hit of the summer at Big Red Tin. Not bad when one is shivering through a bitter Melbourne winter.

As a result of the interest, I decided to convert the code from the original post into a plugin and add it to the WordPress plugin directory.

Further Testing

As I warned in the original article, I’d tested the code in very limited circumstances and found it had worked. Fine for a code sample but not enough for a sub version-1.0-release plugin. Additional testing showed:

  1. Stylesheets intended for IE, through conditional comments, were loading in all browsers
  2. When loading multiple stylesheets, the correct order was not maintained in all browsers

If jQuery was available I wanted to use it for JavaScript event management otherwise I’d use purpose-written JavaScript. There’s no point, after all, of worrying about the rendering delay caused by 600-1000 bytes only to load a 71KB (or 24KB gzipped) file in its place.

Other things I wanted to do included:

  1. Put the PHP in a class to reduce the risk of clashing function/class names
  2. Put the JavaScript in its own namespace
  3. Keep the output code as small as possible

To support conditional comments for IE required adding each stylesheet within a separate <script> tag, using this method the output HTML takes the following form:

<script>
  // add global print.css
</script>
<!--[if IE 6]>
  <script type='text/javascript'>
    // add ie6 specific print.css
  </script>
<![endif]-->

This violates my aim to keep output as small as possible but footprint has to take second place to bug-free. I could have translated the code to use JavaScript conditional comments by translating the IE version to the JavaScript engine it uses but this could lead to future-proofing problems.

To maintain the order of stylesheets, I added each event to an array of functions and then used a single event to loop through the array of functions. If jQuery is used, I add multiple events because jQuery runs events on a first in first out basis.

Putting the PHP in a class and the JavaScript in its own namespace is fairly self-explanatory. Google is your friend if you wish to read up further on this.

Minimising the footprint was also a simple step. I wrote the JavaScript out in full with friendly variable names. Once I was happy with the code, I ran the code through the YUI JavaScript compressor, commented out the original JavaScript in the plugin file and output the compressed version in its place.

The JavaScript is output inline (within the HTML) to avoid additional HTTP requests. I was in two minds about this because browser caching is lost in the process. So it may change in a later version.

I’ve worked out another way to keep the footprint small. Rather than creating a function to pass the stylesheet’s URL and ID to brt_print.add(url, id), I wrote out the full function for each style sheet. I’ll fix that in the next release.

You can download the Delay Print CSS Plugin from the WordPress plugin repository.

Delay loading of print CSS

Recently I stumbled across an article on zOompf detailing browser performance with the CSS print media type. In most recent browsers, Safari being the exception, the print stylesheet held up rendering of the page.

The zOomph article suggests a solution, to load print stylesheets using JavaScript once the page has rendered (ie, on the window.onload event), with a backup for the JavaScript impaired. You can see their code in the original article.

Automating the task for WordPress

Most sites I develop are in WordPress so I decided to automate the process. This relies on using wp_enqueue_style to register the stylesheets:

function enqueue_css(){
  if (!is_admin()){
    wp_enqueue_style (
      'bigred-print', /* handle */
      '/path-to/print.css', /* source */
      null, /* no requirements */
      '1.0', /* version */
      'print' /* media type */
    );
  }
}
add_action('wp_print_styles', 'enqueue_css');

The above code will output the following HTML in the header:

<link rel='stylesheet' id='bigred-print-css'  href='/path-to/print.css?ver=1.0' type='text/css' media='print' />

The first step is to wrap the above html in noscript tags, the WordPress filter style_loader_tag is ideal for this.

function js_printcss($tag, $handle) {
  global $wp_styles;
  if ($wp_styles->registered[$handle]->args == 'print') {
    $tag = "<noscript>" . $tag . "</noscript>";
  }
  return $tag;
}
add_filter('style_loader_tag', 'js_printcss', 5, 2);

The filter runs for all stylesheets, regardless of media type, so the function checks for print stylesheets and wraps them in the noscript tag, other media types are left alone.

The first two arguments are the filter and function names respectively, the third argument specifies the timing (5 is the default) and the final argument tells WordPress how many arguments to pass to the filter – two – in this case $tag and $handle.

With the new filter, WordPress now outputs following HTML in the header:

<noscript>
<link rel='stylesheet' id='bigred-print-css'  href='/path-to/print.css?ver=1' type='text/css' media='print' />
</noscript>

The next step is to add the JavaScript to load the stylesheets, we can do this by changing our original function, js_printcss, and making use of a global variable:

$printCSS = '';

function js_printcss($tag, $handle){
  global $wp_styles, $printCSS;
  if ($wp_styles->registered[$handle]->args == 'print') {

    $tag = "<noscript>" . $tag . "</noscript>";

    preg_match("/<s*links+[^>]*hrefs*=s*["']?([^"' >]+)["' >]/", $tag, $hrefArray);
    $href = $hrefArray[1];

    $printCSS .= "var cssNode = document.createElement('link');";
    $printCSS .= "cssNode.type = 'text/css';";
    $printCSS .= "cssNode.rel = 'stylesheet';";
    $printCSS .= "cssNode.href = '" . esc_js($href) . "';";
    $printCSS .= "cssNode.media = 'print';";
    $printCSS .= "document.getElementsByTagName("head")[0].appendChild(cssNode);";
  }
  return $tag;
}

The code creates the PHP variable $printCSS globally, which is then called into the function using the global command.

After wrapping the tag in the noscript tags, the new function uses a regular expression to extract the URL of the stylesheet from the link tag and placing it the variable $href.

Having extracted the stylesheet’s URL, the function then appends the required JavaScript to the PHP global variable $printCSS.

The final step is to add the JavaScript to the footer of the HTML using the wp_footer action in WordPress. The PHP to do this is:

function printCSS_scriptTags(){
  global $printCSS;
  if ($printCSS != '') {
    echo "<script type='text/javascript'>n";
    echo "window.onload = function(){n";
    echo $printCSS;
    echo "}n</script>";
  }
}

add_action('wp_footer', 'printCSS_scriptTags');

The above code uses window.onload as dictated in the original article. A better method would be to use an event listener to do the work, for those using jQuery we would change the function to:

function printCSS_scriptTags(){
  global $printCSS;
  if ($printCSS != '') {
    echo "<script type='text/javascript'>n";
    echo "jQuery(window).ready(function(){n";
    echo $printCSS;
    echo "});n</script>";
 }

}
add_action('wp_footer', 'printCSS_scriptTags');

The above solution had been tested for very limited circumstances only and found to have worked. Were I to use the function in a production environment I would undertake further testing.

Another question to ask is whether all this is actually worth the effort – even when reduced through automation. On Big Red Tin, the print.css is 595 bytes, the delay in rendering is negligible.

Update Aug 23, 2010: Fixed a type in the code block redefining js_printcss.

Update Aug 27, 2010: I’ve decided to release this as a plugin, get the skinny and the plugin from the followup article.