Archive for the ‘Drupal’ Category

DrupalCon Sessions to help you manage your business

Colin Calnan | Friday, February 26th, 2010

DrupalCon San Francisco 2010 is just around the corner and Raised Eyebrow hopes to “own the podium”, sorry I couldn’t resist. Chris and I have been to 2 Drupalcon’s so far in our Drupal lifetime, and have decided it is time to give something back. We’ve come up with 2 Session Proposals that are overviews about how we used Drupal to create two killer applications for managing a small Web Business.

One stores all kinds of client information; FTP connection info., Drupal logins, client contact info., newsletter provider and vendor info. The other is an online training manual for our clients, enabling us to train them remotely, give them access to it wherever they can find a browser and reduces the need to print large binders that end up getting lost or in the landfill/recycling.

So if you’re interested in hearing more about these the please go cast your vote by following the links below:

Manage your Web Studio using Drupal
Using Drupal to train clients on how to use Drupal

The closing date for voting for Voting is March 1st, so get voting. See you in San Fran.

Using Drupal to deliver video

Colin Calnan | Tuesday, December 22nd, 2009

There are many ways to skin the cat when it comes to putting video on a Drupal site. I’ve tried and tested quite a few methods since my first introduction to Drupal 2 years ago. I’ve used Embedded Media Field as well as Video Filter but finally settled on the combination of FileField with JWPlayer or Flowplayer and in some cases the Media Mover Module for moving files to Amazon S3 storage. I’m going to use our recent launch of the CCPA website as a case study for how we currently handle video delivery. So let’s dissect this a little.

Uploading files

The video files need to be uploaded before we display them. This is best achieved using the wonderful Filefield Module. This is quite a simple yet powerful module developed/maintained by Lullabot, Nate Haug (quicksketch), whom I’ve had the pleasure of being trained by at one of their excellent Drupal Theming workshops. Once you install and enable the module you then add a new CCK field, of type “filefield”. In our case we have a content type called “Multimedia”. We add the field to this content type. You then need to configure the following:

1. Permitted upload file extensions

In most cases this is relatively straightforward, it’s just one file type. If you’re using JWPlayer or Flowplayer it will be FLV. Both these players are built to play Flash Video files (FLV). If you have Quicktime MOV’s or AVI’s that you want to upload then you’ll need to consider different options for playing video. For the purpose of this case study we’re just uploading FLV files.

2. File size restrictions

It’s very important that you set these, otherwise you may end up with users trying to upload 200MB videos, not a very good idea. I set this low as a learning feature for clients. Any reasonably long FLV file that is over 40MB is probably not optimized as well as it should be.

3. Path Settings

I like to keep all files that admin/editor users upload in a folder called uploads so that it’s easy to manage them later if they need to be exported etc.

File Field

Multimedia File Field Settings

Create a placeholder image

Most video players require some sort of poster/placeholder image to display before the video plays. In this case I created another FileField for the placeholder image. We’ll use that later on in conjunction with the ImageCache module to achieve our desired results.

Moving Files to Amazon S3

We’ve been using Amazon S3 for storing video files on quite a number of sites recently. One reason is that we were looking for a location off the webserver that could deliver the video, without impacting the performance of the server, so that in the event of a traffic spike the webserver wouldn’t fall over. We could also have used Amazon EC2 or another CDN service for this, however as most of our clients have a very regional (BC) audience. Most CDN’s have nodes in various locations across the US and Europe and this would have served no real improvement as the nearest cached version will always be in the same place for everyone.

So if they’re uploading the files directly to the Drupal site, how to the files get delivered from Amazon S3. That’s where the Media Mover module comes in. This module has many purposes, but for our needs it simply harvests all the files uploaded via the “Multimedia” content type and moves those files to Amazon S3 so that we can deliver them from there.

Download, install and enable the Media Mover module. You’ll also need an S3 account and will need to set that up via the module setting page. You then need to add a Configuration via https://www.yoursite.ca/admin/build/media_mover/add.

Media Mover has 4 actions which it performs on your files:

  • Harvest – Define/collect the files you want to perform actions on
  • Process – Perform certain actions on the files
  • Storage – Where to store files once the actions have been carried out
  • Complete – Final actions to perform on the files

So in this case we just want to harvest all Multimedia files and store them on Amazon S3.

So for clarification here Media Mover does NOT MOVE the files to Amazon S3, it simply COPIES them over to S3 and the original files remain on your server.

