Drupal

Quick Drupal Tips and Tricks

Easy enough to copy and paste

It's been a LONG time since my last post (roughly a year) so I thought it was time to finally post something new. I've been lucky enough to build quite a few Drupal themes lately and below are some bits of code that I use on a dailly basis when adding to or developing custom themes. The nice part is everything below should be easy enough to copy and paste! *Note: All code below is for Drupal 6.

Views horizontal scrollbar

You know that annoying horizontal scroll bar that appears on your browser everytime you hover over a View on your site? This short bit of CSS gets rid of that. Place the following code in your theme's CSS file and away goes the horizontal scroll. div.view div.views-admin-links { width: auto; }

Admin page columns

Ever built a theme only to have the "/admin" columns display one on top of each other? That's typically due to not enough width in the content area to properly float the two columns. Add this bit of CSS to your theme's CSS file and you will no longer have the problem of floating your admin page columns. div.admin .left, div.admin .right { margin-left: 1%; margin-right: 1%; }

Rounded tabs from Zen

I'm a big fan of the rounded "edit" and "view" tabs on the Zen theme and wanted to incorporate them into my own themes. There's a couple of files you'll need to edit but it's really quite simple copy and paste. Be sure to download the tabs images and place them in your themes folder in the "images/tabs" folder so the paths below match up.

CSS For Tabs

/* styling for node tabs (e.g., View, Edit) */ #content-tabs { margin: 0 0 1em 0; } #content-tabs ul.primary { background: url(images/tabs/tab-bar.png) repeat-x left bottom; border-width: 0; line-height: normal; list-style: none; margin: 0; padding: 0 0 0 10px; white-space: nowrap; } #content-tabs ul.primary li { float: left; margin: 0; padding: 0; } #content-tabs ul.primary li a { background-color: transparent; background: url(images/tabs/tab-left.png) no-repeat left -38px; border-width: 0; color: #777; display: block; font-weight: bold; height: 24px; margin: 0; padding: 0 0 0 5px; /* width of tab-left.png */ text-decoration: none; } #content-tabs ul.primary li a .tab { background: url(images/tabs/tab-right.png) no-repeat right -38px; border-width: 0; display: block; height: 20px; /* 24px (parent) - 4px (padding) */ line-height: 20px; margin: 0; padding: 4px 13px 0 6px; } #content-tabs ul.primary li a:hover, #content-tabs ul.primary li a:focus { background-color: transparent; background: url(images/tabs/tab-left.png) no-repeat left -76px; border-width: 0; color: #4e4e4e; } #content-tabs ul.primary li a:hover .tab { background: url(images/tabs/tab-right.png) no-repeat right -76px; } #content-tabs ul.primary li.active a, #content-tabs ul.primary li.active a:hover, #content-tabs ul.primary li.active a:focus { background-color: transparent; background: url(images/tabs/tab-left.png) no-repeat left 0; border-width: 0; color: #000; } #content-tabs ul.primary li.active a .tab, #content-tabs ul.primary li.active a:hover .tab { background: url(images/tabs/tab-right.png) no-repeat right 0; } #content-tabs ul.secondary { background: url(images/tabs/tab-secondary-bg.png) repeat-x left bottom; border-bottom: 1px solid #c0c0c0; font-size:0.8em; list-style: none; margin: 0; padding: 0; white-space: nowrap; } #content-tabs ul.secondary li { border-right: none; float: left; margin: 0 5px 0 0; padding: 3px 0; } #content-tabs ul.secondary a { background: url(images/tabs/tab-secondary.png) repeat-x left -56px; border: 1px solid #c0c0c0; color: #777; display: block; height: 24px; margin: 0; padding: 0; text-decoration: none; } #content-tabs ul.secondary a .tab { display: block; height: 18px; /* 24px (parent) - 6px (padding) */ line-height: 18px; margin: 0; padding: 3px 8px; } #content-tabs ul.secondary a:hover, #content-tabs ul.secondary a:focus { background: url(images/tabs/tab-secondary.png) repeat-x left bottom; } #content-tabs ul.secondary a.active, #content-tabs ul.secondary a.active:hover, #content-tabs ul.secondary a.active:focus { background: url(images/tabs/tab-secondary.png) repeat-x left top; border: 1px solid #c0c0c0; color: #000; }

