May 05 2008
IO1
May 05

This post is the first in our Drupal SEO series and attempts to give you a reasonably indepth overview of what the different aspects of a standard drupal installation you will need to address for SEO are.

Drupal SEO on a bare bones installation (i.e. no additional modules installed) still needs a fair degree of knowledge if your new to drupal or SEO and can be quite daunting for someone new to SEO and/or Drupal. 

The post is broken down into three sections:

1) Modules and their relevance to Drupal SEO

2) Anatomy of a Blog post from an SEO viewpoint

3) A review of all the admin settings and how they impact SEO 

(Obviously I would never recommend doing a bare bones install as there are some wonderful modules that do loads of the work for you, but I think its important to understand the base your working from.)

Modules and their relevance to Drupal SEO


Aggregator Allows you to quickly fill your site with content from high quality RSS sources, especially useful while you build up your own content, play nice with this and don't abuse it Blog Blogging is critical to any decent SEO campaign is provides a great source of link bait and tends to be extremely topical which is critical in a competitive space Blog API The blog API is fantastically useful, a lot of people use something like the performance plug-in to remotely publish content however while this is useful, this api also provides an ideal opportunity for you to create a centralised publishing system (cover this in more detail later in the series) to allow you to do scheduled postings Book The book module is extremely handy for creating structured content and not having to overly worry about making sure everything links Color Be careful with the color module as if you inadvertently hide navigation or links by having too light of colours on a light background then you might be at risk of getting hit with a penalty by Google Comment Comment is great for allowing user generated content, but watch out for spam Contact Make sure you exclude contact forms via your robots.txt or just show them to authenticated users Drupal of no significance for seo Forum Forums are brilliant if handled properly, ensure that they are well structured and that the individual fit into the overall ontology of the site Help of no significance for seo Legacy of no significance for seo Locale Very handy for doing optimisation for multilingual SEO, normal rules apply Menu Very handy for ensuring that you site is easily navigable by spiders Path Essential to allow you to provide pretty URLs, this is critical Ping This is incredibly important, Google works on a principal of first found is the owner, and it takes effort to get ownership of content back, enabling this allows you to tell Google the minute you publish content and thus claim ownership earl Poll Can be useful for link bait Profile If you allow users to add profiles then this feature is incredibly important as the more content you allow them to put up the more credibility there profile gets, if your targeting name based optimisation this is a much Search OK, this can be used to return search results and drive robots deeper into your site, however I would not recommend this if you don't know what your doing as Google has clearly stated they will penalise for returning search results on URLs. Statistics Critical so you know whats working / not and general stats (obviously better to have a more comprehensive module but will be a separate articles) Taxonomy Taxonomy is the single most important reason for using Drupal, its only truly useful after extensive keyword research, once you have done your research then create all the logical taxonomies and terms for easy use going forward Throttle This is both useful and dangerous, if you get it right then you can ensure that you are showing that your site can handle load which is critical to robots, however if you throttle the wrong things then you actually can damage your SEO campaign significantly, my advice is dont use it unless your experienced Tracker Tracker is very handy for creating additional navigation elements and also provides natural linkbait for users who want to promote their own posts externally Upload Imagery is becoming increasinly more important as a source of traffic and allowing users to upload images can help gain with traffic from things like google image search

Anatomy of a Blog post from an SEO viewpoint 

Click this image to get a full view, its shows the basic elemnts of a blog post and how they relate to Drupal SEO

drupalseo-tutorial1.jpg

Drupal Administation settings from a SEO view.

This section will give some insight into the different settings available under the Drupal Administration section

Administer - Content Management

  • Books admin menu
  • Under Books you will see two options "List" and Orphan Pages", list is not relevant as its just a list of the books, however under Orphan pages its important to make sure that no pages have become ophans search engines like to see nice structured links in and out of pages so make sure that no pages have become ophaned.

  • Categories Admin Menu
  • This section is incredibly important however is driven by your keyword analyis, so as long as it implements the keywords structures as defined in your SEO keyword analysis then you will be fine. You have to really think this part through and make sure that you have taxonomies correctly allocated to types and weighted based on preference, its always a good idea to include a description and help text so that people who are not as familar with the keyword setup dont make silly mistakes.

  • Comment Admin Menu
  • This is really just so that its easier to manage comments by users, its very important that if you do require approval of comments that this section is checked at least daily so that you are not holding up valuable content from being published on the site and so that you dont leave spam on your site. The actual comment settings dont have too much of an impact unless you change the display order (remember the content at the top of the page is seen as the most important) and is pretty much just a best practice excersise outside of not doing silly stuff.

  • Content Admin Menu
  • This is really just an admin function to easy viewing of content in different states.

  • Content Types Menu
  • This is an area where you can really optimise different content types if you want to get into advanced topics, however for a bare bones installation probably best to leave it alone until your more experienced, I will cover this in some depth in a future post. The one area that is however of significance is the default workflow options for each content type and whether or not they are published/promoted etc. review these options and make sure that the defaults suit your purpose but make sure you know the impact of what your changing.

  • Forum Admin Menu

  • This section allows you to setup forums which can be a great source of user generated content, containers and forums should be named and structured inline with your keyword analysis, mostly the default settings here are fine to start with.

  • News Aggregator Menu
  • This section deals with feeds that you are taking from other sites, make sure your categories are based on your keyword research, the only real signifcant area here is the settings menu and in particular the "allowed html tags" make sure that these are sensible and what you want, in most cases the default set will be fine however make sure that if you are adding any additional tags that these are not ones that could be abused against you. Normally you will want to increase the number of items show and mkae sure that the discard is at the longest period available, personally I would not use this module but as were dealing with a bare bones install then its a case of make the most of something that is weak from an SEO viewpoint.

  • Post Settings Menu
  • This is normally fine to leave alone if you dont have a very active site.

  • Rss Publishing
  • This is the part that deals with your outgoing feeds, to be honest this lacks anywhere near the levels of controls I would like but the two that are there are reasonable defautls, always make sure that you dont select Full Text in the "Display of XML feed items" as their is too much danger that someone else will end up owning your content in googles eyes. Items per feed I like to set to the maximum of 30.

  • Search
  • Not relevant for Drupal SEO

Administer - Site Building

  • Blocks
  • Blocks allow you to put navigation elements around your site in a structured and unstructured manner. Its completely dependant on you if these fit in with the purpose of the site however you should always remember that google likes links and the more links that you provide to releated content the better your seo will be. For example when viewing a blog post it would almost always to be able to see the "Recent blogs posts" and likewise if in a forum it would make sense to have "active forum topics" and "new forum topics" blocks enabled.

  • Contact form
  • Not relevant for Drupal SEO

  • Menu
  • This is reall important as it defines the primary navigation for your entire site, make sure keywords are used heavily in menus and make sure that critical parts of the site are part of the primary navigation.

  • Modules
  • Only relevant in the context of making sure SEO related modules are enabled

  • Themes
  • This is very important in that some themes are better suited to SEO than others, so make sure that you choose a good theme from an seo view that still meets your needs (css based, content at the top etc). Configure the theme options such as site slogan etc. so that it display critical pieces of information

  • URL Aliases
  • This section allows you to customise the urls to be friendly i.e. readly by normal users, be careful here, realise thats its not implmenting a proper redirect and as such can cause your duplicate content issues if your not careful

    Administer - Site configuration

  • Administration Theme
  • Not relevant for Drupal SEO

  • Blog APIs
  • This is where you enable remote blogging so that your can use external tools to write and publish content, this is very handy

  • Clean URLS
  • This is essential, make sure you enable this if you want to have a hope of ranking for competitive terms

  • Date and time Menu
  • Ok, if your paranoid (I am) then make sure the date and time settings match your target market not where you are.

  • Distributed authentication
  • Not relevant for Drupal SEO

  • Error Reporting

  • Good quality is the trademark of good SEO so make sure that these settings meet your requirements for logging and customise accordingly

  • File System Menu
  • Again, if really really paranoid name the directory using your primary keyword, as it will be linked in the urls of images etc.

  • File uploads
  • Strictly speaking not really an SEO issue however well SEO'd PDF's etc. can be helpful, but depends on circumstance.

  • Image Toolkit
  • Not relevant for Drupal SEO

  • Input Formats Menu
  • This allows you to control the input of users, its critical that you get this right for public areas of the site or you could suffer from spam or open up major security issues, if unsure leave it alone.

  • Localization Menu (yep I hate the z as well)
  • Very important for multilingual SEO but too indepth to be covered in this post, so I will cover in a dedicated post

  • Perfromance Menu
  • Mostly this is fine but be careful if your using aggressive caching to make sure you know exactly whats getting cached.

  • Search Settings
  • Not relevant for Drupal SEO

  • Site Information
  • This section should be heavily SEO'd, make sure that your messages are well tuned to your target niche and dont keyword stuff

  • Site maintenance menu

  • Customise the message so that you still get some keywords in there, you dont want your site to be down but make sure if it is your still getting something useful across to google et al.

  • Sites Registry Menu
  • Not relevant for Drupal SEO

  • Throttle
  • Be very careful in using this that your not showing a lack of information to robots.

    Administer - User management

  • Access Control Menu

  • Loads of room for messing up here, the rule is simple, Search engines = Anonymous User, if you want it to appear in search results then you have to allow anonymous user to access it.

  • Access Rules Menu

  • Use these to ensure that you dont get spammy user names on your site, you dont want to end with with users called cialisviagrapoker or even something that implies that a normal user has some involvement with the company e.g. customerservices.

  • Profiles Menu
  • This allows you to create rich profiles, remember profiles can be considered user generated content and form a good source of linkbait so put some effort in.

  • Roles Menu

  • Not relevant for Drupal SEO

  • Search Users Menu

  • Not relevant for Drupal SEO

  • Users Menu

  • Not relevant for Drupal SEO

  • User Settings Menu
  • Not relevant for Drupal SEO

Administer - Logs

Pretty self explanatory, keep a regular eye on these and deal with issues that show up, remember search engines like good quality i.e. minimal errors

Bookmark/Search this post with

May 05 2008
IO1
May 05

Drupal SEO - Bare Bones installation is the first in a series of Drupal SEO related posts and this posts looks at SEO for drupal with no additional modules installed. We initially looked at dealing with some of the advanced issues relating to SEO however decided that it would be more useful if we started at the beginning and build up to these topics.  This series is aimed at giving an indepth look into all the primary areas that affect most people when building websites that they need to rank in Google et al.

We do a lot of large scale seo for enterprise clients and have gained an in-depth knowledge of what it takes to really be successful in highly competitive environments. To many people refer to Drupal SEO as easy without realising the critical factor in SEO! If everyone can do it then it gets harder!!! I don't believe that any other framework holds a candle to drupal for SEO, but what makes great SEO is being ahead of the curve not adopting it after everyone else already has. What makes Drupal great for SEO is the ease with which you can bend and shape it to your exact requirements without having to worry about the bits underneath as your know they are handled in a nice seo friendly fashion.

Current List of topics we plan to write on over the coming weeks include:

  • Drupal SEO - Bare Bones
  • SEO Statistics and Analysis - Setting yourself up to win
  • Performance and SEO
  • Security and SEO
  • Taxonomy supporting or killing your SEO
  • RSS and Aggregation
  • Titles and paging issues
  • Ecommerce SEO
  • Advanced Url handling for SEO (beyond pathauto)
  • Handling Multimedia
  • SEO multisite considerations
  • Social networking for SEO
  • Migrating to - SEO impacts
  • Theming impact on SEO
  • Developers and SEO
  • Internationaliz(s)ation and SEO
  • Large Scale SEO
  • Meta data and its real importance

Bookmark/Search this post with

May 04 2008
May 04

The Drupal API at api.drupal.org provides the reference documentation for Drupal core. The documentation within the Drupal API is constructed by the API module which parses the Doxygen comments in the Drupal core files. A major benefit of the API module is that it can also be used to generate documentation for contributed modules.

We're very happy to announce the launch of a new site that will provide much needed reference documentation for contributed modules, the Contributions API.

We've added a handy contextual block that provides quick links to .module files, see the "Modules in <version>" block and the Drupal 6 modules page to see which modules are currently being documented.

At the moment there are only a handful of contributed modules being documented in the Contributions API but you can request more modules using the module request form.

If you have any suggestions, please use the suggestions form.

Posted by psynaptic

May 03 2008
May 03

While upgrading a couple of different Drupal (5.x) sites, I ran into an annoying issue where the update.php script just redirected to the sites homepage after the "Select Version" page. The server in question has PHP's mod_security enabled which has caused some problems with other sites in the past, so I think it's related to that, but I'm not totally sure.

Any way, the fix is to add the following line of code to your update.php script before line 794

if ($_POST['op']) $_REQUEST['op'] = $_POST['op'];

The finished product should look something like:

update_fix_schema_version();


update_fix_watchdog_115();


update_fix_watchdog();


update_fix_sessions();

//start new code
if ($_POST['op']) $_REQUEST['op'] = $_POST['op'];
//end new code

$op = isset($_REQUEST['op']) ? $_REQUEST['op'] : '';