Media Mover Settings

Media Mover Settings

Delivering the moved Video files

So this is where the Drupal theming trickery comes in. Flowplayer and JWPlayer are both Flash based FLV video players than can be called using Javascript and that’s exactly what I do on this site. In plain english this is what happens:

  1. Output the placeholder image to screen as a link.
  2. Use Javascript so that when the user clicks on the image the video plays.
  3. Deliver the video from the file on Amazon S3 rather than the file on the webserver (Drupal site).

We need to modify three files to achive the above:

  • template.php
  • multimedia.js (a newly created JS file)
  • node-multimedia.tpl.php (a custom template file for all multimedia types)

template.php file

Setting up all the variables we’re going to need to use as well as making the javascript available

if($variables['field_file'][0]['view']) { //If there is a file and there is something to display...
  if ($variables['field_aspect_ratio'][0]['value']) { //Aspect ratio handling
    $variables['aspect_ratio'] = $variables['field_aspect_ratio'][0]['value'];
  } else {
  $variables['aspect_ratio'] = 'normal';
  }
  $variables['multimedia_type'] = 'video'; //Set the type of multimedia - we also have audio and interactive...
  custom_theme_get_media_mover_files($variables['field_file'][0], $variables['media_mover'][3]); //Set the filepath to the media moved filepath...
  drupal_add_js(array('videoplayerpath' => path_to_theme() .'/scripts/plugins/flowplayer/flowplayer-3.1.1.swf'), 'setting'); //Set a JS variable to retrieve later...
  drupal_add_js(path_to_theme() .'/scripts/plugins/flowplayer/example/flowplayer-3.1.1.min.js', 'theme'); //Call the player...
  drupal_add_js(path_to_theme() .'/scripts/multimedia.js', 'theme');//Call the custom JQuery to handle creating the player...
}
 
/**
 * A function that takes a file object and a media_mover element array and set the file path to
 * its media moved path on Amazon S3 or wherever it moved to.
 *
 * It uses the unique file_id identifier to match file with media_mover file.
 *
 * $file = $variables['file_image'][0];
 * $media_mover = $variables['media_mover'][{id of media mover configuration}];
 *
 * @param 		&$file A Drupal file array (by reference)
 * @param 		$media_mover A media_mover file/element array
 */
function custom_theme_get_media_mover_files(&$file, $media_mover) {
  if(module_exists('media_mover_api') && $media_mover) { // If media mover is installed...
    foreach($media_mover as $media) { // Loop through each media_moved file...
      if($media['fid'] == $file['fid']) { // If they match (file id is a unique identifier...
        $file['filepath'] = $media['complete_file']; // Replace the attached file path with the media moved file path...
      }
    }
  }
} // custom_theme_get_media_mover_files()

Let me explain one thing in regards to line 9. I’ve created a custom function and I’m passing

$variables['media_mover'][3]

to my custom function. When you create a Media Mover configuration and map it to a CCK field, it creates an array in $variables to keep track of the Media Mover object. The array is called ‘media_mover’ and the number 3 in this case is the ID of the Media Mover configuration.

node-multimedia.tpl.php

Set up the template. Create a wrapper div with the placeholder image as the background image (this is run through imagecache) and display the play button as a link with the path set to the path of the Amazon S3 file. This link will also have an id attribute of ‘multimedia’. This is necessary as it allows us to attach the player, via Javascript, to this link.

<div id="containing-block">
<div id="video-wrapper" class="<?php print $aspect_ratio;?>">
<div>
     &lt; ?php print l('<img src="/'.path_to_theme().'/images/ccpa-button-play-large.png" alt="Play this video" />', $field_file[0]['filepath'], $options = array('html' => TRUE, 'attributes' => array('id' => 'multimedia', 'class' => $multimedia_type))); ?></div>
</div>
</div>

multimedia.js file

Hook the Flowplayer to the link, with id of ‘multimedia’, that we created in the template.

