Blog

SimpleMenu Block Admin Fixed!

Ethan's picture

Lovers of the venerable SimpleMenu module rejoice: the issue with Administration themes overriding the default theme on the Blocks admin page (caused by calling theme() from hook_init()) has been fixed by AlexWilke!

A tiny dash of gloss

Déja Augustine's picture
Tags:

It's the little things that make a good site into a great site. I'm sure that the iPhone's ability to add bookmarks to your home screen is one of its most underused features, but with advances in HTML5 and Mobile WebKit, it is becoming a more useful tool.

Since 1.1.3, iOS has supported custom bookmark icons. The icons are square PNG files (iOS uses 57x57 pixels for its native apps, but I've heard of other sizes, such as 45x45 working as well). You can either name the file apple-touch-icon.png and add it to the root folder of your site, or use the following link tag to point to a custom path:

<link rel="apple-touch-icon" href="/Graphics/iphone-icon.png" />

Mobile site libraries, such as jQTouch, include settings to automatically insert the above code.

Using Tokens in Comment-Triggered Email Notifications

Ethan's picture

The stock "Send Email" action type that ships with Drupal 6 does't offer a whole lot of options for including content from comments in your triggered emails.

In fact, it doesn't offer any.

There has been a good deal of discussion on this: a patch has been proposed and a stop-gap helper module has been posted to drupal.org.

Before you go that route, though, check out this post on using the Token Actions module to provide access to the full array of available tokens in your email. Thanks to Erik Weik at New Rivers Digital for the great post.

We're using Trigger-based email notifications to fight spam and help our clients be engaged with their commenters.

How do you use and implement comment notifications?

Hiding text in IE7 with CSS

Déja Augustine's picture

Negative indent. Hackish solution, but it gets the job done... most of the time. It fails spectacularly in IE7, however.

If you're ever looking to hide that special text from your evil seventh aunty thrice-removed (i.e. ie) try this handy trick


#selector {
color: transparent;
text-transform: capitalize;
}

Interesting tidbit. IE will ignore the transparent color UNLESS you apply a text-transform to it as well. That seems to be the cue that IE waits for before doing anything TOO crazy.

Context Weights

Déja Augustine's picture

The context module is great, but it's lacking one distinct feature: weighting. There's no way to explicitly determine which order the contexts are evaluated in.

This leaves us to rely on a little known, implicit ordering system: alphabetical by context name.

As of version 6.x-3.0-beta5, the context module evaluates contexts in the order they appear on the admin panel. Using ordering prefixes can help to control the order. For example, if we have three contexts that apply to a particular path:

  1. One
  2. Two
  3. Three

they would show up on the admin list as

  1. One
  2. Three
  3. Two

and be evaluated in that order. In order to control the order, one solution might be to do:

  1. a_One
  2. b_Two
  3. c_Three

Making use of this "feature" is obnoxious at best, obfuscative at worst, but it's what we have out of the box.

Tidy up /tmp on dev servers

Today I was made aware of some strange MySQL errors on our development server that ended up being related to a lack of sufficient disk space. Upon inspection, the /tmp partition had completely filled up. A majority of the files were temporary files created by the Drupal module devel with devel_themer enabled. Turns out these temporary files are not deleted at the end of a session. There were also CURLCOOKIE files related to cron jobs to hit cron.php on various dev and production sites, and some other temporary files that if left unattended could result in the same errors.

My solution is to have these files deleted every night, but only if they're three days old, which should be adequate time for the developer to need access to these temporary files. I added this to root's cron.

  1. # Delete some /tmp files older than 3 days
  2. 5 4 * * * find /tmp -type f -name "Apache-Session*" -mtime +3 -exec rm -f {} \;
  3. 6 4 * * * find /tmp -type f -name "backup_migrate_*" -mtime +3 -exec rm -f {} \;
  4. 7 4 * * * find /tmp -type f -name "devel_themer_*" -mtime +3 -exec rm -f {} \;
  5. 8 4 * * * find /tmp -type f -name "CURLCOOKIE_*" -mtime +3 -exec rm -f {} \;

Similarly, I have a cron job to remove old Apache logs, which is helpful since an old project will never have it's logs deleted unless they're removed manually.

  1. # Delete Apache logs older than 30 days
  2. 30 3 * * * find /var/log/httpd -type f -mtime +30 -exec rm -f {} \;

Do you have other ideas for managing temporary files that don't clean up after themselves? Let us know in the comments.

