How NOT to Optimize your Drupal website for a iPhone or iPod

Don’t follow the advice posted below to “optimize” your site based on the user agent string.  The author suggests doing so in the page.tpl.php for your theme.  However, this means you can NEVER turn caching on for your site.  Also, the uses ereg functions to “detect” the device.  These functions are now deprecated by PHP, meaning they won’t be supported in the future.  The matches used are also very simple, and could be done much faster using the strpos or stripos functions. 

Optimise your Drupal website for a iPhone or iPod

If you need to detect the useragent,  you should probably use hook_init() or hook_boot() to do so, since they run regardless of the cache settings.  You’d also have to plan more thoroughly how to react to different devices –  if in fact you thinkg that’s a good solution.  A better approach would be to use pretty clean, flexible markup and use CSS media queries to provide device-specific stylesheets, as in Return of the Mobile Stylesheet.


Drupal: Invoke blocks and views from code

While Panels is great for controlling the layout of drupal pages, there are times when you can’t use the module to theme a page.  For uncached content, it does introduce some performance overhead into the drupal request change.  It can also be tedious to migrate changes from one environment to the other if you don’t export pages and variants to version control.

When you’re working in the stock theme layer, the following functions can come in handy.

Render a Block

   * Convenience function to easily call a block from a module
   * @param string module name
   * @param string delta
   * @return array block
  public function invoke_block($module, $delta) {
    if ('block' == $module) {
      global $theme_key;

      // the block_block view is pretty useless
      $block = db_fetch_object(db_query("SELECT b.*, bl.title, bl.*
                   FROM {boxes} b
                   INNER JOIN {blocks} bl ON (bl.module='block'
                       AND AND bl.theme='%s')
                   WHERE = %d", $theme_key, $delta));
     $data['subject'] = $block->title;
     $data['content'] = check_markup($block->body, $block->format, FALSE);

      if ('n/a' !== $data['content']) {
        return ($object) $data;
    } else {
      if (module_exists($module)) {
        $block =  module_invoke($module, 'block', 'view', $delta);
        $block['delta'] = $delta;
        $block['module'] = $module;
        return (object) $block;
      else {
        trigger_error("Module $module is not enabled.", E_USER_ERROR);

To show block with delta 1 defined by module foo:

$block = invoke_block('foo', 1);
$output = theme('block', $block);

Render a View

   * Convenience function to easily get the output of a view
   * A note about the display id, this is NOT the identifier
   * that you can set in the Views UI. To see the display id, look
   * at the theme information for the display.  For blocks it will
   * be something like block_1 or block_X where X is a number.
   * If the display_id doesn't match then Views automatically
   * uses the default display which can make themeing a pain.
   * modeled on view_embed_view().
   * @param string view name
   * @param string display name (see theme info for the display name)
   * @param array additional options
   * @return string
  static public function invoke_view($name, $display_id = 'default') {
    $args = func_get_args();
    array_shift($args); // remove $name

    if (count($args)) {
      array_shift($args); // remove $display_id

    $view = views_get_view($name);
    if (!$view) {
      trigger_error('Unknown view invoked: ' . $name, E_USER_WARNING);

    // validate the $display_id is valid
    // generate an error to prevent wasted time debugging.
    $defined = array_keys($view->display);

    if (!in_array($display_id, $defined)) {
      trigger_error('In view "' . $name . '" unknown display invoked "'
                  . $display_id . '"', E_USER_WARNING);

      // lets not render, chances are we don't want
      // the default display if we invoke a specific view

    // if a view is empty, dont return anything
    $r = $view->preview($display_id, $args);
    if (false !== strpos($r, '
‘)) { return $r; } else { return null; } }

To render display page_1 from view foo. You can even pass arguments to the view.

$output = invoke_view('foo', 'display1');
$output2 = invoke_view('foo', 'display1', 2010, 111); // with args!

Using Disqus for Comment

I'm testing using Disqus for commenting here.  Drupal's core comment module is adequate but Disqus provides a number of features, particluarly integration with Facebook and Twitter, that would require more work otherwise.  There's even a Disqus module that integrates the plugin as a block. While it doesn't integrate with Mollom, it does integrate with Akismet, but the latter is only free if you do not display advertisements.  I'm curious to see if it has ANY spam blocking built in.


Drupal deployment process example

I've become quite dependent on simple paper checklists for getting work done. As an aside, I've started looking at Google's integrated Tasks list and it looks like a nice, feature-light alternative to paper todo lists. Below is an example of the checklist I used when moving some new features to our staging server. It doesn't capture the how of doing each, some are SVN updates while other steps involve config changes via the UI. I've seen a lot of posts about how to track and automate some/all of this but the manual process works fine when you're managing a limited number of sites – less than 2 or 3.


Drupal: Automatically preprocess css/js for IE

Internet Explorer has a well know bug limiting the number of stylesheets that in can load, see here. This introduces an inconvenient hassle when it comes time to test CSS updates on a Drupal site. You have to remember to go to the performance page and enable CSS preprocessing to get the number of files down to something IE can handle.

Or, if you prefer and are lazy, you can have it done automatically for you. The following snippet will automatically preprocess both CSS and Javascript files if you browse a site using Internet Explorer. Drop it into the settings.php file on your development/staging/test sites and enjoy the convenience!

if (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE')) {
  $conf['preprocess_css'] = 1;
  $conf['preprocess_js'] = 1;

An Evernote module for Drupal

This sounds like a really useful module for synchronizing content from Evernote.  I've been using Evernote off and on, and have it on my phone as well.  Its a great tool for taking notes and having them available everywhere.  Pulling it all into Drupal parallels what I've been doing with my blog, by pulling in updates from other services, including Flickr, Delicious, and Twitter.

One issue I have with sharing information is the multiplicity of channels. How can I expect that someone will monitor my Flickr, Twitter, Facebook, Blip, Digg and Delicious accounts, plus several of my own media channels. And even though there is some integration between these services, as far as I know there's not a single application that provides a centralized method of distributing media, so managing the distribution of the data I want to share requires hooking into multiple interfaces. Even if there was a unified interface, there's then two places to manage that data – your local copy and the copy on the channel, and I feel like it should be possible to reduce this to one. Change it locally, and it changes on the service as well.

Using Evernote and Drupal as the ultimate blogging and social network broadcasting setup


Feature module example to bundle WYSIWYG Configuration

This is a concise example showing how you can use the Features module to bundle configurations in Drupal into a module.  It's great to see the Drupal community moving towards using code to capture, reuse, and deploy configuration settings.  It's been the biggest pain point in working with Drupal for me.

One of the things Drupal core does not do well at all is provide an easy way to switch on a WYSIWYG editor. There is no editor out of the box and setting it up requires some custom configuration of several Drupal core settings, installing and configuring several contributed modules, and also installing one or more external libraries, like the TinyMCE library.

WYSIWYG as a Feature 


Drupal going where ….

Yeah, I'm not going to use that line but Drupal is going to be used in the next Star Trek movie.  Pretty cool, but I wonder what took it so long?  I bet there's a huge overlap between the two communities.

It's no secret that many of us here at Palantir are fans of the science fiction genre, in particular the "Star Trek" franchise. Not only are we obsessed with Trek trivia and memorabilia, but every year for Halloween it's a tradition that at least one of us shows up at the office dressed up in Starfleet uniform.

Drupal for the Enterprise


Can you clone Drupal sites?

I was asked the following question today and this is my stab at a response. I’d appreciate and welcome any feedback if you’ve worked with a Drupal multi-site instance.

Can you clone sites? Or would you have to clone every part of a site and reassemble it for each site?

It depends on what you have to clone, but it tends to be more cloning parts of a site (encapsulated in modules and themes, in Drupal parlance) than cloning entire sites outright.

If you mean to easily add, update features and presentation, the way to go about it is through modules, themes+subthemes, and use of code versioning (I like subversion).

My assumption is that each sub site will be its own drupal instance. Drupal lets you share modules across themes through the use of its /sites directory, particularly /sites/all, anything in that folder is available to all sites. Updating modules/themes in that folder would make the updated code available on all sub sites once they run Drupal’s update command. For a more detailed explanation, see Setup of /sites directory for multi-site

That takes care of moving functionality and some theming changes. Its much trickier to move layout changes, although its possible. To do so, you can forego using some of Drupal’s configuration options (for example, to position blocks). Instead, alter the layout via themeing hooks done in PHP code. This makes it easy to store and track changes with code versioning, this is where subversion (svn) comes in. This means that layout changes affecting how blocks of content appear on the site, more often than not, have to be done my an experienced drupal developer but it saves you from manually having to make these changes via Drupal’s admin interface on every site that you manage.

I would say that using SVN has been the key to making this process mostly painless for me. It is easy to move changes through testing > staging > production environments. The ‘svn update’ command does the work and knows what file-level changes need to be made, including adding/removing files. Coupled with Drupal’s built-in update functions available in modules, and you have a predictable way to propagate changes.


I didn’t touch upon moving actual content from one site to another, since that requires a wholly different approach.


MLS Playoff Widget

Now that the MLS season is close to an end, the playoff picture will start to come into clearer view. Using the Embed Widget module for Drupal, I was able to take a block containing the standings as a single table and make it available as a widget that anyone can put on their own website. The hardest part was theming it to look halfway decent, because the module wants to use the Color API module to generate a color scheme automatically based on one color. I overrode that with a single theme preprocess function to get the exact colors I wanted.

You can get the code for the widget over at Behind the Badge.

Sounder at Heart has questions about how ties are broken, so I’ll have to give that another look to make sure its on the up-and-up.