?View Code JAVASCRIPT
Drupal.behaviors.showMultimedia = function(context) {
  var interactive_path = $('#multimedia').attr('href'); /*Get the path to the video*/
  var interactive_image = $('#multimedia').css('background-image');	/*Get the path to the placeholder image*/
  interactive_image = interactive_image.slice(4,interactive_image.length-1);/*Tidying up the interactive image path*/
 
  if($('#multimedia').hasClass('video')) {/*If the link has a class of video*/
  $('#multimedia').flowplayer( /*Initialize the flowplayer and configure the controls*/
    Drupal.settings.basePath + Drupal.settings.videoplayerpath, /*Path to the player, gotten from temaplate.php*/
    {
      plugins: {
	controls: {
	  stop: true,
	  backgroundColor: '#efefef',
	  backgroundGradient: 'none',
	  borderRadius: '0px',
	  bufferColor: '#d2d6ab',
	  bufferGradient: 'none',
	  buttonColor: '#777777',
	  buttonOverColor: '#99a134',
	  durationColor: '#cccccc',
	  height: 25,
	  opacity: 1.0,
	  progressColor: '#99a134',
	  sliderColor: '#9999999',
	  sliderGradient: 'none',
	  timeBgColor: '#777777',
	  timeColor: '#ffffff',
	  tooltipColor: '#000000',
	  tooltipTextColor: '#ffffff',
	  volumeSliderColor: '#777777',
	  volumeSliderGradient: 'none'
	}
      }
    });
  }
};

I hope that was easy to follow. Now there’s one more thing to cover and that’s Aspect Ratio.

Aspect Ratio

The issue of aspect ratio is very important when figuring out how to display video. Not so recently YouTube switched all video display to the 16:9 ratio thus setting the stage for the proliferation of the widescreen aspect ratio across the web. So how do you allow the user to upload a video and choose it’s aspect ratio. I’m sure there are other ways to do this via Metadata etc, but for our needs on this site I used a CCK field. This is a simple CCK field set with three options:

  1. None (defaults to 4:3)
  2. Normal (4:3)
  3. Widescreen (16:9)
ccpa-aspect-ratio

Aspect Ratio Field Settings

We then check the value of this field in template.php above:

if ($variables['field_aspect_ratio'][0]['value']) { //Aspect ratio handling
    $variables['aspect_ratio'] = $variables['field_aspect_ratio'][0]['value'];
  } else {
  $variables['aspect_ratio'] = 'normal';
  }

and set a variable called ‘aspect_ratio” which we apply as a class to the div wrapping the video in the node-multimedia.tpl.php:

<div id="containing-block">
<div id="video-wrapper" class="<?php print $aspect_ratio;?>">
<div>
     < ?php print l('<img src="/'.path_to_theme().'/images/ccpa-button-play-large.png" alt="Play this video" />', $field_file[0]['filepath'], $options = array('html' => TRUE, 'attributes' => array('id' => 'multimedia', 'class' => $multimedia_type))); ?></div>
</div>
</div>

We have also created image cache presets for the placeholder images to account for both aspect ratios. These are named ‘multimedia_normal’ and ‘multimedia_widescreen’ and these have the appropriate dimensions associated with them:

ccpa-imagecache-presets

Image Cache Presets

So using the amazing article on A List Apart for creating intrinsic ratios for video we use CSS to resize the player based on the aspect ratio chosen by the user.

style.css file

/* -- Multimedia -- */
#containing-block {
  width: 100%;
}
 
#video-wrapper {
  position: relative;
  padding-top: 25px;
  height: 0;
}
 
  #video-wrapper div,
  #video-wrapper embed,
  #video-wrapper object {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
  }
 
  #video-wrapper.normal {
    padding-bottom: 75%;
  }
 
  #video-wrapper.widescreen {
    padding-bottom: 56.25%;
  }
 
  * html #video-wrapper {
    margin-bottom: 45px;
    margin-bot\tom: 0;
  }
 
#video-wrapper #multimedia.audio {
  display:block;
  height:100%;
  margin:1em 0 0 0;
  text-align: center;
  width:100%;
}
 
#video-wrapper #multimedia {
  display:block;
}
 
  #video-wrapper.normal #multimedia img {
    /*margin:118.5px 0 0;*/
    margin:32% 42%;
  }
 
  #video-wrapper.widescreen #multimedia img {
    margin:22% 41%;
  }

And the end result looks something like this http://www.policyalternatives.ca/multimedia/matthew-poverty-and-looking-after-each-other-tough-times. They haven’t added any widescreen content yet, just testing content.

So what are the advantages of doing things this way?

  1. You can easily use any player to play your flash files (all you need to do  is change the path to your player and a few configuration params in multimedia.js)
  2. All your video content is hosted on and delivered from Amazon S3. But there is also a copy on your local server in the event of something going wrong on Amazon S3
  3. You don’t have to worry about your video looking skewed due to aspect ratio problems
  4. You can add many other apsect ratios pretty quickly
  5. The video file is still downloadable when javascript is not present or disabled

