Want to get Lullabot article, videocast, and podcast announcements delivered right to your in-box?
Let us know your email address (we won't share it) and we'll let you know when anything exciting happens.
Making Attachments Appear Across Translations
Drupal 6 supports translation of content with the core Content Translation module. So you can create a page in English, then translate the page to Dutch.
But what if you attach a file to the English page? It does not show up on your Dutch translation. And what if you are using CCK and FileField? That's the case that I want to cover in this article.
First, I installed Drupal 6.6, enabled the Locale module, and added the Dutch translation (for the proper way of installing translations, see Addison Berry's screencast, Installing Drupal with a Translation).
I installed CCK 6.x-2.1 and enabled the Content module and some others (Node Reference, Number, Text, Option Widgets).
I installed the 6.x3.x-dev snapshot of FileField (it's better to use an actual release but I saw some bug fixes going into the module and figured I'd test it). I enabled FileField module.
I enabled the core Content Translation module.
Then I installed i18n 6.x-1.0-BETA6, which is the latest release of the Internationalization Module. I enabled the Internationalization and Synchronize Translations modules.
I needed a CCK content type to test with so I created one:

Solving the permission denied error when updating Drupal via CVS
If you update Drupal via cvs by doing the following kind of command (here I am updating a Drupal 6.4 installation to Drupal 6.5):
$ cvs update -dP -r DRUPAL-6-5
you might run into the following error:
...
cvs update: Updating scripts
cvs update: Updating sites
cvs update: Updating sites/all
cvs update: Updating sites/default
P sites/default/default.settings.php
cvs [update aborted]: cannot open .new.oxI8ko: Permission deniedThe update is aborting because the cvs program does not have permission to create a temporary file in the sites/default directory of your Drupal installation. Notice there's no "w" in the permissions for the "default" directory:
$ ls -l sites/
total 0
drwxr-xr-x 6 jvandyk staff 204 Oct 22 10:07 CVS
drwxr-xr-x 4 jvandyk staff 136 Oct 22 09:18 all
dr-xr-xr-x 6 jvandyk staff 204 Oct 22 09:20 defaultSo the solution is to give write access temporarily to the user running cvs, then take it away again after the update:
$ chmod u+w sites/default
$ cvs update -dP -r DRUPAL-6-5
...
cvs update: Updating scripts
cvs update: Updating sites
cvs update: Updating sites/all
U sites/all/README.txt
cvs update: Updating sites/default
U sites/default/default.settings.php
cvs update: Updating themes
...
[cvs proceeds with no errors]
$ chmod u-w sites/defaultThe chmod u+w command means "give the user who owns this file write permission" and chmod u-w means "take write permission away from the user who owns the file."
Announcing BeautyTips, a jQuery Tooltip Plugin
Well I've done it! I've written my first jQuery plugin. The plugin creates rollover balloon-help style tooltips for any element on your page. While there were a few different tool tips plugins that existed for jQuery, none of them seemed to quite meet my need for a NetFlix (or Google Maps) style talk-balloon popup.
It quickly became apparent that in order to accomplish this type of flexible talk-balloon tooltips, I was going to need to engage the use the HTML 5 canvas element (and a lot of high-school algebra and trigonometry). The result is BeautyTips, a flexible and smart tooltip which calculates the best position for each tooltip bubble and then draws it. Bubbles can have rounded corners with a variable corner radius, "spike" length, color, opacity, and much more.
The canvas element is supported in modern versions of Firefox, Safari, and Opera. However, Internet Explorer needs a separate library called ExplorerCanvas included on the page in order to support canvas drawing functions. ExplorerCanvas was created by Google for use with Google Maps and several of their other web apps. Include it on the page according to the readme file and BeautyTips should work just fine in IE.
Beauty Tips was written to be simple to use and pretty. All of its options are documented at the bottom of the jquery.bt.js file and defaults can be overwritten globally for the entire page, or individually on each call.
Drupal, duplicate content, and you
Does Google's "duplicate content penalty" harm Drupal sites? No! Here's why.
For years, Drupal has enjoyed a solid reputation as a search engine friendly CMS. It generates relatively clean, standards-compliant HTML out of the box; syncs up the important TITLE tag with semantically useful H1 and H2 tags in the body of each page; and provides short, human-readable URLs with plentiful options for customization. (Anecdotal evidence: several years back, I wrote a post on my Drupal-powered blog that mentioned the name of the company I worked for. Within two weeks, my blog post ranked higher than the company's own web site on Google.)
Recently, I've witnessed a number of discussions where people expressed concern about the way Drupal generates the human-readable URLs that help make it Google-friendly. In particular, they were worried about Google's dreaded Duplicate Content Penalty, a system designed to keep spammers from flooding Google with the same content at dozens (or hundreds!) of URLs. There's a lot of confusion floating around, so for the geeks in the crowd (and the not-so-geeky interested in learning how things work behind the scenes), I thought it would be useful to give a guided tour of how Drupal manages and generates URLs.
"Classic" Web Problems, Solved
A lot of energy in the Drupal world goes towards solving complex problems: giving administrators ways to build publishing workflows without writing code, integrating with cool new APIs, automatically translating site content into Klingon... You know. The usual.
With all of that energy focused on complex architectural problems, it's easy to lose sight of the simple solutions that Drupal provides for really common "classic" web problems. This really hit home the other week as I sifted through an old Zip disk with archives of sites I'd built for clients in the heady days of the late 90s. One by one, I started ticking off requests my clients had made that today's site-builders can solve in minutes with Drupal modules -- no wacky configuration, no complicated recipes. Just a simple, "Yes!" when a client says, "Can you...?"
Beginning with Drupal 6 and PostgreSQL on OS X 10.5 Leopard
PostgreSQL (often called Postgres) is the Other Major Database for Drupal. It has one of the same strange characteristics that Drupal does: its adherents swear that it is the best thing since sliced bread. In this article, we'll examine how to get PostgreSQL installed, then get a Drupal 6 installation running on top of it.
Assumptions: XCode Tools from your Mac OS X DVD (also available from Apple Developer Connection) are installed. Your copy of PHP has support for Postgres (I used MAMP and it worked out of the box).
Drupal Community Philosophies
In presentations I usually point out that Drupal is three things:
- A content management system: The forms you fill out, the buttons you click, and the content you work with. The stuff you interact with every day while you manage your site.
- A content management framework: The low-level APIs that let you extend and modify Drupal to make it do everything from ratings to image galleries to your dishes.
- A community: The thousands of documentation writers, developers, testers, support providers, designers, and evangelists from all over the world, working together to make Drupal a better platform every single day.
It's this third point I'd like to talk a little more about today, by providing some insights into the general Drupal community philosophies that guide our interactions with one another, and as a result, the growth and direction of the Drupal project as a whole.
The Drupal community has several core philosophies, some of which are documented, others of which you just kind of pick up from spending enough time watching various interactions on the forums, on issue queues, and on the mailing lists. Here's a brief guide, for the uninitiated.
Avoiding the Template.php of Doom (or, Overriding Theme Functions in Modules)
Drupal's theming system offers developers and designers a flexible way to override default HTML output when specific portions of the page are rendered. Everything from the name of the currently logged in user to the HTML markup of the entire page can be customized by a plugin "theme".
Unfortunately, this system can be its own worst enemy. Themes are very powerful, but in many cases they're the only place where specific output can be changed without hacking core. Because of this, themes on highly customized production sites can easily turn into code-monsters, carrying the weight of making 'Drupal' look like 'My Awesome Site.'
This can make maintenance difficult, and it also makes sharing these tweaks with other Drupal developers tricky. In fact, some downloadable modules also come with instructions on how to modify a theme to 'complete' the module's work. Wouldn't it be great if certain re-usable theme overrides could be packaged up and distributed as part of any Drupal? As it turns out, that is possible. In this article, we'll be exploring two ways to do it: a tweaky, hacky approach for Drupal 5, and a clean and elegant approach that's only possible in Drupal 6.
The Open Security Model, Drupal and ExpressionEngine on Security
I recently evaluated ExpressionEngine for viability as a CMS replacement for Drupal. ExpressionEngine (EE) is a commercial CMS tool built on PHP and mySQL by EllisLab. A client of ours was attracted to its clean interface, built-in features, and expandability.
I was impressed by the well-designed UI and the flexibility of EE's templating engine. There are definitely lessons the Drupal community can learn from their attention to detail. In fact, as I explored the EE support forums, I discovered a great deal of antagonism towards Drupal -- to my surprise, it wasn't based on features or learning curve, but on the idea that Drupal is insecure.
In the forums, comments such as this were common whenever Drupal or other CMS systems were brought up for comparison:
Some reasons why one might not want to use Drupal?
[2/5] Drupal Acidfree Module “node titles” SQL Injection Vulnerability
[2/5] Drupal Unspecified Spoofing Weakness and Cross-Site Scripting
[2/5] Drupal Project Issue Tracking Module Multiple Vulnerabilities
[2/5] Drupal Project Module Script Insertion Vulnerability
[4/5] Drupal Comment Preview Arbitrary Code Execution
Module-In-A-Box: We Built Admin Tools So You Don't Have To
Building a Drupal module from scratch can be remarkably simple -- just create an .info file, create a .module file, then implement a few functions like hook_menu and hook_nodeapi. In no time, you've got a module up and running, leveraging Drupal's APIs and adding functionality to your site.
The problem
Unfortunately, things can get a bit more complicated if your module needs to store and maintain its own collection of data. The Custom Links module, for example, allows users to add clickable links to the bottom of each node on a Drupal site. While the code to actually add the links to each node is only a few dozen lines of PHP, it takes a few hundred lines of code to store and manage the information about those links. The module needs to create a database table to store its records, provide management pages so an admin can add new links, manage permissions, handle adding and editing records, request confirmation when administrators delete a record, and so on.





