Main content begins here

CMS

Customize the Ubercart Email Based on Product

Intro: 

Do you need a customized message or bit of text to show on the confirmation email based on one or more of the products purchased?

Let's learn to customize the Ubercart 2 purchase confirmation email based on product. Modifying the message is fairly straightforward, though not the most user-friendly in a Drupally sense.

What I needed was a way to customize text on the email based on what products had been purchased. I imagine this could be something added later to the node itself so that each product could have it's own text blurb added to the email when purchased, or if related to a purchased product, however I needed a quicker solution.

Find the Ubercart Email Template

In your file structure find modules/ubercart/uc_order/templates/customer.itpl.php for editing. At the top of the template add something like:
<?php foreach ($order->products as $product2) {
    if ($product2->nid == 52) { $flag1 = 1; }
    if ($product2->nid == 53) { $flag2 = 1; }
}
?>

You will of course need the "nid" of whatever your product nodes are. An example of this usage would be if you had a sporting goods store that sold products as well as training events like baseball camps. You could use something like this to check to see if the user had purchased a baseball glove and then insert a blurb into the email about upcoming baseball training camps.

In my case I was selling events and wanted a way to remind the user of the directions to the event. Since the events could be held in different buildings and/or rooms we needed to provide text based on the event.

Theming Drupal 5.x, or, How To Thumb-Wrestle Drupal 5 Into Submission and Lay It Low At Your Mighty Feet, Part 3

Intro: 

Oh no... Part 3 may ruffle your feathers after having loved Parts 1 and 2. I apologize in advance.

Parts 1 and 2 revealed some wonderful theming advice however it is now time for the best piece of Drupal 5 theming advice I can give, summed up in a few small words:

Use Drupal 6

Yep, there it is. The best advice I can give is to use Drupal 6. Unfortunately Drupal 6 is no cake walk either, but it is a vast improvement over 5. I am envious of all my client's Drupal 6 sites, as this one os Drupal 5. As amazing as this site was to me when I created it, with all the glory Drupal provides, it's a dinosaur compared to 6.

Blog terms:

Multiple Event Registration Using Drupal & Ubercart Attributes

Intro: 

A quick, easy way to use Ubercart Attributes to enable multiple event registration using Drupal.

Although not as flexible as Webform, we decided to use Ubercart Attributes to enable multiple event registration using Drupal. Here's a quick look into how to use it yourself. We use Drupal 6 the Ubercart 2 module.

This solution may not be suitable if you have advanced needs for information gathering or special user tracking, however if your need is simply to gather some info and allow a user to pay in advance for an event registration, this does the trick.

If you haven't yet, create an Event product class in Ubercart via the "Manage Classes" page (/admin/store/products/classes). Create a test event node we can play with.

In /admin/store/attributes click "add an attribute", for example, "Attendee Name". Choose "text field". Now let's edit your test event node. Near the top of the edit screen is the extra navigation Ubercart adds to product content types ("classes"). Choose "Attributes". Click the "add attributes form" link. You will see a box containing all the Attributes you created earlier. If you only created the one "Attendee Name" attribute then there will only be one attribute in this box. Select it and click the "add attributes" button. This attribute will now show up in your "add to cart" area of the node.

All that remains is some styling and you're all set!

Theming the Date Module for Drupal 5

Intro: 

Getting that finicky Date module to stop printing dates like "07 Apr 2009 - 12 Apr 2009" and start printing them like "7-12 APR 2009"...

WayCoolWebDesign recently had two Drupal web sites in production at the same time that had design goals of using combined event dates. While the default display for dates running more than one day is something like "07 Apr 2009 - 12 Apr 2009" we instead needed the dates to appear shortened as "7-12 APR 2009". While the date module allows for many different lengths of dates I didn't see that this option was offered. It was time for more drastic measures.

Theming the Date Module

While I'm not certain this exactly qualifies as theming since I am not changing display code but rather some functionality. Semantics aside, thank goodness the function used to display the dates is offered as a themable function.

The function you'd look for is the "date_display_combination" function inside "date.theme" file within the Date module. Before adding this function to my template.php file I had used the normal course of choosing pretty short dates within the Drupal functionality, so I knew that dates were set to show something like "07 Apr 2009" before fiddling with the function.

Next I copied the entire function to the template.php file. I then added this block of code right after the point in the function where $date1 and $date2 have been assigned the Drupal-formatted dates (@line 15 or so):