I’d love to get feedback on how other do this, please leave a comment or send me an email and let me know how you deliver Video content on your site.

Launched: PolicyAlternatives.ca

Lauren Bacon | Monday, December 14th, 2009

Redesigned CCPA home pageWe are very proud to unveil a project we’ve been working on for several months now: a redesign of policyalternatives.ca, the online home of the Canadian Centre for Policy Alternatives. Canada’s leading progressive research institute, the CCPA is a prolific publisher of reports and studies, books, articles, commentary and fact sheets on issues ranging from income equality to environmental policy, privatization of public services, and beyond.

They are highly respected, but like many organizations working towards policy change, they don’t always reach as broad an audience as they might hope; not many people have the time and inclination to read an in-depth research report, so in recent years they have been creating more bite-sized, easy-to-digest content in both written and multimedia formats. As the range of content has grown, though, so has the need to cross-reference related materials — so the CCPA’s website needed to both invite visitors to browse through an extensive library in an intuitive and approachable way, but also allow people seeking more in-depth content to locate related materials quickly and easily. (One of our developers describes the complex interrelationships between the CCPA’s publications as “like Facebook for documents.”)

Their five year-old website, although rich in content and highly trafficked, didn’t offer visitors any way to easily share the CCPA’s content with their social networks, whether through Facebook or Twitter, or even through their own publications, blogs or presentations. Exchange of ideas is the CCPA’s raison d’etre, so it stands to reason that above and beyond extending the website’s “share this” features, the organization would benefit from encouraging online visitors to use and share its content — and they do, using a Creative Commons license.

This project was a complex one on several fronts, as we wrestled with improving navigation through the site (both via menus and site links as well as with improved search tools); updating the site’s look and feel; and migrating the extensive site content (along with the aforementioned relationships between content items) from a commercial CMS platform into Drupal.

Oh, and we also set up a shopping cart (for books, memberships, donations and journal subscriptions).

There’s a real sense of accomplishment here at Raised Eyebrow when we look at the final result, but of course on the web, there’s no such thing as a final edit. Our best hope, in fact, is that we’ve helped to create a solid platform upon which the CCPA can continue to build and extend over the coming years. So while right now we are celebrating the grand opening, the real fun in some ways is still to come. I’m sure we’ll see the CCPA continue to play a leadership role when it comes to presenting research online in accessible and innovative ways.

Ubercart & Content Type machine names

Colin Calnan | Wednesday, November 18th, 2009

If you use Ubercart on your Drupal website you may be familiar with product classes. Ubercart has, by default, a product content type, however say you have other content types on your site that you want to sell, you can create product classes from those – http://www.ubercart.org/docs/user/3341/understanding_product_classes.

This works nicely until that moment when you want to rename your content type machine name.. e.g from “contenttype” to “content_type”

I did that recently thinking everything would be hunky dory once I made the change, the results were not so nice. So to help prevent this from happening to anyone else, here’s a simple rule to follow before making changes to your content type machine name.

Make sure you remove your content type as a product class before changing it’s machine name.

It’s that easy, simply disassociate your content type from Ubercart. The page to do this can be a little scary (www.yoursite.com/admin/store/products/classes), but just click the delete link on the class you want to disassociate and you’ll get a “Are you sure you want to do this message”, go ahead, it won’t delete your nodes, it just removes a flag that tells Ubercart they’re products. Also, if you’re worried about losing your product data, like SKU, Price, Shipping info etc, in my case it retained all product info when I re-instated it. Please backup your data before doing this, I cannot be responsible for any problems this causes on your site. Now, go to your content type, change the machine name.

Oh, and don’t forget to double check all your views are still working, you may need to edit them to ensure they’ve picked up the new content type machine name. I guess this is a good lesson to remind you to give your content types a machine name that you will not want change later.

Drupal vs WordPress: Which one is right for you?

Lauren Bacon | Monday, November 9th, 2009

Here at Raised Eyebrow, while we have experimented with dozens of Content Management Systems (CMS’s), these days we mostly build websites using either Drupal or WordPress.