CSS for tabs - IE7

#content-tabs ul.primary li a:hover { color: #555; cursor: pointer; text-decoration: none; } #content-tabs ul.secondary li a:hover{ color: #555; cursor: pointer; text-decoration: none; }

CSS for tabs - IE6

#content-tabs ul.primary li a, #content-tabs ul.primary li a .tab, #content-tabs ul.secondary li a, #content-tabs ul.secondary li a .tab { display: inline; /* Otherwise the blocks mistakenly get 100% width in IE5 */ display: inline-block; /* Otherwise the blocks mistakenly get 100% width in IE6 */ } #content-tabs ul.primary, #content-tabs ul.secondary { width: 100%; /* Otherwise IE5 treats the ul as floated */ width: auto; /* Reset to auto width for IE6 */ } #content-tabs ul.primary li a { background: url(images/tabs/tab-left-ie6.png) no-repeat left -38px; } #content-tabs ul.primary li a .tab { background: url(images/tabs/tab-right-ie6.png) no-repeat right -38px; } #content-tabs ul.primary li a:hover { background: url(images/tabs/tab-left-ie6.png) no-repeat left -76px; color: #555; cursor: pointer; /* Minor fix for primary and secondary tabs in IE */ text-decoration: none; } #content-tabs ul.secondary li a:hover{ color: #555; cursor: pointer; /* Minor fix for primary and secondary tabs in IE */ text-decoration: none; } #content-tabs ul.primary li a:hover .tab { background: url(images/tabs/tab-right-ie6.png) no-repeat right -76px; } #content-tabs ul.primary li.active a, #content-tabs ul.primary li.active a:hover { background: url(images/tabs/tab-left-ie6.png) no-repeat left 0; } #content-tabs ul.primary li.active a .tab, #content-tabs ul.primary li.active a:hover .tab { background: url(images/tabs/tab-right-ie6.png) no-repeat right 0; }

Template.php