Fatal error: Call to undefined function curl_init() -- FIXED!

Travis Black's picture

If you ever get the error, Fatal error: Call to undefined function curl_init(), have no fear. All you have to do is install php curl libs.

OSX+MacPorts
sudo port install php5-curl

Debian or Aptitude based systems
sudo apt-get install php5-curl

sudo apache2ctl graceful

Vocabularies, Nodequeues, and Views

Déja Augustine's picture

We've all been there. A client wants the nodes of one content type to be filtered and displayed on six different pages based on the content of one of the fields. No problem! Views was MADE for a task like this!

Oh yeah, I forgot, there's this twist. The client wants to be able to control the order that the nodes appear in. Again, no problem! We have Nodequeue!

When you create a nodequeue, it automatically generates a corresponding view that's pre-configured to receive the nodes in the queue, in the prescribed order. Excellent. Let's just whip up a node queue for each page that the customer wants. STOP RIGHT THERE!

This seems like the most straight-forward solution, but there are hidden problems. If we create one nodequeue per page, then we have to maintain each view independently. Need to suddenly add a field to the view? Need to do custom templates? Maintaining six identical nodequeues becomes a black hole of time.

Enter the Smartqueue

Nodequeue ships with the Smartqueue API and includes one for taxonomies right out of the box. A Taxonomy Smartqueue allows you to create a single nodequeue, associate it with content types and vocabularies. When you add a node to the queue, it is automatically placed in one or more subqueues based on its terms. The user can then re-order the nodes within each individual subqueue to the order they would like them displayed.

Our six-page, six-nodequeue, six-view solution can now be reduced to a six-page, one-nodequeue, one-view solution. By utilizing the Nodequeue: Subqueue arguments, you can easily select which subqueue to display in the view, and by adding additional displays, you can easily customize your views to accommodate any minor differences between the different subqueues.

Downloading Modules and Themes when ftp.drupal.org is Down

Paul Venuti's picture

As of this posting, ftp.drupal.org has been down for about five hours. This is kind of a bummer, because as long as FTP is down, you can't download new modules.

Or so I thought. If you use Drush, you can easily check out the code for the latest stable release of a module from CVS using the --package-handler argument:

drush dl betterselect --package-handler=cvs

As always, Drush figures out which version of the module (or theme) is the latest and grabs that for you. The only difference from using ftp.drupal.org is that you'll get the CVS folder in your sites/…/modules directory, but you can just delete it. Or not. It's not hurting anything.

Even if you're not using Drush, though, you can always check the code out from CVS directly.

The really funny thing, however, is that if you're not already using Drush, you can't use Drush to download Drush, which you could do if you were already using Drush — in which case, of course, you would not need to. I believe the lit kids call this "irony".

Drupal Services Module

Déja Augustine's picture

Drupal is an extremely powerful and flexible content management system, and is a very strong foundation for a data-driven website. However, there are times when a solitary website just isn't enough -- for example you may want to have one main site and a number of affiliated sites, you may want to write a stand-alone application that can interact with your Drupal site, or you may want to share data between a Drupal site and a non-Drupal site. Situations like this call for a web service!

A web service is typically an API (application programming interface) that is hosted on a web server and exposed to the internet. One shining example of web services in our daily lives occurs every time you click the Submit button in an online shopping cart. A web service is responsible for telling the vendor that your credit card is valid and has enough room for you to make your purchase. Web services are also used to get your shipping quotes and reserve your tracking number.

The long and the short of it is that web services let websites talk to websites, websites talk with applications, and applications talk to applications.

Now, there are a number of different web service protocols (RPC, SOAP, AMF, REST, etc.). One of the drawbacks to web services is that they tend to be tied to a specific protocol, which means that you have to package up whatever data you wish to send to a web service in the protocol expected by the web service. If you are consuming multiple web services, it's quite possible that you'd have to package your data several different ways. To use the ecommerce example from above, you may have to package your order information (number of packages, each package's weight, source and destination addresses, etc.) for a SOAP-based shipping quote web service, and the customer's payment information for a REST-based credit card authorization service. This creates a lot of unnecessary complication in the world of web service consumption.

With all this in mind, when you sit down to write your own web service, where do you begin? What protocol should you use? How are you going to make the great behemoth of possibility that is Drupal available as a web service without sacrificing all that great power and flexibility by hard-coding your service to serve up only certain types of nodes and fields?

The beautiful answer is you don't have to think about any of that.

Enter the Services module. (http://drupal.org/project/services)