// START:
$jbyear1 = substr($dates['value']['db']['datetime'],0,4);
$jbmonth1 = substr($dates['value']['db']['datetime'],5,2);
$jbyear2 = substr($dates['value2']['db']['datetime'],0,4);
$jbmonth2 = substr($dates['value2']['db']['datetime'],5,2);
$jbday1 = substr($dates['value']['db']['datetime'],8,2);
if (($jbyear1 == $jbyear2) && ($jbmonth1 == $jbmonth2) && ($date1 != $date2)) {
$date1 = $jbday1;
switch($date1) {
case '01': $date1='1'; break;
case '02': $date1='2'; break;
case '03': $date1='3'; break;
case '04': $date1='4'; break;
case '05': $date1='5'; break;
case '06': $date1='6'; break;
case '07': $date1='7'; break;
case '08': $date1='8'; break;
case '09': $date1='9'; break;
default: $date1=$date1; break;
}
}
// END:

More Customization of the Drupal Date Module

I'm not a heavy PHP guy so my code is never elegant. I was not hoping to solve every date issue that may come up, only this particular one. All I was hoping to achieve was that if an event date had more than one day, and the years of both dates were the same, plus the months of both dates were the same, I wanted to combine them. I could see that if Drupal wanted to output "07 Apr 2009" all I need to do was grab the first 2 digits and make that into $date1. Then I ran a switch to get rid of the annoying zero that appears when the date is a single digit 1-9.

After adding this block of code Drupal would now have the first date as a one or two digit number and the second date would be kept as the unaltered second date. Then when combined as normal they'd show the way we intended. The final piece to the puzzle was changing "5-7 Apr 2009" into "5-7 APR 2009" by using CSS text-transform: uppercase.

Blog terms:

Theming Drupal 5.x, or, How To Thumb-Wrestle Drupal 5 Into Submission and Lay It Low At Your Mighty Feet, Part 2

Intro: 

In the land of blind Drupal people, the one-eyed man is Drupal King. I don't know what this means, except now you will know how to theme Drupal 5 so you no longer have to suffer through others' freebie themes. Make your own awesome themes!

In Theming Drupal, Part 1 we talked about some of the basics of the Drupal theme, getting started with your design, code, and the initial steps to creating the theme. Now, as Young MC might say, its time to bust a move.

Your first ally in real theming is the template.php file. This is the place where you override (theme) Drupal's core while maintaining the virgin-freshness of the core itself. If your theme doesn't have a template.php file, add one now. If you're adding one, just add an empty file.

Theming Drupal Regions: Ad, Delete, Mix and Match - More Fun Than Garanimals!

