Author Archive

Dear Drupal: Season’s Greetings. Love, Smashing WordPress.





 



 


Every day I work with WordPress in one way or another. My Twitter feed is full of WordPress types, and I’m a regular at my local WordPress meetup. I’m a WordPress fan.

The developer across the hall from me works with Joomla. His Twitter feed is full of Joomla types, and he uses the CMS every day. It wouldn’t surprise me to learn that he attends the local Joomla user group. He’s a Joomla fan.

Drupal and WordPress

The White House hosts a number of Web developers who use Drupal every day. Their Twitter feeds are probably full of Drupal types, and some may well attend the Washington DC Drupal meetup. They are Drupal fans.

All three of these tools produce the same thing, HTML. Throw in some CSS and JavaScript, and you have yourself a website. This is what I love about Web development: so many tools are available, each with its strengths and weaknesses.

We Have A Problem

In the WordPress community, I often see snide remarks directed at the Drupal and Joomla communities. I see the occasional remark directed at WordPress, too, but because I hang around mostly with WordPress types, I see more outbound comments.

This bickering ranges from overt expressions of contempt to, more subtly, gleeful sharing of accounts of internal disputes on “the other side.�

I am more effective at working with WordPress than with Joomla or Drupal, both of which baffle me to some extent. It’s not that the other CMS’ are inferior, but that my knowledge of them is.

Drupal Is Better Than WordPress

Without a doubt, Drupal is better than WordPress. Out of the box, it can handle higher traffic, its database management is better, and complex data maps are easier to handle. Out of the box, assigning permissions and preventing certain users from accessing data are easier to do. If you were creating a public-facing intranet website – for example, to allow salespeople to access internal documents on the road – this would be comforting.

WordPress Is Better Than Drupal

Without a doubt, WordPress is better than Drupal. Out of the box, content submission is easier for someone who is untrained in HTML, the default rewrite URLs are much nicer than Drupal’s, and customizing the default settings is easier.

The core developers focused on backwards compatibility, so a theme written today for version 3.2.1 will likely work in four years’ time.

The Gift Of Inspiration

Despite the trash talk, Drupal and WordPress have one thing in common: a frequent crossover of features. In some cases, it’s a core feature (a recent example being menus in Drupal being brought over to WordPress).

In other cases, a developer will port a popular module or plugin to their platform of choice. The new functionality may be optional, but it is still cross-platform pollination.

All Software Has Its Weaknesses

Every piece of software I have ever used has at some point made me get up from my desk, walk calmly across the room and kick the crap out of the garbage can. (Try it. It’s cheaper than throwing the computer.)

The big three open-source CMS’ are no different from any other software. There are idiosyncrasies to work around, and there are edge-case and intermittent bugs that will hit you and one other person.

Share Your Weaknesses

Instead of trash-talking the “the other� CMS’ and dwelling on their weaknesses, let’s come together and recognize that we are all part of the same community: the open-source community.

In open-source circles, hearing of the desire to give back to the community is relatively common. Expanding your definition of “community� from the one around your platform to encompass the open-source community will increase your opportunity to give back.

Giving back doesn’t have to mean offering a tangible product, such as a theme, plugin or module repository. It could be as simple as sharing how you solved a particular problem.

Send Christmas Cards

Instead of sending broadsides in each other’s direction, let’s send Christmas cards to each other. If you start sharing with the opposition, it’ll soon reciprocate.

I’m not advocating that all open-source CMS communities strive for the same goals, sitting around a campfire singing Kumbaya and having conversations along the lines of:

“You’re the best.�

“No, you’re the best.�

I am advocating that we respect the strengths of each other’s non-preferred CMS and help improve its weaknesses. Sitting around a campfire is strictly optional.

(al)


© Peter Wilson for Smashing Magazine, 2011.


The Developer’s Guide To Conflict-Free JavaScript And CSS In WordPress





 



 


sm-wp-css-js

Imagine you’re playing the latest hash-tag game on Twitter when you see this friendly tweet:

You might want to check your #WP site. It includes two copies of jQuery. Nothing’s broken, but loading time will be slower.

You check your source code, and sure enough you see this:

<script src="/wp-includes/js/jquery/jquery.js?ver=1.6.1" type="text/javascript"></script>
<script src="/wp-content/plugins/some-plugin/jquery.js"></script>