switch ($op) {


        case 'Update':


                $output = update_update_page();


                break;

Have you had the same problem? Do you know what is causing it? Did the above code work for you?

May 02 2008
May 02

After upgrading to Drupal 6 I opted for a quick and dirty XML sitemap approach. Before I was using the XML Sitemap module which is currently available for Drupal 6 as a development snapshot or directly from CVS. The module offers settings for priority and change frequency. Moreover the module allows for adding taxonomy term and user URLs to the sitemap.

I only wanted nodes and the front page to appear in the sitemap's XML output without priority or change frequency information. Having the path and pathauto modules enabled, which ensure that every node gets a meaningful and search engine friendly URL, a simple database query joining two tables is enough to get the necessary data for all published nodes.

Code Snippets

To make the sitemap reachable via a URL a menu item of the type MENU_CALLBACK goes into the menu hook of a module named custom. The menu hook changed in Drupal 6 and so did the whole menu system which was completely rewritten by chx. To learn more about it, read the menu module documentation.

<?php
function custom_menu() {
 
$items = array();
 
$items['sitemap'] = array(
   
'title' => 'XML Sitemap',
   
'access arguments' => array('access content'),
   
'type' => MENU_CALLBACK,
   
'page callback' => 'custom_sitemap'
 
);
  return
$items;
}
?>

When the URL /sitemap is requested the function custom_sitemap() is called. The sql query joins the node and url_alias tables to retrieve all modified dates and URL aliases of published nodes which are stored in an associative array called urls. The URL aliases 403 and 404, that are used for custom error pages, are omitted from the array.

What follows is putting together the XML output string in a here document and a foreach loop and printing it out.

<?php
function custom_sitemap() {
 
$base = ($_SERVER['HTTPS'] ? 'https://' : 'http://') . $_SERVER['SERVER_NAME'] . base_path();
 
$urls = array();
 
$result = db_query("SELECT ua.dst, n.changed FROM {node} n INNER JOIN {url_alias} ua ON ua.src = CONCAT( 'node/', n.nid ) WHERE n.status =1 ORDER BY n.changed DESC");
  while(
$r = db_fetch_object($result)) {
    if (
$r->dst != 404 && $r->dst != 403) {
     
$urls[$base . $r->dst] = $r->changed;
    }
  }
 
 
header('Content-Type: text/xml');
 
$xml =<<<EOF
<?xml version="1.0" encoding="UTF-8"?>

<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url><loc>$base</loc><changefreq>daily</changefreq></url>
EOF;
  foreach ($urls as $url => $t) {
    $xml .= '<url>';
    $xml .= '<loc>' . $url . '</loc>';
    $xml .= '<lastmod>' . date("Y-m-d", $t) . '</lastmod>';
    $xml .=  '</url>';
  }
  $xml .= '</urlset>';
  print $xml;exit();
}
?>

May 01 2008
May 01

So I'm now aggregated on Planet Drupal. I'm Jakob (hi!), and you may remember me from projects such as Version Control API (Summer of Code '07), Temporary Invitation or the Duration CCK field. Granted, the latter is brand new, so there's little chance you know me from that one.

But introducing myself is not the purpose of this post, of course. The real purpose is to introduce the student that I'll be mentoring (together with AjK) during this year's Summer of Code. In his own words:

Hi! My name is Markus Schanta, I'm 21 years old and I live in Eisenstadt, Austria. I study Software & Information Engineering at the Vienna University of Technology and Business Administration at the Vienna University of Economics.

During this summer I will be working on the Version Control API, preparing it for usage on Drupal 6 and drupal.org. The Version Control API, which originates from Jakob's last year's SoC project, has largely decoupled the Project module from cvs.module. This project will unleash the full potential of the Version Control API and make it production ready for a new set of users including drupal.org.

My project will lead to increased flexibility in handling projects, reduce future maintenance costs and last but not least make it possible to use a more modern revision control system (like Subversion which is frequently in the talks) on drupal.org.

I'm really looking forward to working on this project an I'm sure that it's going to be a really exciting summer!

In other words, this time we're going to kill cvs.module for good. Congrats to Markus and all the other students that were accepted for this year's Google Summer of Code. Little fits better than the wise words of certain KDevelop developers:

It's gonna be great, you're gonna love it!

And that's all there is to say :)

Apr 30 2008
Apr 30

The issue with using the Locale module to translate single strings on your site for tweaking text is that it gives you a performance hit. When the Locale module is used for this, it can make a query to the database every time the locale() function is called through t().

Localization ExportThe solution to this is String Overrides, which stores these string replacements in the variables table, which is cached on every page load anyway. The problem with it was that it proved to be quite difficult to migrate from using the Locale method of string replacement to String Overrides. Well, it just got a whole bunch easier.

With version 1.5 of String Overrides, you have the ability to import *.po files. These *.po files can be generated by the Locale module's language. You can see a demonstration of exporting a *.po file from the Locale module in the image on the right.

String Overrides - ImportOnce you have the *.po file, you can visit the String Override settings at admin/settings/stringoverrides, click on Import, select the *.po file, and import the string replacements straight into String Overrides. You can see a screenshot of it on the right.

This functionality is only part of the Drupal 5 version at the moment, and will shortly be ported to Drupal 6 shortly.

Apr 29 2008
Apr 29

I was recently playing around with the design of my twitter page and got it to look like Garland, the default design for Drupal. A number of you have asked me about it, so I thought I'd publish the values I'm using. So, if you want your Twitter page to also look like Garland, you can input the following values into your Twitter design.

Background Color: EEF5FA Background Image: garlandtwitter.png Text Color: 494949 Name Color: 494949 Link Color: 027AC6 Sidebar File Color: E1F0FA Sidebar Border Color: E1F0FA

Of course, I'd recommend taking my website logo out of garlandtwitter.png, and putting your own image in there, but that's completely up to you.

Apr 28 2008
Apr 28

I was inspired by this episode of SEOMoz's whiteboard friday where Rand talks about tracking non-traditional conversions (like when someone posts a comment on your blog) so I decided to check out how easy this was to do in Drupal.

By default, when someone submits a comment, they are redirected back to the node to view their comment (even if it needs approval first). This causes a problem because it doesn't really give us a unique URL to use as a goal in Google Analytics (unlike the webform module).

What you'll need to do is grab the great actions module which we will use to redirect the user to a custom thank you page once their comment has been submitted. And while thats downloading and installing, create a new page that will be the thank you page when users submit a comment.

Next, navigate to Site Configuration > Actions and create a new advanced action to redirect to your new thank you page click save. Now, just head over to the Triggers settings (Site Building > Triggers > Comments) and assign your new action to the "After saving a new comment" trigger.

Make a new advanced action available

Now all you need to do is setup the goal in Google Analytics and wait for the data.

Do you have any other non-traditional conversions that you're tracking? If so, what are they and how are you tracking them?

Apr 28 2008
Apr 28

This article describes how to install the Drupal 6.2 CMS on MySQL 6.0, using the Falcon Storage Engine. The operating system is a default Ubuntu 8.04 "Hardy Heron" (x86) installation.

I will make a few assumptions here, in order to keep the instructions simple: a fresh OS install, no other MySQL databases or web services are running or have already been installed. Both MySQL and the web server are installed on the same host. You should be able to become root to install packages and to have access to the local file system and the system configuration.

This article will explain how to install and configure Apache/PHP, MySQL 6.0 and Drupal 6.2.

Prerequisites

Running Drupal requires a web server (e.g. Apache) and PHP. We will use the packages as shipped with the distribution and will then install a MySQL 6.0 preview binary from http://dev.mysql.com. Other web servers like lighttpd will work equally well, but this article focuses on using the Apache web server.

Fortunately the MySQL 5.0 client applications as shipped with Ubuntu Linux are compatible with the MySQL 6.0.x client/server protocol, so we only make use of the 6.0 server and will use the installed, pre-compiled client applications and libraries to connect to it - there is no need to recompile PHP or anything to get going!

First of all you have to make sure the following packages have been installed (e.g. by using a package management tool like the Adept Package Manager, synaptic, aptitude or apt-get):

  • apache2
  • libapache2-mod-php5
  • php5
  • php5-common
  • php5-mysql
  • php5-gd
  • mysql-client-5.0

To enable the mod_rewrite Apache module (as recommended for Drupal), you need to enter the directory /etc/apache2/mods-enabled and create a symlink to the module loading instructions:

cd /etc/apache2/mods-enabled/
sudo ln -s ../mods-available/rewrite.load .

This will ensure, that mod_rewrite will be loaded when Apache starts up.

Additionally, you have to edit the file /etc/apache2/sites-available/default and make one change. In the directives for the Directory /var/www, change AllowOverride from "None" to "All". This will make sure that Drupal can enable the rewrite engine to allow nicer looking URLs.

Now restart the Apache server to apply the changes:

sudo /etc/init.d/apache2 restart

To verify that Apache is up and running, try opening http://localhost/ in a browser on the same machine that runs the web server. You should get a simple page, stating that "It works!".

Installing the MySQL 6.0 Falcon preview

Now that the web server is up and running, we need to install a MySQL database server that the Drupal installation can use. Download mysql-6.0.5-alpha-pb87-linux-x86.tar.gz (or any newer package, if available) from http://downloads.mysql.com/forge/falcon_feature_preview/

Create a /etc/mysql/my.cnf file with the following content (replacing the existing file, if necessary):

[client]
socket=/var/run/mysqld/mysqld.sock

[mysqld]
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
socket=/var/run/mysqld/mysqld.sock
default-storage-engine=falcon

The default-storage-engine option will make sure that every CREATE TABLE statement will default to using the Falcon storage engine. Now extract the binary tarball distribution into /usr/local and perform the following steps to finalize the installation/configuration:

$ sudo groupadd mysql
$ sudo useradd -g mysql mysql
$ cd /usr/local
$ sudo tar zxvf ~/mysql-6.0.5-alpha-pb87-linux-x86.tar.gz -C /usr/local
$ cd /usr/local
$ sudo ln -s mysql-6.0.5-alpha-pb87-linux-x86 mysql
$ cd mysql
$ sudo chown -R mysql .
$ chgrp -R mysql .
$ scripts/mysql_install_db --user=mysql
$ sudo chown -R root .
$ sudo chown -R mysql data
$ sudo ./bin/mysqld_safe --user=mysql &

The installation procedure is outlined in more detail in the reference manual at http://dev.mysql.com/doc/refman/6.0/en/installing-binary.html

If you want to enable the automatic startup of MySQL at system bootup time, you need to install an init script in /etc/init.d/ - follow the instructions as outlined in the reference manual. Note that the mysql.server script has been moved from the directory support-files to share/mysql for the binary tarball distributions and that the current 6.0 documentation has not been updated yet (I filed BUG#36382 about this).

Now start the server using the mysqld_safe script:

$ sudo /usr/local/mysql/bin/mysqld_safe &

Next you should verify that you can connect to the server and that the Falcon storage engine is enabled:

$ mysqladmin version
mysqladmin Ver 8.41 Distrib 5.0.51a, for debian-linux-gnu on i486
Copyright (C) 2000-2006 MySQL AB
This software comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to modify and redistribute it under the GPL license

Server version 6.0.5-alpha-pb87
Protocol version 10
Connection Localhost via UNIX socket
UNIX socket /var/run/mysqld/mysqld.sock
Uptime: 43 min 6 sec

Threads: 1 Questions: 6 Slow queries: 0 Opens: 15 Flush tables: 1 Open tables: 8 Queries per second avg: 0.2

$ mysql -u root
[email protected]:(none) > SELECT * FROM information_schema.engines WHERE engine='Falcon';
+--------+---------+-----------------------+--------------+----+------------+
| ENGINE | SUPPORT | COMMENT | TRANSACTIONS | XA | SAVEPOINTS |
+--------+---------+-----------------------+--------------+----+------------+
| Falcon | DEFAULT | Falcon storage engine | YES | NO | YES |
+--------+---------+-----------------------+--------------+----+------------+
1 row in set (0.12 sec)

Before performing the actual Drupal installation, you need to create a Drupal Database and a user account. I chose "drupal" as the user name and password, please use some more sensitive values for your own setup!

[email protected]:(none) > CREATE DATABASE drupal;
Query OK, 1 row affected (0.01 sec)

[email protected]:(none) > GRANT ALL ON drupal.* to 'drupal'@'localhost' IDENTIFIED BY 'drupal';
Query OK, 0 row affected (0.00 sec)

Now MySQL 6.0 is installed and ready!

Installing Drupal 6.2

Now that the web and database server have been set up and configured, it's time to perform the installation of our application, the Drupal content management system. Start by downloading drupal-6.2.tar.gz from http://drupal.org/ (by clicking on the Drupal 6.2 download link on the front page).

Remove the default start page /var/www/index.html and extract the content of the drupal tarball into this directory. Then change the ownerships of these files to the user that apache runs under (www-data by default):

$ sudo rm /var/www/index.html
$ sudo tar --strip-components=1 -zxvf drupal-6.2.tar.gz -C /var/www
$ sudo chown -R www-data /var/www

The Drupal package installation itself is now done, the remaining installation and configuration steps are performed in a browser by opening http://localhost/ in your browser (reload the page if you still see the "It works" default page).

DrupalInstall_1

Follow the instructions in the Drupal installation manual on how to perform the actual installation. In the "Database Configuration" dialogue, use the MySQL database username and password that you created earlier.

DrupalInstall_2

Now the Drupal installer should perform its duty and you should see you fresh Drupal installation up and running!

DrupalInstall_3

Once the installation has finished, let's verify that we're really running on Falcon by running the following query in a MySQL command line client:

mysql> SELECT TABLE_NAME, ENGINE from information_schema.tables WHERE TABLE_SCHEMA='drupal';
+-------------------------+--------+
| TABLE_NAME | ENGINE |
+-------------------------+--------+
| access | Falcon |
| actions | Falcon |
| actions_aid | Falcon |
| authmap | Falcon |
| batch | Falcon |
| blocks | Falcon |
| blocks_roles | Falcon |
| boxes | Falcon |
| cache | Falcon |
| cache_block | Falcon |
| cache_filter | Falcon |
| cache_form | Falcon |
| cache_menu | Falcon |
| cache_page | Falcon |
| cache_update | Falcon |
| comments | Falcon |
| files | Falcon |
| filter_formats | Falcon |
| filters | Falcon |
| flood | Falcon |
| history | Falcon |
| menu_custom | Falcon |
| menu_links | Falcon |
| menu_router | Falcon |
| node | Falcon |
| node_access | Falcon |
| node_comment_statistics | Falcon |
| node_counter | Falcon |
| node_revisions | Falcon |
| node_type | Falcon |
| permission | Falcon |
| role | Falcon |
| sessions | Falcon |
| system | Falcon |
| term_data | Falcon |
| term_hierarchy | Falcon |
| term_node | Falcon |
| term_relation | Falcon |
| term_synonym | Falcon |
| url_alias | Falcon |
| users | Falcon |
| users_roles | Falcon |
| variable | Falcon |
| vocabulary | Falcon |
| vocabulary_node_types | Falcon |
| watchdog | Falcon |
+-------------------------+--------+
46 rows in set (0.00 sec)

Looks like we were successful - all Drupal tables are using the Falcon storage engine! Congratulations.

From here on, you can configure and change Drupal to your heart's content. Note however, that additional Drupal modules may contain code that is specific to the MyISAM or InnoDB storage engine, your mileage may vary. In that case it would be great to notify the module developers about these incompatibilities.

If you want to quickly populate a Drupal installation with content for testing, you can use the "Devel" module. I used it to create 500 users and 10.000 test pages on my demo installation. Even though this was performed within a virtual machine running VirtualBox, the system still was very responsive and the creation of the content proceeded amazingly fast! But I did not perform any serious benchmark or load tests (it would not make much sense in a VM anyway).

Apr 28 2008
Apr 28

Is the future really free?

It seems we've entered an age where there's a land-grab happening for personal data and attention time. Look at all the web start-ups backed by venture capital. They aren't investing out of philanthropy. There's value there. YouTube is "free" but Google paid over a billion dollars for it. Why?

Here's a hint: It's not about the Tube.

You know this freaky land of free as the Web. A decade and a half into the great online experiment, the last debates over free versus pay online are ending. In 2007 The New York Times went free; this year, so will much of The Wall Street Journal. (The remaining fee-based parts, new owner Rupert Murdoch announced, will be "really special ... and, sorry to tell you, probably more expensive." This calls to mind one version of Stewart Brand's original aphorism from 1984: "Information wants to be free. Information also wants to be expensive ... That tension will not go away.")

Once a marketing gimmick, free has emerged as a full-fledged economy. Offering free music proved successful for Radiohead, Trent Reznor of Nine Inch Nails, and a swarm of other bands on MySpace that grasped the audience-building merits of zero. The fastest-growing parts of the gaming industry are ad-supported casual games online and free-to-try massively multiplayer online games. Virtually everything Google does is free to consumers, from Gmail to Picasa to GOOG-411.

The rise of "freeconomics" is being driven by the underlying technologies that power the Web. Just as Moore's law dictates that a unit of processing power halves in price every 18 months, the price of bandwidth and storage is dropping even faster. Which is to say, the trend lines that determine the cost of doing business online all point the same way: to zero.

One of the old jokes from the late-'90s bubble was that there are only two numbers on the Internet: infinity and zero. The first, at least as it applied to stock market valuations, proved false. But the second is alive and well. The Web has become the land of the free.

Has it?

There ain't no such thing as a free lunch.

The idea behind this is that there's always some sort of exchange happening, even if it's not in cash. If I buy you lunch, I'm getting something out of it -- the pleasure of your company, a chance to boast or commiserate, an opportunity to share a new restaurant discovery, freedom from an otherwise mundane meal, relief from a spiritual debt acquired when you bought me lunch last week, whatever.

And yet when I buy you lunch, it does not imply that you now are entitled to inspect my purse, or peruse the messages in my iPhone, or rummage through my dresser. Those things are considered private to most of us, right?

Chris Anderson's entire perception of the "free" present and future seems to depend upon the assumption that not only our time and attention have no value, but that our privacy has no value ... that is, no value to us.

Those things certainly have value to the companies offering the "free" services.

Last year, Yahoo announced that Yahoo Mail, its free webmail service, would provide unlimited storage. Just in case that wasn't totally clear, that's "unlimited" as in "infinite." So the market price of online storage, at least for email, has now fallen to zero....

That's zero in cash. But just because you aren't forking over cash doesn't mean something is really free. With 'free' email, it may not cost you cash, what are you handing over otherwise? It may seem trivial enough, but you are paying for that mail in terms of having advertising rolled in front of your eyes, and in terms of handing over personally identifiable information that can then be leveraged, quantified and sold to others or leveraged in other ways.

It's now clear that practically everything Web technology touches starts down the path to gratis, at least as far as we consumers are concerned. Storage now joins bandwidth (YouTube: free) and processing power (Google: free) in the race to the bottom....

...Basic economics tells us that in a competitive market, price falls to the marginal cost. There's never been a more competitive market than the Internet, and every day the marginal cost of digital information comes closer to nothing.

This brings us back to the question, Why did Google pay 1.7 billion dollars for YouTube? Answer: It's not about the Tube, it's about You.

YouTube gets your information, your attention for advertising ... and all-media licensing rights to your video in perpetuity. Hardly free. And Google gives away search results information, but sells your attention to advertisers who get to hawk their wares on our search results. If you're like me, you consider this a fair trade-off to access the quality search results Google offers.

It may seem fair and trivial, but it's not free. And maybe that's an important thing to remember.

'Who' is on first

Consider that, for decades, television has been giving you "free" programming by selling a huge percentage of your time and attention watching it to advertisers. It's no secret that television advertisers pay big bucks for your attention. (And sometimes we may even appreciate it. Heck, for me the fun of the Super Bowl comes from the new, often very creative ad spots.)

YouTube also has your attention ... and much much more: If you are registered, YouTube also has your email address, your ISP info, your rough geographical location, a record of your viewing habits, and a fair sense of your tastes and how they match up with other YouTube members. That's a lot more information than your local television channel ever had.

Google bought Doubleclick for much the same reason: Data on your attention, and a structure to monetize it.

And so on down the line.

Obviously your privacy, your time and your attention have value -- big money value.

"Hang on a minute!" you say. "I like watching YouTube, so what's the big deal?"

Perhaps that's the real point: It's not a big deal. The price you pay may be small most of the time -- small to the point of practically nothing. It's not a big deal, it's a little deal. And with millions of subscribers and bazillions of views, those little deals do add up to beaucoup bucks.

So can we at least admit that "free" is not really free, even if it is really really cheap most of the time?

Are you opting out as much as you think?

So you realize how you are making an exchange, trading elements of your privacy and attention for some "free" services. Great.

So now you can take charge of your "free" web usage, and move into the future with a full awareness. Wonderful.

So you can opt out of any exchange that crosses the line according to your own valuations and judgments. Terrific!

But what if the exchange of your privacy for "free" services is not so obvious?

Consider Facebook. AP's Martha Irvine reports that privacy-conscious users aren't as private as they might think:

People often think Facebook profiles and sometimes MySpace pages, if they're set as private, are only available to friends or specific groups, such as a university, workplace, or even a city.

But that's not true if they use applications. On Facebook, for instance, applications can only be downloaded if a user checks a box allowing its developers to "know who I am and access my information," which means everything on a profile, except contact info. Given little thought, agreeing to the terms has become a matter of routine for the nearly 70 million Facebook users worldwide who use applications to spruce up their pages and to flirt, play and bond with friends online....

...So what do these third-parties do with the information? Sometimes, they use it to connect users with similar interests. Sometimes, they use it to target ads, based on demographics such as gender and age (something Facebook and MySpace also do)....

...But experts who track online security issues think there's too much personal information flying around out there, with few guarantees that it's safe. They also think social networkers have little understanding where their information goes and how it's used — and as a result, have a false sense of security.

"I suspect that there's a whole lot of clicking without a lot of thinking," says Mary Madden, a senior research specialist at the Pew Internet & American Life Project who studies privacy issues. "So much of this sharing happens in a way that users don't see the consequences. It's kind of a big, black hole."

Part of the risk stems from Facebook applications being created by anyone, some of them tech-related companies and others individuals with know-how. And they could be anywhere in the world....

...Some would argue that it's much like trusting an online vendor with your credit card information.

And of course there's Beacon. Facebook gives us "free" social networking, but sells the "beacon" of our purchasing behavior data. How palatable that is to members is more questionable. Obviously some "free" things are preferable to others.

Facebook scaled back Beacon after a lot of outcry, but the applications system remains largely unnoticed.

[I]t's an honor system, says Adrienne Felt, a computer science major at the University of Virginia....But, in the end, Felt says there's really nothing stopping them from matching profile information with public records. It also could be sold or stolen. And all of that could lead to serious matters such as identity theft.

"People seem to have this idea that, when you put something on the Internet, there should be some privacy model out there — that there's somebody out there that's enforcing good manners. But that's not true," Felt says.

Don't Tread On Track Me

Diane Bartz of Reuters recently reported about a drive to create a "Do Not Track" list much akin to the "Do Not Call" list that was meant to prevent telemarketers from bothering people who don't want to be bothered.

In December, the FTC approved Google's purchase of advertising rival DoubleClick over the objections of some privacy groups.

At the same time, the agency urged advertisers to let computer users bar advertisers from collecting information on them, to provide "reasonable security" for any data and to collect data on health conditions or other sensitive issues only with the consumer's express consent.

In comments to the FTC on online behavioral advertising, advertisers made clear a strong preference for self-regulation rather than government dictates on how personal data are collected, what disclosures are made to computer users and how long the information is stored.

Consumer groups said on Tuesday they were skeptical of self-regulation.

"Self-policing schemes are not enough to protect consumers' privacy and offer no enforcement against improper behavior," said Chris Murray, senior counsel for Consumers Union, in a statement.

"While companies like Google are trying to put pretty good practices in place, we don't want to rely on the good graces of the companies because they might change their minds," he told Reuters in a telephone interview.

Without a better way to get around those shortcomings, "we have...consumers and the FTC and industry agreeing on consumer choice and then no way to technically get there," said Peter Swire, an Ohio State University law professor and a former lead privacy counselor in the Clinton White House....

...A broad coalition of consumer and privacy advocates last fall called on the Federal Trade Commission to establish such a registry. The concept is this: Any advertising entity that sets a "persistent" cookie on a user's machine would be required to give the FTC the domain names of servers used to place it. Consumers would then be able to import that list of domain names and block them from tracking their Internet surfing behavior.

[AOL Chief Privacy Officer Jules] Polonetsky said that while he supports the concept, "I think the way to do it isn't a government place where your browser goes and gets stuff."

Instead, the former New York state legislator said, "the rule should be that whatever technology platform you're using should have no-brainer, easy-to-use labels that people know how to toggle to turn on or off the kinds of personalization, storing, whatever it is that that particular platform does."

Privacy advocates at Thursday's discussion weren't sold on the idea of self-regulation alone. Ultimately the responsibility to understand how their information is being used should not fall on consumers, but "on business to protect and safeguard consumers to whom they are providing these products," said Marc Rotenberg, director of the Electronic Privacy Information Center.

"The system is already in place, it's too late to turn it back," said Jeff Chester, director of the Center for Digital Democracy, which advocates for tighter privacy regulations on Internet companies. "We need real policy safeguards. The Congress and the FTC need to act."

When the privacy stakes are raised

It's one thing to weigh these issues in the domestic (which, in my case means American) context. There are complexities. As Americans, our two strongly held values of Fairness and Freedom (as in freedom of speech) come into conflict here. On the one hand, we don't want people to be abused by entities without accountability. On the other hand, we don't want Big Brother meddling with one of the sectors of our fragile economy that seems to still be going like gangbusters.

These same issues seem much clearer when it comes to other countries, other regimes, such as China, which as won cooperation from Yahoo, Google and others in censoring the internet to suit the Chinese government's policies. Rebecca McKinnon writes:

Many would agree that being a socially responsible Internet or telecommunications company requires respect for users’ rights to privacy and free expression, but there is great disagreement over how to accomplish this ideal.

She goes on about a case where Yahoo's cooperation led to the arrest of a dissident in China.

For two years after Yahoo’s role in Shi Tao’s case first came to light, the company’s public statements characterized the plight of Shi Tao and the three others as if they were acceptable collateral damage in the great task of bringing Internet information services to the Chinese people. Executives argued that the Chinese people were still better off in the long run thanks to Yahoo’s presence....

...Yahoo executives also argued that the company’s nose was legally clean on two fronts: Not only did employees respond to a legally binding written order; actions by Yahoo’s China-based employees were consistent with the user “terms of service” that Shi Tao and all other Yahoo email users agree to in order to create an account. In these terms the user promises not to use the email account to commit a list of actions, including “damaging public security, revealing state secrets, subverting state power, damaging national unity,” etc....

...But a legal victory would have been hollow because it would not have absolved Yahoo in the eyes of the human-rights community and socially responsible investors. They point out that Chinese law in this area contradicts international law–and that socially responsible companies have an obligation to do something more than participate in a “race to the bottom” as far as global practices on privacy and freedom of expression are concerned....

...With data privacy, things are much more clear cut: when user data is handed over a person can go to jail and his or her life is ruined or shortened. So what to do?

In the "freeconomy" picture Anderson paints, of course, there is no secret police ready to arrest you for buying that book about genital herpes or searching for websites about bankruptcy counseling.

But does that mean you have no interest at all in how that information about your supposedly private behavior is used and shared by other parties? Does that mean that your privacy has no value? Does that mean you can just "choose" not to use the Internet at all?

After all, do such uses of your private information really harm you in any way? How can you quantify it?

And if you can't quantify it, if you can't point to any real damages, then what can you do about it, anyway?

Judging the value of privacy

Lauren Gelman, Executive Director of Stanford Law School's Center for Internet and Society, writes of a recent DC Circuit court ruling:

holding that the federal Privacy Act's requirement that Plaintiffs show actual damages does not require pecuniary harm but can be met by a showing of emotional distress. Am. Fed'n of Gov't Employees v. Hawley, D.D.C., No. 07-00855, 3/31/08.

[T]he plaintiffs' alleged injury is not speculative nor dependent on any future event, such as a third party's misuse of the data, the court said. The court finds that plaintiffs have standing to bring their Privacy Act claim.

...I think this is a great decision that supports the belief that people's harm from a privacy loss is not just another's use of that information to cause financial loss (i.e. identity theft), but that emotional damages and embarrassment are cognizable harms of privacy violations.

Other lawsuits about privacy are hitting the courts. We seem to be reaching the point where companies' right to swing their information-gathering-and-sharing arms is starting to meet private citizens' right to not have their private elbows bumped.

And, last I checked, lawyers aren't free.

And this doesn't even get into cases relating to people's private information where the damages are much more apparent.

Meanwhile, the rest of us should not simply sit around and wait for our Internet and email service providers, Web-hosting services, and mobile-phone carriers to do the right thing on their own. Technology users around the world have an interest in joining together to insist that the products and services with which we increasingly entrust our careers, our beliefs and the most intimate parts of our lives, will not sell us out because they feel they have “no choice” since all their competitors are selling out their users too.

Who's identity is it, anyway?

The question I keep coming to is this: If the web is so distributed, why are people flocking to centralized management of their information (and in doing so trading away so much of their privacy)?

The answer, it seems to me, is that it's easy that way. GMail is easy. Google Calendar is easy. Connecting with friends via Facebook is easy.

But maybe the easy way is not always the best way. Maybe?

What I want is option (with set of tools) for individuals taking charge of their identities.* And on the web that starts with exercising sovereignty over my data. This alternative must be networked and not third party dependent or platform based....

...The key is in realising that authorisation and identity are related but separate.

Authentication is the act of establishing an identity - this is separate from the existing identity approach where the focus is on collection and disbursement of bits of data to do with someone. The cheap and cheerful explanation of this is that you can authenticate with a password (i.e. something that only you know). However, that password need not reveal anything about you/your identity. It just reveals that you are someone who knows the password. Therefore, authentication is free to be separate from identity. They are in separate but related domains. Have I mentioned that they are separate?

I owe this point to Alec who explains:

Traditionally authentication is one-or-more of three things.

  • something you KNOW, e.g, you KNOW the password
  • something you HAVE, e.g, you HAVE the door key,
  • something you ARE, e.g, you ARE a 4-star general on an army base

The latter tends to be a bit weak, as authentication goes, in my experience it is prone to social hacking. Good authentication might be combining something like: KNOWING the password that UNLOCKS the certificate that you HAVE on the laptop, that permits a remote website to challenge you and get the response it expects, since it KNOWS that you have your certificate on your laptop....

In short, let me have a go at my identity myself, on my own terms, the web way, without intermediaries, ‘trusted’ parties and hierarchical non-direct ways. Locking me into new ‘better’ platforms, offering ’services’ to manage my meta-identity is like putting a band-aid on a gaping wound. Instead, give me tools, flexible and modular, to reclaim my digital personae, help me piece together my fractured identity. And then allow me to drive it forward with all of the benefits that it can bring me and to those I interact and transact with. Learn to live with the unpredictability and emergent juicy goodness that comes from my independence and lack of your control over me.

Object-Oriented Identity?

One approach to protecting privacy in some way draws from a fundamental tenet of basic object-oriented programming: That the data and logic to accessing that data are combined into an object; any other object or entity wanting to access that data engages the object as a whole, and gets what the object is 'willing' to give, under its own logic. This is in contrast to function-based programming, where any procedure or function can access the data by its own means.

(Programmers reading this: please be kind. I'm trying to over-simplify to make a point.)

The same approach can be handled for identity, with systems such as OpenID: Rather than managing identity through multiple sites that parse your information through their own individual functions, according to their own rules, your identity and access to it are managed as a unit -- an object.

You can use a verifiable identity token instead of a password that you may be using on a few dozen other sites. You can keep your profile information in one place, and share it according to your own terms.

It's just an idea, and in its infancy at that, and while it's seeing in-roads with adoption by Wordpress, Drupal and others, it's something that so far has been met with a bit of resistance from some of the major players who have found big money in the identity stakes.

But it seems clear that the way things have been going so far is not how we things will be going in the future. Change is a constant on the web, and that's all the more true in how we treat privacy.

When privacy is protected...

...does this threaten the "free" world of which Anderson writes? I don't think so.

Fifteen or so years into the evolution of the web, we already have many of the key ideas and technologies in place to start describing and sharing personal preference information - or what we might colloquially call "taste" - in order to personalize web experiences. So, why haven't we yet seen widespread adoption of web personalization? Mostly because user expectations and online business models haven't yet evolved to the point that user-controlled, ‘open taste’ sharing is a viable option.

For the more pragmatic: each time we make choices, we generate data which empirically describes our preferences. This is data that can be encapsulated and shared just like any other picture, blog post, video, or other piece of online content that we create; and which the DataPortability project is focused on.

A few ideas for open taste sharing

As a DataPortability use case, open taste sharing embodies and embraces the culture shift that the Web 2.0 movement represents. With regard to data ownership, the DataPortability concept has even more succinct expression: our tastes should be ours to share, or not. This puts the user in control of their online experience, so they can set the boundaries of how much they want to share and with whom.

Meanwhile, two new companies are offering to ISPs the service of tracking everything the ISPs' customers do, every website they visit, while claiming, counterintuitively (they admit), that their services actually improve the privacy of the users:

Phorm has agreements to work with the three largest Internet providers in Britain and will start operations there in the next few weeks. NebuAd says it is working with several smaller Internet providers in the United States that collectively serve 10 percent of the nation’s Internet users. Both companies are working hard to convince the large cable and phone companies in this country to join their systems. To do so, they must convince the Internet providers that they will not be offending their customers.

“Consumer acceptance is key to our progress,” Mr. Dykes said.

Of course, this "service" is "free" to the consumers, so why should you complain, right?

Apr 25 2008
Apr 25

Shadowbox.js is a modal media viewer application that enables web content to be displayed in an interface overlaid on the originating page.

The concept of Shadowbox is not a new one, the author Michael J. I. Jackson says:

Shadowbox was inspired by Lokesh Dhakar's Lightbox and Kevin Miller's LightWindow.

We've not used LightWindow ourselves but we have used Lightbox and, more often than not, Cody Lindley's Thickbox.

Part of the reason we use Thickbox so much is our early adoption of Ubercart, an exciting, open source e-commerce suite for Drupal (Thickbox is recommended as an optional module within the Ubercart documentation).

Looking over the demos of Shadowbox I was very impressed and immediately started creating a Drupal module. I initially tried out Shadowbox with Drupal 5.7 and the jquery_update module. Unfortunately, some of the critical features of Shadowbox didn't work with those earlier versions of jQuery so the module is Drupal 6 only.

The Drupal Shadowbox module is currently in development status but don't let that put you off. Most of the Shadowbox options have been implemented globally but you can still override these options inline by using a JSON-formatted parameter.

Suffice to say we're really happy with Shadowbox and feel it will make an excellent alternative to the Thickbox and Lightbox2 Drupal modules. At the moment you have to manually add the required attribute. Watch this space for integration with imagefield, imagecache and image modules.

Posted by psynaptic

Apr 24 2008
Apr 24

As part of a project in work I have been looking into the manipulation of PDFs using PHP. I am looking to create a system within drupal to allow multiple PDFs to be merged into one whilst adding custom titles, section headings and contents pages.

Read the full post on Millwood Online

Apr 24 2008
Apr 24

No sooner had we put the wrap on an April 9 Commonwealth Club panel interview on Collaborating for Change, than PBS announced a really cool collaborative project on Nova to design the "Car of the Future".   Both of these recent productions focus on the application of open source design to social and economic needs beyond software.  The promise of open source economics is popping up everywhere.  It must be something in the water, (or the atmosphere).   Network based open source design efforts have been written about before, and there's more than a few established non-software open source design projects, but they were hardly regarded as mainstream.  And open source as a business model has been a fringe enterprise.  But all that is changing.

The upcoming Nova special, and the Commonwealth Club interview (with Amy Novogratz, Kate Stohr, Maria Giudice, and myself (video courtesy fora.tv)) serve as proof points that this phenomena has exceeded meme status and is spilling over into the broader socioeconomic graph.   But we knew this was inevitable, right?  We just needed the right conditions for humanity's collaborative tendency to come out of the proprietary deep freeze.

The substrate upon which this new culture is rising pairs flexible licensing models a'la Creative Commons with accessible technology for building collaborative online communities a'la Drupal and WordpressYahoo!groups and PBWiki.  Among the catalysts for this reaction are frustration over obscene economic inequities around the world, abuses of people and planet for profit, and utter neglect by federal governments.  As was discussed here in the video interview about the Open Architecture Network, these frustrations can be overcome by collaborating for change on the net.

Need more proof of the trend toward an open source economy?  Just check with the folks at Open Everything.  They're tracking numerous open collaboratives, which are exogenous to  the software world, but infused with many of the same principles, practices and tools as open source software projects. 

One of the most prominent tools applied to these new collaboratives is Drupal, and we discuss it's role in the Open Architecture Network in the video (at :37:30, :46:30, and :51:00).

Ten years ago who would have imagined that:

Yet these, and plenty of other examples show that collaborative culture is on the rise.  Does this signal the next generation economy in which businesses profit less from market lockout and legal protection and more from direct value delivered in open markets?  Or does it lead to a more fundamental shift wherein socioeconomic prosperity derives less through commerce than through collaborations for which the primary incentive to contribute is sociocentric good? 

Apr 24 2008
Apr 24

Yes, this is yet another rant about how people incorrectly dismiss state-of-art databases. (Famous people have done it, why shouldn’t I?) It’s amazing how much the Web 2.0 crowd abhors relational databases. Some people have declared real SQL-based databases dead, while some have proclaimed them to be as not cool any more. Amazon’s SimpleDB, Google’s BigTable and Apache’s CouchDB are trendy, bloggable ideas that to be honest, are ideal for very specific, specialized scenarios. Most of the other use cases, and that comprises 95 out of a 100 web startups can do just fine with a memcached + Postgres setup, but there seems to be a constant attitude of “nooooo if we don’t write our code like google they will never buy us…!” that just doesn’t seem to go away, spreading like a malignant cancer throughout the web development community. The constant argument is “scaling to thousands of machines”, and “machines are cheap”. What about the argument “I just spent an entire day implementing the equivalent of a join and group by using my glorified key-value-pair library”? And what about the mantra “smaller code that does more”?

Jon Holland (who shares his name with the father of genetic algorithms) performs a simple analysis which points out a probable cause: People are just too stupid to properly use declarative query languages, and hence would rather roll their own reinvention of the data management wheel, congratulating themselves on having solved the “scaling” problem because their code is ten times simpler. It’s also a hundred times less useful, but that fact is quickly shoved under the rug.

It’s not that all Web-related / Open Source code is terrible. If you look at Drupal code, you’ll notice the amount of sane coding that goes on inside the system. JOINs used where needed, caching / throttling assumed as part of core, and the schema allows for flexibility to do fun stuff. (Not to say I don’t have a bone to pick with Drupal core devs; the whole “views” and “workflow” ideas are soon going to snowball into the reinvention of Postgres’s ADTs; all written in PHP running on top of a database layer abstracted Postgres setup.)

If Drupal can do this, why can’t everyone else? Dear Web 2.0, I have a humble request. Pick up the Cow book if you have access to a library, or attend a database course in your school. I don’t care if you use an RDBMS after that, but at least you’ll reinvent the whole thing in a proper way.

Apr 22 2008
Apr 22

For the second year running, Drupal placed in the Webware 100 awards in the Publishing & Photography category.

In this publishing category, the only other contender in the top 10 that comes close to matching the flexibility and functionality of Drupal was Wordpress, which would probably do well to continue to focus on the blog niche and not try to play catch-up with the more mature Drupal (current versions: Drupal 6.2, WP 2.5). Missing altogether were projects that match up better with Drupal, such as Joomla and Plone.

Check out all 10 winners:

Apr 20 2008
Apr 20


Only hours ago, after over three years of work on the SimpleTest module, Dries committed the SimpleTest module to core. This is an amazing achievement. Drupal is looking at getting 100% core test coverage, both unit and functional. A lot of work went into the SimpleTest module today before it was committed. We (the Drupal SimpleTest Sprinters) set up an SVN repository containing a version of Drupal with SimpleTest there as a module, and opened it up for all of us to commit. It was chaos (in a good way). Without the roadblock of patches, code was rapidly sucked into the SimpleTest module; finally Dries had to give us a SimpleTest "code freeze" so as to actually start to get stuff to work.

Current SimpleTest Status

SimpleTest is in core! What can be left to do? Actually, a lot, but first, let's go over what we've done today:

And then, there are the things that are left to do:

  • (Update: ) Make the SimpleTest module use the Batch API. This will give us that nice little progress bar that shows us our progress, which is one of the few feasible ways of running so much code.
  • (Update: ) Make the SimpleTest module REALLY comply with coding standards. Not only do we have all the old coding standards SimpleTest issues, but we also now have to make our own SimpleTest-Light library coding standard compliant, as well as alter our code to fit the new string concatenation rule.
  • We need to write tests! Our estimated test coverage at the moment is between 30 and 60 percent, unacceptably low levels. Tests are now easy to write, SimpleTests are in core; everyone, answer this call for help! Write SimpleTests for both core and contributed modules! Make test-driven development a reality!

For more and/or updated ways to help out, please visit http://groups.drupal.org/node/10099.

Apr 20 2008
Apr 20

Today was an amazing day in Paris. It's hard to imagine without the pictures, but we all gathered on the first floor of the facility that hosted yesterday's Drupal Camp. A good portion of yesterday was planning and thinking leaving today for massive amounts of hacking and coding. Charlie Gordon, Jimmy Berry, Roel De Meester, Erik Stielstra, Rok Žlender, Károly Négyesi, Miglius Alaburda, Dries Buytaert, Douglas Hubler, myself and our gracious host Ori Pekelman of AF83 gathered for more than 10 hours to solidify the framework that will help lead Drupal to it's next Killer Release.

Primary amongst todays developments was http://drupal.org/cvs?commit=111813 which brought a framework for functional tests to core. This is the culmination of "Three years, one month and twenty four days" according to Károly who also had this to say before he started dancing in his seat:
(12:24:52 PM) chx: YES YES YES YES YES YES YES
(12:24:54 PM) chx: YES YES YES YES YES YES YES
(12:24:54 PM) chx: YES YES YES YES YES YES YES
(12:24:55 PM) chx: YES YES YES YES YES YES YES
During the discussions following the commit it was pointed out that much of the effort has been a direct result of the organizations that seem to be constantly there in support of what Drupal is and where it is going. Companies like pingVision, Now Public, AF83, Rain City Studios and Google have made work like this possible for us to all enjoy. In particular, if it were not for the results from GSoC and GHoP Drupal simply would not have the testing framework it now does.

I'm sure that each of the participants will be blogging about their accomplishments in the upcoming days so I will leave each of them to fill in the gaps. Most of my work centered directly around getting a full automated testing system in place for testing.drupal.org as outlined at http://drupal.org/node/239542. The benefit of these type of sprints are immeasurable ... simply being able to ask a person on the other side of the table an answer, show them a problem, and talk about a solution is something you can not put a price on. We accomplished a lot but many questions, decisions and work remain.

For those willing to help with improving the test framework, here are some next steps and issues to resolve:
- How to best approach unit tests and mock functions?
- How to test drupal_mail() and drupal_http_request()?
- How to improve the admin UI so we have a nice progress bar?
- How best to do code coverage?
- See http://groups.drupal.org/node/10099 for more ...

My laptop battery is telling me it is time to end this post. My focus is getting back to Colorado and working to help others understand the framework and what needs to be accomplished in the near future. We have a framework but we do not have 100% code coverage. It is going to take an army to finish what has been begun and we are going to have to be organized to complete the work in front of us.

Apr 20 2008
Apr 20

It has come time to consider a phone system. While most of the company clan uses mobile phones for personal calls, we do have sales and support that do need real phones, with voicemail, multiple simultaneous dialtones, etc. We tried the Vonage thing, but that had too many "can you hear me now?" moments for a business to suffer, so we went to the multiple Qwest lines, which required little in equipment investment but is far too costly each month -- not to mention every time we move or want to add a line.

Last week we got a pitch from Qwest reps. The part that probably does make sense is doing a T1 with dynamic bandwidth allocation and integrated access, opening up some channels and handling all the phone switching from a box. (Not sure if Qwest is best choice for that, but I'll reserve judgment for now.)

The part I'm less sure of is the Oracle Cisco box they are bundling with the service package. They are going to put some numbers together but my hunch is that it's going to be just a tad more expensive than we are wanting (or even able) to spend.

It's also a closed-source solution, which gives me pause. Any time I'm plunking down a good chunk of change, I want to know I have ownership of the future. While I don't figure on Cisco going away anytime soon, past experience has shown that a company doesn't need to go under to EOL a product line.

There is Asterisk, which is open source. It even has a Drupal module for integration with Drupal (maintained by fellow Boulderite hunmonk). I plan on giving Chad a ping to see what kind of insights he may have. And Matthew has some measure of experience with it.

But just because it's open source doesn't mean it's enterprise-ready. This phone system realm is completely alien territory for me. Any recommendations? Warnings? Happy tales with flowers and dancing cats?

Apr 20 2008
AjK
Apr 20

The Problem

Drupal 7 Testing Timeline

During recent presentations at FOSDEM 2008 and DrupalCon 2008 Boston, founder Dries Buytaert presented the idea of bringing full testing of Drupal Core ( here and here ) to the Drupal community. When a system changes as rapidly as Drupal does, it becomes increasingly important to provide quantifiable reporting on the health of the system so that growth may continue. Without such reporting, Drupal 7 will realize a substantially shorter development cycle before a 7 month code freeze is enacted around July 15th, 2008. This will allow testers and developers a 7 month period to guarantee the quality of Drupal's next major release.

By providing an automated system of testing and reporting for Drupal, the Community will be able to extend the development cycle an additional 4 months placing the code freeze around November 15th, 2008. The 4 months spent testing and fixing bugs could instead be applied to providing new functionality and innovation. Using an automated testing and reporting system would allow us to release a better system without sacrificing quality.

What We Have

At the time Dries was announcing the problem, several projects were underway to help realize the ideals of full test coverage for Drupal Core. These projects are leading the way to providing Drupal Core testing:

Additionally, the following g.d.o groups exist to forward this project:

In addition to these efforts, the weekend of April 19-20th will see the first of the Test Code Sprints aimed at furthering progress and solidifying a framework to continue the great work already in progress.

What is Missing

The workflow framework created by SimpleTest and SimpleTest Auto provide the basis for a solid testing infrastructure. SimpleTest is the vehicle that tests are being written for and processed in while SimpleTest Auto is the mechanism that creates test instances, initiate tests on them and reports findings from the SimpleTests. What is missing from this equation is Code coverage, a measure used in software testing. It describes the degree to which the source code of a program has been tested. It is a form of testing that inspects the code directly and is therefore a form of white box testing.

Jimmy Berry took great effort to compile Functional SimpleTest Status - List of all tests which comes the closest to what a Code Coverage report could contain. However, manual entry of this data is a time consuming process that is dependent upon the tests ... it has no concept of what is really getting tested at the code level.

The DCOV Proposal

The concept of DCOV (Drupal Code Coverage) is to allow developers, testers, reviewers and just about anyone with an interest to see what parts of Drupal Core are currently covered by test scripts, whether they pass or fail and other basic metrics including function execution times, invocation counts, etc. This will provide additional basic profiling on various aspects of the tests that are performed as part of the function test cycles. A prime example of usage of this data would be to evaluate what percentage of a documents code was run during the processing of a specific SimpleTest. In addition, the community at large should be able to run tests locally reporting findings back to the testing group.

The first public reference of Code Coverage is recorded in 1963 by the Association for Computing Machinery placing it amongst the first techniques invented for systematic software testing. Finding working examples relevant to Drupal are not difficult because Drupal is written in PHP. The PHP Quality Assurance Team has pioneered the techniques of Code Coverage as they apply to the PHP language. Their landing page serves as a clean and efficient method for communication of the groups objectives, possibly serving as a module for Drupal.

The true efforts of the PHP Quality Assurance Team's hard work are visible in the reporting component of their Code coverage testing known as GCOV. The GCOV site is an automated system that checks out from various RELEASES and SNAPHOTS of PHP from CVS, builds them and then runs the PHPT test suite. It reports data consumed from the LTP GCOV extension. The PHPT unit testing is the method of choice for PHP as it is better suited to the nature of PECL and Internals constructs for PHP than SimpleTest is for Drupal. The actual method of testing (whether it be PHPT, SimpleTest or some other system) is not DCOV's purpose. DCOV is a coverage tool that's designed to show how far the tests went, what PHP user space functions were executed (with pass/fail data acquired from the test layer above) and the other metrics previously alluded to earlier. If you follow the link above and browse, then the ideals of what DCOV seeks to become for Drupal won't be lost on the reader.

However, lets draw some examples as links and discuss the types of output the DCOV project is intended to offer Drupal:-

  • Sample 1. This link shows the output of a test run based on libraries the PHPT test suite "touched" on. DCOV would produce a similar output, however, it would be "file based" (ie, includes/database.inc, etc).
  • Sample 2. This shows an example of source code that was "touched on" by the tests thus revealing functions that were missed in an obvious to read presentation. Again, DCOV would produce a similar output showing what functions a test run actually invoked. Color coding can be used to indicate functions invoked that passed all their parent tests, or failed or fact simply haven't been invoked by any test script at all

The basic proposal of the DCOV project is to provide useful feedback on how the Drupal Core code base is performing, how functions run with some primitive profiling metrics and how the tests themselves are matching to the code base either in CVS or from CVS with patches applied.

Structure

  • The DCOV platform.
    • Stage 1 is expected to implement code coverage analysis and deliverables are expected to include a Drupal DCOV system which, at it's heart, will encompass Xdebug and additional software as a wrapper to read the results of Xdebug's code coverage. Already some minor additional feature enhancements have been made to Xdebug to enable better placement within an automated test environment (as opposed to the single enviroment Xdebug expects to find itself). These enhancements to Xdebug are being fed back to Derick Rethans (author and maintainer of Xdebug) for consideration for inclusion for the benefit of the greater Xdebug community.

      (Note, any final DCOV implementation will be designed to work with those patches Derick will commit. We don't want to find ourselves in a position of hacking Xdebug for the DCOV platform to work. Should patches not be committed, we'll work around them. An example of one such patch that already has been fed back is "limitation of code coverage scope". When running Simpletest AND Drupal it's currently found that to a greater degree, Xdebug is working on Simpletest execution far more than Drupal execution and wasting cycles, data, etc. We don't want to run Xdebug on Simpletest, just on Drupal. The first patch allows to target where Xdebug actually performs data acquisition and thus allows Xdebug to work in a more test oriented role rather than do everything).

    • Stage 2 of DCOV is expected to enhance the platform to include functional tracing (including parameters) for executed tests that fail. This way, DCOV can supply a code path analysis to developers explicitly for failed tests to assist in bug/problem location. Additionally, DCOV will export to the testing layer runtime information as required. So, if a test assertion fails, the testing layer will be able to query DCOV for additional details of the runtime enviroment at assertion failure. However, this would require that the tests themselves become DCOV aware which is more work on those creating .test scripts. For this reason, this aspect of Stage 2 is deferred until such time as full maturity within the testing architecture arrives.
  • The dcov.module. This Drupal module would be used to provide relevant reporting on the DCOV data, similar to the approach taken by the PHP QA Team and would be comprised of the following reports slanted towards Drupal Testing:
    • An overview report - listing each CVS tag that has been monitored by the testing system including relevant statistics and information about the project as a whole.
    • A tag detail report - highlighting test cases run, passes, failures, exceptions and other relevant information.
    • A code coverage report - providing an overview of the coverage in an easy to understand format.
    • A results report - This would be similar to the compile report and test failures reports used by the PHP team but would be slanted toward Drupal.
    • A system report - To allow for multiple developers to test on multiple systems and report their findings back to the Drupal testing system.
  • Various test scripts. TBA

Medium term goals

The production of DCOV would lead to a central testing center (website) that publishes the various metrics derived from all the automated tests. However, it's intended to extend this site in the medium term to become a true QA site for Drupal where developers can upload test cases for evaluation and inclusion and disseminate essential quality metrics on the Drupal project as a whole.

Summary/Conclusion

The end result of the DCOV project will tie together and leverage the existing unit and auto-browser based testing suites into a completely automated test environment with full reporting made available to those that need the data to push forward with development.

Generally speaking, the DCOV project aims to provide details similar to Jimmy Berry's excellent post though in an automated fashion and providing far more details about each test case and realistic code coverage based on actual functions executed during the test run.

Realistically, the DCOV project needs to be delivered with a reasonably short time frame to aid and assist the Drupal 7 release cycle. The following developers are currently prepared to commit to DCOV and deliver a working framework by months end:-

  • Kevin Bridges (cyberswat). Responsible for :-
    • DCOV for Drupal reality (delivery).
    • The dcov.module, Drupal analysis, reporting, etc
  • Andy Kirkham (AjK). Responsible for :-
    • The DCOV platform.
    • Xdebug integration/modification/patching.
    • Wrapper scripts/module assistance.
Apr 19 2008
Apr 19

Today we began the SimpleTest code sprint! This is an area of huge importance to Drupal, as one of our weaknesses has proven to be the number of testers we have, particularly how small that number is. Automated testing will provide an easy way to maintain the quality of core— each time a patch is created for core, it will be sent off to a testing server where the patch will be applied to a copy of the Drupal core and all the SimpleTests run on it. If there are failures, the patch would be marked as such and whoever submitted the patch would be forced to hang their head in shame.

What we accomplished today

Today, Dries Buytaert, Rok Žlender, Károly Négyesi, Jimmy Berry, Kevin Bridges, Douglas Hubler, Miglius Alaburda and I got together for 10 hours for the sole purpose of improving automated testing in core. It was great. We bounced ideas off one another, and came up with a great plan for unit testing with mock functions and classes without runkit. We made our test coverage tests work, although they are still running :). We gave a presentation to the people at Drupal Camp Paris on how to write basic functional tests for both core and contributed modules. We talked to Dries about the possibility of getting SimpleTest into core.

Unit testing with mock functions and objects

Here's the difference between functional testing and unit testing: functional testing makes sure the code functions the way you expect it to, e.g. if you load a page, is it the page you expected to get? Most of our current tests our functional tests. However, there is another kind of test that is valuable as well: unit testing. Unit tests know about certain internal or API functions that exist in Drupal, and make sure those functions work as expected.

The problem with efficient unit testing is that there are so many conditions that have to be accounted for, and in many cases, these conditions are hard to achieve. For example, if I were calling cache_get(), I have to account for this line:

$cache_flush = variable_get('cache_flush', 0);

which is used in further if() statements. In order to fully test it, I should call it both when this for all possible values of $cache_flush. In order to do this, I need to override the variable_get function which is used to generate this variable's value. Solutions such as runkit would work, but we want to have tests that all Drupal users can use, not just the small percentage with the ability to set up an environment with runkit.

How can we override functions? Once they are defined in their files, they cannot be undefined. However, that is just the key: don't include the files at all. Only include the specific function you are testing, and everything else can be represented by mock functions, used to return a certain value that can be set within the SimpleTest test case. In essence you're plucking a function out of its nest, making it think it's safe at home, and making sure it performs backflips properly. This awesome idea can be attributed to chx and Jimmy Berry. Basically you'd read all of the Drupal code base without parsing it, have PHP tokenize it, find all the functions (and classes and interfaces), cycle through and define them as:

function $function_name() {
  \$args = func_get_args();
  return simpletest_handle_mock_function($function_name, \$args);
}

This is an amazing code snippet. You basically make every single function in the Drupal code base call one centralized function from which you make all your mock-function settings.

We hope to work on this more on the next few days and hopefully get it into a working condition. This will also, hopefully, be made easier with the addition of the registry.

Drupal SimpleTest test coverage

In his blog, Dries promised that we could have three extra months of development time with complete core test coverage. Well, this raises the question: how do we determine how much of the Drupal core we've actually covered with our tests? We're looking on a way to figure this out.

There are many coverage-testing tools, but nearly all of them are based on the same principle: they look at your code while you run your tests, count the physical number of lines that were hit and not hit, and return that result. A tool we've been looking at called Spike PHPCoverage provides a means of doing this in PHP. Relying on XDebug for the heavy lifting, Spike PHPCoverage is a relatively lightweight utility which generates a nice html report of our current test coverage. A demo report generated by an early attempt at determining code coverage can be found here. (Note: this data is not accurate, but gives an idea of what the test coverage reports will look like.)

We have gotten the test coverage tests to work, but due to the massive amounts of time it takes to run all tests— plus the fact that adding test coverage makes it about twice as slow— and you can see that this is going to take a while not only to run all tests, but to record which lines of code are called and then generate a huge series of html files on our test coverage. But it should be awesome once we're finished, as not only will we know what are status is in regard to overall SimpleTest testing, but also where, exactly, our weaknesses are.

Presentation on Simpletest, and what you can do to help

Our testing sprint was going on parallel to Drupal Camp Paris, and we decided to give a short session on SimpleTest. However, come time for our session, we were nowhere near ready to present on our new unit tests. So we decided that I would do a repeat of my dojo lesson on writing functional SimpleTests for the Talk module. Not only did this go amazingly well, but there were a lot of questions— people seemed genuinely interested, and some even volunteered to help us out tomorrow by actually writing some of the tests we were making easier to write. This is completely and insanely AWESOME. And the best part is, you can help too, even if you're not in Paris! We have a list of tests that need to be written, and now we need people like you to write them! This is your opportunity to push back the dreadful day of the Drupal 7 code freeze. Let's get to it!

Apr 19 2008
Apr 19

Today was the first official day of the Paris Code Sprint. Approximately 50-60 Drupalers from around the world gathered on the first floor to learn about and discuss Drupal while the sprinters gathered upstairs to solidify and unify our testing efforts. Ori Pekelman of AF83 has been a gracious and entertaining host providing the foundation for a good amount of discussion and coding.

Primary among the new developments was the resounding identification for the need to provide Code Coverage for Drupal. Dries Buytaert, Rok Žlender, Charlie Gordon, Jimmy Berry, Kevin Bridges, Douglas Hubler and Andy Kirkham (remote from Scotland) participated in the discussion. The concept of DCOV (Drupal Code Coverage) is to allow developers, testers, reviewers and just about anyone with an interest to see what parts of Drupal Core are currently covered by test scripts, whether they pass or fail and other basic metrics including function execution times, invocation counts, etc. This will provide additional basic profiling on various aspects of the tests that are performed as part of the function test cycles. A prime example of usage of this data would be to evaluate what percentage of a documents code was run during the processing of a specific SimpleTest. In addition, the community at large should be able to run tests locally reporting findings back to the testing group.

A good example of how this reporting could be used by the Drupal community are visible in the reporting component of the PHP QA Team's Code coverage testing known as GCOV. The GCOV site is an automated system that checks out from various RELEASES and SNAPHOTS of PHP from CVS, builds them and then runs the PHPT test suite. DCOV is a coverage tool that will be designed to show how far the tests went, what PHP user space functions were executed (with pass/fail data acquired from the test layer above) and the other metrics of interest. Rok and Charlie have been able to get a proof of concept working.

Additionally, we were able to finish the automatic generation of test stubs. A plan was put in place to define how test stubs and unit testing will work together. Once testing of the work is complete, Jimmy Berry will be posting additional details on his blog. Simpletestauto was modified to allow for easier distribution and configuration among multiple servers by Kevin Bridges. Charlie Gordon gave an excellent session on Simpletest to the Paris Drupal Camp laying the foundation for educating Drupal Developers on how and why they should participate in our testing efforts in addition to getting the trigger test errors under control. We would like to see these educational presentations spread to Drupal Meetups and Camps around the world.

It is time to break for dinner, but we will be back tonight to continue working ... pictures and more details are upcoming ... adieu for now.

Apr 17 2008
Apr 17

I have a love hate relationship with microformats. The apostles who think they're the end all be all of the semantic web drive me insane. 'Semantic Web' aside, microformats are a powerful approache to reusable design. Consistent markup with the appropriate JS or CSS can make for great reusable UI widgets.

This morning I was dabbling with derivative which goes through some acrobatics to display multiple media types, in light of the classes I recently added to the tags imagecache produces, I thought it would be awsome to use a simple microformat for files. Some quick Googling (proper verbs what is english coming to) led me to http://microformats.org/wiki/file-format-examples.

I'm seriously considering merging both examples from the page into something like:

The Gorge - MPEG video (22MB, 320x200, 228s, MP3 192Kbps audio, MPEG-2 video)

<?php
// ignore the php tags.<div class="hFileFormat">
  <
a type="video/mpeg; 
                  audio-codec=MP3,
                  audio-codec-sample-rate=192Kbps, 
                  video-codec=MPEG-2"
       
length=23068672
       href
="/angels_arete.mpg">The Gorge MPEG video</a>  <!-- should meta-data be in a wrapper or have a general class? -->
  <
abbr class="size-in-octets" title="23068672">22MB</abbr>,
  <
abbr class="duration-in-seconds" title="228.23">228.23s</abbr>
  <
abbr class="width-in-px" title="320">320px</abbr>
  <
abbr class="height-in-px" title="200">200px</abbr>
  <
span class="custom copyright-year">2006</span>
  <!-- 
allow addition of custom meta data with .custom -->  <!-- should codec data be in wrapper or have a general class? -->   
  <
span class="audio-codec ">MP3</span>
  <
abbr class="audio-codec-sample-rate" title=192000>192Kbps 
</abbr>
  <
abbr class="audio-code-bit-depth" title=16>16bit</abbr>  <!-- should codec data be in wrapper or have a general class? -->   
  <
span class="video-codec">MPEG-2</span
  <
span class="video-codec-sample-rate" title=200000>200K</span>
  <!-- include 
additional codec data if present -->
</
div>?>

The format will need some refinement, so I am to soliciting feedback from people familiar with JQuery and CSS. Are there limitations to the markup? Can it be more succinct? Can it be made more self explanatory? Are there ways to make it an easier target for selectors? Is anyone else doing anything similar?

Apr 15 2008
Apr 15

pingVision has generously covered my airfare and hotel accomodations to ensure I am able to contribute to the Automated Testing Code Sprint happening in Paris this upcoming weekend. This is an important event that will help lay the foundation for Drupal's continued growth and evolution. It is a great responsibility and honor to be able to contribute and I look forward to helping make this effort a success. It is the continued effort of progressive companies like pingVision that help prove the Drupal Community is simply the best out there.

In addition, a special thanks goes to Greg Knaddison for his donation and support in this project ... there would simply be no Drupal without people like Greggles in the community.

Thanks

Apr 15 2008
Apr 15

It seems that a shell history meme is passing around the blogosphere. I first saw it on Dan Mills' blog post via Planet Mozilla. There are already 10 Mozilla hackers posting their top used shell commands, so I thought I'd do it too.

koeji:~ kourge$ uname -a
Darwin koeji.local 9.2.2 Darwin Kernel Version 9.2.2: Tue Mar  4 21:17:34 PST 20
08; root:xnu-1228.4.31~1/RELEASE_I386 i386
koeji:~ kourge$ history | awk '{a[$2]++} END {for(i in a){print a[i] " " i}}' | 
sort -rn | head
88 ls
81 cd
28 cvs
26 rm
26 md5sum
23 ./firefox-bin
22 sudo
12 ssh
12 js
9 less

A few notes:

  • md5sum is actually md5 on Mac OS X. I aliased md5 so that I wouldn't suddenly have a hard time adapting should I start using a Linux system.
  • js is an alias of java -Xms256m -Xmx512m org.mozilla.javascript.tools.shell.Main, which is the command to invoke the Rhino shell, which I sometimes use when I write shell scripts in JavaScript. Rhino is an awesome JavaScript implementation in Java.
  • You can see from the cvs count that I'm slacking off recently when it comes to maintaining Drupal modules.

So, fellow Drupalers / Drupalites, what are your most commonly used terminal commands? Beware of the line break before sort -rn when pasting the command into your terminal.

Apr 15 2008
Apr 15
recently i posted some encouraging performance benchmarks for drupal running on a variety of servers in amazon's elastic compute cloud. while the performance was encouraging, the suitability of this environment for running lamp stacks was not. ec2 had some fundamental issues including a lack of static ip addresses and no viable persistent storage mechanism.

amazon are quickly rectifying these problems, and recently announced elasic ip addresses; a "static" ip address that you own and can dynamically point at any of your instances.

today amazon indicated that persistent storage will soon be available. they claim that this storage will:

  • behave like raw, unformatted hard drives or block devices
  • be significantly more durable than the local disks within an amazon ec2 instance
  • support snapshots backed up to S3
  • support volumes ranging in size from 1GB to 1TB
  • allow the attachment of multiple volumes to a single instance
  • allow high throughput, low latency access from amazon ec2
  • support applications including relational databases, distributed file systems and hadoop processing clusters using amazon ec2

if this works as advertised, it will make ec2 a wonderful platform for your lamp application. amazon promise public availability of this service later this year.

Apr 14 2008
Apr 14

Google has just announced Salesforce.com for Google Apps. This is something that I'm really excited about because we use Salesforce.com as our CRM system and we also work with several large enterprise clients to integrate their web marketing with their Salesforce.com CRM system. Since migrating all my email, calendar and documents over to Google Apps in the last two months I've looked for a way to attach gmail emails to Salesforce contacts but there was only talk about it on the SFDC feature requests boards. I guess they were keeping this one quite until today.

Here's a quick look at how each of the main Google Apps applications will integrate with Salesforce.com

Now I'll just need to keep an eye on the Salesforce.com module for Drupal so we can integrate Drupal applications into Salesforce.com as well.

Apr 14 2008
Apr 14

Template Monster that is. Template monster has decided to offer Drupal templates.

I am glad to see this happen. I have said many times in the Drupal IRC channel that Drupal needs to get more CSS'ers involved. Or, get more freelancer themers involved, like those from Joomla and Wordpress.

It is my belief that WordPress became so popular so fast was due to it's themers, cranking out themes day and night. Now those themes are a commodity on SitePoint. You can't find Drupal themes there, mostly WordPress and sometimes Joomla themes.

My only concern about Template Monster stepping in, will they output some great themes that show the robust of Drupal? And continue to keep that standard up? I guess that falls into the hands of their designers and CSS coders. What ever the case may be I am glad to see design related companies to notice Drupal.

Congrats to the Template Monster team for taking the leap of providing services for Drupal.

Apr 12 2008
Apr 12

Submitted by リーボック シューズ レディース、リーボッ (not verified) on Thursday, December 12, 2013 at 12:56pm.

{
{I have|I've} been {surfing|browsing} online more than {three|3|2|4} hours today, yet I never found any
interesting article like yours. {It's|It is}
pretty worth enough for me. {In my opinion|Personally|In my view},
if all {webmasters|site owners|website owners|web owners} and bloggers made good content as you did, the {internet|net|web} will be {much more|a lot more}
useful than ever before.|
I {couldn't|could not} {resist|refrain from} commenting.
{Very well|Perfectly|Well|Exceptionally well} written!|
{I will|I'll} {right away|immediately} {take hold of|grab|clutch|grasp|seize|snatch} your
{rss|rss feed} as I {can not|can't} {in finding|find|to find} your {email|e-mail} subscription {link|hyperlink} or {newsletter|e-newsletter} service.

Do {you have|you've} any? {Please|Kindly} {allow|permit|let} me {realize|recognize|understand|recognise|know} {so that|in order that} I {may just|may|could} subscribe.
Thanks.|
{It is|It's} {appropriate|perfect|the best} time to make some plans for the
future and {it is|it's} time to be happy.
{I have|I've} read this post and if I could I {want to|wish to|desire
to} suggest you {few|some} interesting things or {advice|suggestions|tips}.
{Perhaps|Maybe} you {could|can} write next articles referring to this article.
I {want to|wish to|desire to} read {more|even more} things
about it!|
{It is|It's} {appropriate|perfect|the best} time
to make {a few|some} plans for {the future|the longer term|the long run} and {it is|it's} time to be happy.
{I have|I've} {read|learn} this {post|submit|publish|put up} and
if I {may just|may|could} I {want to|wish to|desire to} {suggest|recommend|counsel} you {few|some} {interesting|fascinating|attention-grabbing} {things|issues} or {advice|suggestions|tips}.
{Perhaps|Maybe} you {could|can} write {next|subsequent} articles {relating to|referring to|regarding} this article.
I {want to|wish to|desire to} {read|learn} {more|even more} {things|issues} {approximately|about} it!|
{I have|I've} been {surfing|browsing} {online|on-line} {more than|greater than} {three|3} hours {these days|nowadays|today|lately|as
of late}, {yet|but} I {never|by no means} {found|discovered}
any {interesting|fascinating|attention-grabbing}
article like yours. {It's|It is} {lovely|pretty|beautiful} {worth|value|price} {enough|sufficient} for me.
{In my opinion|Personally|In my view}, if
all {webmasters|site owners|website owners|web owners} and bloggers made {just right|good|excellent} {content|content material} as {you did|you probably did}, the {internet|net|web} {will be|shall be|might be|will probably be|can be|will likely be} {much more|a lot more} {useful|helpful} than ever before.|
Ahaa, its {nice|pleasant|good|fastidious} {discussion|conversation|dialogue} {regarding|concerning|about|on the topic of} this {article|post|piece of writing|paragraph} {here|at this
place} at this {blog|weblog|webpage|website|web site}, I have read
all that, so {now|at this time} me also commenting {here|at this
place}.|
I am sure this {article|post|piece of writing|paragraph} has touched all the internet {users|people|viewers|visitors}, its
really really {nice|pleasant|good|fastidious} {article|post|piece of writing|paragraph}
on building up new {blog|weblog|webpage|website|web site}.|
Wow, this {article|post|piece of writing|paragraph} is {nice|pleasant|good|fastidious}, my {sister|younger sister} is analyzing {such|these|these kinds of} things, {so|thus|therefore} I am going
to {tell|inform|let know|convey} her.|
{Saved as a favorite|bookmarked!!}, {I really like|I like|I love} {your blog|your
site|your web site|your website}!|
Way cool! Some {very|extremely} valid points!
I appreciate you {writing this|penning this} {article|post|write-up} {and the|and
also the|plus the} rest of the {site is|website is} {also very|extremely|very|also really|really} good.|
Hi, {I do believe|I do think} {this is an
excellent|this is a great} {blog|website|web site|site}.
I stumbledupon it ;) {I will|I am going to|I'm going to|I may} {come back|return|revisit} {once again|yet again}
{since I|since i have} {bookmarked|book marked|book-marked|saved as a favorite} it.
Money and freedom {is the best|is the greatest} way to change, may you be
rich and continue to {help|guide} {other people|others}.|
Woah! I'm really {loving|enjoying|digging} the
template/theme of this {site|website|blog}. It's simple, yet effective.

A lot of times it's {very hard|very difficult|challenging|tough|difficult|hard} to get that
"perfect balance" between {superb usability|user friendliness|usability} and {visual appearance|visual appeal|appearance}.
I must say {that you've|you have|you've} done a {awesome|amazing|very
good|superb|fantastic|excellent|great} job with this.
{In addition|Additionally|Also}, the blog loads {very|extremely|super} {fast|quick} for me on {Safari|Internet
explorer|Chrome|Opera|Firefox}. {Superb|Exceptional|Outstanding|Excellent} Blog!|
These are {really|actually|in fact|truly|genuinely} {great|enormous|impressive|wonderful|fantastic} ideas in {regarding|concerning|about|on the topic of} blogging.

You have touched some {nice|pleasant|good|fastidious} {points|factors|things} here.
Any way keep up wrinting.|
{I love|I really like|I enjoy|I like|Everyone loves} what you guys {are|are
usually|tend to be} up too. {This sort of|This type of|Such|This kind of} clever work
and {exposure|coverage|reporting}! Keep up the {superb|terrific|very
good|great|good|awesome|fantastic|excellent|amazing|wonderful}
works guys I've {incorporated||added|included} you guys to {|my|our||my personal|my own} blogroll.|
{Howdy|Hi there|Hey there|Hi|Hello|Hey}! Someone in my {Myspace|Facebook} group shared this {site|website} with us so I came
to {give it a look|look it over|take a look|check it out}.

I'm definitely {enjoying|loving} the information. I'm {book-marking|bookmarking} and will be
tweeting this to my followers! {Terrific|Wonderful|Great|Fantastic|Outstanding|Exceptional|Superb|Excellent} blog and {wonderful|terrific|brilliant|amazing|great|excellent|fantastic|outstanding|superb} {style and design|design
and style|design}.|
{I love|I really like|I enjoy|I like|Everyone loves} what you guys {are|are usually|tend to
be} up too. {This sort of|This type of|Such|This kind
of} clever work and {exposure|coverage|reporting}! Keep up
the {superb|terrific|very good|great|good|awesome|fantastic|excellent|amazing|wonderful} works guys I've {incorporated|added|included} you guys to {|my|our|my personal|my
own} blogroll.|
{Howdy|Hi there|Hey there|Hi|Hello|Hey} would you mind {stating|sharing} which
blog platform you're {working with|using}?
I'm {looking|planning|going} to start my own blog {in the near future|soon} but I'm having a {tough|difficult|hard} time
{making a decision|selecting|choosing|deciding} between BlogEngine/Wordpress/B2evolution and Drupal.
The reason I ask is because your {design and
style|design|layout} seems different then most blogs and I'm looking for something {completely unique|unique}.
P.S {My apologies|Apologies|Sorry} for {getting|being} off-topic but I had to ask!|
{Howdy|Hi there|Hi|Hey there|Hello|Hey} would you mind letting me know which {webhost|hosting company|web host} you're {utilizing|working
with|using}? I've loaded your blog in 3 {completely different|different}
{internet browsers|web browsers|browsers} and I must say this blog loads a lot {quicker|faster} then most.

Can you {suggest|recommend} a good {internet hosting|web
hosting|hosting} provider at a {honest|reasonable|fair} price?

{Thanks a lot|Kudos|Cheers|Thank you|Many thanks|Thanks},
I appreciate it!|
{I love|I really like|I like|Everyone loves} it {when people|when individuals|when folks|whenever
people} {come together|get together} and
share {opinions|thoughts|views|ideas}. Great {blog|website|site}, {keep it up|continue the good work|stick with it}!|
Thank you for the {auspicious|good} writeup. It in fact was
a amusement account it. Look advanced to {far|more} added agreeable from you!

{By the way|However}, how {can|could} we communicate?|
{Howdy|Hi there|Hey there|Hello|Hey} just wanted to give you a quick
heads up. The {text|words} in your {content|post|article} seem to be running off the screen in
{Ie|Internet explorer|Chrome|Firefox|Safari|Opera}. I'm not sure if
this is a {format|formatting} issue or something to do with {web browser|internet browser|browser}
compatibility but I {thought|figured} I'd post to let you know.
The {style and design|design and style|layout|design} look great though!

Hope you get the {problem|issue} {solved|resolved|fixed} soon.
{Kudos|Cheers|Many thanks|Thanks}|
This is a topic {that is|that's|which is} {close to|near to} my heart...
{Cheers|Many thanks|Best wishes|Take care|Thank you}! {Where|Exactly where} are your contact details though?|
It's very {easy|simple|trouble-free|straightforward|effortless} to find out any {topic|matter} on {net|web} as compared to {books|textbooks}, as I found this {article|post|piece of writing|paragraph} at this {website|web site|site|web page}.|
Does your {site|website|blog} have a contact page? I'm having {a tough time|problems|trouble} locating it but, I'd like to {send|shoot} you an {e-mail|email}.

I've got some {creative ideas|recommendations|suggestions|ideas} for your blog you might be interested in hearing.
Either way, great {site|website|blog} and I look forward to seeing it {develop|improve|expand|grow} over time.|
{Hola|Hey there|Hi|Hello|Greetings}! I've been {following|reading} your {site|web site|website|weblog|blog} for {a long time|a while|some time} now and finally
got the {bravery|courage} to go ahead and give you a shout out from
{New Caney|Kingwood|Huffman|Porter|Houston|Dallas|Austin|Lubbock|Humble|Atascocita} {Tx|Texas}!
Just wanted to {tell you|mention|say} keep up the {fantastic|excellent|great|good} {job|work}!|
Greetings from {Idaho|Carolina|Ohio|Colorado|Florida|Los angeles|California}!
I'm {bored to tears|bored to death|bored} at work so I decided
to {check out|browse} your {site|website|blog} on my iphone during lunch break.
I {enjoy|really like|love} the {knowledge|info|information} you {present|provide} here and can't wait to take
a look when I get home. I'm {shocked|amazed|surprised} at how {quick|fast} your blog loaded
on my {mobile|cell phone|phone} .. I'm not even using
WIFI, just 3G .. {Anyhow|Anyways}, {awesome|amazing|very good|superb|good|wonderful|fantastic|excellent|great} {site|blog}!|
Its {like you|such as you} {read|learn} my {mind|thoughts}!

You {seem|appear} {to understand|to know|to grasp} {so much|a lot} {approximately|about}
this, {like you|such as you} wrote the {book|e-book|guide|ebook|e book} in it or something.

{I think|I feel|I believe} {that you|that you simply|that you just} {could|can} do with {some|a few} {%|p.c.|percent} to {force|pressure|drive|power} the message
{house|home} {a bit|a little bit}, {however|but} {other than|instead of} that, {this is|that is} {great|wonderful|fantastic|magnificent|excellent} blog.
{A great|An excellent|A fantastic} read. {I'll|I will}
{definitely|certainly} be back.|
I visited {multiple|many|several|various} {websites|sites|web sites|web pages|blogs} {but|except|however} the audio
{quality|feature} for audio songs {current|present|existing} at this {website|web site|site|web page} is {really|actually|in fact|truly|genuinely}
{marvelous|wonderful|excellent|fabulous|superb}.|
{Howdy|Hi there|Hi|Hello}, i read your blog {occasionally|from time to time} and i own a similar one and
i was just {wondering|curious} if you get a lot of spam {comments|responses|feedback|remarks}?
If so how do you {prevent|reduce|stop|protect against} it, any plugin or anything you can {advise|suggest|recommend}?
I get so much lately it's driving me {mad|insane|crazy} so any {assistance|help|support} is very much appreciated.|
Greetings! {Very helpful|Very useful} advice
{within this|in this particular} {article|post}! {It is the|It's the}
little changes {that make|which will make|that produce|that will make} {the biggest|the largest|the greatest|the most important|the most significant} changes.
{Thanks a lot|Thanks|Many thanks} for sharing!|
{I really|I truly|I seriously|I absolutely} love {your blog|your site|your website}..
{Very nice|Excellent|Pleasant|Great} colors & theme.

Did you {create|develop|make|build} {this website|this site|this
web site|this amazing site} yourself? Please reply back as I'm {looking to|trying
to|planning to|wanting to|hoping to|attempting to} create {my own|my very own|my own personal}
{blog|website|site} and {would like to|want to|would
love to} {know|learn|find out} where you got this
from or {what the|exactly what the|just what the} theme {is called|is named}.
{Thanks|Many thanks|Thank you|Cheers|Appreciate it|Kudos}!|
{Hi there|Hello there|Howdy}! This {post|article|blog post}
{couldn't|could not} be written {any better|much better}!
{Reading through|Looking at|Going through|Looking through} this {post|article} reminds me of my previous
roommate! He {always|constantly|continually} kept {talking
about|preaching about} this. {I will|I'll|I am going to|I
most certainly will} {forward|send} {this article|this information|this
post} to him. {Pretty sure|Fairly certain} {he will|he'll|he's going to} {have a good|have
a very good|have a great} read. {Thank you for|Thanks for|Many thanks for|I appreciate you for} sharing!|
{Wow|Whoa|Incredible|Amazing}! This blog looks {exactly|just} like my old one!

It's on a {completely|entirely|totally} different {topic|subject} but it has
pretty much the same {layout|page layout} and design.

{Excellent|Wonderful|Great|Outstanding|Superb} choice of colors!|
{There is|There's} {definately|certainly} {a lot to|a great deal to} {know about|learn about|find out about} this
{subject|topic|issue}. {I like|I love|I really like}
{all the|all of the} points {you made|you've made|you have
made}.|
{You made|You've made|You have made} some {decent|good|really good} points there.

I {looked|checked} {on the internet|on the web|on the net} {for more info|for more information|to
find out more|to learn more|for additional information} about the
issue and found {most individuals|most people} will go along with your views on {this website|this site|this web site}.|
{Hi|Hello|Hi there|What's up}, I {log on to|check|read} your {new stuff|blogs|blog} {regularly|like every week|daily|on a regular basis}.
Your {story-telling|writing|humoristic} style is {awesome|witty}, keep {doing
what you're doing|up the good work|it up}!|
I {simply|just} {could not|couldn't} {leave|depart|go away} your {site|web site|website} {prior to|before} suggesting that
I {really|extremely|actually} {enjoyed|loved} {the standard|the usual} {information|info}
{a person|an individual} {supply|provide} {for your|on your|in your|to your} {visitors|guests}?
Is {going to|gonna} be {back|again} {frequently|regularly|incessantly|steadily|ceaselessly|often|continuously} {in order to|to} {check up on|check out|inspect|investigate cross-check} new posts|
{I wanted|I needed|I want to|I need to} to thank you for this {great|excellent|fantastic|wonderful|good|very good} read!!
I {definitely|certainly|absolutely} {enjoyed|loved} every {little bit of|bit of} it.

{I have|I've got|I have got} you {bookmarked|book marked|book-marked|saved as a favorite}
{to check out|to look at} new {stuff you|things you} post…|
{Hi|Hello|Hi there|What's up}, just wanted to {mention|say|tell you},
I {enjoyed|liked|loved} this {article|post|blog post}.
It was {inspiring|funny|practical|helpful}.
Keep on posting!|
I {{leave|drop|{write|create}} a {comment|leave a response}|drop a {comment|leave a response}|{comment|leave a
response}} {each time|when|whenever} I {appreciate|like|especially enjoy} a {post|article} on a {site|{blog|website}|site|website} or {I have|if I have} something to {add|contribute|valuable
to contribute} {to the discussion|to the conversation}.

{It is|Usually it is|Usually it's|It's} {a result of|triggered by|caused by} the {passion|fire|sincerness} {communicated|displayed} in the {post|article} I {read|looked at|browsed}.
And {on|after} this {post|article} Reply to comment | Schoonzie.
I {{was|was actually} moved|{was|was actually} excited} enough to {drop|{leave|drop|{write|create}}|post} a
{thought|{comment|{comment|leave a response}a response}} {:-P|:)|;)|;-)|:-)} I {do have|actually do have} {{some|a few} questions|a couple of questions|2 questions} for you {if
you {don't|do not|usually do not|tend not to} mind|if it's {allright|okay}}.

{Is it|Could it be} {just|only|simply} me or {do|does it
{seem|appear|give the impression|look|look as if|look like} like} {some|a few} of
{the|these} {comments|responses|remarks} {look|appear|come across} {like they are|as
if they are|like} {coming from|written by|left by} brain dead {people|visitors|folks|individuals}?
:-P And, if you are {posting|writing} {on|at} {other|additional} {sites|social sites|online
sites|online social sites|places}, {I'd|I would}
like to {follow|keep up with} {you|{anything|everything} {new|fresh} you have to post}.
{Could|Would} you {list|make a list} {all|every one|the complete urls} of {your|all your} {social|communal|community|public|shared} {pages|sites} like your
{twitter feed, Facebook page or linkedin profile|linkedin profile,
Facebook page or twitter feed|Facebook page, twitter feed, or linkedin profile}?|
{Hi there|Hello}, I enjoy reading {all of|through} your {article|post|article post}.
I {like|wanted} to write a little comment to support you.|
I {always|constantly|every time} spent my half an hour to read this {blog|weblog|webpage|website|web
site}'s {articles|posts|articles or reviews|content} {everyday|daily|every day|all the time} along with a {cup|mug} of coffee.|
I {always|for all time|all the time|constantly|every time} emailed this {blog|weblog|webpage|website|web site}
post page to all my {friends|associates|contacts}, {because|since|as|for
the reason that} if like to read it {then|after that|next|afterward} my {friends|links|contacts} will too.|
My {coder|programmer|developer} is trying to {persuade|convince}
me to move to .net from PHP. I have always disliked the idea
because of the {expenses|costs}. But he's tryiong none the less.
I've been using {Movable-type|WordPress} on {a number of|a variety of|numerous|several|various} websites for about a year and am {nervous|anxious|worried|concerned}
about switching to another platform. I have heard {fantastic|very good|excellent|great|good} things about blogengine.net.

Is there a way I can {transfer|import} all my wordpress {content|posts}
into it? {Any kind of|Any} help would be {really|greatly} appreciated!|
{Hello|Hi|Hello there|Hi there|Howdy|Good day}! I could have sworn I've {been to|visited} {this blog|this web site|this website|this site|your blog}
before but after {browsing through|going through|looking at} {some of the|a few of the|many of the} {posts|articles} I realized
it's new to me. {Anyways|Anyhow|Nonetheless|Regardless}, I'm {definitely|certainly} {happy|pleased|delighted}
{I found|I discovered|I came across|I stumbled upon} it and I'll
be {bookmarking|book-marking} it and checking back
{frequently|regularly|often}!|
{Terrific|Great|Wonderful} {article|work}! {This is|That is} {the
type of|the kind of} {information|info} {that are meant to|that are supposed to|that should} be shared {around the|across the}
{web|internet|net}. {Disgrace|Shame} on {the {seek|search} engines|Google}
for {now not|not|no longer} positioning this {post|submit|publish|put up} {upper|higher}!
Come on over and {talk over with|discuss with|seek advice from|visit|consult with} my {site|web site|website} .

{Thank you|Thanks} =)|
Heya {i'm|i am} for the first time here. I {came across|found} this board and I find It {truly|really} useful
& it helped me out {a lot|much}. I hope to give something back
and {help|aid} others like you {helped|aided} me.|
{Hi|Hello|Hi there|Hello there|Howdy|Greetings}, {I think|I believe|I do believe|I do
think|There's no doubt that} {your site|your website|your web site|your blog} {might be|may be|could
be|could possibly be} having {browser|internet browser|web browser} compatibility {issues|problems}.
{When I|Whenever I} {look at your|take a look at your} {website|web site|site|blog} in Safari, it looks fine {but when|however when|however,
if|however, when} opening in {Internet Explorer|IE|I.E.},
{it has|it's got} some overlapping issues.
{I just|I simply|I merely} wanted to {give you a|provide you
with a} quick heads up! {Other than that|Apart from that|Besides that|Aside from that}, {fantastic|wonderful|great|excellent} {blog|website|site}!|
{A person|Someone|Somebody} {necessarily|essentially}
{lend a hand|help|assist} to make {seriously|critically|significantly|severely} {articles|posts} {I would|I might|I'd} state.
{This is|That is} the {first|very first} time I frequented your {web page|website page} and {to this point|so far|thus far|up to now}?

I {amazed|surprised} with the {research|analysis} you made to {create|make} {this actual|this particular} {post|submit|publish|put up} {incredible|amazing|extraordinary}.
{Great|Wonderful|Fantastic|Magnificent|Excellent}
{task|process|activity|job}!|
Heya {i'm|i am} for {the primary|the first} time here.
I {came across|found} this board and I {in finding|find|to find} It
{truly|really} {useful|helpful} & it helped me
out {a lot|much}. {I am hoping|I hope|I'm hoping} {to give|to offer|to provide|to present} {something|one thing} {back|again}
and {help|aid} others {like you|such as you} {helped|aided} me.|
{Hello|Hi|Hello there|Hi there|Howdy|Good day|Hey there}!
{I just|I simply} {would like to|want to|wish to} {give you a|offer you a} {huge|big} thumbs up
{for the|for your} {great|excellent} {info|information} {you have|you've got|you
have got} {here|right here} on this post. {I will be|I'll
be|I am} {coming back to|returning to} {your blog|your site|your
website|your web site} for more soon.|
I {always|all the time|every time} used to {read|study} {article|post|piece of writing|paragraph} in news papers but now as
I am a user of {internet|web|net} {so|thus|therefore} from now I am using net for {articles|posts|articles or reviews|content}, thanks to web.|
Your {way|method|means|mode} of {describing|explaining|telling} {everything|all|the whole thing} in this {article|post|piece of writing|paragraph}
is {really|actually|in fact|truly|genuinely} {nice|pleasant|good|fastidious},
{all|every one} {can|be able to|be capable of} {easily|without difficulty|effortlessly|simply} {understand|know|be aware of} it, Thanks
a lot.|
{Hi|Hello} there, {I found|I discovered} your {blog|website|web site|site} {by means of|via|by the use of|by way of}
Google {at the same time as|whilst|even as|while} {searching for|looking for}
a {similar|comparable|related} {topic|matter|subject},
your {site|web site|website} {got here|came} up, it {looks|appears|seems|seems to be|appears to
be like} {good|great}. {I have|I've} bookmarked it in
my google bookmarks.
{Hello|Hi} there, {simply|just} {turned into|became|was|become|changed into} {aware of|alert to} your {blog|weblog} {thru|through|via} Google, {and found|and located} that {it
is|it's} {really|truly} informative. {I'm|I am} {gonna|going to} {watch out|be careful} for brussels.
{I will|I'll} {appreciate|be grateful} {if you|should you|when you|in the event you|in case you|for those who|if you
happen to} {continue|proceed} this {in future}.

{A lot of|Lots of|Many|Numerous} {other folks|folks|other people|people} {will be|shall be|might be|will probably be|can be|will likely
be} benefited {from your|out of your} writing.

Cheers!|
{I am|I'm} curious to find out what blog {system|platform} {you have been|you happen to be|you are|you're} {working with|utilizing|using}?

I'm {experiencing|having} some {minor|small} security {problems|issues} with
my latest {site|website|blog} and {I would|I'd} like to find something more {safe|risk-free|safeguarded|secure}.
Do you have any {solutions|suggestions|recommendations}?|
{I am|I'm} {extremely|really} impressed with your writing skills {and also|as well as} with the layout
on your {blog|weblog}. Is this a paid theme or did you {customize|modify} it yourself?
{Either way|Anyway} keep up the {nice|excellent} quality writing, {it's|it is} rare
to see a {nice|great} blog like this one {these days|nowadays|today}.|
{I am|I'm} {extremely|really} {inspired|impressed} {with your|together with your|along with your} writing {talents|skills|abilities} {and also|as {smartly|well|neatly} as} with the
{layout|format|structure} {for your|on your|in your|to your} {blog|weblog}.

{Is this|Is that this} a paid {subject|topic|subject matter|theme} or did you {customize|modify} it {yourself|your self}?
{Either way|Anyway} {stay|keep} up the {nice|excellent} {quality|high quality} writing, {it's|it is}
{rare|uncommon} {to peer|to see|to look} a {nice|great} {blog|weblog} like this one {these days|nowadays|today}..|
{Hi|Hello}, Neat post. {There is|There's} {a problem|an issue} {with your|together with your|along with your} {site|web site|website}
in {internet|web} explorer, {may|might|could|would} {check|test} this?
IE {still|nonetheless} is the {marketplace|market} {leader|chief} and
{a large|a good|a big|a huge} {part of|section
of|component to|portion of|component of|element of} {other folks|folks|other people|people} will {leave out|omit|miss|pass over} your {great|wonderful|fantastic|magnificent|excellent} writing {due to|because of} this problem.|
{I'm|I am} not sure where {you are|you're} getting your {info|information}, but {good|great} topic.
I needs to spend some time learning {more|much more} or understanding more.
Thanks for {great|wonderful|fantastic|magnificent|excellent} {information|info} I was looking for this {information|info} for my
mission.|
{Hi|Hello}, i think that i saw you visited my {blog|weblog|website|web site|site} {so|thus} i came to
“return the favor”.{I am|I'm} {trying to|attempting to} find things to {improve|enhance} my {website|site|web site}!I suppose its ok to use {some of|a few of} your i
\

Apr 11 2008
Apr 11

All in all, the response to Drupal Tough Love, the new code reviewing blog from chx and I, has been quite favorable, and we've already got a queue of at least a dozen submitted modules to look over. I had a grande chuckle at Amy Stephen's post on it over at OpenSourceCommunity.org:

I lift this service up because it's a perfect example of a functioning community ... What I am trying to say to those of you who are considering this service, but are not quite in touch with the inner geek inside, is this --> don't ask these guys if they think you are fat if you have your box of big clothes out and your skinny clothes are pushed in the back of the closet. It would be just like asking Simon Cowell if you can sing ... Károly and Morbus are not only acknowledged for who they are, and they are not only accepted for who they are, but who they are is celebrated. So, rock on, Drupal community!

Apr 11 2008
Apr 11

A few days ago I copied a Drupal site up on a GoDaddy server for somebody and noticed something immediately. My freaking sites were running REALLY slow on my server. This shared $10/mo GoDaddy server was outperforming my beefed up dedicated box hosted at a really good company by like 10x. How could this be? I wasn't quite sure, but it made me realize that Drupal sites really could run fast and I needed to find out what I was doing wrong.

Well there were a few things I have discovered during my search these last few days. Below I will share some steps on how to get your Drupal 5 site rocking like Stephen Hawking.

.htaccess

This is where I went wrong. It turns out that adding lots of rewrite cases to your .htaccess has a huge performance hit, like really big. So big, that it's the first thing I'm listing in my list and I think this is probably one of the most overlooked things. Changing my .htaccess 301s and redirects to a PHP server-side redirect improved performance literally 10x. It made all these other changes seem small, although they still help. If you have full control over your box you may also want to consider ditching the .htaccess and moving it into your conf file.

Opcode Cache

I also installed eAccelerator on my box and noticed about a 20 - 30% increase in PHP render time. I would definitely recommend this as a quick way to get your sites rendering quicker.

External File Server

I store many of my files on an external file server that is built lightweight and for static content delivery. I would highly recommend abstracting most of your theme and site files to an external source. This greatly cuts down http requests and allows your web server to focus on what it does best.

Minimize http requests

Speaking of external files, you will also want to minimize as many http requests as possible - and we all know Drupal does quite a bit in the CSS arena. By default Drupal has like 10 or so CSS files individually loaded in on each page request. These can all be compiled into 1 in your performance settings in Drupal and this will help cut down http requests. It is also recommended to include your javascript at the bottom of each page request if possible.

MySQL / PHP Configuration

It is important to make sure that your MySQL and PHP have the right variables set and are optimized according to your needs. In most cases you are going to want to allocate a good amount of resources towards MySQL and PHP as Drupal is very database and server-side intensive.

Boost Module

This is a great module for sudden traffic bursts, IE Digg or other social sites that may crush your server or SQL. This module basically redirects visitors (via htaccess) to a static page that has been rendered out. The module is pretty clean and the performance increase is HUGE. If you are looking to get around 50,000 or more anonymous visitors in a short period of time, this is a great way to handle it.

Keep in mind, that while this module saves your SQL and PHP it can slow down page display time as it has various rewrite rules in the htaccess that may not be needed when traffic is lower.

Devel Module

The Devel module for Drupal is a great way to check and see how your code is running. You are able to see the queries running for each page, the page rendering time and a lot of other helpful stuff. This module helped me figure out that my SQL and PHP was working really well so my bottleneck had to be something else. I'm sure in some cases you'd be able to find your SQL or PHP bottlenecking by using this module.

Lots of Modules

It should also be noted that having lots of modules enabled will require more processing time and could slow your site down. Despite the performance cost, I run LOTS of modules on most of my sites and although the render time may be 400ms VS 200ms I don't really see this as a super big issue because you're getting like 10x the site. Under heavy traffic these types of things could creep up on you, but I think the performance cost is worth it because it's making your site better. Right now I'm rocking lots of modules on my sites and my pages are loading very fast. This also depends greatly on how well the modules are codes as well.

XML-RPC

Be careful if you're using a lot of XML-RPC requests. It should be noted that each XML-RPC call runs a full Drupal bootstrap which could potentially slow your server down quite a bit if you're doing a lot of these.

That's it!

These are some good starting points towards speeding up your Drupal site. Hopefully this helps some of you guys out that may be suffering from what I have been suffering from these last few months.

Drupal for president of the United States!

 Filed under: Internet / Tech, Drupal, Server, Performance, Optimization
Apr 10 2008
Apr 10

We all make mistakes; that's how we learn. Sometimes, though, we need someone to point out our mistakes, to sift through the chaos that is Drupal's contributions repository. Inspired by jpoesen's comment on my code quality entry, chx and I have taken up the task of giving some tough love to Drupal's greatest strength: the army of developers using its APIs. Want your own code publicly reviewed at DrupalToughLove.com? Let us know!

Apr 10 2008
Apr 10

chx and Morbus reviewed Printer-Friendly Pages 5.x-3.4 which "allows you to generate printer friendly versions of any node by navigating to www.example.com/print/nid, where nid is the node id of content to render. A link is inserted in the each node (configurable in the content type settings), that opens a version of the page with no sidebars, search boxes, navigation pages, etc."

First-post disclaimers: As the first post, we're still figuring out the best format and approach to distilling the information we proffer. If you have suggestions, concerns, or have eyeballed one of our own mistakes, please let us know by leaving a comment. Likewise, also note that there was no ulterior motive to picking Printer-Friendly Pages as our first review: we literally just browsed through the 5.x taxonomy term until we found a recent release of a module we knew was in actual use. Our reviews are also not necessarily security reviews: if we don't mention any problems, it doesn't mean we assert the module is Security Team approved (of which we're both members). Finally, if you'd like us to review your own (contributed) module code, don't hesitate to let Morbus or chx know and we'll add it to our queue.

The Review

  1. $nodetype should be $node_type. Additionally, the use of $nodetype has a slight problem:

    <?php
    $nodetype
    = isset($node->type) ? $node->type : '';
    $print["submitted"] = theme_get_setting("toggle_node_info_$nodetype") ...
    ?>

    Your use here, and similarly on line 55, allows a theme_get_setting() check on a variable that would never exist ("toggle_node_info_"). It'll be a few more lines of code, but you're better served with an if that checks if $node->type exists, then calls the proper display options. Your final use on line 508 ($print["type"] = $nodetype;) could be moved into the same if.

  2. Coder only caught 3 errors (great job!) involving camelCase variable names (specifically, $queryArr). camelCase and mungedwords should be replaced with lower case variable names, split on word boundaries with a "_".
  3. As the PHP documentation says on strstr(): "If you only want to determine if a particular needle occurs within haystack, use the faster and less memory intensive function strpos()..." Instead of strstr($module, 'book_printer'), use strpos($module, 'book_printer')) !== FALSE instead.
  4. There's plenty of text files shipped with the module, and nearly all of them need work. Besides the standard "string retardation" (the name of the module is listed as "print", the module's filename, as opposed to "Printer-Friendly Pages", the module's actual name), and the README.txt and INSTALL.txt not using core style (in the absence of a style guide, Do What Core Does), they also can't agree on which format they themselves would like to use (README.txt uses numbered lists with either a), b) or i., ii., sub-items, whilst INSTALL.txt uses a dashed-list with i., ii., etc.). More egregious is the lack of hard newlines (depending, instead, on an editor's default word-wrapping capability, which browsers don't have, making these docs difficult to read online). In some cases, the docs are also slightly wrong (suggesting that it only works on nodes when it currently defaults to working on every page, an error that print.info also perpetuates). Finally, there's not a whole lot of rationale to have a CREDITS.txt and a MAINTAINER.txt in a contrib module - certainly, yes, it's "like core", but core is a lot bigger and maintained by far more people, which justifies their existence. Move the contents of your versions into your README.txt and get rid of 'em.
  5. print.css has some missing semi-colons and its formatting could be improved.
  6. Your print.install is great; thanks for deleting your variables. However, it's a bit odd to store most of a module's configuration inside a single variable (print_settings, etc.). Ideally, you'd only do that for things like lists, not for the entire batch of variables offered on a module's admin page. It's entirely possible this was a misstep or misuse of Forms API - there shouldn't ever be a real need to use #tree on a form intended for system_settings_form(). If you get rid of the #tree, you'll also be able to remove/collapse your various "default" functions (like print_robot_settings_default()).
  7. The print.module starts off with a spurious use of a constant - there's no real need for define("PRINT_PATH", "print"), and if one is concerned about having a single place to customize the root path for all printer-friendly pages, move it into a variable for the admin pages. It's only four or five extra lines of code to make the module friendlier, and more inline with what core does (no part of core hardcodes a menu path to a constant).
  8. A module that overrides hook_help() without providing its own help documentation is amusing.
  9. Another bad habit we often see is "string first on equality tests" such as lines 128 and 137:

    <?php
    if ('node_type_form' == $form_id) {
    ?>

    The implication, of course, is that a mistype of == to = would cause an error, since you can never assign anything to a string. The only rationale for using the above "workaround" is to indicate that not enough testing is happening. If a developer tests every line of code, obsessively and iteratively, they'd find "assignment instead of equality" bugs and could write and maintain code that doesn't use lazy tricks like the above. To make it worse, the module isn't consistent in this usage, with $type == 'comment' and count($matches) == 4 elsewhere. Replace these sorts of constructs, and don't rely on them to protect you from yourself - that's what testing is for.

  10. Theme functions (here theme_print_format_link() and theme_print_text()) should never return an array. If you want data or configuration to be override-able, use a hook and module_invoke_all(); developers can decide the ordering of the overrides via the standard module weight capabilities of the system table. In Drupal 6, there's also the new drupal_alter(), which allows you to pass around data and get hooks for free. Theme documentation tends to start with "Generate the themed output", traditionally HTML, not "return a structured array of strings". The true intent of these functions seems to be to control the strings displayed in the generated printer-friendly version, such as on line 466:

    <?php
    $print
    ["printdate"] = $print_sourceurl_settings['date'] ? (" (". $themed['retrieved'] ." ". format_date(time(), 'small') .")") : "";
    ?>

    But this is also considered bad form: one shouldn't ever concatenate strings onto a t() (here, the t() is stored inside the $themed['retrieved'], which was generated with a call to theme('print_text')). Assuming that the above string is assigned to $print["printdate"], you end up with t('retrieved on') . $date. One would think this OK until they consider a language where the date would read before, or in the midst of, the translated "retrieved on" (such as Japanese). Because the date is always appended to the translated string, it would always translate incorrectly. This even assumes translation... in English, one wouldn't be able to rephrase this to "[DATE] (retrieved on)". A much better approach is:

    <?php
    $print
    ["printdate"] = $print_sourceurl_settings['date'] ? t('(retrieved on %date)', array('%date' => format_date(time(), 'small'))) : "";
    ?>

    Besides reading more clearly from a code perspective, it allows translators to put the %date where they need it. One could also argue that this gives themers more control over the strings displayed. While the conceit is nice, it's still wrong: the site's developers should have properly setup a locale toolkit to allow translating of strings stored in Drupal's t() or, in Drupal 6, you could modify the strings inside the revised settings.php (scroll all the way to the bottom for documentation on how to do this). The shortest guideline here is: don't override the theme functionality (or, for that matter, any programming construct that is meant to do only one thing). Theme functions are intended for HTML, not a piggy-back into developmental hooks (as your use of theme_print_format_link(), which replicates hook_link_alter() functionality, promotes).

  11. print_generate_path() has very familiar menu code: this was committed to core for a few days and then rolled back (cf. this issue). This patch was one of those "unfixable" problems that lead to the menu system rewrite in Drupal 6. To sum up, _menu_append_contextual_items() was only ever designed to run once during a single page load: calling it a second time causes unpredictable results. One potential fix would be to set a flag in $_SESSION and do a drupal_goto() instead. Capturing the output passed to theme('page') is not easy in Drupal 5; you'd probably need to implement a phptemplate_variables() function or instruct your users to add your code there and use it to catch the content of theme hook page. You can check Advanced Forum for an example. Another trick you could pull is to provide an entirely new theme called 'print' and change to this theme in hook_menu() !$may_cache by tweaking the global $custom_theme (see Sections for an example).
  12. Something else we see a lot of are bad #descriptions for form elements. Either they're wrong or out-of-date, an exact repetition of the element's #title, or they contain spurious information. There's a little bit of all three in the elements that the module adds to some of Drupal's standard forms:

    <?php
    $form
    ['viewing_options']['print_display_comment'] = array(
     
    '#type' => 'checkbox',
     
    '#title' => t('Show printer-friendly version link in individual comments'),
     
    '#return_value' => 1,
     
    '#default_value' => variable_get('print_display_comment', '0'),
     
    '#description' => t('Displays the link to a printer-friendly version of the comment. Further configuration is available on the !settings.', array('!settings' => l(t('settings page'), 'admin/settings/print' ))),
    );
    ?>

    We'll start with the "Further configuration" sentence, which includes a link to the primary settings page. Not only is this dangerous (there's no check against user_access('administer print'), so a user who can administer comments may receive an "Access denied" message), but there's not a lot of benefit of going to the suggested URL: there's nothing additional that specifically affects the current decision. Removing that entire sentence leaves us with something that repeats the #title in a few more words and serves no useful purpose. This form element, as well as a similar checkbox for node types, should have its #description removed entirely. One final itch: integers don't use quotes (see #default_value).

  13. Core uses "Implementation of hook_NAME()." - you've forgotten the ending period on a few of yours.
  14. Use dangling commas on your arrays (From the coding standards: "Note the comma at the end of the last array element; This is not a typo! It helps prevent parsing errors if another element is placed at the end of the list later."). Some of your arrays do, others don't. Consistency, above all else, is key: if a developer is going to commit to something (mistake or otherwise), commit to it fully. Otherwise, it just looks sloppy.
  15. If the module is named "Printer-Friendly Pages", use that as the title of the admin settings page, not "Printer-friendly". Also, the description should be revised to note that it can now function on more than just nodes. Decide if it's "Printer-Friendly" (the capitalization on drupal.org) or "Printer-friendly" (the more grammatically correct usage, and what most of your documentation properly repeats).
  16. Lowercase AS in the foreach ($links AS $module => $link) on line 89.
  17. Don't use '#return_value' => 1 on boolean checkboxes in Forms API. #return_value is one of those fun and obscure constructs where you can specify what value you want if the checkbox has been clicked. It defaults to 1 already, which is usually what people expect and want.
  18. Standardize your form elements: under admin/settings/printer-friendly, you offer radio buttons ("Enabled" and "Disabled") for the printer-friendly link on nodes, but then change tactics by offering a single checkbox for the same feature, only for non-content pages. Get rid of the radio buttons and use the checkbox - for a decision involving merely "on" or "off" or "yes" and "no", a checkbox is always stronger than two radios.
  19. Drupal core uses TRUE and FALSE not true and false.
  20. Don't use PHP function aliases: use count(), not sizeof().
  21. If an array has only one item, implode() does the right thing (i.e., no joining with the glue string). Don't isset($robots_meta[1]) ? implode(', ', $robots_meta) : $robots_meta[0];, just skip the ternary entirely and use implode() as normal.
  22. The module's function documentation needs work - most functions have a one-line summary (good), but either skimp on the details (a @return string that depends on the one-liner to describe the results; best to remove the @return entirely) or leave them out wholesale (such as missing @params). Function summaries should always be one-line: "The first line of the block should contain a brief description of what the function does, beginning with a verb in the form "Do such and such" (rather than "Does such and such"). A longer description with usage notes may follow after a blank line. Each parameter should be listed with a @param directive, with a description indented on the following line."
  23. We're not entirely sure why the code uses $base_url or $base_path in _print_var_generator() and print_rewrite_urls(). You should be able to do most everything you need with url() and its "absolute URL?" parameter. Part of our confusion lies in the fact that url() is used for some conditions, but not others. Regardless, if you absolutely did require $base_path, use base_path() instead.
  24. $base_url is unused in print_generate_node() and the other _generate functions.
Apr 10 2008
Apr 10

Lasts night Drupal updated to version 6.2.

Read the full post on Millwood Online

Apr 10 2008
Apr 10


Thanks to the amazing Leslie Hawthorn and the awesome Chris DiBona, we can add an additional two sprinters to the list for SimpleTest Sprint, Paris! Both Charlie Gordon (me) and Jimmy Berry (aka boombatower) are now going to be at the testing sprint! Let's all thank Google for this awesome act of kindness towards the Drupal community!

SimpleTest is critical to Drupal, not only for quality assurance, but also to postpone the code freeze so we can add more features to Drupal 7 and make it as awesome as possible.


As this beautiful graph clearly shows, after Drupal has made the switch to complete SimpleTest coverage for core, the quality of Drupal will skyrocket, as we will be able to ensure that each patch committed to core does not break any of the SimpleTests, therefore less bugs and more features! When we have complete core SimpleTest coverage for Drupal, we will be free to explore awesome new features instead of spending precious time on bug hunting and bug fixing.

Let's make that Drupal 7 release a killer! :)

Thanks to Google, Leslie Hawthorn, and Chris DiBona for speeding up this process. We promise to save the world for you!

Apr 09 2008
Apr 09

This site is now running on Drupal 6, yeah! The basic part of the upgrade process was straightforward:

  • Backing up the site with a backup script.
  • Deactivating all contrib modules and themes.
  • Moving the Drupal 5 files to a new directory.
  • Unpacking Drupal 6 and contrib modules in the web root directory.
  • Running the database update script.
  • Activating contrib modules and themes.
  • Running the database update script again.

If you plan to upgrade a Drupal site without having done so before, I highly recommend this screencast by Angie Byron. The video walks you through upgrading a site from Drupal 4.7 to Drupal 5, but most of the information applies to a Drupal 5 to 6 upgrade as well. Also read the Upgrading Handbook.

The most involving part of this particular upgrade was getting the theme and a custom module to work with Drupal 6. Fortunately there is a fantastic theming handbook for Drupal 6, articles about converting 5.x themes to 6.x and converting 5.x modules to 6.x and the very helpful coder module.

The coder module generates a report for the selected modules and themes, telling which parts of your source code need to be changed to work with Drupal 6. Though it missed some occurrences of the url() and l() functions, that changed in Drupal 6, and the deprecated _phptemplate_variables() function, that is replaced by preprocess functions, the coder module was a great help.

Below is a screenshot of the coder module report. For each warning or error the line number of the file, a description of the problem linking to relevant documentation and the problematic piece of code are displayed.

Code Review Screenshot

Thanks to the available documentation, tutorials and tools the upgrade to Drupal 6 was quick and painless.

Apr 09 2008
Apr 09
Posted by Heine on 9 Apr 2008 at 20:25 UTC
  • Advisory ID: DRUPAL-SA-2008-026
  • Project: Drupal core
  • Version: 6.x
  • Date: 2008-April-09
  • Security risk: Moderately critical
  • Exploitable from: Remote
  • Vulnerability: Access bypass

Description

The menu system routes page requests to appropriate handlers. It also determines whether a user has access to pages based on several criteria, such as permissions assigned to a role. Drupal 6 features an entirely revised menu system, including changes to the way access is dealt with, which if not properly understood by developers can lead to vulnerabilities. This security release provides a more secure access behaviour by default, and fixes incorrectly set menu items in Drupal core.

Access to some pages was not appropriately controlled:

  • Any user can edit profile pages of other users.
  • Users who can view administration pages are able to edit content types.
  • The tracker and blog pages expose information to users without the "access content" permission.

Versions affected

  • Drupal 6.x before version 6.2.

Solution

Install the latest version:

  • If you are running Drupal 6.x then upgrade to Drupal 6.2.

If you are unable to upgrade immediately, you can apply a patch to secure your installation until you are able to do a proper upgrade. The patch fixes incorrectly set menu items in Drupal core, but does not contain the menu API change which would provide secure defaults. This patch is a temporary solution to be used if modules are required which are still incompatible with the new API changes.

If you used SA-2008-026-6.1.patch or SA-2008-026-6.1b.patch: the patch was incorrect. Please reverse the patch, such as patch -R, and apply the current patch.

Important notes

It is essential to follow this process when updating:

  • First make sure that you are logged in as user number 1 or that your site's settings.php has $update_free_access = TRUE; so that anyone can access the update.php script while you update the site. We suggest you log in as user 1 because you might have difficulties in gaining write access to your settings file.
  • Turn your site into offline mode.
  • Then, and only then replace your Drupal source code files with the new ones from Drupal 6.2.
  • Run update.php.
  • Turn your site back to online mode.
  • If you edited your site's settings.php, make sure to set $update_free_access = FALSE;

If you do not follow the above procedure, and just replace the source files, any attempt to access the site will be greeted with the message: "Fatal error: Call to undefined function user_uid_optional_to_arg() in includes/menu.inc on line 594" and you will have no way to set the site to offline mode on the web interface until you get through update.php.

Contributed modules may require an update to work properly with Drupal 6.2. Failing to update modules will lead to some pages of the affected modules not being accessible.

Note for Module developers

Drupal 6.2 contains two API changes.

  • Menu access callbacks are no longer inherited from parent items.
  • %user_current has been renamed to %user_uid_optional.

Additional information can be found in Updating your 6.x module to work with 6.2.

Reported by

  • The tracker and profile access issue were respectively reported by Peter Wolanin and Greg Knaddison of the Drupal security team.

Contact

The security contact for Drupal can be reached at security at drupal.org or via the form at http://drupal.org/contact.

Apr 09 2008
Apr 09

I have found Img Package (http://drupal.org/project/img_filter) to be a great module to get images into posts while the CCK situation is still up in the air. Whithin this module there is the choice between Lightbox or Thickbox, becuase Thickbox is not available for Drupal 6 I went for Lightbox.

Read the full post on Millwood Online

Apr 09 2008
Nik
Apr 09

Just a quick tip for an extra, more accessible theming variable. I have personally found that on nearly all the sites I’ve built, I’ve never had a use for the Mission variable. So it struck me that I could probably use this field to output something else; something relevant to the general workings of the site, for sure though.

So, on this site, I have edited the mission variable and put in the copyright notice that you see at the bottom of the page. I saved the config screen and carried on, thinking that it would just be working – I had tested it out on the front page, and the value was appearing where I had placed the $mission variable in the footer area in my page template. No problems, I thought.

Today, I actually noticed that this was not appearing, and I couldn’t work it out for a while, but I trawled through the phptemplate.engine, and in there is some code that conditionally sets the $mission variable on only the front page – perhaps that’s why it doesn’t get used so much?

Anyway, I opened up the template.php file for my theme, and placed in it the code below, in the _phptemplate_variables bit under case &#039;page&#039; – see here. Now I have a usable variable across all pages of my site, with the added advantage that this is accessible from the admin interface at “site information”. I guess that the theme settings API in Drupal 6 may alleviate this problem, but for simple things like updating the year (which is contained in my © statement) in D5, this is a potential time saver (and face-saver) for administrators.

<?php
 
// populate the $mission variable on every page so we can use it universally
  // don't check <front>, it's already handled in phptemplate.engine
if (!$vars['is_front']) {
   
$vars['mission'] = filter_xss_admin(theme_get_setting('mission'));
  }
?>
Apr 04 2008
Apr 04

Kieran just posted a great write-up on How to test 20 000 Drupal 7 core patches followed by Jimmy Berry's posting Paris Coding Sprint - Unit Testing. It summarizes many of the challenges Drupal is facing to be able to provide 100% testing coverage for Drupal core in addition to outlining the details of code sprint in Paris to help gather key developers to provide solutions.

During the code sprint, it is my goal to work closely with Rok Žlender to provide a mechanism for complete automated testing of HEAD in addition to a full reporting of the results in such a way that problems can be addressed and resolved. The issue queue at http://drupal.org/project/issues/Drupaltestbed will be cleaned up with specific resolutions being provided for issue http://drupal.org/node/239542, http://drupal.org/node/239546 and http://drupal.org/node/190987. Awareness of the Unit Testing Plan will need to be implemented into the Automated Testing as well.

Funding for this trip is generously being provided by pingVision, LLC

Pages

About Drupal Sun

Drupal Sun is an Evolving Web project. It allows you to:

  • Do full-text search on all the articles in Drupal Planet (thanks to Apache Solr)
  • Facet based on tags, author, or feed
  • Flip through articles quickly (with j/k or arrow keys) to find what you're interested in
  • View the entire article text inline, or in the context of the site where it was created

See the blog post at Evolving Web

Evolving Web