The first thing to notice inside template.php is the regions function: "function themename_regions()". If you don't have this function because you're starting with an empty file, add it now (Garland doesn't have it). It looks something like this:

function mythemename_regions()
{
return array(
"sidebar_left"=>t("left sidebar"),
"sidebar_right"=>t("right sidebar"),
"content"=>t("content area"),
"header"=>t("site header"),
"footer_message"=>t("site footer")
);
}

The regions function allows you to add regions to your design. Be sure each theme's region function is named appropriately. For example in our example from Part 1 the theme is called "my_theme" so the function name will be "function my_theme_regions()".

An example of adding a new region to your theme is, say on the home page you wanted to have a rotating promo. Create a new variable name such as $promo then insert this variable into your page.tpl file like you do any other Drupal snippet such as $content or $sidebar_left. Then in your region function add a new line so we can make the region appear in your blocks for that theme:
"promo"=>t("home page rotating promo")

Creating a Drupal Content Type

Now you'll need to create a new "content type" in Drupal for your home page called "Promo". To do this go to "administer > content management > content types" and choose "add content type". This will be where we store our promos from which we will randomly draw one for display on the home page. Once you create the content type, create a couple dummy promos so you can see this in action when we're done.

Next go to Views and add a Block List View of 1 called "promo_view" with the field of Node:Body, a filter of Published:Yes & Node:Type->"promo", and Sort Criteria: Random. Next visit Blocks where we tell our theme we want the "promo_view" to be placed inside our "promo" region. Shazzam! You have rotating promos. Ain't life grand?

Now I will touch on more customization that I half-promised back in Part 1. It's more template.php magic. That's not magic as in Merlin, it's magic as in Penn & Teller in that I'm gonna show you how it's done. Sort of...

Getting Control of the Drupal Navigation

The default Drupal nav was pretty uninspiring to me at first, back when the only way I knew how to accomplish tasks was hacking core. Naughty, naughty. Now I've learned a few things and I'd like to share them because it is frustrating to a lot of people. That is namely dealing with some navigation customization. Things like adding a selected state to a list item instead of the anchor, adding a span INSIDE the anchor, and enabling a way to allow for using images in the navigation.

I'm not really an intensely learned PHP guy. I can understand most of what's going on and can usually edit existing PHP to achieve a desired outcome, though it may not be the most efficient way, so your mileage may vary, but here is the function I use to spice up my Drupal menus:

function phptemplate_menu_item($mid, $children = '', $leaf = TRUE, $extraclass = '') {
if (menu_get_active_nontask_item() == $mid) {
$class_active = ' selected';
}

if ((menu_in_active_trail($mid)==1)) {
$active_section = ' selectedSection';
}

if($mid) {$mid_id='item'.$mid;}
if($children) {$hasChild=' hasChild';}
else {$hasChild='';}

return $thing.'<li class="'. $mid_id . $active_section . $class_active . $hasChild . ($leaf ? '' : ($children ? ' expanded' : ' collapsed')) . ($extraclass ? ' ' . $extraclass : '') . '">'. menu_item_link($mid, TRUE, $extraclass) . $children . "</li>\n";
}

The above makes a list item (not its anchor) have a "selected" class when active, and its parent will have addionally a "selectedSection" class. This is helpful when you want to control what sections are open/closed using CSS in a menu.

The above also adds an "item#" class such as "item69" to a nav item. People often use an id for this instead of a class but I often have to generate menu items or parts of the menu several times on a page, and muliiple ID usage is improper HTML, so use a class. This is useful if you want to use images for your nav items because you can target specific list items.

The above also adds a "hasChild" class so you can do things such as using an arrow bullet in your nav to indicate which sections have children. You can see this in use on this site by rolling over "Projects" in the main nav to see an arrow indicating that "Industries" has child nodes.

In Part 3 of this series I will continue discussing some template.php magic. Be sure to tune in next time, same Bat Time, same Bat Channel...

Theming Drupal 5.x, or, How To Thumb-Wrestle Drupal 5 Into Submission and Lay It Low At Your Mighty Feet, Part 1

Intro: 

Here it is, better late than never. How to theme Drupal 5. Get your ya-yas out and party like its 1999! I mean, stop using crummy themes that make your site "look like a Drupal site". Get your act together and make your sites look awesome!

This will be as short and sweet as I can make it while covering the entire theme development from concept to launch, with occasional pitstops for my bad humour... Whew, what an undertaking!

Web Design, The First Step to Theming Drupal

Example of using Photoshop guides in a design

Start with a design in Photoshop. Stop using Illustrator to design web sites. Stop using Fireworks or ImageReady to cut them. For goodness's sake, if you're a designer, then be one for real. Use Photoshop. Use vector shapes and guides to cleanly define areas using a grid to setup the design. It doesn't have to be perfect but if you're making your own design then it should at least be good, otherwise you may as well go grab a free theme somewhere and save yourself some time.

Do not use images for navigation unless you are prepared to constantly edit them yourself, meaning if this job is for a client, get off your designer's high horse and use text for navigation. Its irresponsible to use images for nav when YOU won't have to maintain it, just because you think it looks pretty. Keep the client in mind. Use text.

Coding Your Drupal Theme

Code a HTML/CSS tableless template by hand. Do not use an app to export it. Just look at the darn design and visualize the rows and columns you'll need. A header is usually one row (div set), the nav might be another, the body content another, and then a footer, generally speaking. Within the rows are columns, each column is another div set. For example often the body content area has columns, in the case of this site there are 3; the left column for navigation/quotes, the center for body content, and the right column for callouts. You will define a width for these columns, then float them all left and then clear the floats afterward. If all this is mundane to you and you want a new challenge try coding so that your page content is at the top of your HTML.

I've really plowed through the design and code portion of creating a theme because the main topic of this post is the Drupal aspect, theming Drupal, and not really the creation of a design/HTML template. If you need more in depth info on those aspects I may have other articles later, or again, save yourself some trouble and pick up a free theme somewhere.

Once you have the HTML template code complete (with some dummy content in place) or have purchased a plain HTML theme elsewhere, and have tested it in FireFox, IE6 (hopefully dead soon), IE7 and Safari, you'll need to create your own theme folder. To start it may be easier to just duplicate the garland theme, then rename the folder whatever you want (hint: if you plan to have spaces in the name it is best to use underscores instead). For now let's assume your folder has been renamed "my_theme". Inside /themes/my_theme/page.tpl.php is where most of the work goes into creating a theme. If you don't know what the page.tpl.php file is, again, check into an existing Drupal theme such as Garland to see an example of the file.

The Drupal Guts Switcheroo

Next is swapping out your pieces of code for Drupal's guts. When I am creating a new theme I usually paste the entire new HTML code ahead of the old code of an existing page.tpl.php file. This makes the copying/pasting of the Drupal guts easier... Be careful to copy/paste all the region variables you'll need to ensure a smooth transition. If you see PHP in the old theme's code, it probably belongs in the new theme but you will have to learn over time exactly what you can add/keep/discard.

I'm not going through the whole list of region swaps you'll need to make but an example would be, cutting out the body content area of your HTML code and adding Drupal's <?php print $content ?> snippet. Another example is, deleting the code for what should be the left column content of your HTML template then inserting Drupal's <?php if($sidebar_left) {print $sidebar_left;} ?> region snippet.

When working on this part of the process, you'll have to consider your client's needs. Generally for my projects, clients don't need every bell and whistle. For example how often will a client change their logo? Nearly never is the answer in my case, so I don't usually use Drupal's $logo variable. Same with the mission statement ($mission variable) since most of the time designs incorporate the mission statement as a part of the logo. But you be the judge of what works best for you.

More In-Depth Drupal Theming Tips

We've covered the basics. Now it's time for the nitty-gritty...

Your theme should be well inside the ballpark now, with Drupal trying to generate its Drupally system bits in the right places, however now the devil is in the details. At this point Drupal will be inserting content in the right place in your theme, the $content variable, and even though it may be trying to insert left-column stuff in the $sidebar_left region variable, you may not have told Drupal what it is exactly that you want in that area. This is where blocks come into play.

In "administer > site building > blocks" you will see any themes that are registering with Drupal, such as garland and minelli. As long as your new theme has been enabled in "administer > site building > themes" you should see it in the blocks area. Clicking the name of your theme will allow you to instruct Drupal what content should appear in which region (the variables you just added to your new theme) Now you can control what shows in the various regions of your page, the header, left and right columns, and footer. For example if you need a copyright statement in the footer, as long as you have swapped the $footer_message into your new theme, all you need to do is add a new block called, say, "my copyright", add the copyright statement into this new block, then in the "my_theme" theme tell this new block to reside in the footer by choosing "footer" from the dropdown.

This ia a pretty simple way to get a quick site created in Drupal. The thing is... people always want to customize. They want this and that coded exactly this and that way. This leads to the need for more control over what Drupal is exporting and where it is exporting it.

For example, what if we need our main navigation to render a bit differently, say with a span tag inside the anchor, or a div surrounding each ul for special effects? What if we are creating a site for ourselves and we DO want to use images in the navigation because we know we can update the images ourselves if needed? What if we want a view to sometimes render items as a list that DOES use a proper list format (unordered or ordered) and in other cases we want a list of items that are NOT inside a list structure?

All these questions and more might be answered in Part 2, or possibly Part 3, or the way I'm rambling it could be in Part 12, after this commercial break!

Drupal Accessibility, Usability

Intro: 

I had a quick conversation with Duane Degler from Design for Context at DrupalConDC 2009 this past week. It gave me a great idea to try out a usability feature in my next implementation of the Drupal Content Management System, which is to use CSS to make some of the action functions appear as buttons. Links connote taking a user some place, buttons connote action.

I had a quick conversation with Duane Degler from Design for Context at DrupalConDC 2009 this past week. It gave me a great idea to try out a usability feature in my next implementation of the Drupal Content Management System, which is to use CSS to make some of the action functions appear as buttons. Links connote taking a user some place, buttons connote action.

At the moment the plan is to use them in the upper left admin navigation screen. Since the few actionable items most of my clients need can be so tough for a new user to find, I create additional links here to ease the pain such as "Edit Content", or "Edit Blocks". These, along with "Create Content" would be great candidates for action buttons.

I am very pleased with the outcome of this project. A solution that compensates for critical deficiencies in IE support for CSS was provided by John, enabling us to push ahead with a strategy that may not have been possible otherwise. My advice to you if you're considering working with John Barrick on a project is: Do it! I intend to continue working with John on this and other future projects.

Lane MobilSense
Copyright ©2001-2017 Way Cool Web Design LLC. All Rights Reserved.