What Went Wrong?

The first copy of jQuery is included the WordPress way, while some-plugin includes jQuery as you would on a static HTML page.

A number of JavaScript frameworks are included in WordPress by default, including:

  • Scriptaculous,
  • jQuery (running in noConflict mode),
  • the jQuery UI core and selected widgets,
  • Prototype.

A complete list can be found in the Codex. On the same page are instructions for using jQuery in noConflict mode.

Avoiding the Problem

WordPress includes these libraries so that plugin and theme authors can avoid this problem by using the wp_register_script and wp_enqueue_script PHP functions to include JavaScript in the HTML.

Registering a file alone doesn’t do anything to the output of your HTML; it only adds the file to WordPress’s list of known scripts. As you’ll see in the next section, we register files early on in a theme or plugin where we can keep track of versioning information.

To output the file to the HTML, you need to enqueue the file. Once you’ve done this, WordPress will add the required script tag to the header or footer of the outputted page. More details are provided later in this article.

Registering a file requires more complex code than enqueueing the files; so, quickly parsing the file is harder when you’re reviewing your code. Enqueueing the file is far simpler, and you can easily parse how the HTML is being affected.

For these techniques to work, the theme’s header.php file must include the line <?php wp_head(); ?> just before the </head> tag, and the footer.php file must include the line <?php wp_footer(); ?> just before the </body> tag.

Registering JavaScript

Before registering your JavaScript, you’ll need to decide on a few additional items:

  • the file’s handle (i.e. the name by which WordPress will know the file);
  • other scripts that the file depends on (jQuery, for example);
  • the version number (optional);
  • where the file will appear in the HTML (the header or footer).

This article refers to building a theme, but the tips apply equally to building a plugin.

Examples

We’ll use two JavaScript files to illustrate the power of the functions:

The first is base.js, which is a toolkit of functions used in our example website.

function makeRed(selector){
  var $ = jQuery; //enable $ alias within this scope
  $(function(){
    $(selector).css('color','red');
  });
}

The base.js file relies on jQuery, so jQuery can be considered a dependency.

This is the first version of the file, version 1.0.0, and there is no reason to run this file in the HTML header.

The second file, custom.js, is used to add the JavaScript goodness to our website.

makeRed('*');

This custom.js file calls a function in base.js, so base.js is a dependency.

Like base.js, custom.js is version 1.0.0 and can be run in the HTML footer.

The custom.js file also indirectly relies on jQuery. But in this case, base.js could be edited to be self-contained or to rely on another framework. There is no need for jQuery to be listed as a dependency of custom.js.

It’s now simply a matter of registering your JavaScript using the function wp_register_script. This takes the following arguments:

  • $handle
    A string
  • $source
    A string
  • $dependancies
    An array (optional)
  • $version
    A string (optional)
  • $in_footer
    True/false (optional, default is false)

When registering scripts, it is best to use the init hook and to register them all at once.

To register the scripts in our example, add the following to the theme’s functions.php file:

function mytheme_register_scripts() {
  //base.js – dependent on jQuery
  wp_register_script(
    'theme-base', //handle
    '/wp-content/themes/my-theme/base.js', //source
    array('jquery'), //dependencies
    '1.0.0', //version
    true //run in footer
  ); 

  //custom.js – dependent on base.js
  wp_register_script(
    'theme-custom',
    '/wp-content/themes/my-theme/custom.js',
    array('theme-base'),
    '1.0.0',
    true
  );
}
add_action('init', 'mytheme_register_scripts');

There is no need to register jQuery, because WordPress already has. Re-registering it could lead to problems.

You Have Achieved Nothing!

All of this registering JavaScript files the WordPress way has, so far, achieved nothing. Nothing will be outputted to your HTML files.

To get WordPress to output the relevant HTML, we need to enqueue our files. Unlike the relatively long-winded commands required to register the functions, this is a very simple process.

Outputting the JavaScript HTML

Adding the <script> tags to your HTML is done with the wp_enqueue_script function. Once a script is registered, it takes one argument, the file’s handle.

Adding JavaScript to the HTML is done in the wp_print_scripts hook with the following code:

function mytheme_enqueue_scripts(){
  if (!is_admin()):
    wp_enqueue_script('theme-custom'); //custom.js
  endif; //!is_admin
}
add_action('wp_print_scripts', 'mytheme_enqueue_scripts');