Why these two CMS’s, of the thousands of content management systems available? Both CMS’s share several key qualities:

  • They’re open-source projects. Over the past few years, Raised Eyebrow has increasingly turned to open-source software options because of the flexibility and security they offer.
  • Both WordPress and Drupal boast huge communities of developers and widespread adoption; those are important things to look at when working with open-source software, because we like to see a critical mass of people who are invested in making the software better, both on the coding side and from the end-user perspective.
  • They offer a rich and robust feature set, both within the core CMS and in terms of the plugins (or in Drupal parlance, modules) that are available — plugins and modules help us extend the base functionality of your site with features such as photo galleries, event calendars, interactive forms, shopping carts, and so on.
  • Perhaps the most compelling reason we’ve chosen these two, though, is that our clients like using them. The interfaces are user-friendly; the software is reliable; and the basic functions that our clients need (from uploading a file attachment to creating new pages and blog posts) are available, easy to use, and intuitive. (I won’t claim that there aren’t things I wouldn’t change if I could wave a magic wand — but of the CMS’s we’ve tested, these two are far and away at the top of the heap.)

So how do you choose which one is appropriate for your project? Drupal & WordPress are very different systems, with different strengths and weaknesses. Here’s a quick overview of some of the distinguishing features of each CMS.

Drupal

Drupal welcome screen

Drupal welcome screen

Community focus: Drupal has extensive functionality for allowing people to interact with one another via your website. Creating accounts; logging in to access special content — or create their own; connecting with one another — all of these are possible with a Drupal site, so if your short- or long-range plans include turning your website into a social hub for your visitors, Drupal is a better choice.

Editing a page in Drupal

Editing a page in Drupal

Editing is seamless: In Drupal, if you have administrative privileges, and you are logged in, you can edit your content simply by navigating to the page you want to update, and clicking an unobtrusive “Edit” tab. Many people find this a particularly intuitive approach to site editing. (Not only that, but Drupal is so profoundly customizable that if you want to, you can create custom themes for different areas of your site — so your back-end could look totally different from your front-end, should you feel so inspired.)

Specialized content types in Drupal

Specialized content types in Drupal

Built for dynamic content: Drupal has some very clever ways of cross-categorizing content, so if you have the kind of website where you want content to appear in multiple places based on various categories you assign to it, Drupal may be just right for you. And it’s often the better choice for managing complex kinds of content, where a simple 2-field “Title” and “Body” editing screen won’t suffice.

Highly modular & extensible: The underlying architecture of Drupal is quite flexible, and the CMS can be adapted for a wide variety of purposes. Drupal is like a Swiss Army knife or a food processor: it is many tools in one, and you can choose to use it for one task or several. WordPress is much more specific in its function: it does a handful of things and does them very well, but it isn’t the right tool for every job. (On the other hand, if you need a simple site, Drupal may be overkill, and you could spend a lot of time turning off the features you don’t want.)

Greater investment required up front: Drupal’s out-of-the-box configuration is somewhat limiting, and most people prefer to customize it pretty heavily. This requires not only a solid understanding of HTML and CSS, but also of PHP and of Drupal’s underlying architecture, which has a fairly steep learning curve. As a result, Drupal sites tend to cost more to set up, though the initial investment is well worth it if you plan to extend your site’s functionality to take advantage of Drupal’s flexibility.

WordPress

WordPress's editing screen looks quite different from your site's front-end. This is the screen I see while editing the blog post you're reading.

WordPress's editing screen looks quite different from your site's front-end. This is the screen I see while editing the blog post you're reading.

Built for blogging: I personally find Drupal’s blogging capabilities somewhat limited — for example, creating blog category lists, tag clouds and date-based archives is rather onerous in Drupal, whereas in WordPress they take a matter of minutes to set up. WordPress was first developed as blogging software, and it shows: its blogging features are well thought-through and have been polished by years of improvements.

WordPress's Media Library gives you easy access to all the files you've uploaded to your site: images, PDFs, media files, etc.

WordPress's Media Library gives you easy access to all the files you've uploaded to your site: images, PDFs, media files, etc.

Easy-to-use file management: WordPress’s “Media Library” feature allows you to browse through all the files you’ve uploaded to your site — images, PDFs, multimedia files, whatever they might be — in a clean, attractive & easy-to-use interface. It makes managing your files and inserting them into your blog posts and site pages a much easier task.

Smart spam filtering: Because of WordPress’s blogging focus, the developers had to pay close attention to managing spam. (Blogs attract a lot of spam via comments and pingbacks.) WordPress comes bundled with spam-filtering software that does a remarkably good job — and moreover, its comment-management features are well thought-out and simple to use.