/** * Adds class of "tab" to tab menu items so they can be styled. */ function phptemplate_menu_item_link($link) { if (empty($link['options'])) { $link['options'] = array(); } // If an item is a LOCAL TASK, render it as a tab if ($link['type'] & MENU_IS_LOCAL_TASK) { $link['title'] = ''. check_plain($link['title']) .''; $link['options']['html'] = TRUE; } if (empty($link['type'])) { $true = TRUE; } return l($link['title'], $link['href'], $link['options']); } /** * Duplicate of theme_menu_local_tasks() but adds clear-block to tabs. */ function phptemplate_menu_local_tasks() { $output = ''; if ($primary = menu_primary_local_tasks()) { $output .= "

    \n". $primary ."

\n"; } if ($secondary = menu_secondary_local_tasks()) { $output .= "

    \n". $secondary ."

\n"; } return $output; } After making these changes go to the Performance page and clear your site's cache "/admin/settings/performance".

Hover working on non-links in IE6

Since IE6 isn't capable of handling hovers on anything other than links (a href), it requires a specific bit of jQuery to get things working right. Thankfully Drupal 6 ships with jQuery so we can leverage it's power for the site's needs. For this example I am using a background image for my submit buttons on the site and I wanted to have the hover work for all browser, including IE6. You'll need to create a "script.js" file and add this bit of code. The reason I said to create a "script.js" file is that Drupal 6 picks that up by default, just as how it picks up the "style.css" file automatically.

script.js

Drupal.behaviors.myModuleBehavior = function (context) { // IE6 & less-specific functions // Add hover class to primary menu li elements on hover if ($.browser.msie && ($.browser.version < 7)) { $('.form-submit').hover(function() { $(this).addClass('hover'); }, function() { $(this).removeClass('hover'); }); }; }; Now that we have the code in place for the script, it's time to edit the CSS to make it all come together. Normally we do the ".form-submit:hover" to make the style change per hover on the submit button. Since IE6 doesn't understand that, we need to change that a little bit. We need to add a "form-submit.hover" along with the "form-submit:hover". The above Javascript code goes in and makes things work so IE6 can understand what we are trying to do.

CSS

.form-submit { background: url(images/input-submit.png) repeat-x top center; color: #000; } .form-submit:hover, .form-submit.hover { background-position: bottom center; color: #fff; } Well that should do it for now. I've got a LOT more tips and tricks with Drupal theming, just need to get them out of my mind an up here. Hopefully I'll get around to soon. If you have any tips or tricks and it's easy enough to copy and paste please leave a comment below. Would love to hear what other's are using with their themes.

Miscellaneous:

Open Source Bridge Proposal Deadline Coming

Look, I know this isn't our normal type of post.  No code snippets, no real world examples, etc.  Barely even a trace of wit and/or style.

Ok, maybe the lack of style thing really is in keeping with our normal posts.  Whatever.

Point is that this is Important Stuff and, therefore, you need to know:

The deadline for submitting proposals for Open Source Bridge is fast approaching, as in you-need-to-get-yours-in-in-under-20-days-as-of-this-writing fast.  Or, more specifically, by March 31.

So what, exactly, is Open Source Bridge?  Well, my under-rock dwelling friend, it is:

 

Open Source Bridge is a new conference for developers working with open source technologies. It will take place June 17-19 in Portland, OR, with five tracks connecting people across projects, languages, and backgrounds to explore how we do our work, and why we participate in open source. The conference structure is designed to provide developers with an opportunity to learn from people they might not connect with at other events.

 

Them's their words, of course.  Me?  I like to think of it as The OSCON Replacement That Will No Doubt Be Better Than Its Predecessor, So San Jose Can Just Keep That Bloody Thing Because We Don't Need Them In Portland, Anyway, Conference. 

Granted, "Open Source Bridge" rolls off the tongue a little easier.

So go to the Open Source Bridge site.  Submit a proposal!  Volunteer!  Sponsor!  

And if you can't do any of those things, just make sure to register and get your bums to Portland in JUNE

 

OSs:

Miscellaneous:

Upgrading from Drupal 5.x to Acquia Drupal 1.0.3-ISR

My God, we've been behind the 8 ball.

Seriously, did you realize that there have been something like 1.8 million Drupal releases since we last upgraded? Here we are sitting on Drupal 5.2 when the rest of the world is runnin' 6.6. Clearly, time to upgrade.

This afternoon, we decided to jump from Drupal 5.2 to Acquia Drupal, and this here article is the first of two that will document the process.

In this post, we're just talking about the actual Drupal upgrade process. No coding, no theming. Just updating Drupal to a version created in the last, oh, decade or so. Later, Jeremy will tackle updating your 5.x themes to work with 6.x.

Ok, so first thing's first. Before you do squat, there are a couple of files you'll want read.

First, check out the UPGRADE.txt file in your root Drupal directory. That bad boy is the Bible of your upgrade process, and you should have a pretty good idea of what's in there before you get going.

Likewise, if you're installing the Acquia flavor, get familiar with the
Acquia Getting Started with Acquia Drupal doc.

There are steps in there that aren't covered by a normal Drupal upgrade and, while this here post will talk about some of them, your own installation and upgrade experience could be drastically different. This post is just a supplement and, frankly, might not apply to certain installations.

We're also going a slightly different route in our migration. For instance, we're skipping the "Place the site in 'Off-line' mode" step because we're doing a copy-upgrade-rename thing rather than upgrading the live version of the site in place. That works for us, since we're a low traffic site and our comments are few and far between. You popular kids (God, I hate you guys...) might be better served putting the live site in Off-Line mode anyway, just so you don't lose any comments made while you're fiddling around with the copy.

Oh, and before you even start, make sure that there are 6.x versions of any modules you're using before you get too far into this. Wouldn't it suck to update your page only to find out that your favorite, my-site-depends-on-it module doesn't have a 6.x flavor? Yeah. It would.

So, without further ado, let's get rollin'.

Like I mentioned, we aren't going to just update our site in place. Frankly, the idea scares me. Instead, we're going to make a copy of our site and database and update that. After we've finished, we'll swap the copied-and-updated site for the live one, then crack open a cold one to toast our success.

And here's how we do it:

  1. Make a copy of current Drupal install directory.

    cp -R <drupal directory> <copy directory>

2.   Make a copy of the database for the upgrade.
      Easy as pie:

  • Create a new database using whatever means you normally would.  My provider has a little control panel tool I use.  Maybe you do it from the command line, maybe you use phpMyAdmin.  Whatever.  Just create a blank database.
  • Create a new MySQL user and give it the necessary rights to the new database.  Or grant those priveleges to your old user.  Whatever makes you happy (I went with Option B, just because I like to minimize the number of users I have to manage.  Up to you.) 
  • Export the data from your live database.  I used phpMyAdmin for this.  Just logon and click the Export button.  Select your database and choose the SQL format.  I left all the other options at their default values.
  • Modify the export file to point to the new database.  In my case, I changed the "USE" statement on line 22 of my dump to point to the new file.  I also deleted the "CREATE DATABASE" line because my host makes me use their aforementioned tool for the process.  Your mileage may vary.
  • Import the data file.  With phpMyAdmin, you just click the Import tab, browse to the file you want to import (the one you just exported/modified) and click Go.  Done.

        That's it.  You should now have a copy of your DB.  Of course, there are other methods.  Feel free to share your fav in the comments.
     

3. Update the settings.php file in the new directory to point to the new database.

IMPORTANT.  If you don't go to your settings.php file (/sites/default/settings.php) and edit the $db_url line, any changes you make from this point forward will happen on your live database.  That could be very, very bad if things blow up on you.  Edit that $db_url line to point to the new database name you created in the last step.  If you created a new user, change that, too.
    
4.  Confirm that you're using the new database, etc.  

Ok, I'm anal about this kind of thing.  I want to be 100% certain I'm about to jack with my copy rather than the real site.  In my case, I created a new subdomain that points to the new directory, so when I browse to "http://nerdtest.nerdliness.com," Apache serves up the files in my ./nerdtest directory instead of my original ./nerdliness one.  Make sense?

How you do this will depend on your host.  In my case, I get a handy little control panel with a "create subdomain" link that takes care of the Apache and DNS changes.  If you're hosting yourself, you might have to make your own httpd.conf and DNS record changes.  Or if you have another host, you'll need to check with them.  Sorry, but there are as many different steps for this part as there are hosting providers. 

Anyway.
    
After creating the subdomain, browse to your site copy and make a small change.  Maybe leave yourself a comment or make a test post.  Whatever you do, make sure it only appears on the subdomain and not on the original.

5.  Get your modules in order.
Ok, we've been bad.  We had a ton of modules chillin' in our /modules directory instead of in the /sites/all/modules 'hood where they belong.  The longest part of this process involved moving those user contributed, third party modules into their correct location.

The Acquia guide has a good list of core Drupal modules that need to stay in the /modules directory, but it isn't all-inclusive.  Before you start moving all the modules from /modules to /sites/all/modules, make sure you're moving the right ones.  Check out the docs online for the full list.  In my case, I just had one window opened to my Drupal Admin page and made sure I didn't touch any modules that were listed under the Core - Required or Core - Optional headings.

Make sure you check out your site after making all thes moves, just to be safe.  Would hate to try to update after you've already moved out some core module that you shouldn't have touched only to find that nothing works right.

6.  More module maintenance...
Acquia includes fancy-pants versions of some important modules, so you need to 86 any versions you have installed already before you do The Upgrade.  Make sure you deactive and remove them before you continue.  There's a full list of modules in the Acquia Getting Started guide, starting on Page 24, and it includes stuff you're almost certainly using (CCK, anyone? How 'bout Views?)

Note:  there's a special case around the Printer-Friendly Pages and Filefield Meta modules. Didn't apply to us, might apply to you.  Make sure you RTFAcquiaGettingStartedGuide, page 25 ("Special Cases:  Printer-Friendly Pages Module and Filefield Meta Module").

7.  Download/unpack the Acquia Drupal goods.
Browse to http://acquia.com/downloads and download the current "Update Existing" version.  Copy that bad boy over to your web server and untar it.

8.  Update!
Now the real fun starts.

First, since we downloaded the "Update Existing" version of Acquia, the directory created when we untarred that file is missing some key elements from our actual site.  We need to copy those over before we do anything else.  Basically, we need to copy our .htaccess and robots.txt files, our entire sites directory (and its contents), as well as any other customized files that live outside those folders.

    cp <copy directory>/.htaccess <acquia directory>/
    cp <
copy directory>/robots.txt <acquia directory>/
    cp -R <
copy directory>/sites <acquia directory>/

9.  Rename your directories
Now that our customized files are in the Acquia untar directory, we just need to rename our copy directory to something new, then rename the Acquia directory to the same name our copy directory used to have. 

Good God, that doesn't make much sense, does it?

Ok, so say we untarred the Acquia files to a directory called "acquia," and our old working Drupal directory was "nerdtest."  Now, we're going to rename "nerdtest" something like "old_nerdtest," then rename "acquia" to "nerdtest."  Got it?
    
    mv <copy directory> <new name for copy directory>
    mv <acquia directory> <
copy directory>

10.  Run the update.php file
Just browse to the /update.php file on your site and do what it says.

11.  Pray.

12.  Check for errors
You should get a progress report immediately after the update that mentions any specific errors.  Also check the Status Report page (/admin/reports/status).  Make sure you follow any advice given on this update results page.

In our case, we had a couple issues.  First, the Status Report mentioned that the "files" directory didn't exist.  Sure enough, we'd forgotten to copy that over from our previous install back in step 8.  Easily fixed with a little "cp -R <new name for copy directory>/files <copy directory>" action.

Second, we noticed this blurb:

Updates for CCK-related modules are not run until the modules are enabled on the administer modules page. When you enable them, you'll need to return to update.php and run the remaining updates.

Piece of cake.  All we had to do at that point was go into the Administer Modules page, enable those CCK modules, then rerun the /update.php script.  No problems.

13.  Update and reactivate modules
You'll probably find that several modules you used with 5.x have big red X's next to them in the Admin page now.  Yeah.  Sucks, huh?  Probably should have checked for newer versions of those modules ahead of time, right?  Like we warned you about before you even started? 

Anyway, now's the time to download and install those newer versions.  You know how.  And this time, remember to put them in /sites/all/modules.

15.  Bring the site "On-Line"
We didn't put ours in Off-Line mode, but if YOU did, make sure you bring it back up.

16.  Test.
Browse around, check everything out.  If it all looks good, fantastic!  If not, well...  Can't really help you there.  Our's went just fine.  :)

Ok, maybe "fine" is a bit too...  um... Pollyanna of a word. We had some issues with some permissions (anonymous users couldn't see content for some reason) and formatting (former header/footer blocks ended up in the sidebar), etc.  But all of those were things that were pretty easy fixes.  Nothing major.

If YOU have something major come up though, leave comments.  We (or someone reading this) might be able to help.

17.  Go live!
If everything looks good, it's time to bring it live. 

Remember that we did this with a copy of the site, so we need to change a couple directory names.  It's really the same exact process as in step 9, just with different directories:

    mv <drupal directory> <some other name>
    mv <copy directory> <drupal directory>

 

Also, if you put yours in Maintenance Mode, remember to disable that.

And that's pretty much it.  Really not too difficult.  I'm sure we'll continue to find little pieces here and there that need some massaging every now and then, but overall the process was relatively painless.

Now if we could just get Jeremy to update our old theme...  Not like he's got a full time job and a newborn daughter keeping him busy or anything...

SQL:

OSs:

Miscellaneous:

Because Network Solutions Sucks

One man's frustration is not lost in vain.

The Drupal community, and open-source community at that, has always had the altruistic goal of being accessible to all. The hope is that as freelancers and tech gurus go out into the world, maybe we can help by making better, more secure websites.

And then you have piece-of-crap hosting like that of Network Solutions.

Now, I only bring this up because as I work with clients to get their internet presence setup, sometimes you're stuck working with their choice of hosting provider, hosting package, and admin credentials.

This means crazy php.ini setups, no ssh access (because the cheap plans don't enable this), and passwords like '1234myfirstname'. Never the eternal pessimist, I figured I'd leave a few words of encouragement and one small tip to those that run into this.

First, don't give up. Although you can't convince your client to pay you monthly hosting fees on your leased vps (who hasn't tried that?), continue to make their internet presence more than a site built by iPowerweb. Yeah, you may have to wrestle with a table-filled layout, but a little progress is better than no progress.

Second, scour the drupal forums for a solution. Sometimes it may take a couple of days, but it seems like everytime I run into a roadblock, someone else has as well. A forked, non-hacked core, Drupal install on a POS hosting provider is STILL better than an MS Access-driven site hosted by 1and1. :-)

Third...if you're on Network Solutions, and get the dreaded email of 'we will not turn off register_globals or magic_quotes_gpc because it would affect other shared hosted sites', take a deep breath, laugh at them uncontrollably, blog about it, then put this piece of code in the cgi-bin of your vhost within a text file called 'php.ini':

register_globals = off
magic_quotes_gpc = off

Yeah, this whole blog post was all about solving the Drupal install message of 'TURN THIS CRAP OFF', but I figured the it was better suited for the community to at least know I didn't give up! Why it ignores this directive in .htaccess or the ini_set() in the settings.php is beyond me, but....it does work.

Thanks go to this forum post, btw.

Miscellaneous:

Coding:

6 Tips: In the Know

So how do I stay 'in the know' and increase my Drupaliness?

I'll go ahead and warn the readers that this article won't have any fancy code snippets or super dark magic to turn your site into ten billion dollars of reoccurring ad revenue. What it WILL do is give you some great pointers in ramping up your Drupal knowledge as you begin to take over the world...one Drupal site at a time.

Muahahahahahaha....but I digress.

1.) Stay on the channels

While you probably need some clout to get anything answered or explained in #drupal, #drupal-support is where the n00bies flock...and flock often. Although I wouldn't consider myself any type of <air quote> expert </air quote>, I can say that I have learned a lot by seeing some of the questions float through the channel. If you've got something interesting to add, be sure to speak up and give your support. The Open Source world is live and let live, so if you're on, say hi! I'm caramelson, btw.

Other channels to check out are #drupal-dojo and #drupal-themes (for the themers in the house).

Note: For those that don't know what I mean by <air quote>channels</ air quote>, I'm talking about IRC.

2.) Groups

Drupal groups is a cool thing. I've played with other CMS platforms before (Plone, Wordpress), and I can say that groups.drupal.org is a great bonus to this particular CMS community! You can find discussions tailored to just about anything. From local meetups to other Drupalers looking to make the next Facebook, you learn a lot from the ideas being tossed around. Some of the n00bie groups include Drupal Dojo and Drupal for Evil (semi-n00bie), and often have neat websites that have a host of tutorials, screencasts, and podcasts.

3.) Lullabot

This kind of goes without saying, but Lullabot is what we in the business call 'that fire'. Podcasts, video casts, teaching sessions, and a neat company mascot. What else is there?

4.) Conferences

Everyone probably knows about the grandaddy conference coming up in Boston, but don't forget to peruse the feeds for local ones! Even if you can't make it out, beg the crap out of someone who has some pull in organizing to stream it live on ustream.tv, perhaps even to post videos of the presentations. I'm hoping Crell comes through for me this year with Drupalcon 2008 since I'm not cool enough to go this year. :-(

5.) Drupal Planet Feed

Speaking of feeds, the mother of all feeds is that of Drupal Planet. Aggregating pretty much all of the 'it' list of Drupalers in one ginormous feed, it may be a good idea to stick that puppy in your Google reader. I will admit, some of it can be a little dense. But hey, no one ever said that genius was always entertaining. Alas, drupal.org/planet is where it's at.

6.) Certs and Skillset

This last one could go either way, but I've always believed that technology moves so fast that you can't simply believe that learning a language in 1998 is adequate enough to do some real damage in 2008. Stay current and don't be afraid to learn new functions and features. The list of applications at gophp5.org aren't coincidental. The Drupal community will continue to pump out new versions, use obscure built-in PHP functions like 'stream_filter_append', and n00bies will continue to live in ignorant bliss of all the new functionality hotness. I say no more! Bonus: look at getting a Zend certification.

Miscellaneous:

Pages

Subscribe to RSS - Drupal