Of our two registered JavaScript files (base.js and custom.js), only the second adds JavaScript functionality to the website. Without the second file, there is no need to add the first.

Having enqueued custom.js for output to the HTML, WordPress will figure out that it depends on base.js being present and that base.js, in turn, requires jQuery. The resulting HTML is:

<script src="/wp-includes/js/jquery/jquery.js?ver=1.6.1" type="text/javascript"></script>
<script src="/wp-content/themes/my-theme/base.js?ver=1.0.0" type="text/javascript"></script>
<script src="/wp-content/themes/my-theme/custom.js?ver=1.0.0" type="text/javascript"></script>

Registering Style Sheets

Both of the functions for adding JavaScript to our HTML have sister PHP functions for adding style sheets to the HTML: wp_register_style and wp_enqueue_style.

As with the JavaScript example, we’ll use a couple of CSS files throughout this article, employing the mobile-first methodology for responsive Web design.

The mobile.css file is the CSS for building the mobile version of the website. It has no dependencies.

The desktop.css file is the CSS that is loaded for desktop devices only. The desktop version builds on the mobile version, so mobile.css is a dependency.

Once you’ve decided on version numbers, dependencies and media types, it’s time to register your style sheets using the wp_register_style function. This function takes the following arguments:

  • $handle
    A string
  • $source
    A string
  • $dependancies
    An array (optional, default is none)
  • $version
    A string (optional, the default is the current WordPress version number)
  • $media_type
    A string (optional, the default is all)

Again, registering your style sheets using the init action is best.

To your theme’s functions.php, you would add this:

function mytheme_register_styles(){
  //mobile.css for all devices
  wp_register_style(
    'theme-mobile', //handle
    '/wp-content/themes/my-theme/mobile.css', //source
    null, //no dependencies
    '1.0.0' //version
  ); 

  //desktop.css for big-screen browsers
  wp_register_style(
    'theme-desktop',
    '/wp-content/themes/my-theme/desktop.css',
    array('theme-mobile'),
    '1.0.0',
    'only screen and (min-width : 960px)' //media type
  ); 

  /* *keep reading* */
}
add_action('init', 'mytheme_register_styles');

We have used CSS3 media queries to prevent mobile browsers from parsing our desktop style sheet. But Internet Explorer versions 8 and below do not understand CSS3 media queries and so will not parse the desktop CSS either.

IE8 is only two years old, so we should support its users with conditional comments.

Conditional Comments

When registering CSS using the register and enqueue functions, conditional comments are a little more complex. WordPress uses the object $wp_styles to store registered style sheets.

To wrap your file in conditional comments, add extra information to this object.

For Internet Explorer 8 and below, excluding mobile IE, we need to register another copy of our desktop style sheet (using the media type all) and wrap it in conditional comments.

In the code sample above, /* *keep reading* */ would be replaced with the following:

global $wp_styles;
wp_register_style(
  'theme-desktop-ie',
  '/wp-content/themes/my-theme/desktop.css',
  array('theme-mobile'),
  '1.0.0'
); 

$wp_styles->add_data(
  'theme-desktop-ie', //handle
  'conditional',  //is a conditional comment
  '!(IEMobile)&(lte IE 8)' //the conditional comment
);

Unfortunately, there is no equivalent for wrapping JavaScript files in conditional comments, presumably due to the concatenation of JavaScript in the admin section.

If you need to wrap a JavaScript file in conditional comments, you will need to add it to header.php or footer.php in the theme. Alternatively, you could use the wp_head or wp_footer hooks.

Outputting The Style Sheet HTML

Outputting the style sheet HTML is very similar to outputting the JavaScript HTML. We use the enqueue function and run it on the wp_print_styles hook.

In our example, we could get away with telling WordPress to queue only the style sheets that have the handles theme-desktop and theme-desktop-ie. WordPress would then output the mobile/all media version.

However, both style sheets apply styles to the website beyond a basic reset: mobile.css builds the website for mobile phones, and desktop.css builds on top of that. If it does something and I’ve registered it, then I should enqueue it. It helps to keep track of what’s going on.

Here is the code to output the CSS to the HTML:

function mytheme_enqueue_styles(){
  if (!is_admin()):
    wp_enqueue_style('theme-mobile'); //mobile.css
    wp_enqueue_style('theme-desktop'); //desktop.css
    wp_enqueue_style('theme-desktop-ie'); //desktop.css lte ie8
  endif; //!is_admin
}
add_action('wp_print_styles', 'mytheme_enqueue_styles');

What’s The Point?

You may be wondering what the point is of going through all of this extra effort when we could just output our JavaScript and style sheets in the theme’s header.php or using the wp_head hook.

In the case of CSS in a standalone theme, it’s a valid point. It’s extra work without much of a payoff.

But with JavaScript, it helps to prevent clashes between plugins and themes when each uses a different version of a JavaScript framework. It also makes page-loading times as fast as possible by avoiding file duplication.

WordPress Frameworks

This group of functions can be most helpful when using a framework for theming. In my agency, Soupgiant, we’ve built a framework to speed up our production of websites.

As with most agencies, we have internal conventions for naming JavaScript and CSS files.

When we create a bespoke WordPress theme for a client, we develop it as a child theme of our framework. In the framework itself, we register a number of JavaScript and CSS files in accordance with our naming convention.

In the child theme, we then simply enqueue files to output the HTML.

function clienttheme_enqueue_css() {
  if (!is_admin()):
    wp_enqueue_style('theme-mobile');
    wp_enqueue_style('theme-desktop');
    wp_enqueue_style('theme-desktop-ie');
  endif; //!is_admin
}
add_action('wp_print_styles', 'clienttheme_enqueue_css'); 

function clienttheme_enqueue_js() {
  if (!is_admin()):
    wp_enqueue_script('theme-custom');
  endif; //!is_admin
}
add_action('wp_print_scripts', 'clienttheme_enqueue_js');

Adding CSS and JavaScript to our themes the WordPress way enables us to keep track of exactly what’s going on at a glance.

A Slight Limitation

If you use a JavaScript framework in your theme or plugin, then you’re stuck with the version that ships with the current version of WordPress, which sometimes falls a version or two behind the latest official release of the framework. (Upgrading to a newer version of the framework is technically possible, but this could cause problems with other themes or plugins that expect the version that ships with WordPress, so I’ve omitted this information from this article.)

While this prevents you from using any new features of the framework that were added after the version included in WordPress, the advantage is that all theme and plugin authors know which version of the framework to expect.

A Single Point Of Registration

Register your styles and scripts in a single block of code, so that when you update a file, you will be able to go back and update the version number easily.

If you use different code in different parts of the website, you can wrap the logic around the enqueue scripts.

If, say, your archive pages use different JavaScript than the rest of the website, then you might register three files:

  • base JavaScript (registered as theme-base),
  • archive JavaScript (registered as theme-archive),
  • general JavaScript (registered as theme-general).

Again, the base JavaScript adds nothing to the website. Rather, it is a group of default functions that the other two files rely on. You could then enqueue the files using the following code:

function mytheme_enqueue_js(){
  if (is_archive()) {
    wp_enqueue_script('theme-archive');
  }
  elseif (!is_admin()) {
    wp_enqueue_script('theme-general');
  }
}
add_action('wp_print_scripts', 'mytheme_enqueue_js');

Using The Google AJAX CDN

While using JavaScript the WordPress way will save you the problem of common libraries conflicting with each other, you might prefer to serve these libraries from Google’s server rather than your own.

Using Jason Penny’s Use Google Libraries plugin is the easiest way to do this. The plugin automatically keeps jQuery in noConflict mode.

Putting It All Together

Once you’ve started registering and outputting your scripts and styles the WordPress way, you will find that managing these files becomes a series of logical steps:

  1. Registration to manage:
    • version numbers,
    • file dependencies,
    • media types for CSS,
    • code placement for JavaScript (header or footer);
  2. Enqueue/output files to HTML:
    • logic targeting output to specific WordPress pages,
    • WordPress automating dependencies.

Eliminating potential JavaScript conflicts from your WordPress theme or plugin frees you to get on with more important things, such as following up on sales leads or getting back to that hash-tag game that was so rudely interrupted.

(al)


© Peter Wilson for Smashing Magazine, 2011.


  •   
  • Copyright © 1996-2010 BlogmyQuery - BMQ. All rights reserved.
    iDream theme by Templates Next | Powered by WordPress