The WordPress Dashboard gives you an overview of activity on your blog or website.

The WordPress Dashboard gives you an overview of activity on your blog or website.

Quick to install and configure: WordPress is famous for its 5-minute install, and it really does live up to its name. Although that doesn’t mean you’ll have a fully-functioning website in 5 minutes, it works well “out of the box” for most simple sites & blogs. As a result it is often less costly then Drupal to set up.

Easy to theme: Both Drupal and WordPress have a great deal of flexibility with regard to visual design — you can make a site built in either CMS look beautiful via either free templates or by applying your own custom design. However, theming a Drupal site is a much bigger task than theming a WordPress site, unless you are simply going to download a free theme and slap it on your site. If you want to be able to tweak design details, in our experience, that’s a much faster job in WordPress.

If you aren’t planning to use WordPress’s blogging features, navigating through the CMS can be a little confusing, because blog posts are the primary focus in the menus, and page editing is less prominent. In this sense, its focus on blogging can be a weakness as well as a strength.

WordPress keeps your site’s back-end (that’s the area where you create & edit content) totally separate from the front-end (the part your visitors see). Some people (like yours truly) prefer this approach, where content is more or less divorced from presentation, whereas others prefer Drupal’s integrated editing options. In my experience, this is a highly subjective preference, and it’s worth trying both to see which feels better to you.

In Summary

As with most decisions about your website, you are well advised to consider the long-range goals of your site before selecting the CMS you’re going to use. If you foresee a highly dynamic website with complex content types, and/or community features such as member login areas, multiple blogs, or user-created content, Drupal may be better suited to the job. On the other hand, if your content management needs are relatively straightforward, or if you intend to have a blog-centered website, WordPress could be just right for you.

Still have questions? Please feel free to leave them in the comments & we’ll do our best to answer them.

Drupal at Whitehouse.gov

Emira Mears | Friday, October 30th, 2009

There’s a great piece on the Drupal and the current White House website in today’s New York Times. Worth a read for Drupal users/fans or Open Source keeners.

Contribute to the Community? Yes You Can!

Colin Calnan | Thursday, October 22nd, 2009

I’d been a little skeptical about the idea that anyone can contribute to the Open Source community by giving a little help now and again. This skepticism came from the flaming given for asking ‘newbie’ questions, asking a question in the wrong room or from suffering the raging ego of a well seasoned and highly adored contributor. Today however, I feel much more positive about my ability to give back to Drupal and the Open Source community, and it all came from a simple (or maybe not so simple) thank you. Here’s the story:

Yesterday afternoon, while tearing my hair out over some tricky views problem that I could not find a solution to, I logged in to IRC, which I don’t usually do, to see if I could get some help.

In the #drupal room I asked my question and as usual didn’t receive any replies (which is why I don’t usually log in). It’s a bit of a difficult VIEWS problem and those usually don’t get answered quickly in IRC. While waiting for a response I noticed a question that was similar to mine but not as complex. I took some time (2 minutes) to review the code and I was able to speculate on what the problem was. I posted a proposed solution and it worked. I didn’t really think much of it until later on when I received an email via drupal.org from the person I helped asking me for my e-mail address. I sent it on and this morning I awoke to the email below. Until now I had been wary of devoting my time to hanging around in the IRC channels. This experience has changed my feelings on this quite a bit and I hope to spend a little more of my time in there, when I have it, helping others. In this case, it definitely did pay to help others, but the thank you email was more than enough, it made my day, my week, my month and maybe even my year :) Here’s to contributing more to the community. It doesn’t take much, and just a simple thank you for the help, when given, makes all the difference.

Hi Colin,

Thanks. I am in Fort Smith, NT just on the Alberta/NWT border directly north of Edmonton.
I am a Fire Scientist, I model Wildfire on the landscape. Yesterday I was completing the Drupal Integration part of a multi-year government project, most of us running on little or no sleep and less patience. I CVS updated VIEWS and it became way more strict about the PHP code and broke my drupal. I had been begging for assistance in different irc drupal chats for about 45 mintues when you came along. It really was like saving our team, when the view worked, the entire fire science team cheered. We just wanted to say a real heartfelt thanks.
I am sending you, $20 via email, its a small gesture, as our team knows that $20 will buy a friday case of beer anywhere in canada except north of Norman Wells NWT ;-) Perhaps you can claim to be the first in your office to have been mailed a case of beer by the drupal community – LOL

The Big Reveal: Recent Launches at Raised Eyebrow

Lauren Bacon | Tuesday, October 6th, 2009

The past few weeks have been quiet here on our blog, and as often happens, that silence has been an indicator of just how busy things have been here at Raised Eyebrow headquarters. We’ve been putting the final touches on some exciting new websites that we’re very proud to share with the world. Two major redesigns have just launched – one for a wonderful nonprofit group here in British Columbia and the other for a foundation that’s changing the face of lung cancer research across the United States.

Deaf Children's Society of BC - home pageThe Deaf Children’s Society of BC offers programs, support and resources for families of young children with hearing challenges that range from parent groups for new parents of deaf or hard of hearing infants, preschool and summer programs for young kids, to a library and bookstore where families can access print resources. Their small staff includes several speech-language pathologists and sign language instructors, and they came to us looking to extend the reach of the services they are able to offer through the web. We helped them extend their resources online through the use of instructional videos for new parents to learn sign language that can then be used with their children as they develop language and reading skills.

The new website is a clean but cheerful home for their fun, informative, instructional videos as well as detailed information about the society’s programs and services. Parents can learn sign language in child-sized portions – with signs grouped in themes like animals, colours, numbers, and of course the alphabet, which they can then use to help their young children with developing language skills.

Uniting Against Lung Cancer home pageUniting Against Lung Cancer is a nonprofit foundation that formed in 2001 as Joan’s Legacy, in honour of 47 year-old New Yorker Joan Scarangello McNeive, who never smoked, but died after a valiant battle with lung cancer. Her family and friends rallied and established the foundation to fund research and raise awareness about the disease; over the years it has attracted partnerships with other family foundations, and now Uniting Against Lung Cancer serves as a connector for groups across the United States who are raising awareness and funds. To date, the foundation and its partners have awarded over $6 million in direct research grants in 20 different states.

We worked with Uniting’s staff and board to develop and implement a transition strategy for their online presence, as they re-branded from Joan’s Legacy to Uniting Against Lung Cancer. The new website better reflects the scope and reach of the foundation’s work, and showcases their mission, partners, and events in a design that evokes a deep breath of fresh air on a sunny day.

On a technical note: Both sites run on Drupal’s open-source CMS platform, which gives them a strong foundation on which to develop future site enhancements – something that’s increasingly top-of-mind for our clients. We’re finding that more of our clients are looking at an iterative approach to making site adjustments, and even after a major redesign such as these ones, there are often “wish list” items that we can add to a site over time. We find Drupal provides a robust framework that allows this iterative approach to work well.

Drupal Six Raised Eyebrow Online Help Manual Really Helps!

Anna | Friday, July 24th, 2009

As of Tuesday, with each new Drupal 6 website we build, we will be providing access to an online manual. Like our paper manual, the online manual describes the basic functions of Drupal in easy to understand language and has customized client-specific content. But the new format also has many new benefits.

Book Module

The online manual uses the Drupal book module, which is a great because the book module lends to organizing things… like a book. The book module automatically creates a listing of the child entries, like a table of contents. You can order the child pages in any way you choose. I also like the book module because is has a printer-friendly version of each page. It does a really nice job of stripping out the unnecessary stuff and optimizing the content for printing, so you don’t get pages broken in half or extra white pages when you print.

Information in a New Dimension

What I loved about moving from a Word document to an online manual is how easily you can cross-reference. With the old manual, you could footnote or reference other pages, but ultimately it had to be a very important reference to disrupt the reader in this way. Now with the online manual, text and images can be linked to other sections of the manual. So if I think a word sounds a little jargon-like, but is still useful, I can add it to the glossary and link the word to its definition. This is great, because it allows us to introduce some language that we might have otherwise shied away from using. This is beneficial in the long run because it helps us develop a more accurate shared language with our clients to talk about their websites.

Keeping the Manual Up to Date

The best thing about the new manual is that if I discover an inaccuracy or a better explain something, I can simply log in and edit the site. Clients instantly have access to the up to date manual. Also, if a client adds a new feature, I can simply add a new page to their online manual and they will instantly have access to the file. This saves sending updated .pdfs and having many trees wasted as manuals are reprinted.

Works Great for Remote Training

We’ve also been experimenting with online meetings for trainings with remote clients and the new manual is great for this. I have three online trainings this summer!

Have You Ever Searched for Drupal Help?

Uhg! Lots of the information available online is too techie for words! Seriously, try Googling “Help Logging Into Drupal” and you’ll see that you get the weirdest stuff! Our help manual covers all the basic functions of editing and creating content for your site. Clients can access it from anywhere and it is constantly growing and evolving. There is a text-based search, allowing you to search the entire contents of your manual instantly, with a listing view of relevant results. It’s a help manual that really helps!

_______________________________

Thanks to the whole team at RE who helped conceive of, build, create content for, and test the Raised Eyebrow Help Website!

Generic caching function for Drupal 6

Chris | Wednesday, June 24th, 2009

One of the pieces of the Drupal performance puzzle is caching. After weeding out a couple of very demanding sql queries in a busy Drupal site, we decided to make more use of Drupal’s caching mechanisms to cut down some of the database load.

Back in 2007, Lullabot’s Jeff Eaton wrote a blog post about caching including a sample implementation for a caching function. This function was almost exactly what we wanted, but we wanted something more generic—a function that we could use in multiple places in the same module or template.php file without modification.

But in order to use one function to populate and retrieve different cache entries, we needed a way to call an arbitrary function from inside the caching function. Fortunately, PHP supports variable functions. This meant that we could pass the name and parameters of an arbitrary function to our caching function and, when necessary, populate the cache with the output from that function (alternatively, we could also have used the call_user_func() function or, like Drupal’s own theme() function, the func_get_args() function).

/**
 * This function returns the cached value for a given cache entry. If the entry does not exist, or if
 * the entry is empty, this function executes the passed function, caches the result and returns it.
 *
 * RENAME THIS FUNCTION FOR USE IN YOUR THEME OR MODULE'S NAMESPACE!
 *
 * @param string $cache_entry The full name of the cache entry--remember the namespace!
 * @param array $function An array with two keys:
 *			string $function['name'] The name of the function
 *			string $function['parameters'] A comma-separated list of parameters
 * @param string $table The name of the cache table to use (see cache_set())
 * @param CACHE_PERMANENT|CACHE_TEMPORARY|unix timestamp $expire Expiry period for this cache entry
 * @param boolean $reset If true, regenerate cache entry; if false, check first
 * @return string|array|object $cache_data The contents of the relevant row in the cache table
 * @see http://api.drupal.org/api/function/cache_set/6
 * @see http://api.drupal.org/api/function/cache_get/6
 */
function theme_name_theme_cache($cache_entry, $function, $table = 'cache', $expire = CACHE_PERMANENT, $reset = FALSE) {
  static $cache_data; // Establish the $cache_data variable for this page load...
  if(!isset($cache_data) || $reset) { // If the variable is not set, or if a cache reset has been requested...
  	if(!$reset &amp;&amp; ($cache = cache_get($cache_entry)) &amp;&amp; !empty($cache-&gt;data)) { // If $cache-&gt;data is set and reset not requested...
  		$cache_data = $cache-&gt;data; // Store the current value of $cache-&gt;data...
  	} else { // If we need to (re) generate the cache...
  		$function_name = $function['name']; // Get the function name to call..
  		$function_parameters = $function['parameters']; // Get the parameters for the function...
  		$cache_data = $function_name($function_parameters); // Set cache data to the return value of the function...
  		cache_set($cache_entry, $cache_data, $table, $expire); // Cache the resulting value...
  	}
  }
  return $cache_data; // Return the cached value...
} // theme_name_theme_cache()

In the above code sample, we pass an array ‘$function’ with two keys, ‘name’ and ‘parameters’ to the function. If the cache is not already populated, we determine the cacheable value with the following line:

$cache_data = $function_name($function_parameters);

We might use this function like this (for illustration purposes only!):

$cache_entry = 'theme_name:website_link';
$function = array(
	'name' => 'l',
	'parameters' => '"Drupal Website", "http://www.drupal.org/"'
);
$table = 'cache';
$expire = time() + (360*24*7);
$output = theme_name_theme_cache($cache_entry, $function, $table, $expire);

This would result in $output being set to the output of the call to Drupal’s l() function, and the cache entry ‘theme_name:website_link’ in the ‘cache’ table being set (or updated) to that value, with an expiry time one week in the future.

Of course the use of a function like this—like the use of the cache in general—should be limited to queries or calculations that are very resource intensive. The example above would actually add overhead compared to simply calling l() directly.

 


t. 604.684.2498 | f. 604.721.4007 | e. turningheads [at] raisedeyebrow.com