3 Aug 2007

Drupal Handbook

Table of Contents
Installation and configuration . . . . . . . . . . . . System requirements . . . . . . . . . . . . . . Client System Requirements . . . . . . . . . . . Javascript . . . . . . . . . . . . . . . CSS . . . . . . . . . . . . . . . . . RSS . . . . . . . . . . . . . . . . . Browser Specifics . . . . . . . . . . . . . Browser Popularity . . . . . . . . . . . . . Known Problems . . . . . . . . . . . . . Validation . . . . . . . . . . . . . . . Caveats . . . . . . . . . . . . . . . . HOWTO: Server requirement recommendations for your consulting clients Message to the Client . . . . . . . . . . . . Benchmark . . . . . . . . . . . . . . . What Drupal.org runs on . . . . . . . . . . . Requirements - older versions . . . . . . . . . . . Installing Drupal, modules and themes . . . . . . . . . Installing Drupal . . . . . . . . . . . . . . Formatted Drupal 5.x Installation instructions for better readability . Installation . . . . . . . . . . . . . . Changes . . . . . . . . . . . . . . . Requirements . . . . . . . . . . . . . . Optional Requirements . . . . . . . . . . . Installation . . . . . . . . . . . . . . Drupal Administration . . . . . . . . . . . Customizing your theme(s) . . . . . . . . . . Multi-site configuration . . . . . . . . . . . More Information . . . . . . . . . . . . . Formatted Drupal 4.7.x Installation instructions for better readability . Installation . . . . . . . . . . . . . . REQUIREMENTS . . . . . . . . . . . . . SERVER CONFIGURATION . . . . . . . . . . . OPTIONAL COMPONENTS . . . . . . . . . . . INSTALLATION . . . . . . . . . . . . . 1. DOWNLOAD DRUPAL . . . . . . . . . . . 2. CREATE THE DRUPAL DATABASE . . . . . . . 3. LOAD THE DRUPAL DATABASE SCHEME . . . . . . 4. CONNECTING DRUPAL . . . . . . . . . . 5. CONFIGURE DRUPAL . . . . . . . . . . . 6. CRON TASKS . . . . . . . . . . . . . DRUPAL ADMINISTRATION . . . . . . . . . . CUSTOMIZING YOUR THEME(S) . . . . . . . . . UPGRADING . . . . . . . . . . . . . . MORE INFORMATION . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 2 3 3 4 4 4 4 4 4 4 5 5 6 6 6 8 8 13 13 14 14 14 14 16 16 16 17 17 17 18 18 18 19 19 19 20 20 21 22 22 22 23 23

i

Drupal Handbook

3 Aug 2007

10 minute install using PuTTY SSH/Telnet client . . . . . . . . . How I installed Drupal: The Eightfold Way . . . . . . . . . . Installing virtual hosts for Drupal sites and subsites . . . . . . . . Mac OS X-specific guidelines . . . . . . . . . . . . . . Important notes for MySQL install: . . . . . . . . . . . . HOWTO: Create a local server environment for drupal using MAMP . . . . HOWTO: Installing PostgreSQL and MySQL on the same Mac OS X machine . . Installing Drupal on Mac OS X 10.4 Tiger . . . . . . . . . . Installing and Configuring MySQL . . . . . . . . . . . Sending mail . . . . . . . . . . . . . . . . . Creating the Drupal Database and Database User . . . . . . . . Installing using CVS repository . . . . . . . . . . . . Prefixed database.mysql for search and replace . . . . . . . . . . Setup Drupal on Windows XP Pro using IIS . . . . . . . . . . Basic /sites directory setup . . . . . . . . . . . . . . Special cases . . . . . . . . . . . . . . . . . . Compilation failed: this version of PCRE is not compiled with PCRE_UTF8 support Configure .htaccess to allow awstats to work with clean URL’s . . . . . Configuring .htaccess to ignore specific subfolders . . . . . . . . Ignoring Subfolders that exist in the DocumentRoot . . . . . . . Ignoring subfolders that are included via Apache Alias directives . . . . Create a custom php.ini . . . . . . . . . . . . . . . How to create a custom php.ini file when nothing else works . . . . . 1. Get and modify your custom php.ini file . . . . . . . . . 2. Creating your CGI script . . . . . . . . . . . . . 3. Modifying your .htaccess file . . . . . . . . . . . . 4. Test your site . . . . . . . . . . . . . . . . Create Drupal database using Plesk . . . . . . . . . . . . Drupal with safe mode enabled and open basedir . . . . . . . . Generic Mass SQL Import into Drupal . . . . . . . . . . . DrupalCon site . . . . . . . . . . . . . . . . How to degrade your Drupal db from MySQL 4.1.X/5.0.X to MySQL 4.0.X . . How-To: Virtual Hosting with Drupal . . . . . . . . . . . Introduction . . . . . . . . . . . . . . . . . Environment . . . . . . . . . . . . . . . . . Requirements . . . . . . . . . . . . . . . . . Next pages . . . . . . . . . . . . . . . . . How-To: Virtual Hosting with Drupal :: Prepare environment . . . . . Introduction . . . . . . . . . . . . . . . . . The drupal group . . . . . . . . . . . . . . . . The temp directory . . . . . . . . . . . . . . . The reference location . . . . . . . . . . . . . . . Navigation . . . . . . . . . . . . . . . . . How-To: Virtual Hosting with Drupal :: Solution Overview . . . . . Introduction . . . . . . . . . . . . . . . . . Safe mode . . . . . . . . . . . . . . . . . Open Basedir . . . . . . . . . . . . . . . . .

23 . 24 . 25 . 26 . 27 . 28 . 29 . 30 . 30 . 32 . 32 . 33 . 36 . 51 . 52 . 53 . 53 . 54 . 55 . 55 . 55 . 56 . 60 . 60 . 60 . 61 . 61 . 61 . 62 . 65 . 67 . 67 . 68 . 68 . 68 . 69 . 69 . 69 . 69 . 70 . 70 . 70 . 70 . 71 . 71 . 71 . 71 .

ii

3 Aug 2007

Drupal Handbook

Plesk integration . . . . . . . . . . . . . . Managed application . . . . . . . . . . . . . eAccelerator . . . . . . . . . . . . . . . Each individual vhost requirements . . . . . . . . . Navigation . . . . . . . . . . . . . . . HOWTO: copy a site to a local computer using XAMPP . . . . . HOWTO: Copy site to another directory for testing . . . . . . HOWTO: Install Drupal 5.x using cPanel . . . . . . . . HOWTO: Install Drupal using cPanel . . . . . . . . . HOWTO: Site to site transfer with phpMyAdmin and a FTP Client . . Import a MySQL data dump with BigDump . . . . . . . . What is BigDump? . . . . . . . . . . . . . Setting up BigDump . . . . . . . . . . . . . Uploading the sql file and bigdump.php to the webserver . . . . Running BigDump . . . . . . . . . . . . . Installing Drupal behind an Actiontec GT701-WG router . . . . . Installing Drupal in a subdirectory in 4.6 . . . . . . . . . More than one Drupal site on one machine . . . . . . . . General rules for multiple Drupal deployments . . . . . . Moving your Drupal installation to a new directory . . . . . . PCRE_UTF8 solution for VPS servers | FreeBSD . . . . . . . Known causes of PCRE server errors . . . . . . . . . Redirecting specific pages to new URLs (301 redirects in Drupal) . . . How to create 301 redirects in Drupal Apache mod_rewrite . . . The tolerant base URL . . . . . . . . . . . . . Using .htaccess to stop page caching . . . . . . . . . . Linux specific guidelines . . . . . . . . . . . . . Installing PHP, MySQL and Apache under Linux . . . . . . XAMPP for Linux Packages . . . . . . . . . . . . Installing XAMPP in Debian . . . . . . . . . . . Download XAMPP Latest version from the following link . . . . Start XAMPP Server . . . . . . . . . . . . . Windows-specific guidelines . . . . . . . . . . . . How to install Drupal for newbies using FTP and phpMyAdmin . . . Change "/tmp" on your drupal site. . . . . . . . . . Get Drupal ready . . . . . . . . . . . . . . Upload the database . . . . . . . . . . . . . HOWTO: Create an apache sandbox using Windows and Apache2Triad . Before you begin . . . . . . . . . . . . . . Installing Apache2Triad . . . . . . . . . . . . Installing Drupal . . . . . . . . . . . . . . Importing and exporting Drupal databases updated with PHPMyAdmin To export a database with PHPMyAdmin . . . . . . . . To import a database with PHPMyAdmin . . . . . . . . Using bigdump.php to deal with large databases . . . . . . Installing Apache (with PHP) on Windows . . . . . . . . Installing MySQL on Windows . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

72 . 72 . 72 . 73 . 73 . 73 . 74 . 75 . 77 . 80 . 82 . 82 . 83 . 83 . 84 . 84 . 85 . 85 . 86 . 86 . 87 . 88 . 88 . 89 . 89 . 90 . 90 . 90 . 91 . 91 . 91 . 91 . 94 . 95 . 95 . 95 . 96 . 96 . 97 . 97 . 98 . 100 . 100 . 101 . 102 . 102 . 104 .

iii

Drupal Handbook

3 Aug 2007

Installing PHP4 on Windows . . . . . . . . . . . . . 105 . Drupal 4.7 on Windows/IIS Requires PHP in ISAPI mode . . . . . . 105 . Installing PostgreSQL on Windows . . . . . . . . . . . . 105 . Multiple Drupal Sites under Windows . . . . . . . . . . . 106 . Running multiple sites on a local PC (localhost) from a single codebase, using Windows 106 Untar . . . . . . . . . . . . . . . . . . . 108 . Installing Drupal on Windows . . . . . . . . . . . . . 109 . PostgreSQL specific guidelines . . . . . . . . . . . . . 109 . ERROR: DB connect failed . . . . . . . . . . . . . . . 109 . ERROR: language "plpgsql" does not exist . . . . . . . . . . 110 . ERROR: null value in column "uid" violates not-null constraint . . . . . 110 . PostgreSQL support in Drupal 4.7.x . . . . . . . . . . . . 110 . Drupal 4.5 and PGSQL 8 configuration . . . . . . . . . . . 110 . Installing contributed modules . . . . . . . . . . . . . . 111 . HOWTO: Install glossary module . . . . . . . . . . . . . 113 . Where is the Glossary? . . . . . . . . . . . . . . . 113 . What is the purpose of the Glossary Module, and what does it do? . . . . 113 . Installing the Glossary Module . . . . . . . . . . . . . 114 . Configuring the Glossary . . . . . . . . . . . . . . 114 . Adding Full Page Definitions . . . . . . . . . . . . . 115 . Adding Glossary To Menus . . . . . . . . . . . . . . 115 . Leech - automating content addition . . . . . . . . . . . . 116 . Relationships between modules . . . . . . . . . . . . . 116 . Installing new modules (Drupal 4.6 or older) . . . . . . . . . . 117 . Multi-site installation and set-up . . . . . . . . . . . . . . 118 . 10 Minute Multisite Install & Configuration . . . . . . . . . . 119 . Access all multisites with www. only [.htaccess] . . . . . . . . . 121 . Drupal as a library . . . . . . . . . . . . . . . . 121 . Multi-site setup in 5.x using CPanel . . . . . . . . . . . . 123 . Multi-Site, Single Codebase, Shared Database, Shared Sign-on 4.6 . . . . . 124 . Apache (http) Configuration . . . . . . . . . . . . . 124 . Download and Placement . . . . . . . . . . . . . . 124 . SQL Setup . . . . . . . . . . . . . . . . . . 125 . Individual Site Configuration & Theming . . . . . . . . . . 126 . Some things which can be improved: . . . . . . . . . . . 127 . Multi-Site, Single Codebase, Shared Database, Shared Sign-on 5.x . . . . . 127 . 1. Prepare database and database user . . . . . . . . . . . 128 . 1.1. create a database and user . . . . . . . . . . . . . 128 . 2. create and modify site configuration . . . . . . . . . . . 128 . 2.1. duplicate settings folder . . . . . . . . . . . . . . 128 . 2.2. Modify config files . . . . . . . . . . . . . . . 128 . 2.2.1. provide DB connection detail . . . . . . . . . . . . 128 . 2.2.2. set prefixes for table names . . . . . . . . . . . . 128 . 3. create static links . . . . . . . . . . . . . . . . 129 . 4. install drupal . . . . . . . . . . . . . . . . . 130 . Multiple domains or vhosts using different databases . . . . . . . . 130 . Sharing Drupal tables between databases using MySQL5 Views . . . . . 131 .

iv

3 Aug 2007

Drupal Handbook

Multiple domains using the same database . . . . . . . . . Same codebase, completely different content and users . . . . . . Setup of /sites directory for multi-site . . . . . . . . . . Installing new themes . . . . . . . . . . . . . . Basic site configuration . . . . . . . . . . . . . . Settings . . . . . . . . . . . . . . . . . . General settings . . . . . . . . . . . . . . . Default front page . . . . . . . . . . . . . . . Examples . . . . . . . . . . . . . . . . Clean URLs . . . . . . . . . . . . . . . . .htaccess for clean urls on specific shared hosts . . . . . . . 403 Permission denied error . . . . . . . . . . . . A mod_rewrite bug causing occasional corruption of the query string . . Apache 2 configuration of clean URLs on Debian . . . . . . . Apache 2 on Ubuntu . . . . . . . . . . . . . Editing apache2.conf . . . . . . . . . . . . . Editing apache2/sites-available . . . . . . . . . . Clean URL Support in Abyss . . . . . . . . . . . Clean URL support in XAMPP . . . . . . . . . . . Clean URLs in Mac OS X Server . . . . . . . . . . . Clean URLs with different webservers . . . . . . . . . Microsoft Internet Services Server . . . . . . . . . . Lighttpd . . . . . . . . . . . . . . . . Clean URLs with Easyphp. . . . . . . . . . . . . Example Clean URL configuration of httpd.conf for performance . . . Existing URLs for server overwrite Drupal paths . . . . . . . IIS CleanURLs using some of the available ISAPI filters. . . . . . Translating Apache’s rewrite rules . . . . . . . . . Pathauto and Localizer . . . . . . . . . . . . . Setting up clean URLs above web document root on virtual private servers reboot vps after making change . . . . . . . . . . Using Clean URLs with IIS . . . . . . . . . . . . Alternate method . . . . . . . . . . . . . . set your sites 403 and 404 Error pages . . . . . . . . . . Configure your sites error reporting . . . . . . . . . . Cache support . . . . . . . . . . . . . . . Primary and secondary links . . . . . . . . . . . . General Information: . . . . . . . . . . . . . Setting Up Your Primary and Secondary Links: . . . . . . . Theming Your Link Menus . . . . . . . . . . . . Set length of trimmed posts and # of posts on front page . . . . . URL Alias Optimization . . . . . . . . . . . . . File system settings . . . . . . . . . . . . . . Download method . . . . . . . . . . . . . . Path settings . . . . . . . . . . . . . . . Date and time settings . . . . . . . . . . . . . . Customizing the interface . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

132 . 132 . 135 . 137 . 139 . 139 . 140 . 140 . 141 . 141 . 143 . 146 . 147 . 147 . 149 . 149 . 150 . 151 . 153 . 153 . 154 . 154 . 154 . 154 . 155 . 156 . 156 . 156 . 157 . 158 . 159 . 159 . 160 . 160 . 161 . 161 . 161 . 161 . 162 . 162 . 162 . 162 . 163 . 163 . 164 . 164 . 164 .

v

Drupal Handbook

3 Aug 2007

Customizing user login . . . . . . . . . . . . Beginner’s guide for Cron on a shared hosting provider . . . . Check your filters . . . . . . . . . . . . . Configure user registration . . . . . . . . . . . Creating a menu structure . . . . . . . . . . . Creating a menu . . . . . . . . . . . . . Simplifying the workflow . . . . . . . . . . . Helping search engines and robots.txt . . . . . . . . Controlling what gets indexed -- the robots.txt file . . . . . Add ’Disallow: /node/’ if your setup has aliases for all nodes . Selective Bot Crawling . . . . . . . . . . . Increase upload size in your php.ini . . . . . . . . . Need images etc? - check Filtered HTML . . . . . . . . Set default content options - Stop automatic promotion to the front page Show/hide ’Submitted by’ on posts . . . . . . . . . Blocks . . . . . . . . . . . . . . . . Block configuration . . . . . . . . . . . . Restricting blocks to certain pages . . . . . . . . Preventing a block from appearing in Drupal 4.5 . . . . . Custom blocks . . . . . . . . . . . . . Increase memory in your php.ini . . . . . . . . . . Database table prefix (and sharing tables across instances) . . . Share tables across instances . . . . . . . . . . Setup tip for Drupal 5 . . . . . . . . . . . Using schema prefixes with PostgreSQL . . . . . . . Define shared variables for all sites . . . . . . . . Drupal Cookbook (for New Drupallers) . . . . . . . . Purpose . . . . . . . . . . . . . . . . Background . . . . . . . . . . . . . . . Myths . . . . . . . . . . . . . . . . Using the Drupal Web Site . . . . . . . . . . . Typing Convention . . . . . . . . . . . . . Some Preliminary Advice . . . . . . . . . . . Drupal Is Supposed to be Easy? . . . . . . . . . . A. Getting Started . . . . . . . . . . . . . B. Basic Configuration . . . . . . . . . . . . C. Creating Multiple Sites On Your Local Computer . . . . . D. Error Pages . . . . . . . . . . . . . . Page Not Found . . . . . . . . . . . . . Access Denied . . . . . . . . . . . . . E. Accessing Your Test Site(s) . . . . . . . . . . F. Adding Modules and Themes . . . . . . . . . . Installation . . . . . . . . . . . . . . Modules . . . . . . . . . . . . . . . Modules . . . . . . . . . . . . . . This Site . . . . . . . . . . . . . . Themes . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

165 . 166 . 167 . 168 . 168 . 169 . 169 . 169 . 170 . 171 . 171 . 175 . 176 . 177 . 178 . 178 . 178 . 179 . 180 . 182 . 182 . 183 . 184 . 185 . 185 . 187 . 189 . 189 . 189 . 189 . 190 . 190 . 190 . 191 . 192 . 193 . 194 . 197 . 197 . 197 . 198 . 198 . 199 . 199 . 199 . 200 . 200 .

vi

3 Aug 2007

Drupal Handbook

Themes . . . . . . . . . . . . . . . . Logo and Favorite Icon . . . . . . . . . . . . G. Creating Content . . . . . . . . . . . . . . Content Types . . . . . . . . . . . . . . Page . . . . . . . . . . . . . . . . . Story . . . . . . . . . . . . . . . . . Book Page . . . . . . . . . . . . . . . Blog Entry . . . . . . . . . . . . . . . G1. Creating a Page . . . . . . . . . . . . . G2. Creating a Story . . . . . . . . . . . . . What’s a Teaser? . . . . . . . . . . . . . G3. Creating a Book Page . . . . . . . . . . . . G4. Creating a Blog entry . . . . . . . . . . . . H. Custom Blocks . . . . . . . . . . . . . . Address . . . . . . . . . . . . . . . . Last Updated . . . . . . . . . . . . . . . I. Working with the Menu . . . . . . . . . . . . Introduction . . . . . . . . . . . . . . . How To Menu . . . . . . . . . . . . . . Textual Menu . . . . . . . . . . . . . . . Tabbed Menu . . . . . . . . . . . . . . . Books . . . . . . . . . . . . . . . . . More . . . . . . . . . . . . . . . . . I2. The Contact Form . . . . . . . . . . . . . Set Up . . . . . . . . . . . . . . . . Make It Accessible . . . . . . . . . . . . . Add "Contact" to the Menu . . . . . . . . . . . Using It In Content . . . . . . . . . . . . . J. URL Aliases . . . . . . . . . . . . . . . K. Moving Entire Drupal Site with Databases . . . . . . . . Backup Process with phpMyAdmin . . . . . . . . . Backup Process with phpMyAdmin . . . . . . . . . . L. Moving Stuff to Your Web Site . . . . . . . . . . M. Setting Up Cron . . . . . . . . . . . . . . N. Categories (Taxonomy) . . . . . . . . . . . . O. Common Problems . . . . . . . . . . . . . P. Links and IMG . . . . . . . . . . . . . . Q. Additional Tips and Tricks . . . . . . . . . . . Q1. Tracking Module Status . . . . . . . . . . . Q2. Making Multiple Site Maintenance a Bit Easier . . . . . . Q3. Controlling User Log In . . . . . . . . . . . How do I disable "Create New Account?" . . . . . . . How do I disable User Log In entirely, and how would I get in if I do? R. Keeping Your Local and Remote Sites Synchronized . . . . . S. More Reading . . . . . . . . . . . . . . . T. Glossary . . . . . . . . . . . . . . . . Taking your site live . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

200 . 200 . 201 . 202 . 202 . 202 . 202 . 203 . 203 . 204 . 204 . 205 . 205 . 206 . 206 . 206 . 207 . 207 . 207 . 208 . 208 . 208 . 209 . 209 . 209 . 209 . 210 . 210 . 210 . 211 . 213 . 213 . 216 . 216 . 217 . 219 . 219 . 220 . 220 . 220 . 221 . 221 . 221 . 222 . 222 . 223 . 226 .

vii

Drupal Handbook

3 Aug 2007

Moving from a temporary location . . . . . . . . Moving Drupal . . . . . . . . . . . . . Redirecting your server . . . . . . . . . . . Excluding paths from Drupal . . . . . . . . . Core modules . . . . . . . . . . . . . . Aggregator: publishing syndicated content . . . . . . Old page . . . . . . . . . . . . . . Open aggregator links in new browser window . . . . User Aggregator:user submitted feeds . . . . . . . What do I need to subscribe to a feed? . . . . . . . Configuring news feeds . . . . . . . . . . Filter feeds by keyword, time, by summary . . . . . Creating categories in the aggregator . . . . . . . Tagging individual items in the aggregator . . . . . . Using the news aggregator . . . . . . . . . RSS feed blocks . . . . . . . . . . . . Block: controlling content in the sidebars . . . . . . . Module blocks . . . . . . . . . . . . Administrator defined blocks . . . . . . . . . Blog: a blog for every user . . . . . . . . . . HOWTO: Configure user blogs . . . . . . . . Most recent blog post block . . . . . . . . . Navigate throught categories inside a blog . . . . . . What is a blog or weblog? . . . . . . . . . . Making user blogs more accessible . . . . . . . . Additional features . . . . . . . . . . . BlogApi: post from blog tools . . . . . . . . . Book: structured document publishing . . . . . . . Customising the book navigation menu . . . . . . Maintaining a FAQ using a collaborative book . . . . . Categories (taxonomy): A way to organize your content . . . Modules that do more with categories . . . . . . . Content Management System comparison focused on Taxonomy Taxonomy - some guidelines for effective design of taxonomies . Taxonomy Garden: Managing Categories . . . . . . Taxonomy Garden: Navigation by category . . . . . Taxonomy Garden: Organize content by category . . . . The taxonomy module for Drupal 4.x . . . . . . . Understanding categories for new users . . . . . . Using taxonomy to organize content . . . . . . . Using vocabularies for navigation . . . . . . . . Vocabularies and terms . . . . . . . . . . Creating a vocabulary . . . . . . . . . . Creating terms . . . . . . . . . . . . Advanced taxonomies: using hierarchies . . . . . . More about Taxonomy . . . . . . . . . . Creating a Block with links belonging to certain taxonomy terms

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

226 . 226 . 226 . 227 . 228 . 228 . 229 . 229 . 229 . 230 . 230 . 231 . 231 . 231 . 231 . 232 . 232 . 232 . 233 . 233 . 233 . 234 . 234 . 234 . 235 . 235 . 236 . 236 . 237 . 238 . 239 . 242 . 244 . 244 . 246 . 247 . 254 . 260 . 261 . 262 . 265 . 266 . 267 . 267 . 268 . 268 . 270 .

viii

3 Aug 2007

Drupal Handbook

Taxonomy terms on a page . . . . . . . . . . . . . Comment: allow comments on content . . . . . . . . . . . Detailed comment documentation . . . . . . . . . . . . User control of comment display . . . . . . . . . . . Additional comment configurations . . . . . . . . . . . Notification of new comments . . . . . . . . . . . . Comment moderation . . . . . . . . . . . . . . Moderation votes . . . . . . . . . . . . . . . Moderator vote/values matrix . . . . . . . . . . . . Creating comment thresholds . . . . . . . . . . . . Initial comment scores . . . . . . . . . . . . . . Aggregator comments . . . . . . . . . . . . . . Contact: a way for users to get in touch . . . . . . . . . . . Make your site wide contact form look prettier . . . . . . . . . Drupal: Drupal sites directory server . . . . . . . . . . . . Old page . . . . . . . . . . . . . . . . . . Filter: Input formats for user content . . . . . . . . . . . . Forum: create threaded discussions . . . . . . . . . . . . HOWTO: Create a forum . . . . . . . . . . . . . . HOWTO: Create forum containers . . . . . . . . . . . . Help: context-sensitive guidance . . . . . . . . . . . . . More about the help module . . . . . . . . . . . . . Legacy: remapping of old-style URLs . . . . . . . . . . . Locale: multi-language support . . . . . . . . . . . . . Adjusting your php.ini settings for importing .po files . . . . . . . Editing text for translation . . . . . . . . . . . . . . How to create Drupal site in Marathi (Devnagari) . . . . . . . . How to install a different language . . . . . . . . . . . HOWTO: Creating a customized language set to replace Drupal terminology . HOWTO: Use a customized language set to change Drupal text and terminology Note for the curious . . . . . . . . . . . . . . . Menu: customize site navigation . . . . . . . . . . . . . Using named anchors with menus . . . . . . . . . . . . Node: the content . . . . . . . . . . . . . . . . Page: post static pages . . . . . . . . . . . . . . . Difference between page and story . . . . . . . . . . . . Specify page by title . . . . . . . . . . . . . . . Path: readable URLs . . . . . . . . . . . . . . . . Mass URL aliasing . . . . . . . . . . . . . . . Ping: notify services of changes . . . . . . . . . . . . . Write a custom module to ping a set of sites . . . . . . . . . Poll: community voting . . . . . . . . . . . . . . . Profile: extending user account information . . . . . . . . . . Enabling user pictures (avatars) . . . . . . . . . . . . HOWTO: Create new profile fields . . . . . . . . . . . . HOWTO: Make a field part of the registration process . . . . . . . Form Validation in plugin . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

271 . 272 . 272 . 272 . 273 . 273 . 274 . 274 . 274 . 274 . 275 . 275 . 275 . 276 . 276 . 277 . 277 . 278 . 279 . 279 . 279 . 280 . 280 . 280 . 281 . 282 . 282 . 283 . 283 . 284 . 286 . 286 . 286 . 287 . 288 . 288 . 289 . 289 . 290 . 291 . 291 . 292 . 293 . 294 . 295 . 295 . 295 .

ix

Drupal Handbook

3 Aug 2007

HOWTO: Create a ’country’ profile field . . . . . . . . . CiviCRM: Tags, Profiles, Groups, advanced community member management Search: an internal site search system . . . . . . . . . . . Add searching to your custom module . . . . . . . . . . Statistics: tracking referrers, page hits, etc. . . . . . . . . . Story: post static pages . . . . . . . . . . . . . . System: cron and caching . . . . . . . . . . . . . Configuring cron jobs . . . . . . . . . . . . . . Configuring cron jobs on DreamHost . . . . . . . . . Cron Job configuration line by line . . . . . . . . . . Cronjobs without wget/lynx or curl . . . . . . . . . . Configuring cron jobs on Windows . . . . . . . . . . Throttle: congestion control . . . . . . . . . . . . . When to use the throttle module? . . . . . . . . . . . Tracker: viewing new and updated content . . . . . . . . . Upload: collaborate with files . . . . . . . . . . . . User: access and management settings . . . . . . . . . . Access Permissions reference . . . . . . . . . . . . block module . . . . . . . . . . . . . . . filter module . . . . . . . . . . . . . . . menu module . . . . . . . . . . . . . . . node module . . . . . . . . . . . . . . . path module . . . . . . . . . . . . . . . user module . . . . . . . . . . . . . . . system module . . . . . . . . . . . . . . . Access rules (email filters) . . . . . . . . . . . . . Managing access control with permissions and user roles . . . . . Assigning permissions and users to roles . . . . . . . . Taxonomy_access: Restrict user roles to access specific categories only . Adjusting permissions after adding modules . . . . . . . . User authentication . . . . . . . . . . . . . . Make a Drupal site use Basic Auth/ldap instead of the normal login block NTLM Authentication . . . . . . . . . . . . . User preferences and profiles . . . . . . . . . . . . Using distributed authentication . . . . . . . . . . . Distributed authentication . . . . . . . . . . . . Drupal . . . . . . . . . . . . . . . . . Watchdog: monitor your site . . . . . . . . . . . . . End user guide . . . . . . . . . . . . . . . . Registering as a user . . . . . . . . . . . . . . . Logging in . . . . . . . . . . . . . . . . . Changing your account settings . . . . . . . . . . . . Creating new content . . . . . . . . . . . . . . A step-by-step example . . . . . . . . . . . . . Controlling Teaser Location . . . . . . . . . . . . How to add a page to the Handbook . . . . . . . . . . Types of content . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

295 . 296 . 297 . 298 . 298 . 299 . 299 . 301 . 302 . 303 . 304 . 305 . 306 . 307 . 307 . 308 . 308 . 309 . 309 . 309 . 309 . 309 . 310 . 310 . 310 . 310 . 311 . 312 . 312 . 312 . 313 . 313 . 315 . 317 . 317 . 317 . 317 . 318 . 319 . 319 . 320 . 320 . 321 . 321 . 323 . 324 . 324 .

x

3 Aug 2007

Drupal Handbook

Topics, categories and terms . . . . . . . . . Permissions . . . . . . . . . . . . . Moderation and the submission queue . . . . . . . Creating comments . . . . . . . . . . . Alternative ways to enter content . . . . . . . . HOWTO: Posting and editing blog entries with TextMate . Posting and editing content with w.bloggar . . . . . Posting content with mailhandler . . . . . . . Preparing content offline . . . . . . . . . Editing and deleting content . . . . . . . . . . Search . . . . . . . . . . . . . . . Beyond the basics . . . . . . . . . . . . Sports . . . . . . . . . . . . . . . . football . . . . . . . . . . . . . . . Best practices guidelines . . . . . . . . . . . Back up your Drupal site . . . . . . . . . . Backing up the database . . . . . . . . . . Backing up the core files . . . . . . . . . . Backing up the non-core files . . . . . . . . . Test your backups . . . . . . . . . . . . Backup and restore using bash shell scripts . . . . . Functional Overview . . . . . . . . . . Usage notes and cautions . . . . . . . . . Site backup script . . . . . . . . . . . Usage notes and warnings: . . . . . . . . fullsitebackup.sh . . . . . . . . . . . Updated fullsitebackup.sh . . . . . . . . Site restore script . . . . . . . . . . . Usage notes and warnings: . . . . . . . . fullsiterestore.sh . . . . . . . . . . . Updated fullsiterestore.sh . . . . . . . . . Accounts and roles . . . . . . . . . . . . Configuring Apache and PHP for Drupal in a Shared Environment Creating a Test Site workflow . . . . . . . . . File and directory management . . . . . . . . . Other Tips . . . . . . . . . . . . . Test Sites . . . . . . . . . . . . . . Version update considerations . . . . . . . . . Do not modify core Drupal . . . . . . . . . . Security . . . . . . . . . . . . . . . Test php before putting it in blocks . . . . . . . . HowTo: The Advanced user’s guide . . . . . . . . HowTo: enable Imagemagick for the Image module . . . . Tips and Tricks . . . . . . . . . . . . . August 2005: Upgrade, Play B-I-N-G-O!, & E-commerce . . UPGRADE . . . . . . . . . . . . . PLAY B-I-N-G-O! . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

324 . 324 . 325 . 325 . 325 . 326 . 327 . 328 . 328 . 328 . 329 . 330 . 331 . 331 . 332 . 332 . 332 . 333 . 333 . 334 . 334 . 334 . 334 . 335 . 335 . 336 . 338 . 340 . 341 . 341 . 344 . 346 . 347 . 348 . 352 . 353 . 353 . 353 . 354 . 355 . 355 . 356 . 357 . 357 . 357 . 357 . 358 .

xi

Drupal Handbook

3 Aug 2007

E-COMMERCE . . . . . . . . . . . . . . . . . 358 . Commentator array . . . . . . . . . . . . . . . . 358 . June 2005: Custom Content Types, WYSIWIG Editors, Organize Your Content & Quick Support . . . . . . . . . . . . . . . . . . . 359 . September 2005: Newest modules, Change any string, Remote authentication, and tracking project issues . . . . . . . . . . . . . . . . 360 . Get the newest modules -- fast! . . . . . . . . . . . . . 360 . Change any string . . . . . . . . . . . . . . . . 360 . Remote authentication . . . . . . . . . . . . . . . 360 . Keep tabs on project issues . . . . . . . . . . . . . . 361 . Winter 2005/2006: Tracking projects with RSS and Module Linking . . . . . 361 . Planning a web site . . . . . . . . . . . . . . . . . 361 . Server tuning considerations . . . . . . . . . . . . . . . 365 . Identifying Drupal performance goals . . . . . . . . . . . . 365 . Analysing your site’s traffic and resource consumption . . . . . . . . 365 . Understanding and configuring your stack for performance . . . . . . 365 . Enable default 404 handling for some file types . . . . . . . . . . 367 . Simple Decision Tree for Drupal Enterprise Scalability . . . . . . . . 368 . Slow contributed modules determined using the developer module . . . . . 369 . Squid Caching . . . . . . . . . . . . . . . . . 369 . Tools, tips, and links on optimizing mysql . . . . . . . . . . . 370 . Tuning MySQL for Drupal . . . . . . . . . . . . . . 372 . Tuning PHP . . . . . . . . . . . . . . . . . . 372 . Persistent database connections . . . . . . . . . . . . . 373 . PHP caches . . . . . . . . . . . . . . . . . . 373 . APC : Alternative PHP Cache . . . . . . . . . . . . . 374 . eAccelerator . . . . . . . . . . . . . . . . . 374 . Turck MMCache . . . . . . . . . . . . . . . . 374 . Useful article on optimizing PHP . . . . . . . . . . . . . 376 . Tuning Drupal on OS X Tiger . . . . . . . . . . . . . . 376 . Upgrading from previous versions . . . . . . . . . . . . . . 378 . Introduction to upgrading . . . . . . . . . . . . . . . 378 . Getting started: Choosing your method and preparing the site . . . . . . 378 . Preparing the site . . . . . . . . . . . . . . . . 379 . Do I need to upgrade my database? . . . . . . . . . . . . 379 . Important! : Backing up the database and existing files . . . . . . . . 379 . Backing up your site (GUI) . . . . . . . . . . . . . . 379 . Back up your site (command line) . . . . . . . . . . . . 380 . Create a test site first or upgrade your existing site? . . . . . . . . 381 . Copy your live site to a test site (GUI) . . . . . . . . . . . 381 . Copying your live site to a test site (command line) . . . . . . . . 382 . Downloading Drupal and installing the files . . . . . . . . . . 384 . Downloading Drupal and installing the files (GUI) . . . . . . . . 384 . Downloading Drupal and installing the files (command line) . . . . . . 385 . Running update.php . . . . . . . . . . . . . . . . 386 . Optional configuration steps . . . . . . . . . . . . . . 387 . Post-upgrade steps . . . . . . . . . . . . . . . . 388 .

xii

3 Aug 2007

Drupal Handbook

Testing Your Newly Upgraded Site . . . . . . . . Copy your test site to a live site . . . . . . . . . Copying your test site to your live site (command line) . . . Copy your test site to a live site (GUI) . . . . . . . Differences from 4.7 to 5.x . . . . . . . . . . . Important note on upgrading from 4.7 to 5.1 . . . . . . Important note on upgrading from 4.7 to 5.1 . . . . . . Version specific upgrades . . . . . . . . . . . Upgrading from Drupal 4.4 to 4.5 . . . . . . . . . Upgrading from Drupal 4.5 to 4.6.3 . . . . . . . . Before you Start . . . . . . . . . . . . . Step-by-step Upgrade from Drupal 4.5 to 4.6.3 . . . . . Finalising your upgrade . . . . . . . . . . . Rebuilding your Drupal Search Index. . . . . . . . Blocks . . . . . . . . . . . . . . . . Permissions . . . . . . . . . . . . . . Forums . . . . . . . . . . . . . . . Images . . . . . . . . . . . . . . . Events . . . . . . . . . . . . . . . Upgrading from Drupal 4.6.3 to 4.6.5 . . . . . . . . Before you Start . . . . . . . . . . . . . Step-by-step Upgrade from Drupal 4.6.3 to 4.6.5 . . . . . Upgrading from Drupal 4.6.4 to 4.6.5 . . . . . . . . Before you Start . . . . . . . . . . . . . Step-by-step Upgrade from Drupal 4.6.4 to 4.6.5 . . . . . Differences from 4.6 to 4.7 . . . . . . . . . . . Block visibility settings . . . . . . . . . . . Configure options centralized . . . . . . . . . . core module help text linked to the handbook now . . . . . Creating context sensitive menus with primary and secondary menus Don’t turn off contributed modules that provide an .install file . . Module .install files . . . . . . . . . . . . Primary/secondary links now part of the menu system . . . . queue module removed from core . . . . . . . . . Removal of base href statement from header . . . . . . Some HTML Tags stripped from mission statement . . . . XTemplate engine removed from core . . . . . . . . Troubleshooting FAQ . . . . . . . . . . . . . How to troubleshoot (read this first) . . . . . . . . . Stop and think . . . . . . . . . . . . . Read the errors . . . . . . . . . . . . . Validate your page . . . . . . . . . . . . Read the README . . . . . . . . . . . . Search the right way . . . . . . . . . . . . Identify the source of the problem . . . . . . . . . Dump some diagnostics . . . . . . . . . . . Ask the right questions . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

388 . 389 . 390 . 390 . 391 . 391 . 392 . 392 . 392 . 393 . 394 . 394 . 396 . 396 . 396 . 396 . 397 . 397 . 397 . 397 . 398 . 398 . 398 . 398 . 399 . 399 . 399 . 399 . 400 . 400 . 400 . 401 . 401 . 401 . 402 . 403 . 403 . 404 . 404 . 404 . 404 . 405 . 405 . 405 . 406 . 406 . 407 .

xiii

Drupal Handbook

3 Aug 2007

Identify the module that’s giving you problems . . . . . . . . My admin > modules page is blank . . . . . . . . . . . . How do I get the User Login block back . . . . . . . . . . . Client does not support authentication protocol requested by server... . . . . Webhosting issues for new Drupal users . . . . . . . . . . . Brief intro to Unix file permissions . . . . . . . . . . . . Host-specific error messages . . . . . . . . . . . . . SELinux may cause mysterious permission problems . . . . . . . Typical webhosting setups . . . . . . . . . . . . . Using PHP to change files on the webserver . . . . . . . . . What do all those Unix commands mean? . . . . . . . . . . Some Unix command you’ll see mentioned: . . . . . . . . . Special characters: . . . . . . . . . . . . . . . What permissions does Drupal need? . . . . . . . . . . . Why is this uploading stuff so difficult? . . . . . . . . . . "Headers already sent" error . . . . . . . . . . . . . . "LOCK TABLES sequences WRITE" error . . . . . . . . . . "Method POST is not allowed for the URL /index.htm" error (Error 405) . . . "Page Not Found" error when trying to access a subdirectory . . . . . . Block referrer spam . . . . . . . . . . . . . . . . .htaccess sample list plus domain blocking . . . . . . . . . . Color picker doesn’t appear on theme configuration page . . . . . . . Drupal 4.7 Install inserts CGI-BIN in URL . . . . . . . . . . Duplicate entry error . . . . . . . . . . . . . . . E-Mail from Drupal is bouncing or not being sent . . . . . . . . Relay SMTP mail to external mail server using smtp.class . . . . . . Error 1364 upon importing database.mysql with MySQL 5.0+ . . . . . . Error on installation step 3: Warning: Table ’[database].access’ doesn’t exist [...] . Fatal error: Allowed memory size of X bytes exhausted (tried to allocate Y bytes)... Fatal error: Call to undefined function . . . . . . . . . . . Fatal error: Call to undefined function: form_*() on Drupal 4.7 . . . . . Fatal error: Cannot redeclare blah_function() in ../modules/blah.module . . . Forgotten your Drupal account password . . . . . . . . . . Forum overview stopped working . . . . . . . . . . . . The Fix . . . . . . . . . . . . . . . . . . FTP uploads and file permissions using Transmit . . . . . . . . . Help! I enabled a buggy module and now I can’t disable it! . . . . . . How can I adminstrate my navigation on my Drupal site? (version 4.5 or older) . How do I get rid of the "Welcome to your new Drupal website" on the front page? . How do I get the Navigation block back . . . . . . . . . . . How do I unset the clean URLs? . . . . . . . . . . . . . How to login once you have turned your site off-line for maintenance . . . . HOWTO: Download a fresh copy of a missing or corrupted module/image/file . Installation/configuration . . . . . . . . . . . . . . 406 Error when XMLRPC is used . . . . . . . . . . . . Junk {head} {styles} codes as output . . . . . . . . . . . . Login after disabling the User login block . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

407 . 407 . 408 . 408 . 409 . 409 . 411 . 411 . 412 . 413 . 413 . 413 . 414 . 414 . 416 . 416 . 417 . 417 . 418 . 418 . 419 . 420 . 420 . 421 . 423 . 423 . 424 . 425 . 426 . 426 . 426 . 427 . 427 . 428 . 428 . 429 . 429 . 429 . 431 . 432 . 432 . 432 . 433 . 434 . 434 . 434 . 435 .

xiv

3 Aug 2007

Drupal Handbook

Login doesn’t work or must be done twice . . . . . . . . . . . Cookies . . . . . . . . . . . . . . . . . . . Cache Problems . . . . . . . . . . . . . . . . . Logging in at www on a site with no www in the baseurl . . . . . . . Login problems on PHP 5.2 . . . . . . . . . . . . . . . My layout collapses - content appears below left column (IE) or overflows over the right (FF) . . . . . . . . . . . . . . . . . . . . . The content is too wide for the space it’s been given . . . . . . . . Validation Woes . . . . . . . . . . . . . . . . . Mysterious 403, 404, 406 or 500 errors depending on submitted content . . . . Permission denied in includes/file.inc . . . . . . . . . . . . Persistent ’Welcome to Drupal’ for anonymous users . . . . . . . . . phpinfo . . . . . . . . . . . . . . . . . . . . Plain unstyled HTML output . . . . . . . . . . . . . . Setting up Clean URLs . . . . . . . . . . . . . . . . unblocking account through SQL . . . . . . . . . . . . . Weird behaviour - module-theme name collision . . . . . . . . . . Where is the taxonomy choice when adding content? . . . . . . . . . Miscellaneous . . . . . . . . . . . . . . . . . . How can I change Drupal’s character encoding? (UTF-8 and Unicode) . . . .

435 . 435 . 435 . 436 . 436 . 436 . 437 . 437 . 438 . 438 . 439 . 440 . 440 . 441 . 442 . 442 . 442 . 443 . 443 .

xv

3 Aug 2007

Drupal Handbook

Installation and configuration
Here is a guide for installing and configuring a Drupal site. This guide includes extensive How-to’s for using all core modules and installing themes. It also includes a guide for end users, the people who visit a Drupal site. Note: Feel free to add handbook pages relevant to this section.

1

Drupal Handbook

3 Aug 2007

System requirements
1. A Web Server that can execute PHP scripts 2. Recommended: Apache. Drupal will work on Apache 1.3 or Apache 2.x hosted on Unices or Windows. The majority of Drupal development is done using Apache so there is more community experience and testing performed. Optional: You can use the Apache extension mod_rewrite to allow for clean urls. Optional: IIS Drupal core will work using IIS5 or IIS6 if PHP is configured correctly. You will need to use a third party solution to achieve Clean URLs. In view of Microsoft’s support life cycle it is suggested you use IIS6. To achieve clean_url’s you will need to use a third party product. Drupal is being developed to be web server independent but we have limited or no reports of successful use on web servers not listed here. 3. PHP 4. Drupal 4.7 and above require PHP version 4.3.3 or higher. PHP 5.2 is a special case; only Drupal 4.7.5 (and greater) and 5.0 (and greater) run on PHP 5.2, older Drupal versions do not. We recommend using the latest version of PHP 4.x. or 5.x for security and future compatibility. PHP memory of approximately 8MB for a Drupal core installation. In reality you will probably need to use a higher setting depending on your site and contributed modules you are using. A good starting point is 16-24 MB. PHP XML extension (for blogapi, drupal, and ping modules). This extension is enabled by default in a standard PHP installation; the windows version of PHP has built-in support for this extension. PHP needs the following configuration directives for Drupal to work (only directives that differ from the default php.ini-dist / php.ini-recommended): session.save_handler: user error_reporting set to E_ALL & ~E_NOTICE. Work is ongoing to change this to E_ALL for Drupal 6. In addition, we recommend the following settings: session.cache_limiter: none Some of these settings are contained in the default .htaccess file that ships with Drupal, so you shouldn’t need to set them explicitly. Note, however, that setting PHP configuration options from .htaccess only works: with Apache (or a compatible web server),

2

3 Aug 2007

Drupal Handbook

if the .htaccess file is actually read, i.e. AllowOverride is not None, if PHP is installed as an Apache module. See the PHP manual for how to change configuration settings for other interfaces to PHP. 5. A PHP-supported Database Server 6. Recommended: MySQL 4.1 or MySQL 5.0. Drupal will work on v3.23.17 and 4.0 but it is strongly suggested you use 4.1 or 5.0 for future compatibility with Drupal 6 which will drop support for older versions of MySQL. NOTE: Drupal makes use of some features not available on some inexpensive hosting plans so please check that your host allows database accounts with the following rights: SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES Note: If your system/host is running MySQL 4.1 or newer and you receive the error "Client does not support authentication protocol requested by server", address the problem by following the instructions provided by MySQL AB. There is a minor OS issue with some MySQL 5+ installations primarily on Windows but affecting some Unices as well. PostgreSQL, version 7.3 or newer. Note, some of the contributed modules are not as abstracted from MySQL specific code as everyone would like. If you are familiar with PostgreSQL please file issues with those contributed modules as you find them. Currently MS SQL and Oracle are not supported but various efforts are underway to supply schemas. Please see discussions in the Enterprise Group if you are interested in working on this.

Client System Requirements
Drupal aims to conform with internet standards and deviate where necessary to comply with popular clients that are not standards compliant.

Javascript
For the Javascript, we currently test for all required API features (DOM APIs) and based on that, enabled or disable all JS functionality. That way, we don’t care about particular browsers, only what they support.

3

Drupal Handbook

3 Aug 2007

CSS
For CSS, the situation is quite similar to Javascript. The only difference is that here there is a strong difference between the standard compliant browsers and Internet Explorer. We can use CSS2 where needed and provide IE6 workarounds if necessary.

RSS
Drupal RSS feeds should work with any RSS feed reader. (note: could use more information).

Browser Specifics
In practice, this means that IE6, FF1.0/1.5, Opera 8-9 and Safari 1.x/2.0 get the whole experience. Konqueror should work if it’s the latest version.

Browser Popularity
The general net usage is 85% IE, 10% Ffox, 3% Safari, 2% Opera or so. For Drupal.org, it is 50% Ffox/Moz, 30% IE, 20% other.

Known Problems
IE5 and IE5.5 will experience some layout issues. IE5.0 will not do any Javascript. We can assume that for Firefox and Opera, the users have a high chance of running the latest version. IE4 and NS4, we no longer care about because they are no longer maintained and they are not in widespread use.

Validation
Drupal HTML and RSS should validate using the W3C Markup Validation Service.

Caveats
These guidelines are the guide for Drupal core, modules, and themes but are not always completely accurate. In practice, Drupal Core is expected to follow these standards more closely than various contributed pieces of code. If you find a problem with client compatability that deviates from the above client support guidelines, please try to find the root of the problem and submit an issue ideally including a patch to fix the problem.

4

3 Aug 2007

Drupal Handbook

HOWTO: Server requirement recommendations for your consulting clients
When thinking about the server hardware for a Drupal site, there are two important questions to ask: 1. Which modules are you going to use? Certain modules require more server power than others, but generally speaking more modules means more server requirements. 2. How many users will you have and what will they be doing? More users means more of a demand on the server, but especially if these users login and make comments or nodes you will need a more powerful server. You need to consider these two answers together. For example, you could have a highly complex site with very few users and be able to use a shared hosting environment. You could also use very few modules, only have one editor, use the cache, and have reasonable traffic on a shared environment. If your project is a more interactive environment with more users logging in and posting to the site you will need to consider more powerful hardware. As you move out of a shared environment there are other options available to you like using the methods described in the handbook to Tune Your Server for optimal Drupal performance. Tuning the server may allow you to continue using the same hardware and not upgrade, but it comes at the cost of time which can be more expensive than simply buying new hardware. When deciding which parts of your server to upgrade, remember that "Apache is bandwidth limited, PHP is CPU limited, and MySQL is memory limited and disk I/O bound".

Message to the Client
It’s probably best to give the message to the client of a "recommended" installation and a level below that in case their budget is limited and a level above that to provide for future growth with purchasing new hardware and services. If you are rolling out a new service (as opposed to installing Drupal in place of an existing solution) keep an eye towards a solid upgrade path. You can purchase a single server with the intent of upgrading as your site grows. For example, start with the web server and database on one server that is optimized for web serving. As the site grows in popularity and you need to handle more users you can then move the database to it’s own server separate from the web server. If your site grows beyond a two server "web server" and "database server" configuration then you can consider using a single web server and multiple database servers in a cluster.

5

Drupal Handbook

3 Aug 2007

Benchmark
One benchmark of a server is MBR.org which required serious intervention for optimisation at roughly the 2m pages per month mark, on a server running Apache1.3 and MySQL 4.1 with 1GB of memory. MySQL indexing, database memory use tweaks and abandoning MyISAM for InnoDB brought it under control - the jury’s out on using persistent connections. There is a need for more case studies like this to be documented on this handbook page

What Drupal.org runs on
As of April 2007 (and for a long time before that) Drupal.org has been running on a group of 3 servers. For details on those servers see Dries post about the "future" drupal.org hardware as it was being delivered.

Requirements - older versions
1. A Web Server that can execute PHP scripts 2. Recommended: Apache. Development is done with version 1.3.x. Successfully tested with version 2.0.x. Optional: IIS. Drupal is being developed with IIS compatibility in mind, and IIS5 and IIS6 work with a correctly configured PHP setup. 3. PHP 4. As of Drupal 4.6, the CMS requires PHP version 4.3.3+ (PHP 5 is supported for the 4.6 release). Drupal 4.2 to 4.5.2 inclusive require PHP version 4.1+. Older versions of Drupal will run on PHP 4.0.6+. We recommend using the latest version of PHP 4.x. PHP XML extension (for blogapi, drupal, and ping modules). This extension is enabled by default in a standard PHP installation; the windows version of PHP has built-in support for this extension. PHP memory of 8MB for a Drupal core install. If you install additional contributed modules you may need to raise your php allowed memory. Prepackaged Drupal distributions such as CivicSpace may have higher PHP memory requirements then a Drupal core install. PHP needs the following configuration directives for drupal to work: session.save_handler: user In addition, we recommend the following settings: session.cache_limiter: none (We only mention directives that differ from the default php.ini-dist / php.ini-recommended starting with PHP 4.0.6) These settings are contained in the default .htaccess file that ships with Drupal, so you shouldn’t need to set them explicitly. Note, however, that setting PHP configuration options from .htaccess only works:

6

3 Aug 2007

Drupal Handbook

with Apache (or a compatible web server), if the .htaccess file is actually read, i.e. AllowOverride is not None, if PHP is installed as an Apache module. See here for how to change configuration settings for other interfaces to PHP. Using a PEAR-supported Database (see below) requires (of course) PEAR to be installed. A PHP-supported Database Server Recommended: MySQL, v3.23.17 or newer (for our use of INNER JOIN’s with join_condition’s). MySQL 4 is fine. Drupal makes use of features not available on some inexpensive hosting plans, like LOCK TABLE Working well since 4.7: PostgreSQL, version 7.3 or newer (7.2 will probably work too, but you’ll get some errors when updating from 4.6). Experiences with other databases are greatly welcome. Note: If your system/host is running MySQL 4.1 or newer, a link in the troubleshooting section (http://drupal.org/node/35226) points to this page, which has some helpful info on addressing this problem with PHP 4.x and PHP5. There is a minor OS issue with some MySQL 5+ installations primarily on Windows but affecting some *nix installs as well. Also, xTemplate (the default theme engine for Drupal 4.6.x and previous) is reported to have issues with PHP 5.0.5 and 5.1. Converting your themes to the phpTemplate engine (default in 4.7) will work around this issue.

7

Drupal Handbook

3 Aug 2007

Installing Drupal, modules and themes
Installing Drupal, new modules and themes uses roughly the same process so once you are familiar with it you can repeat as needed. After you successfully install Drupal, you will want to perform some basic site configuration starting with the settings menu. Installing and configuring your site is only part of your responsibilities. You must remember to backup, test and maintain it as well. Please stop by the Best Practices section for some important tips on this and sign up for the security newsletter

Installing Drupal
This page is autogenerated from the current development text in CVS. See the various other provided instructions linked in the menu on the left for additional environments. // $Id: INSTALL.txt,v 1.39 2007/01/08 11:59:16 dries Exp $ CONTENTS OF THIS FILE --------------------* Changes * Requirements * Optional requirements * Installation * Drupal administration * Customizing your theme(s) * Multisite Configuration * More Information CHANGES ------As of Drupal 5.0 installation has been automated by an install script. It is no longer necessary to manually edit the "settings.php" file, and database tables are created automatically. REQUIREMENTS -----------Drupal requires a web server, PHP4 (4.3.3 or greater) or PHP5 (http://www.php.net/) and either MySQL (http://www.mysql.com/) or PostgreSQL (http://www.postgresql.org/). The Apache web server and MySQL database are recommended; other web server and database combinations such as IIS and PostgreSQL have been tested to a lesser extent. When using MySQL, version 4.1 or greater is recommended to assure you can safely transfer the database.

8

3 Aug 2007

Drupal Handbook

For more detailed information about Drupal requirements, see "Requirements" (http://drupal.org/requirements) in the Drupal Handbook. Guidelines for setting up a server environment with a variety of operating systems and in special cases are available in the Drupal handbook (http://drupal.org/node/260) OPTIONAL REQUIREMENTS --------------------- To use XML-based services such as the Blogger API, Jabber, and RSS syndication, you will need PHP’s XML extension. This extension is enabled by default. - If you want support for clean URLs, you’ll need mod_rewrite and the ability to use local .htaccess files. INSTALLATION -----------1. DOWNLOAD DRUPAL You can obtain the latest Drupal release from http://drupal.org/. The files are in .tar.gz format and can be extracted using most compression tools. On a typical Unix command line, use: wget http://drupal.org/files/projects/drupal-x.x.tar.gz tar -zxvf drupal-x.x.tar.gz This will create a new directory drupal-x.x/ containing all Drupal files and directories. Move the contents of that directory into a directory within your web server’s document root or your public HTML directory: mv drupal-x.x/* drupal-x.x/.htaccess /var/www/html 2. CREATE THE DRUPAL DATABASE Drupal requires access to a database in order to be installed. Your database user will need sufficient privileges to run Drupal. Additional information about privileges, and instructions to create a database using the command line are available in INSTALL.mysql.txt (for MySQL) or INSTALL.pgsql.txt (for PostgreSQL). To create a database using PHPMyAdmin or a web-based control panel consult the documentation or ask your webhost service provider. Take note of the username, password, database name and hostname as you

9

Drupal Handbook

3 Aug 2007

create the database. You will enter these items in the install script. 3. RUN THE INSTALL SCRIPT The install script will set the base URL, connect Drupal to the database, and create tables in the database. To run the install script point your browser to the base url of your website (i.e. http://www.example.com). You will be presented with the "Database Configuration" page. The install script will attempt to write-protect the settings.php after updating it with the information you provide in the installation routine. If you make manual changes to that file later, be sure to protect it again after making your modifications. Failure to remove write permissions to that file is a security risk. The default location for the settings.php file is at sites/default/settings.php, but it may be in another location if you use the multi-site setup, as explained below. 4. CONFIGURE DRUPAL When the install script succeeds, you will be directed to the "Welcome" page. In "step one" click "create the first account" which will become the main administrator account with total control. Login as the administrator and complete the initial configuration steps on the "Welcome" page. Consider creating a "files" subdirectory in your Drupal installation directory. This subdirectory stores files such as custom logos, user avatars, and other media associated with your new site. The sub-directory requires "read and write" permission by the Drupal server process. You can change the name of this subdirectory at "administer > site configuration > file system". 5. CRON TASKS Many Drupal modules (such as the search functionality) have periodic tasks that must be triggered by a cron job. To activate these tasks, call the cron

10

3 Aug 2007

Drupal Handbook

page by visiting http://www.example.com/cron.php --this will pass control to the modules and the modules will decide if and what they must do. Most systems support the crontab utility for scheduling tasks like this. The following example crontab line will activate the cron tasks automatically on the hour: 0 * * * * wget -O - -q http://www.example.com/cron.php More information about the cron scripts are available in the admin help pages and in the Drupal handbook at drupal.org. Example scripts can be found in the scripts/ directory. DRUPAL ADMINISTRATION --------------------A new installation of Drupal defaults to a very basic configuration with only a few active modules and minimal user access rights. Use your administration panel to enable and configure services. For example: General Settings administer > site configuration > site information Enable Modules administer > site configuration > modules Set User Permissions administer > users management > access control Configure Themes administer > site building > themes For more information on configuration options, read the instructions which accompany the different configuration settings and consult the various help pages available in the administration panel. Community-contributed modules and themes are available at http://drupal.org/. CUSTOMIZING YOUR THEME(S) ------------------------Now that your installation is running, you will want to customize the look of your site. Several sample themes are included and more can be downloaded from drupal.org. Simple customization of your theme can be done using only CSS. Further changes require understanding the phptemplate engine that is now part of Drupal. See http://drupal.org/handbook/customization to find out more. MULTISITE CONFIGURATION -----------------------

11

Drupal Handbook

3 Aug 2007

A single Drupal installation can host several Drupal-powered sites, each with its own individual configuration. Additional site configurations are created in subdirectories within the ’sites’ directory. Each subdirectory must have a ’settings.php’ file which specifies the configuration settings. The easiest way to create additional sites is to copy the ’default’ directory and modify the ’settings.php’ file as appropriate. The new directory name is constructed from the site’s URL. The configuration for www.example.com could be in ’sites/example.com/settings.php’ (note that ’www.’ should be omitted if users can access your site at http://example.com/). Sites do not have to have a different domain. You can also use subdomains and subdirectories for Drupal sites. For example, example.com, sub.example.com, and sub.example.com/site3 can all be defined as independent Drupal sites. The setup for a configuration such as this would look like the following: sites/default/settings.php sites/example.com/settings.php sites/sub.example.com/settings.php sites/sub.example.com.site3/settings.php When searching for a site configuration (for example www.sub.example.com/site3), Drupal will search for configuration files in the following order, using the first configuration it finds: sites/www.sub.example.com.site3/settings.php sites/sub.example.com.site3/settings.php sites/example.com.site3/settings.php sites/www.sub.example.com/settings.php sites/sub.example.com/settings.php sites/example.com/settings.php sites/default/settings.php If you are installing on a non-standard port, the port number is treated as the deepest subdomain. For example: http://www.example.com:8080/ could be loaded from sites/8080.www.example.com/. The port number will be removed according to the pattern above if no port-specific configuration is found, just like

12

3 Aug 2007

Drupal Handbook

a real subdomain. Each site configuration can have its own site-specific modules and themes in addition to those installed in the standard ’modules’and ’themes’ directories. To use site-specific modules or themes, simply create a ’modules’ or ’themes’ directory within the site configuration directory. For example, if sub.example.com has a custom theme and a custom module that should not be accessible to other sites, the setup would look like this: sites/sub.example.com/: settings.php themes/custom_theme modules/custom_module NOTE: for more information about multiple virtual hosts or the configuration settings, consult the Drupal handbook at drupal.org. MORE INFORMATION ---------------For platform specific configuration issues and other installation and administration assistance, please consult the Drupal handbook at http://drupal.org/handbook. You can view the wide range of other support options available at http://drupal.org/support.

Formatted Drupal 5.x Installation instructions for better readability
Installation
// $Id: INSTALL.txt,v 1.39 2007/01/08 11:59:16 dries Exp $ Table of Contents 1. 2. 3. 4. 5. 6. 7. 8. Changes Requirements Optional requirements Installation Drupal administration Customizing your theme(s) Multisite Configuration More Information

13

Drupal Handbook

3 Aug 2007

Changes
As of Drupal 5.0 installation has been automated by an install script. It is no longer necessary to manually edit the "settings.php" file, and database tables are created automatically.

Requirements
Drupal requires a web server, PHP4 (4.3.3 or greater) or PHP5 (http://www.php.net/) and either MySQL (http://www.mysql.com/) or PostgreSQL (http://www.postgresql.org/). The Apache web server and MySQL database are recommended; other web server and database combinations such as IIS and PostgreSQL have been tested to a lesser extent. When using MySQL, version 4.1 or greater is recommended to assure you can safely transfer the database. For more detailed information about Drupal requirements, (http://drupal.org/requirements) in the Drupal Handbook. see "Requirements"

Guidelines for setting up a server environment with a variety of operating systems and in special cases are available in the Drupal handbook (http://drupal.org/node/260)

Optional Requirements
- To use XML-based services such as the Blogger API, Jabber, and RSS syndication, you will need PHP’s XML extension. This extension is enabled by default. - If you want support for clean URLs, you’ll need mod_rewrite and the ability to use local .htaccess files.

Installation
1. Download Drupal You can obtain the latest Drupal release from http://drupal.org/. The files are in .tar.gz format and can be extracted using most compression tools. On a typical Unix command line, use: wget http://drupal.org/files/projects/drupal-x.x.tar.gz tar -zxvf drupal-x.x.tar.gz This will create a new directory drupal-x.x/ containing all Drupal files and directories. Move the contents of that directory into a directory within your web server’s document root or your public HTML directory: mv drupal-x.x/* drupal-x.x/.htaccess /var/www/html 2. Create the Drupal database Drupal requires access to a database in order to be installed. Your database user will need sufficient privileges to run Drupal. Additional information about privileges, and instructions to create a database using the command line are available in INSTALL.mysql.txt (for MySQL) or

14

3 Aug 2007

Drupal Handbook

INSTALL.pgsql.txt (for PostgreSQL). To create a database using PHPMyAdmin or a web-based control panel consult the documentation or ask your webhost service provider. Take note of the username, password, database name and hostname as you create the database. You will enter these items in the install script. 3. Run the install script The install script will set the base URL, connect Drupal to the database, and create tables in the database. To run the install script point your browser to the base url of your website (i.e. http://www.example.com). You will be presented with the "Database Configuration" page. The install script will attempt to write-protect the settings.php after updating it with the information you provide in the installation routine. If you make manual changes to that file later, be sure to protect it again after making your modifications. Failure to remove write permissions to that file is a security risk. The default location for the settings.php file is at sites/default/settings.php, but it may be in another location if you use the multi-site setup, as explained below. 4. Configure Drupal When the install script succeeds, you will be directed to the "Welcome" page. In "step one" click "create the first account" which will become the main administrator account with total control. Login as the administrator and complete the initial configuration steps on the "Welcome" page. Consider creating a "files" subdirectory in your Drupal installation directory. This subdirectory stores files such as custom logos, user avatars, and other media associated with your new site. The sub-directory requires "read and write" permission by the Drupal server process. You can change the name of this subdirectory at "administer > site configuration > file system". 5. Cron Tasks Many Drupal modules (such as the search functionality) have periodic tasks that must be triggered by a cron job. To activate these tasks, call the cron page by visiting http://www.example.com/cron.php --this will pass control to the modules and the modules will decide if and what they must do. Most systems support the crontab utility for scheduling tasks like this. The following example crontab line will activate the cron tasks automatically on the hour: 0 * * * * wget -O - -q http://www.example.com/cron.php

More information about the cron scripts are available in the admin help pages and in the Drupal handbook at drupal.org. Example scripts can be found in the scripts/ directory.

15

Drupal Handbook

3 Aug 2007

Drupal Administration
A new installation of Drupal defaults to a very basic configuration with only aw active modules and minimal user access rights. Use your administration panel to enable and configure services. For example: General Settings administer > site configuration > site information Enable Modules administer > site configuration > modules Set User Permissions administer > users management > access control Configure Themes administer > site building > themes For more information on configuration options, read the instructions which accompany the different configuration settings and consult the various help pages available in the administration panel. Community-contributed modules and themes are available at http://drupal.org/.

Customizing your theme(s)
Now that your installation is running, you will want to customize the look of your site. Several sample themes are included and more can be downloaded from drupal.org. Simple customization of your theme can be done using only CSS. Further changes require understanding the phptemplate engine that is now part of Drupal. See http://drupal.org/handbook/customization to find out more.

Multi-site configuration
A single Drupal installation can host several Drupal-powered sites, each with its own individual configuration. Additional site configurations are created in subdirectories within the ’sites’ directory. Each subdirectory must have a ’settings.php’ file which specifies the configuration settings. The easiest way to create additional sites is to copy the ’default’ directory and modify the ’settings.php’ file as appropriate. The new directory name is constructed from the site’s URL. The configuration for www.example.com could be in ’sites/example.com/settings.php’ (note that ’www.’ should be omitted if users can access your site at http://example.com/). Sites do not have to have a different domain. You can also use subdomains and subdirectories for Drupal sites. For example, example.com, sub.example.com, and sub.example.com/site3 can all be defined as independent Drupal sites. The setup for a configuration such as this would look like the following: sites/default/settings.php sites/example.com/settings.php sites/sub.example.com/settings.php sites/sub.example.com.site3/settings.php

16

3 Aug 2007

Drupal Handbook

When searching for a site configuration (for example www.sub.example.com/site3), Drupal will search for configuration files in the following order, using the first configuration it finds: sites/www.sub.example.com.site3/settings.php sites/sub.example.com.site3/settings.php sites/example.com.site3/settings.php sites/www.sub.example.com/settings.php sites/sub.example.com/settings.php sites/example.com/settings.php sites/default/settings.php If you are installing on a non-standard port, the port number is treated as the deepest subdomain. For example: http://www.example.com:8080/ could be loaded from sites/8080.www.example.com/. The port number will be removed according to the pattern above if no port-specific configuration is found, just like a real subdomain. Each site configuration can have its own site-specific modules and themes in addition to those installed in the standard ’modules’and ’themes’ directories. To use site-specific modules or themes, simply create a ’modules’ or ’themes’ directory within the site configuration directory. For example, if sub.example.com has a custom theme and a custom module that should not be accessible to other sites, the setup would look like this: sites/sub.example.com/: settings.php themes/custom_theme modules/custom_module NOTE: for more information about multiple virtual hosts or the configuration settings, consult the Drupal handbook at drupal.org.

More Information
For platform specific configuration issues and other installation and administration assistance, please consult the Drupal handbook at http://drupal.org/handbook. You can view the wide range of other support options available at http://drupal.org/support.

Formatted Drupal 4.7.x Installation instructions for better readability
Installation
// $Id: INSTALL.txt,v 1.6 2004/11/27 11:28:55 dries Exp $ This document outlines the standard installation process.

17

Drupal Handbook

3 Aug 2007

1. 2. 3. 4. 5. 6. 7. 8.

REQUIREMENTS SERVER CONFIGURATION OPTIONAL COMPONENTS INSTALLATION DRUPAL ADMINISTRATION CUSTOMIZING YOUR THEME(S) UPGRADING MORE INFORMATION

REQUIREMENTS
1. Drupal requires a web server, PHP4 (http://www.php.net/) and either MySQL, PostgreSQL or a database server supported by the PHP PEAR API (http://pear.php.net/). 2. To Install you will need an FTP program to upload files to the server, or shell access if you wish to install using the commands listed below; access to run database scripts directly or a tool such as PHPMyAdmin to manage a database; knowledge of how to use either FTP programs or shell access to set permissions on directories, and how to run database scripts. 3. NOTE: The Apache web server and MySQL database are strongly recommended; other web server and database combinations such as IIS and PostgreSQL are possible but tested to a lesser extent.

SERVER CONFIGURATION
Your PHP must have the following settings: session.save_handler user

In addition, we recommend the following settings: session.cache_limiter none

These values are set in php.ini and can be overwritten in a .htaccess file; you can print out your local PHP settings with PHP’s phpinfo() function.

OPTIONAL COMPONENTS
To use XML-based services such as the Blogger API, Jabber, RSS syndication, you will need PHP’s XML extension. This extension is enabled by default in standard PHP4 installations. If you want support for clean URLs, you’ll need mod_rewrite and the ability to use local .htaccess files. (More information can be found in the Drupal handbook on drupal.org.)

18

3 Aug 2007

Drupal Handbook

INSTALLATION
1. DOWNLOAD DRUPAL
You can obtain the latest Drupal release from http://drupal.org/. Download the current tar.gz format and extract the files: $ wget http://drupal.org/files/project/drupal-x.x.x.tgz $ tar -zxvf drupal-x.x.x.tgz This will create a new directory drupal-x.x.x/ containing all Drupal files and directories. Move the contents of that directory into a directory within your web server’s document root or your public HTML directory: $ mv drupal-x.x.x/* drupal-x.x.x/.htaccess /var/www/html

2. CREATE THE DRUPAL DATABASE
These instructions are for MySQL. If you are using another database, check the database documentation. In the following examples, "dba_user" is an example MySQL user which has the CREATE and GRANT privileges. You will need to use the appropriate user name for your system. First, you must create a new database for your Drupal site: $ mysqladmin -u dba_user -p create drupal MySQL will prompt for the dba_user database password and then create the initial database files. Next you must login and set the access database rights: $ mysql -u dba_user -p Again, you will be asked for the dba_user database password. At the MySQL prompt, enter following command: GRANT ALL PRIVILEGES ON drupal.* TO nobody@localhost IDENTIFIED BY ’password’; where ’drupal’ is the name of your database ’nobody@localhost’ is the userid of your webserver MySQL account ’password’ is the password required to log in as the MySQL user

19

Drupal Handbook

3 Aug 2007

If successful, MySQL will reply with Query OK, 0 rows affected to activate the new permissions you must enter the command flush privileges; and then enter ’\q’ to exit MySQL.

3. LOAD THE DRUPAL DATABASE SCHEME
Once you have a database, you must load the required tables: $ mysql -u nobody -p drupal < database/database.mysql

4. CONNECTING DRUPAL
The default configuration can be found in the ’sites/default/settings.php’ file within your Drupal installation. Before you can run Drupal, you must set the database URL and the base URL to the web site. Open the configuration file and edit the $db_url line to match the database defined in the previous steps: $db_url = "mysql://username:password@localhost/drupal"; Set $base_url to match the address to your web site: $base_url = "http://www.example.com"; In addition, a single Drupal installation can host several Drupal-powered sites, each with its own individual configuration. If you don’t need to run multiple Drupal sites, you can skip to the next section. Additional site configurations are created in subdirectories within the ’sites’ directory. Each site subdirectory must have a ’settings.php’ file which specifies the configuration settings. The easiest way to create additional sites is to copy the ’default’ directory and modify the ’settings.php’ file as appropriate. The new directory name is constructed from the site’s URL. The configuration for www.example.com could be in ’sites/example.com/settings.php’ (note that ’www.’ should be omitted if users can access your site at http://example.com/). Sites do not each have to have a different domain. You can use subdomains and subdirectories for Drupal sites also. For example, example.com, sub.example.com, and sub.example.com/site3 can all be

20

3 Aug 2007

Drupal Handbook

defined as independent Drupal sites. The setup for a configuration such as this would look like the following: sites/default/settings.php sites/example.com/settings.php sites/sub.example.com/settings.php sites/sub.example.com.site3/settings.php When searching for a site configuration (for example www.sub.example.com/site3), Drupal will search for configuration files in the following order, using the first configuration file it finds: sites/www.sub.example.com.site3/settings.php sites/sub.example.com.site3/settings.php sites/example.com.site3/settings.php sites/www.sub.example.com/settings.php sites/sub.example.com/settings.php sites/example.com/settings.php sites/default/settings.php Each site configuration can have its own site-specific modules and themes that will be made available in addition to those installed in the standard ’modules’ and ’themes’ directories. To use site-specific modules or themes, simply create a ’modules’ or ’themes’ directory within the site configuration directory. For example, if sub.example.dom has a custom theme and a custom module that should not be accessible to other sites, the setup would look like this: sites/sub.example.com/: settings.php themes/: custom_theme modules/: custom_module NOTE: for more information about multiple virtual hosts or the configuration settings, consult the Drupal handbook at drupal.org.

5. CONFIGURE DRUPAL
You can now launch your browser and point it to your Drupal site. Create an account and login. The first account will automatically become the main administrator account.

21

Drupal Handbook

3 Aug 2007

6. CRON TASKS
Many Drupal modules have periodic tasks that must be triggered by a cron job. To activate these tasks, you must call the cron page; this will pass control to the modules and the modules will decide if and what they must do. The following example crontab line will activate the cron script on the hour: 0 * * * * wget -O - -q http://HOSTNAME/cron.php

More information about the cron scripts are available in the admin help pages and in the Drupal handbook at drupal.org. Example scripts can be found in the scripts/ directory.

DRUPAL ADMINISTRATION
Upon a new installation, your Drupal website defaults to a very basic configuration with only a few active modules, one theme, and no user access rights. Use your administration panel to enable and configure services. For example, set some general settings for your site with "Administration configuration". Enable modules via "Administration - configuration modules". User permissions can be set with "Administration - accounts - permissions". For more information on configuration options, read through the instructions which accompany the different configuration settings and consult the various help pages available in the administration panel. Note that additional community-contributed modules and themes are available at http://drupal.org/.

CUSTOMIZING YOUR THEME(S)
Now that your server is running, you will want to customize the look of your site. Several sample themes are included in the Drupal installation and more can be downloaded from drupal.org. Customizing each theme depends on the theme. In general, each theme contains a PHP file themename.theme which defines a function header() that can be changed to reference your own logos.

22

3 Aug 2007

Drupal Handbook

Most themes also contain stylesheets or PHP configuration files to tune the colors and layouts; check the themes/ directory for README files describing each alternate theme.

UPGRADING
1. Backup your database and Drupal directory - especially your configuration file (www.example.com.conf or includes/conf.php). 2. Log on as the user with user ID 1. 3. Remove all the old Drupal files then unpack the new Drupal files into the directory that you run Drupal from. 4. Modify the new configuration file to make sure it has the correct information. 5. Run update.php by visiting http://www.example.com/update.php.

MORE INFORMATION
For platform specific configuration issues and other installation and administration assistance, please consult the Drupal handbook at http://drupal.org/. You can also find support at the Drupal support forum or through the Drupal mailing lists.

10 minute install using PuTTY SSH/Telnet client
I’ve been developing best practices for my development company and wanted to share/collaborate on some of them. Development environment: Server: LAMP SSH/Telenet Client: PuTTY Server Interface: WHM Must have root access. 10 minute Install: [login root via PuTTY] # cd /home/youraccountname # wget http://ftp.osuosl.org/pub/drupal/files/projects/drupal-x.x.tar.gz [Note: the "x.x" should be replaced with the version of drupal you’re installing, e.g. "5.1"] # tar -zxvf drupal-5.1.tar.gz # mv drupal-x.x/* drupal-x.x/.htaccess /home/youraccountname/public_html [Note: See the note above regarding "x.x"]

23

Drupal Handbook

3 Aug 2007

# rm drupal-x.x.tar.gz # cd public_html # mkdir files # chmod 777 files # cd sites/all # mkdir modules # mkdir themes # cd modules # mkdir custom # mkdir drupal-contrib # cd ../ # cd themes # mkdir custom # mkdir drupal-contrib # cd ../ # cd ../ # cd default # chmod 777 settings.php # mysql mysql> CREATE DATABASE youraccountname_drupal; mysql> GRANT ALL PRIVILEGES ON youraccountname_drupal.* TO ’your accountname_yourusername’@’localhost’ IDENTIFIED BY ’yourpassword’; mysql> \q [open your browser. enter your site’s URL, and enter database information] [go back to PuTTY to chmod on "settings.php"] # chmod 755 settings.php # logout [back to browser, refresh browser, and then "visit new site" (or whatever the link says to new website), create first "superuser" account, etc.]

How I installed Drupal: The Eightfold Way
Try this for a supereasy install. This installation is for a test site. The aim is to have a test site: \http://drupal.yoursite.com\ When the test site is functioning, the drupal subdomain prefix will be deleted. Therefore the domain name in the root will be mysite.com The DNS servers will automatically point to this (hopefully!). This is what worked for me: 1) Downloaded Drupal 5.0 2) Created a subdomain ("drupal") via my webhost’s control panel 3) Created a database ("dbname") via my webhost’s control panel (note the user name and

24

3 Aug 2007

Drupal Handbook

password). Noted the hostname, e.g., testsite.yoursite.com 4) Using browser, pointed to URL \http://drupal.yoursite.com\ 5) The install.php script automatically installed Drupal 6) Entered information. Database name ("dbname"), username, password 7) Clicked "Advanced options" 8) Entered hostname (e.g., testsite.yoursite.com). Went to testsite.yoursite.com in browser.

Installing virtual hosts for Drupal sites and subsites
The purpose of this guide is to concisely summarize how to implement apache vhost settings for each site or subsite. All steps for this tutorial were implemented with Debian using Apache version 2.0.54. 1. Gain entrance into your shell system, and su to root or another user that can edit apache2 configuration files. 2. Go to your apache configuration files: cd /etc/apache2/sites-available 3. Create a configuration file for your new site. For an example site, www.example.com, we make the site as such: nano example.com <VirtualHost *:80> ServerAdmin me@myserver DocumentRoot /home/web/drupal/ ServerName www.example.com ServerAlias example.com *.example.com RewriteEngine On RewriteOptions inherit CustomLog /var/log/apache2/example.com.log combined </VirtualHost> <VirtualHost *:443> ServerAdmin me@myserver DocumentRoot /home/web/drupal/ ServerName www.example.com ServerAlias example.com *.example.com RewriteEngine On RewriteOptions inherit CustomLog /var/log/apache2/example.com.log combined # SSL Specific options SSLEngine on SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL SSLCertificateFile /etc/ssl/apache/CA.crt SSLCertificateKeyFile /etc/ssl/apache/CA.key SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown </VirtualHost>

25

Drupal Handbook

3 Aug 2007

Activate the site’s configuration: a2ensite www.example.com Reload Apache’s configuration: /etc/init.d/apache2 force-reload Done! Please post any changes or concerns, Tarek : )

Mac OS X-specific guidelines
Install and configure Mysql and PHP, if necessary. Server Logistics provides nice pre-compiled packages and instructions. PHP is also available from Marc Liyanage. PHP may already be installed on your system, so check first. The stock version of Apache should be fine (typically 1.33). Turn on "personal web sharing" in the sharing panel of System Preferences to start Apache. Now comes the more involved part- changing the webserver configuration. To make changes to the Apache configuration you should NOT edit /etc/httpd/httpd.conf but instead edit files in /private/etc/httpd/users/. Any file in the directory /private/etc/httpd/users/ ending with â.confâ will effectively be appended to /etc/httpd/httpd.conf. So any changes you want to make should be made in one or more configuration files of your own construction. System updates will leave these files untouched. You can create a file /private/etc/httpd/users/drupal.conf for all your Drupal-specific changes (even if you have no user named Drupal) and they will be loaded when Apache starts up. Note: for Mac OS X Server 10.4 (Tiger Server) and most likely previous versions as well, do not make changes to /etc/httpd/httpd.conf expecting the AllowOverride All directive to work. The correct file to add the AllowOverride All directive is in the directory /etc/httpd/sites/. In that directory are the virtual host configuration files. Each virtual server has a configuration file in that directory so it is in those files that you must enable AllowOverride All. If you only have one web server on your server configured, then the file you want to modify is /etc/httpd/sites/0000_any_80_.conf. To enable clean URLs you will need the following code in your conf file. You’ll need to be root (or sudo) to do this. Don’t forget to restart apache after modifying httpd.conf (turn personal web sharing off, then back on again, or use /usr/sbin/apachectl restart). # # This controls which options the .htaccess files in directories can # override. Can also be "All", or any combination of "Options", "FileInfo", # "AuthConfig", and "Limit" #

26

3 Aug 2007

Drupal Handbook

#

AllowOverride None AllowOverride All

You may also need to edit this file to enable the PHP module for Apache. You have to uncomment two lines. First in this section: # # Dynamic Shared Object (DSO) Support # Uncomment this line (around line 235) by removing the #: #LoadModule php4_module Then go below to this section: # Reconstruction of the complete module list from all available modules # (static and shared ones) to achieve correct module execution order. and uncomment this line (around line 278) by removing the #: #AddModule mod_php4.c Drupal goes into /Library/WebServer/Documents/, or ~/Sites. If you use ~/Sites, you may also have to edit the .conf file in /etc/httpd/users that corresponds to your user account. You must AllowOverride in this file for your ~/Sites for clean URLs to work there. After any edits to your .conf files, be sure to restart Apache (as described above). MacZeaolots has a good tutorial on installing Drupal on Mac OS X 10.4. The same tutorial applies to 10.3 as well. While the tutorial talks about Drupal 4.6, the setup of the server environment is the same for any version of Drupal. libexec/httpd/libphp4.so

Important notes for MySQL install:
The version of PHP that Apple included with Mac OS X 10.4.4 has mysql.default_socket set to "/var/mysql/mysql.sock", while the binary version of MySQL from mysql.com uses "/tmp/mysql.sock". This will cause PHP to fail to connect to mysql with a message in Drupal like can’t connect to local MySQL server through socket ’/var/lib/mysql/mysql.sock’ (2) Make PHP look for "/tmp/mysql.sock" by setting this in /etc/php.ini: ; Default socket name for local MySQL connects. built-in ; MySQL defaults. mysql.default_socket = /tmp/mysql.sock If empty, uses the

27

Drupal Handbook

3 Aug 2007

You can instead set this in /etc/my.cnf. #Name of the socket file to use. socket=/var/mysql/mysql.sock Both work, but the second one may make the MySQL preference pane stop working. You may also need to restart apache to have this take effect. Restart from the terminal: $ sudo apachectl restart or restart by disabling and re-enabling personal web sharing.

HOWTO: Create a local server environment for drupal using MAMP
MAMP creates a local server environment on Mac OS X by installing PHP, MySQL, and Apache all at once. This will hopefully make Drupal much easier to install because the components don’t have to be installed separately. This page is to be used in conjunction with the installation instructions for Drupal on Mac OS X. 1. Download MAMP (This will install Apache, MySQL, and PHP in one step.) Find the latest version here: http://www.mamp.info/ Download and drag to Applications folder to install. Open MAMP and click "start servers," then "Open start page." 2. Download Drupal Find the latest Drupal release here: http://drupal.org/. Move the directory containing the Drupal files into the MAMP htdocs directory: mv drupal-x.x.x/* drupal-x.x.x/.htaccess /Applications/MAMP/htdocs/ 3. Create the Drupal database Go to the MAMP start page and click "phpMyAdmin." Create a new database and follow the instructions in INSTALL.mysql.txt to upload the required files from your Drupal installation. 4. Connect Drupal Set the database URL in the ’sites/default/settings.php’ file in your Drupal installation using the information provided on the MAMP start page and the name you used for the database you created in step 3. $db_url = "mysql://username:password@localhost/databasename";

28

3 Aug 2007

Drupal Handbook

5. Start configuring Drupal! Go to http://localhost:8888/drupal-x.x.x/ and create the first account. Continue with instructions in INSTALL.txt.

HOWTO: Installing PostgreSQL and MySQL on the same Mac OS X machine
If you’re interested in helping to ensure that Drupal and its contributed modules are compatible with both MySQL and PostgreSQL (also known as "pgsql"), you should consider setting up local test sites using both database back ends on the same machine. You can even configure both sites to point to the same Drupal installation, using symbolic links. Unfortunately, the version of PHP that ships with Mac OS by default is not compatible with PostgreSQL, so to do this, you will need to compile both pgsql and php from source. While you’re at it, you might want to upgrade to a newer version of MySQL, as well. 1. Make a directory where you can build all of these programs. For example: mkdir /usr/local/src cd /usr/local/src Download the latest copies of everything you need: PHP -- http://www.php.net/downloads.php MySQL -- http://www.mysql.com/downloads PostgreSQL -- http://www.postgresql.org/download Unpackage all of these inside /usr/local/src Configure and build MySQL. Good instructions can be found on this page: MySQL on Mac OS X. The important thing is that when you run configure you use a reasonable value for the --prefix flag. For example: ./configure --prefix=/usr/local/mysql Configure and build PostgreSQL. Once again, useful installation docs can be found here: PostgreSQL on Mac OS X, though the section about "Postgres and PHP" isn’t what you want to read. Again, be sure you use a reasonable value for the--prefix flag. For example: ./configure --prefix=/usr/local/pgsql Configure and build PHP. After some trial and error, getting PHP working properly with both MySQL and PostgreSQL required a carefully crafted configure line: ./configure --with-pgsql=/usr/local/pgsql --with-mysql=/usr/local/mysql --with-apxs --with-kerberos=/usr --with-zlib-dir=/usr --enable-cli --enable-trans-sid --with-xml --enable-exif --enable-ftp --enable-mbstring --enable-mbregex --enable-dbx --enable-sockets --with-iodbc=/usr --with-curl=/usr --with-config-file-path=/etc --sysconfdir=/private/etc --with-mysql-sock=/var/mysql/mysql.sock Some noteworthy things about this command: This matches the flags used for the default PHP installed on Mac OS X as closely as possible, while also enabling PostgreSQL support.

29

Drupal Handbook

3 Aug 2007

The path you use for --with-pgsql must match whatever you specified for --prefix when building PostgreSQL. The path you use for --with-mysql must match whatever you specified for --prefix when building MySQL. The path you use for --with-mysql-sock should match whatever you specified for --with-unix-socket-path when building MySQL. Additional information about building PHP on Mac OS X machines can be found on the developer.apple.com site: PHP on Mac OS X

Installing Drupal on Mac OS X 10.4 Tiger
Mac OS X 10.4 Tiger comes with PHP (though it’s disabled by default) and without MySQL. Here’s how to get Drupal up and running from a stock Tiger installation.

Installing and Configuring MySQL
Downloaded the latest MySQL installer from dev.mysql.com. I chose the Mac OS X Installer Package for 10.3. I double-clicked the file that I downloaded (mysql-standard-4.1.11-apple-darwin7.8.0-powerpc.dmg), then double-clicked the mysql-standard-4.1.11-apple-darwin7.8.0-powerpc.pkg icon to run the installer and install MySQL. Next, I installed the MySQLStartupItem.pkg because I want MySQL to start up when I start my Mac. Then, I copied the MySQL.prefPane into the PreferencePanes folder in my Library folder at the root level of my hard drive. Tiger asked me to authenticate when I did this. Upon opening my System Preferences, I can indeed see a pretty MySQL icon. I wanted to test to see if MySQL would really start up, so I restarted. Sure enough, MySQL was running. Next, it was time to set initial passwords for MySQL. To do that, I opened the Terminal (in the Utilities folder). Then I typed in the following: export PATH="$PATH:/usr/local/mysql/bin" This tells your computer that when it interprets commands, it should also look in the freshly created MySQL installation for MySQL commands. If you want it added permanently instead of just for this terminal session, you could edit the third line of /etc/profile to read PATH="/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/mysql/bin"

30

3 Aug 2007

Drupal Handbook

and then start a new Terminal window. Next, we want to make MySQL secure by setting a MySQL root password. Fortunately a handy utility is provided to make that easy. I typed in: mysql_secure_installation Interacting with the script looked like this (note that at the first prompt I just pressed enter since no root password has been set yet: Enter current password for root (enter for none): OK, successfully used password, moving on... Setting the root password ensures that nobody can log into the MySQL root user without the proper authorisation. Set root password? [Y/n] Y New password: zoinks Re-enter new password: zoinks Password updated successfully! Reloading privilege tables.. ... Success! By default, a MySQL installation has an anonymous user, allowing anyone to log into MySQL without having to have a user account created for them. This is intended only for testing, and to make the installation go a bit smoother. You should remove them before moving into a production environment. Remove anonymous users? [Y/n] Y ... Success! Normally, root should only be allowed to connect from ’localhost’. This ensures that someone cannot guess at the root password from the network. Disallow root login remotely? [Y/n] Y ... Success! By default, MySQL comes with a database named ’test’ that anyone can access. This is also intended only for testing, and should be removed before moving into a production environment. Remove test database and access to it? [Y/n] Y - Dropping test database... ... Success! - Removing privileges on test database... ... Success! Reloading the privilege tables will ensure that all changes made so far will take effect immediately. Reload privilege tables now? [Y/n] Y ... Success! Cleaning up... All done! If you’ve completed all of the above steps, your MySQL

31

Drupal Handbook

3 Aug 2007

installation should now be secure. Thanks for using MySQL! I verified that MySQL was running: $ mysqladmin -u root -p status Enter password: zoinks Uptime: 938 Threads: 1 Questions: 16 Slow queries: 0 Opens: 21 Flush tables: 1 Open tables: 0 Queries per second avg: 0.017 It was running fine. Now on to the task of setting up MySQL for Drupal.

Sending mail
Current versions of OS X use Postfix as the mail server but you have to enable it. For a detailed how-to, see: http://www.stepwise.com/Articles/Workbench/eart.index.html Or save yourself lots of frustration and time and spend $10 for Postfix Enabler and get running in a couple of minutes. http://cutedgesystems.com/software/PostfixEnabler/

Creating the Drupal Database and Database User
Now that MySQL is installed and we have a root password established for it, it’s time to create the database that Drupal will use: $ mysqladmin -u root -p create drupal Enter password: zoinks The database was created. Time to create the user. The user in this example will be called drupaldbuser and the password for that user will be fuffy. $ mysql -u root -p Enter password: zoinks Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 15 to server version: 4.1.11-standard Type ’help;’ or ’\h’ for help. Type ’\c’ to clear the buffer. mysql> GRANT ALL PRIVILEGES ON drupal.* TO drupaldbuser@localhost IDENTIFIED BY ’fuffy’; Query OK, 0 rows affected (0.04 sec) If you are using MySQL 4.1 or later, the following command is necessary because Tiger comes with PHP 4, and the MySQL libraries for PHP 4 use a different authentication protocol. mysql> SET PASSWORD FOR ’drupaldbuser’@’localhost’ = OLD_PASSWORD(’fuffy’); Query OK, 0 rows affected (0.00 sec)

32

3 Aug 2007

Drupal Handbook

Now we apply the new settings: mysql> flush privileges; Query OK, 0 rows affected (0.19 sec) mysql> \q Bye Now I paused to rejoice. MySQL was installed and ready for Drupal. Now it was time to install Drupal itself.

Installing using CVS repository
Development of the Drupal codebase is fairly quick, with a new release every six months or so. So I decided to use the CVS repository to download Drupal. That way I can use the "cvs update" command to keep my Drupal installation current with bug fixes and improvements. I have the cvs option available to me because I installed the developer tools that were included on the OS 10.4 DVD. If you don’t have them installed, or don’t want to install them, you could always download Drupal directly and place the resulting directory inside /Library/WebServer/Documents First, I navigated to where I want my Drupal installation. Just to be consistent with Mac OS 10.4, I used /Library/WebServer/Documents: cd /Library/WebServer/Documents And now I pulled down the latest version of the Drupal 4.6 release: cvs -z9 -d:pserver:anonymous:anonymous@cvs.drupal.org:/cvs/drupal checkout -r DRUPAL-4-6 drupal This created a directory called drupal that contains the latest code for version 4.6. If, next week, I hear that a bugfix has been issued for 4.6, all I have to do is cd /Library/WebServer/Documents cvs update By default, Apache on the Mac runs as user ’www’ with group ’www’, so you probably need to do the following in order to allow drupal to create directories and files: chown -R www drupal chgrp -R www drupal Now it was time to create all the database tables that Drupal needs: $ mysql -u drupaldbuser -p drupal < /Library/WebServer/Documents/drupal/database/database.mysql Enter password: fuffy

33

Drupal Handbook

3 Aug 2007

Now I had MySQL running, and had a Drupal database populated by Drupal’s fields. It was time to tell Drupal how to find that database. In the Finder, I went to /Library/WebServer/Documents/Drupal/sites and duplicated the folder called default, and renamed it localhost. Then inside the new localhost directory I edited the settings.php file, changing line 81 to read: $db_url = ’mysql://drupaldbuser:fuffy@localhost/drupal’; and changing line 90 to read: $base_url = ’http://localhost/drupal’; The reason I duplicated the "default" settings folder was to avoid conflicts when I update CVS in the future, since CVS would have seen the changed settings.php file and tried to merge it with the original one. By keeping my settings file separate, I avoid this. As long as I access my Drupal installation through the URL http://localhost/drupal it will use the settings in the localhost folder. PHP is not enabled by default on OS 10.4. So I enabled it by editing Apache’s configuration file. I used BBEdit, but you can use any text editor you want. For example, you could choose Go To Folder from the Finder’s Go menu and type in /etc/httpd, then double-click on httpd.conf and OS 10.4 will prompt you for an application to edit the file with. Here’s me opening the file for editing in BBEdit: sudo bbedit /etc/httpd/httpd.conf Then I removed the # from in front of line 240: #LoadModule php4_module and line 284: #AddModule mod_php4.c and line 406: AllowOverride All After changing the configuration file, I stopped, then started the Personal Web Sharing service in the Sharing pane of System Preferences. This forces Apache to reread the configuration file and apply the changes. So now PHP was enabled. Now, with my hands shaking from excitement, I entered http://localhost/drupal into my web browser. I was greeted with Drupal’s welcome page: libexec/httpd/libphp4.so

34

3 Aug 2007

Drupal Handbook

I clicked on the link entitled "create the first account", and saw:

Since this was the first account I created on Drupal, I knew it would have special privileges, so I named it admin and typed in my e-mail address. (Warning: naming your administrative account "admin" is bad security! Don’t do this!) Then I clicked on the "Create new account" button. Drupal responded with a randomly generated password and an opportunity to log in immediately:

35

Drupal Handbook

3 Aug 2007

I took the opportunity to log in immediately by clicking the "Log in" button. On the resulting screen I changed my password to something I could remember and clicked Submit. Now I’ve got Drupal running on Mac OS 10.4. Time to celebrate with a swig of flavinoid-laden grape juice.

Prefixed database.mysql for search and replace
Use a texteditor with search & replace functionality to replace ’prefix’ with your own eg. site1, site2. This is database.mysql from 4.6.5. Contributed by Shane Birley. -- MySQL dump 8.22 --- Host: localhost Database: drupal_devel -- Server version 3.23.52-nt --- Table structure for table ’access’ -CREATE TABLE prefix_access ( aid tinyint(10) NOT NULL auto_increment, mask varchar(255) NOT NULL default ’’, type varchar(255) NOT NULL default ’’, status tinyint(2) NOT NULL default ’0’, PRIMARY KEY (aid) ) TYPE=MyISAM; --- Table structure for table ’accesslog’ -CREATE TABLE prefix_accesslog ( aid int(10) NOT NULL auto_increment, title varchar(255) default NULL, path varchar(255) default NULL, url varchar(255) default NULL,

36

3 Aug 2007

Drupal Handbook

hostname varchar(128) default NULL, uid int(10) unsigned default ’0’, timestamp int(11) unsigned NOT NULL default ’0’, KEY accesslog_timestamp (timestamp), PRIMARY KEY (aid) ) TYPE=MyISAM; --- Table structure for table ’aggregator_category’ -CREATE TABLE prefix_aggregator_category ( cid int(10) NOT NULL auto_increment, title varchar(255) NOT NULL default ’’, description longtext NOT NULL, block tinyint(2) NOT NULL default ’0’, PRIMARY KEY (cid), UNIQUE KEY title (title) ) TYPE=MyISAM; --- Table structure for table ’aggregator_category_feed’ -CREATE TABLE prefix_aggregator_category_feed ( fid int(10) NOT NULL default ’0’, cid int(10) NOT NULL default ’0’, PRIMARY KEY (fid,cid) ) TYPE=MyISAM; --- Table structure for table ’aggregator_category_item’ -CREATE TABLE prefix_aggregator_category_item ( iid int(10) NOT NULL default ’0’, cid int(10) NOT NULL default ’0’, PRIMARY KEY (iid,cid) ) TYPE=MyISAM; --- Table structure for table ’aggregator_feed’ -CREATE TABLE prefix_aggregator_feed ( fid int(10) NOT NULL auto_increment, title varchar(255) NOT NULL default ’’, url varchar(255) NOT NULL default ’’, refresh int(10) NOT NULL default ’0’, checked int(10) NOT NULL default ’0’, link varchar(255) NOT NULL default ’’, description longtext NOT NULL, image longtext NOT NULL, etag varchar(255) NOT NULL default ’’, modified int(10) NOT NULL default ’0’,

37

Drupal Handbook

3 Aug 2007

block tinyint(2) NOT NULL default ’0’, PRIMARY KEY (fid), UNIQUE KEY link (url), UNIQUE KEY title (title) ) TYPE=MyISAM; --- Table structure for table ’aggregator_item’ -CREATE TABLE prefix_aggregator_item ( iid int(10) NOT NULL auto_increment, fid int(10) NOT NULL default ’0’, title varchar(255) NOT NULL default ’’, link varchar(255) NOT NULL default ’’, author varchar(255) NOT NULL default ’’, description longtext NOT NULL, timestamp int(11) default NULL, PRIMARY KEY (iid) ) TYPE=MyISAM; --- Table structure for table ’authmap’ -CREATE TABLE prefix_authmap ( aid int(10) unsigned NOT NULL auto_increment, uid int(10) NOT NULL default ’0’, authname varchar(128) NOT NULL default ’’, module varchar(128) NOT NULL default ’’, PRIMARY KEY (aid), UNIQUE KEY authname (authname) ) TYPE=MyISAM; --- Table structure for table ’blocks’ -CREATE TABLE prefix_blocks ( module varchar(64) DEFAULT ’’ NOT NULL, delta varchar(32) NOT NULL default ’0’, status tinyint(2) DEFAULT ’0’ NOT NULL, weight tinyint(1) DEFAULT ’0’ NOT NULL, region tinyint(1) DEFAULT ’0’ NOT NULL, custom tinyint(2) DEFAULT ’0’ NOT NULL, throttle tinyint(1) DEFAULT ’0’ NOT NULL, visibility tinyint(1) DEFAULT ’0’ NOT NULL, pages text NOT NULL, types text NOT NULL ) TYPE=MyISAM; --- Table structure for table ’book’ --

38

3 Aug 2007

Drupal Handbook

CREATE TABLE prefix_book ( nid int(10) unsigned NOT NULL default ’0’, parent int(10) NOT NULL default ’0’, weight tinyint(3) NOT NULL default ’0’, log longtext, PRIMARY KEY (nid), KEY parent (parent) ) TYPE=MyISAM; --- Table structure for table ’boxes’ -CREATE TABLE prefix_boxes ( bid tinyint(4) NOT NULL auto_increment, title varchar(64) NOT NULL default ’’, body longtext, info varchar(128) NOT NULL default ’’, format int(4) NOT NULL default ’0’, PRIMARY KEY (bid), UNIQUE KEY title (title), UNIQUE KEY info (info) ) TYPE=MyISAM; --- Table structure for table ’cache’ -CREATE TABLE prefix_cache ( cid varchar(255) NOT NULL default ’’, data longtext, expire int(11) NOT NULL default ’0’, created int(11) NOT NULL default ’0’, headers text, PRIMARY KEY (cid), INDEX expire (expire) ) TYPE=MyISAM; --- Table structure for table ’comments’ -CREATE TABLE prefix_comments ( cid int(10) NOT NULL auto_increment, pid int(10) NOT NULL default ’0’, nid int(10) NOT NULL default ’0’, uid int(10) NOT NULL default ’0’, subject varchar(64) NOT NULL default ’’, comment longtext NOT NULL, hostname varchar(128) NOT NULL default ’’, timestamp int(11) NOT NULL default ’0’, score mediumint(9) NOT NULL default ’0’, status tinyint(3) unsigned NOT NULL default ’0’,

39

Drupal Handbook

3 Aug 2007

format int(4) NOT NULL default ’0’, thread varchar(255) NOT NULL, users longtext, name varchar(60) default NULL, mail varchar(64) default NULL, homepage varchar(255) default NULL, PRIMARY KEY (cid), KEY lid (nid) ) TYPE=MyISAM; --- Table structre for table ’node_last_comment’ -CREATE TABLE prefix_node_comment_statistics ( nid int(10) unsigned NOT NULL auto_increment, last_comment_timestamp int(11) NOT NULL default ’0’, last_comment_name varchar(60) default NULL, last_comment_uid int(10) NOT NULL default ’0’, comment_count int(10) unsigned NOT NULL default ’0’, PRIMARY KEY (nid), KEY node_comment_timestamp (last_comment_timestamp) ) TYPE=MyISAM; --- Table structure for table ’directory’ -CREATE TABLE prefix_directory ( link varchar(255) NOT NULL default ’’, name varchar(128) NOT NULL default ’’, mail varchar(128) NOT NULL default ’’, slogan longtext NOT NULL, mission longtext NOT NULL, timestamp int(11) NOT NULL default ’0’, PRIMARY KEY (link) ) TYPE=MyISAM; --- Table structure for table ’files’ -CREATE TABLE prefix_files ( fid int(10) unsigned NOT NULL default ’0’, nid int(10) unsigned NOT NULL default ’0’, filename varchar(255) NOT NULL default ’’, filepath varchar(255) NOT NULL default ’’, filemime varchar(255) NOT NULL default ’’, filesize int(10) unsigned NOT NULL default ’0’, list tinyint(1) unsigned NOT NULL default ’0’, PRIMARY KEY (fid) ) TYPE=MyISAM; --

40

3 Aug 2007

Drupal Handbook

-- Table structure for table ’filter_formats’ -CREATE TABLE prefix_filter_formats ( format int(4) NOT NULL auto_increment, name varchar(255) NOT NULL default ’’, roles varchar(255) NOT NULL default ’’, cache tinyint(2) NOT NULL default ’0’, PRIMARY KEY (format) ) TYPE=MyISAM; --- Table structure for table ’filters’ -CREATE TABLE prefix_filters ( format int(4) NOT NULL default ’0’, module varchar(64) NOT NULL default ’’, delta tinyint(2) DEFAULT ’0’ NOT NULL, weight tinyint(2) DEFAULT ’0’ NOT NULL, INDEX (weight) ) TYPE=MyISAM; --- Table structure for table ’flood’ -CREATE TABLE prefix_flood ( event varchar(64) NOT NULL default ’’, hostname varchar(128) NOT NULL default ’’, timestamp int(11) NOT NULL default ’0’ ) TYPE=MyISAM; --- Table structure for table ’forum’ -CREATE TABLE prefix_forum ( nid int(10) unsigned NOT NULL default ’0’, tid int(10) unsigned NOT NULL default ’0’, PRIMARY KEY (nid), KEY tid (tid) ) TYPE=MyISAM; --- Table structure for table ’history’ -CREATE TABLE prefix_history ( uid int(10) NOT NULL default ’0’, nid int(10) NOT NULL default ’0’, timestamp int(11) NOT NULL default ’0’, PRIMARY KEY (uid,nid) ) TYPE=MyISAM; --- Table structure for table ’locales_meta’

41

Drupal Handbook

3 Aug 2007

-CREATE TABLE prefix_locales_meta ( locale varchar(12) NOT NULL default ’’, name varchar(64) NOT NULL default ’’, enabled int(2) NOT NULL default ’0’, isdefault int(2) NOT NULL default ’0’, plurals int(1) NOT NULL default ’0’, formula varchar(128) NOT NULL default ’’, PRIMARY KEY (locale) ) TYPE=MyISAM; --- Table structure for table ’locales_source’ -CREATE TABLE prefix_locales_source ( lid int(11) NOT NULL auto_increment, location varchar(255) NOT NULL default ’’, source blob NOT NULL, PRIMARY KEY (lid) ) TYPE=MyISAM; --- Table structure for table ’locales_target’ -CREATE TABLE prefix_locales_target ( lid int(11) NOT NULL default ’0’, translation blob NOT NULL, locale varchar(12) NOT NULL default ’’, plid int(11) NOT NULL default ’0’, plural int(1) NOT NULL default ’0’, KEY lid (lid), KEY lang (locale), KEY plid (plid), KEY plural (plural) ) TYPE=MyISAM; --- Table structure for table ’menu’ -CREATE TABLE prefix_menu ( mid int(10) unsigned NOT NULL default ’0’, pid int(10) unsigned NOT NULL default ’0’, path varchar(255) NOT NULL default ’’, title varchar(255) NOT NULL default ’’, description varchar(255) NOT NULL default ’’, weight tinyint(4) NOT NULL default ’0’, type int(2) unsigned NOT NULL default ’0’, PRIMARY KEY (mid) ) TYPE=MyISAM; --

42

3 Aug 2007

Drupal Handbook

-- Table structure for table ’moderation_filters’ -CREATE TABLE prefix_moderation_filters ( fid int(10) unsigned NOT NULL auto_increment, filter varchar(255) NOT NULL default ’’, minimum smallint(6) NOT NULL default ’0’, PRIMARY KEY (fid) ) TYPE=MyISAM; --- Table structure for table ’moderation_roles’ -CREATE TABLE prefix_moderation_roles ( rid int(10) unsigned NOT NULL default ’0’, mid int(10) unsigned NOT NULL default ’0’, value tinyint(4) NOT NULL default ’0’, KEY idx_rid (rid), KEY idx_mid (mid) ) TYPE=MyISAM; --- Table structure for table ’moderation_votes’ -CREATE TABLE prefix_moderation_votes ( mid int(10) unsigned NOT NULL auto_increment, vote varchar(255) default NULL, weight tinyint(4) NOT NULL default ’0’, PRIMARY KEY (mid) ) TYPE=MyISAM; --- Table structure for table ’node’ -CREATE TABLE prefix_node ( nid int(10) unsigned NOT NULL auto_increment, type varchar(16) NOT NULL default ’’, title varchar(128) NOT NULL default ’’, uid int(10) NOT NULL default ’0’, status int(4) NOT NULL default ’1’, created int(11) NOT NULL default ’0’, changed int(11) NOT NULL default ’0’, comment int(2) NOT NULL default ’0’, promote int(2) NOT NULL default ’0’, moderate int(2) NOT NULL default ’0’, teaser longtext NOT NULL, body longtext NOT NULL, revisions longtext NOT NULL, sticky int(2) NOT NULL default ’0’, format int(4) NOT NULL default ’0’, PRIMARY KEY (nid),

43

Drupal Handbook

3 Aug 2007

KEY node_type (type(4)), KEY node_title_type (title,type(4)), KEY status (status), KEY uid (uid), KEY node_moderate (moderate), KEY node_promote_status (promote, status), KEY node_created (created), KEY node_changed (changed), KEY node_status_type (status, type, nid) ) TYPE=MyISAM; --- Table structure for table ‘node_access‘ -CREATE TABLE prefix_node_access ( nid int(10) unsigned NOT NULL default ’0’, gid int(10) unsigned NOT NULL default ’0’, realm varchar(255) NOT NULL default ’’, grant_view tinyint(1) unsigned NOT NULL default ’0’, grant_update tinyint(1) unsigned NOT NULL default ’0’, grant_delete tinyint(1) unsigned NOT NULL default ’0’, PRIMARY KEY (nid,gid,realm) ) TYPE=MyISAM; --- Table structure for table ’profile_fields’ -CREATE TABLE prefix_profile_fields ( fid int(10) NOT NULL auto_increment, title varchar(255) default NULL, name varchar(128) default NULL, explanation TEXT default NULL, category varchar(255) default NULL, page varchar(255) default NULL, type varchar(128) default NULL, weight tinyint(1) DEFAULT ’0’ NOT NULL, required tinyint(1) DEFAULT ’0’ NOT NULL, register tinyint(1) DEFAULT ’0’ NOT NULL, visibility tinyint(1) DEFAULT ’0’ NOT NULL, options text, KEY category (category), UNIQUE KEY name (name), PRIMARY KEY (fid) ); --- Table structure for table ’profile_values’ -CREATE TABLE prefix_profile_values ( fid int(10) unsigned default ’0’,

44

3 Aug 2007

Drupal Handbook

uid int(10) unsigned default ’0’, value text, KEY uid (uid), KEY fid (fid) ); --- Table structure for table ’url_alias’ -CREATE TABLE prefix_url_alias ( pid int(10) unsigned NOT NULL auto_increment, src varchar(128) NOT NULL default ’’, dst varchar(128) NOT NULL default ’’, PRIMARY KEY (pid), UNIQUE KEY dst (dst) ) TYPE=MyISAM; --- Table structure for table ’permission’ -CREATE TABLE prefix_permission ( rid int(10) unsigned NOT NULL default ’0’, perm longtext, tid int(10) unsigned NOT NULL default ’0’, KEY rid (rid) ) TYPE=MyISAM; --- Table structure for table ’poll’ -CREATE TABLE prefix_poll ( nid int(10) unsigned NOT NULL default ’0’, runtime int(10) NOT NULL default ’0’, polled longtext NOT NULL, active int(2) unsigned NOT NULL default ’0’, PRIMARY KEY (nid) ) TYPE=MyISAM; --- Table structure for table ’poll_choices’ -CREATE TABLE prefix_poll_choices ( chid int(10) unsigned NOT NULL auto_increment, nid int(10) unsigned NOT NULL default ’0’, chtext varchar(128) NOT NULL default ’’, chvotes int(6) NOT NULL default ’0’, chorder int(2) NOT NULL default ’0’, PRIMARY KEY (chid), KEY nid (nid) ) TYPE=MyISAM; --

45

Drupal Handbook

3 Aug 2007

-- Table structure for table ’queue’ -CREATE TABLE prefix_queue ( nid int(10) unsigned NOT NULL, uid int(10) unsigned NOT NULL, vote int(3) NOT NULL default ’0’, PRIMARY KEY (nid, uid) ) TYPE=MyISAM; --- Table structure for table ’role’ -CREATE TABLE prefix_role ( rid int(10) unsigned NOT NULL auto_increment, name varchar(32) NOT NULL default ’’, PRIMARY KEY (rid), UNIQUE KEY name (name) ) TYPE=MyISAM; --- Table structure for table ’search_index’ -CREATE TABLE prefix_search_index ( word varchar(50) NOT NULL default ’’, sid int(10) unsigned NOT NULL default ’0’, type varchar(16) default NULL, fromsid int(10) unsigned NOT NULL default ’0’, fromtype varchar(16) default NULL, score int(10) unsigned default NULL, KEY sid (sid), KEY fromsid (fromsid), KEY word (word) ) TYPE=MyISAM; --- Table structure for table ’search_total’ -CREATE TABLE prefix_search_total ( word varchar(50) NOT NULL default ’’, count int(10) unsigned default NULL, PRIMARY KEY word (word) ) TYPE=MyISAM; --- Table structure for table ’sessions’ -CREATE TABLE prefix_sessions ( uid int(10) unsigned NOT NULL, sid varchar(32) NOT NULL default ’’, hostname varchar(128) NOT NULL default ’’, timestamp int(11) NOT NULL default ’0’,

46

3 Aug 2007

Drupal Handbook

session longtext, KEY uid (uid), PRIMARY KEY (sid), KEY timestamp (timestamp) ) TYPE=MyISAM; --- Table structure for table ’sequences’ -CREATE TABLE prefix_sequences ( name varchar(255) NOT NULL default ’’, id int(10) unsigned NOT NULL default ’0’, PRIMARY KEY (name) ) TYPE=MyISAM; --- Table structure for table ’node_counter’ -CREATE TABLE prefix_node_counter ( nid int(11) NOT NULL default ’0’, totalcount bigint(20) unsigned NOT NULL default ’0’, daycount mediumint(8) unsigned NOT NULL default ’0’, timestamp int(11) unsigned NOT NULL default ’0’, PRIMARY KEY (nid), KEY totalcount (totalcount), KEY daycount (daycount), KEY timestamp (timestamp) ) TYPE=MyISAM; --- Table structure for table ’system’ -CREATE TABLE prefix_system ( filename varchar(255) NOT NULL default ’’, name varchar(255) NOT NULL default ’’, type varchar(255) NOT NULL default ’’, description varchar(255) NOT NULL default ’’, status int(2) NOT NULL default ’0’, throttle tinyint(1) DEFAULT ’0’ NOT NULL, bootstrap int(2) NOT NULL default ’0’, PRIMARY KEY (filename) ) TYPE=MyISAM; --- Table structure for table ’term_data’ -CREATE TABLE prefix_term_data ( tid int(10) unsigned NOT NULL auto_increment, vid int(10) unsigned NOT NULL default ’0’, name varchar(255) NOT NULL default ’’, description longtext,

47

Drupal Handbook

3 Aug 2007

weight tinyint(4) NOT NULL default ’0’, PRIMARY KEY (tid), KEY vid (vid) ) TYPE=MyISAM; --- Table structure for table ’term_hierarchy’ -CREATE TABLE prefix_term_hierarchy ( tid int(10) unsigned NOT NULL default ’0’, parent int(10) unsigned NOT NULL default ’0’, KEY tid (tid), KEY parent (parent) ) TYPE=MyISAM; --- Table structure for table ’term_node’ -CREATE TABLE prefix_term_node ( nid int(10) unsigned NOT NULL default ’0’, tid int(10) unsigned NOT NULL default ’0’, KEY nid (nid), KEY tid (tid), PRIMARY KEY (tid,nid) ) TYPE=MyISAM; --- Table structure for table ’term_relation’ -CREATE TABLE prefix_term_relation ( tid1 int(10) unsigned NOT NULL default ’0’, tid2 int(10) unsigned NOT NULL default ’0’, KEY tid1 (tid1), KEY tid2 (tid2) ) TYPE=MyISAM; --- Table structure for table ’term_synonym’ -CREATE TABLE prefix_term_synonym ( tid int(10) unsigned NOT NULL default ’0’, name varchar(255) NOT NULL default ’’, KEY tid (tid), KEY name (name(3)) ) TYPE=MyISAM; --- Table structure for table ’users’ -CREATE TABLE prefix_users ( uid int(10) unsigned NOT NULL default ’0’, name varchar(60) NOT NULL default ’’,

48

3 Aug 2007

Drupal Handbook

pass varchar(32) NOT NULL default ’’, mail varchar(64) default ’’, mode tinyint(1) NOT NULL default ’0’, sort tinyint(1) default ’0’, threshold tinyint(1) default ’0’, theme varchar(255) NOT NULL default ’’, signature varchar(255) NOT NULL default ’’, created int(11) NOT NULL default ’0’, changed int(11) NOT NULL default ’0’, status tinyint(4) NOT NULL default ’0’, timezone varchar(8) default NULL, language varchar(12) NOT NULL default ’’, picture varchar(255) NOT NULL DEFAULT ’’, init varchar(64) default ’’, data longtext, PRIMARY KEY (uid), UNIQUE KEY name (name), KEY changed (changed) ) TYPE=MyISAM; --- Table structure for table ’users_roles’ -CREATE TABLE prefix_users_roles ( uid int(10) unsigned NOT NULL default ’0’, rid int(10) unsigned NOT NULL default ’0’, PRIMARY KEY (uid, rid) ) TYPE=MyISAM; --- Table structure for table ’variable’ -CREATE TABLE prefix_variable ( name varchar(48) NOT NULL default ’’, value longtext NOT NULL, PRIMARY KEY (name) ) TYPE=MyISAM; --- Table structure for table ’vocabulary’ -CREATE TABLE prefix_vocabulary ( vid int(10) unsigned NOT NULL auto_increment, name varchar(255) NOT NULL default ’’, description longtext, help varchar(255) NOT NULL default ’’, relations tinyint(3) unsigned NOT NULL default ’0’, hierarchy tinyint(3) unsigned NOT NULL default ’0’, multiple tinyint(3) unsigned NOT NULL default ’0’, required tinyint(3) unsigned NOT NULL default ’0’,

49

Drupal Handbook

3 Aug 2007

module varchar(255) NOT NULL default ’’, weight tinyint(4) NOT NULL default ’0’, PRIMARY KEY (vid) ) TYPE=MyISAM; --- Table structure for table ’vocabulary_node_types’ -CREATE TABLE prefix_vocabulary_node_types ( vid int(10) unsigned NOT NULL DEFAULT ’0’, type varchar(16) NOT NULL DEFAULT ’’, PRIMARY KEY (vid, type) ) TYPE=MyISAM; --- Table structure for table ’watchdog’ -CREATE TABLE prefix_watchdog ( wid int(5) NOT NULL auto_increment, uid int(10) NOT NULL default ’0’, type varchar(16) NOT NULL default ’’, message longtext NOT NULL, severity tinyint(3) unsigned NOT NULL default ’0’, link varchar(255) NOT NULL default ’’, location varchar(128) NOT NULL default ’’, hostname varchar(128) NOT NULL default ’’, timestamp int(11) NOT NULL default ’0’, PRIMARY KEY (wid) ) TYPE=MyISAM; --- Insert some default values -INSERT INTO prefix_system VALUES (’modules/block.module’,’block’,’module’,’’,1,0,0); INSERT INTO prefix_system VALUES (’modules/comment.module’,’comment’,’module’,’’,1,0,0); INSERT INTO prefix_system VALUES (’modules/filter.module’,’filter’,’module’,’’,1,0,0); INSERT INTO prefix_system VALUES (’modules/help.module’,’help’,’module’,’’,1,0,0); INSERT INTO prefix_system VALUES (’modules/node.module’,’node’,’module’,’’,1,0,0); INSERT INTO prefix_system VALUES (’modules/page.module’,’page’,’module’,’’,1,0,0); INSERT INTO prefix_system VALUES (’modules/story.module’,’story’,’module’,’’,1,0,0); INSERT INTO prefix_system VALUES (’modules/system.module’,’system’,’module’,’’,1,0,0); INSERT INTO prefix_system VALUES

50

3 Aug 2007

Drupal Handbook

(’modules/taxonomy.module’,’taxonomy’,’module’,’’,1,0,0); INSERT INTO prefix_system VALUES (’modules/user.module’,’user’,’module’,’’,1,0,0); INSERT INTO prefix_system VALUES (’modules/watchdog.module’,’watchdog’,’module’,’’,1,0,0); INSERT INTO prefix_system VALUES
(’themes/bluemarine/xtemplate.xtmpl’,’bluemarine’,’theme’,’themes/engines/xtemplate/xtemplate.engine’,1,0,0);

INSERT INTO prefix_system VALUES
(’themes/engines/xtemplate/xtemplate.engine’,’xtemplate’,’theme_engine’,’’,1,0,0);

INSERT INTO prefix_users (uid, name, mail) VALUES (’0’, ’’, ’’); INSERT INTO prefix_users_roles (uid, rid) VALUES (0, 1); INSERT INTO prefix_role (rid, name) VALUES (1, ’anonymous user’); INSERT INTO prefix_permission VALUES (1,’access content’,0); INSERT INTO prefix_role (rid, name) VALUES (2, ’authenticated user’); INSERT INTO prefix_permission VALUES (2,’access comments, access content, post comments, post comments without approval’,0); REPLACE prefix_variable SET name=’update_start’, value=’s:10:"2005-03-21";’; REPLACE prefix_variable SET name=’theme_default’, value=’s:10:"bluemarine";’; REPLACE prefix_blocks SET module = ’user’, delta = ’0’, status = ’1’; REPLACE prefix_blocks SET module = ’user’, delta = ’1’, status = ’1’; INSERT INTO prefix_sequences (name, id) VALUES (’menu_mid’, 1); INSERT INTO prefix_node_access VALUES (0, 0, ’all’, 1, 0, 0); INSERT INTO prefix_filter_formats VALUES (1,’Filtered HTML’,’,1,2,’,1); INSERT INTO prefix_filter_formats VALUES (2,’PHP code’,’’,0); INSERT INTO prefix_filter_formats VALUES (3,’Full HTML’,’’,1); INSERT INTO prefix_filters VALUES (1,’filter’,0,0); INSERT INTO prefix_filters VALUES (1,’filter’,2,1); INSERT INTO prefix_filters VALUES (2,’filter’,1,0); INSERT INTO prefix_filters VALUES (3,’filter’,2,0); INSERT INTO prefix_variable (name,value) VALUES (’filter_html_1’,’i:1;’); INSERT INTO prefix_locales_meta (locale, name, enabled, isdefault) VALUES (’en’, ’English’, ’1’, ’1’);

Setup Drupal on Windows XP Pro using IIS
While trying to install Drupal on stand alone machine with Windows XP Pro & IIS I was unable to find all the installation information at one place therefore I am sharing my experiences and solutions to the problems. I think it will be useful for people who are new to Drupal because Drupal on stand alone machine reduces the learning curve. Setup Drupal on Windows XP Pro using IIS: 1. Download Mysql server and install. (I have used ver. 5.0) 2. Download PHP and install. (I have used ver. 4) 3. Download Drupal (I have used ver. 4.7.3).

51

Drupal Handbook

3 Aug 2007

4. Create a folder with any name for example Drupal in Inetpub folder in C: drive. 5. Open IIS and create virtual folder giving alias and path of the Drupal folder which you have just created in Inetpub. 6. Untar (you can use Winrar for this) the downloaded drupal file contents in Drupal folder. 7. Create a schema/database with any name example drupaldata and create a user. 8. Now grant privileges to this user. Grant ALL ON databasename.* TO ’username’@’localhost’ IDENTIFIED BY ’password’; Flush privileges; 9. Modify the file C:\Inetpub\wwwroot\[YOURDIRNAME]\sites\default\settings.php by giving user name, password and database name. 10. Now browse this virtual http://localhost/"aliasname" folder with its alias name in IE example

11. If following error is displayed; Client does not support authentication protocol requested by server; consider upgrading MySQL client Then use these commands; SET PASSWORD FOR ’some_user’@’some_host’ = OLD_PASSWORD(’newpwd’); Flush privileges; 12. Repeat step 10, I hope its working â¦. Have a look at one of the pretty clean theme implementation in drupal - ENJOY . . .

Basic /sites directory setup
Version 5.x supports a new /sites/all directory. Best practice for basic initial setup is the following placements in the /sites directory: Directory /drupal/sites/all /drupal/sites/default /drupal/sites/example.com Contents /modules /themes settings.php /tmp /files (but see below)

Understand the different common locations. The /sites/all and the /sites/default directories are exclusive, and are intended for the above items. The critical principle is to keep all your site customizations within the /sites directory so that it is easy to upgrade when a new minor version of the Drupal core code is released (e.g. to update from 5.1 to 5.2).

52

3 Aug 2007

Drupal Handbook

Contributed and custom modules should be placed in /drupal/sites/all/modules. Additional and custom themes should be placed in /drupal/sites/all/themes. The /files directory is usually best placed in the /sites/example.com directory, which you will have to create. Then set the ’File system path’ at administer > site configuration > file system. This is ideal if a second site will likely need a separate /files directory; just create a second site-specific /files directory at /sites/example2.com/files. The same applies for the /tmp directory. Upon initial installation the /files directory is set to /sites/default/files (you will need to create the actual directory). It can be fine to leave it there (or even to use /sites/files) if you are 100% you will never want to use multi-site features. However, this location shares the /files directory in a multi-site setup , which may or may not be desired. See "Setup of /sites directory for multi-site." Backup is simplified by use of the /sites directory for all customizations. You can then easily backup all non-core material by backing up the /sites directory and the database. For multi-site setup, see Multi-site installation and set-up, the sub-topic Setup of /sites directory for multi-site, and the installation instructions (INSTALL.txt). As stated above, there are two common locations in Drupal 5.x and above: /sites/default (for settings.php) and/sites/all (for common /modules and /themes). This allows a new site to be set up using the multi-site features by simply copying the /sites/default directory to /sites/example2.com Version 4.6 and 4.7: To simplify backups and updates, the best practice (for a single-site install) is to place contributed modules in /sites/default/modules/, contributed or custom themes in /sites/default/themes/, and files in /sites/default/files (or even /sites/files). The /sites/all/ feature was added in Drupal 5.x. It will also work, but be more difficult to update your site, if contributed modules are placed in /drupal/modules, additional themes were placed in /drupal/themes, and files are stored in /drupal/files. If you expect to use multi-sites, then you should make use of /sites/example.com as explained in the "Setup of /sites directory for multi-site." Using /drupal/modules and /drupal/themes will also still work in 5.x, but the best practice above allows easier backup and expansion to multi-site.

Special cases
Various special situations (e.g., installing Drupal behind a firewall, installing Drupal in a subdirectory of the webserver’s document root) are discussed in this section. Information specific to particular operating systems or database platforms may be found elsewhere.

Compilation failed: this version of PCRE is not compiled with PCRE_UTF8 support
This error occurrs on release 4.6.1 onwards. Note: This issue is fixed by default on all VPS3 and new VPS2 servers, resolve-able on VPS1 and old VPS2 (with some updating).

53

Drupal Handbook

3 Aug 2007

This fix works for Verio VPS2 Servers which are installed with PCRE 6.4 by default (at this time). I see no reason why it should not work for all unix servers (perhaps with directory changes etc). The fix is to uninstall pcre and install the correct version as follows: login as root Type: # pkg_info which will show you the installed packages. type: # pkg_delete pcre-6.4 (assuming you see pcre-6.4 as version, change as required) change to the directory where your ports collection is. on FreeBSD it is: /ports/devel/pcre-utf8 so type into your shell prompt: # cd /ports/devel/pcre-utf8 # make # make install # make clean then restart the apache server... something like this (this is a VPS2 specific script, yours may be different): # restart_apache

the

installed

Configure .htaccess to allow awstats to work with clean URL’s
When I installed Drupal with clean url’s it made my Awstats (within the cgi-bin) not work and just return a Drupal page not found error. Drupal is installed in the root directory (public_html) of my web space so is the cgi-bin folder that Awstats is in. I fixed the problem by changing the protect files and adding 1 rewriteCond line to the .htaccess file as follows: In the FilesMatch section, find " |code-style\.pl " without the quotes and remove it from the following code: # Protect files and directories from prying eyes. <FilesMatch
"(\.(engine|inc|install|module|sh|.*sql|theme|tpl(\.php)?|xtmpl)|Entries.*|Repository|Root)$">

Order deny,allow Deny from all </FilesMatch> Now add this line (RewriteCond %{REQUEST_URI} "!cgi-bin/") to the following:

54

3 Aug 2007

Drupal Handbook

# Rewrite current-style URLs of the form ’index.php?q=x’. RewriteCond RewriteCond RewriteCond RewriteRule %{REQUEST_URI} "!cgi-bin/" %{REQUEST_FILENAME} !-f %{REQUEST_FILENAME} !-d ^(.*)$ index.php?q=$1 [L,QSA]

This was all done on the default install of Drupal w/.htaccess.

Configuring .htaccess to ignore specific subfolders
Ignoring Subfolders that exist in the DocumentRoot
With clean URL’s enabled, when running other software applications in subfolders (subdirectories) of a Drupal root installation. your .htaccess file may rewrite those URL’s to Drupal. This may be a particular problem for those with a Drupal installation in the root of their domain using Cpanel and Fantastico where Fantastico installs other software into subfolders. For example, phpSurveyor’s admin interface as installed by Fantastico will not work with Drupal’s default .htaccess settings. The URL for the admin interface is inaccessible and will return a "page not found" page in your Drupal site. The trick is to modify .htaccess to ignore specific files/folders. So for example, if you have two folders, <folder1> and <folder2> in the root of your Drupal installation, modify your .htaccess file by inserting the following code: =========[ start of .htaccess snippet]========== <IfModule mod_rewrite.c> RewriteEngine on # # stuff to let through (ignore) RewriteCond %{REQUEST_URI} "/folder1/" [OR] RewriteCond %{REQUEST_URI} "/folder2/" RewriteRule (.*) $1 [L] # ====================[ end ]===================== For each folder you want to bypass, add a RewriteCond line, and end all but the final RewriteCond with [OR]. Note that the [L] in the rewrite rule tells it to stop there and bypass the rest of the rewrite rules.

Ignoring subfolders that are included via Apache Alias directives
As of 4.7, files and directories should be automatically allowed through in drupal’s .htaccess setup. Thats what the !-f and !-d lines do. However if you are working with Apache Alias or similar directives the file doesn’t actually exist so drupal will take over like it should. The best way around it is to just add one more conditional that matches your location and make it skip it too. Thats what the ! means. Please see

55

Drupal Handbook

3 Aug 2007

below: RewriteCond RewriteCond RewriteCond RewriteRule %{REQUEST_URI} !^/yourDirectoryName %{REQUEST_FILENAME} !-f %{REQUEST_FILENAME} !-d ^(.*)$ index.php?q=$1 [L,QSA]

It essentially means Apply this rule if the REQUEST_URI doesn’t start with /yourDirectoryName and the REQUEST_FILENAME isn’t a real file or a real folder. Which is exactly what you want. There is an implied "AND" between the lines of that rule. The ! says "not like this". Special thanks to Mike Smullin for help on this fix.

Create a custom php.ini
This article explains how to set up a custom php.ini that overides your servers default php.ini, providing an easier alternative (in the long run) than using .htaccess to overide php.ini settings. Itassumes that you have a ssh account set-up and are using a ssh client (e.g. putty - link to be added). You are also expected to logically replace directory structures given here, with your own, if they are different. Procedure for allowing php.ini configuration for a website (shows changing file upload max) 1/ Create a cgi-bin Directory First you’ll need a cgi-bin directory: mkdir ~/[your website directory]/cgi-bin/ This directory will be hosting your copy of php and your php.ini file. 2/ Create a script to retrieve the latest copy of php.cgi and php.ini Make a file in ~/ called php-copy.sh containing the following, where 100M contains whatever file size limit you like, and [your website directory] is appropriately substituted. For PHP4: #!/bin/sh CGIFILE="$HOME/[your website directory]/cgi-bin/php.cgi" INIFILE="$HOME/[your website directory]/cgi-bin/php.ini" rsync -a /dh/cgi-system/php.cgi "$CGIFILE" # REMOVE THE FOLLOWING LINE TO CREATE THE UPDATE-ONLY SCRIPT: cp /etc/php/cgi/php.ini "$INIFILE" perl -p -i -e ’ s/.*post_max_size.*/post_max_size = 100M/; s/.*upload_max_filesize.*/upload_max_filesize = 100M/; ’ "$INIFILE"

56

3 Aug 2007

Drupal Handbook

For PHP5: #!/bin/sh CGIFILE="$HOME/[your website directory]/cgi-bin/php.cgi" INIFILE="$HOME/[your website directory]/cgi-bin/php.ini" rsync -a /dh/cgi-system/php5.cgi "$CGIFILE" # REMOVE THE FOLLOWING LINE TO CREATE THE UPDATE-ONLY SCRIPT: cp /etc/php5/cgi/php.ini "$INIFILE" perl -p -i -e ’ s/.*post_max_size.*/post_max_size = 100M/; s/.*upload_max_filesize.*/upload_max_filesize = 100M/; ’ "$INIFILE" A more general script with options (for references purposes only, do not do this): #!/bin/sh test $# = 0 && exit 1 while test "$1";do case $1 in -php5) PHP=php5 ;; -sm) shift; SM=$1 ;; -rg) shift; RG=$1 ;; -pms) shift; PMS=$1 ;; -umfs) shift; UMFS=$1 ;; -mqg) shift; MQG=$1 ;; -met) shift; MET=$1 ;; -mit) shift; MIT=$1 ;; -ml) shift; ML=$1 ;; *) D=$1 ;; esac shift done test "$D" || exit 1 test -d "$HOME/$D" || exit 1 CGI="$HOME/$D/cgi-bin" mkdir -m0755 -p $CGI || exit 2 PHP=${PHP:-php} SM=${SM:-On} RG=${RG:-Off} PMS=${PMS:-8M} UMFS=${UMFS:-7M} MQG=${MQG:-Off} MET=${MET:-30} MIT=${MET:-60} ML=${ML:-8M} CGIFILE="$CGI/$PHP.cgi" INIFILE="$CGI/php.ini"

57

Drupal Handbook

3 Aug 2007

echo "CGI=$CGI MQG=${MQG} UMFS=${UMFS} PMS=${PMS} RG=${RG} SM=${SM} MET=${MET} MIT=${MIT} ML=${ML}" >&2 rsync -au /dh/cgi-system/$PHP.cgi "$CGIFILE" [ -s /etc/$PHP/cgi/php.ini ] && \ sed -e "s/^safe_mode[ ]*=.*/safe_mode = $SM/" \ -e "s/register_globals[ ]*=.*/register_globals = $RG/" \ -e "s/magic_quotes_gpc[ ]*=.*/magic_quotes_gpc = $MQG/" \ -e "s/.*post_max_size.*/post_max_size = $PMS/" \ -e "s/.*upload_max_filesize.*/upload_max_filesize = $UMFS/" \ -e "s/.*max_execution_time.*/max_execution_time = $MET/" \ -e "s/.*max_input_time.*/max_input_time = $MIT/" \ -e "s/.*memory_limit.*/memory_limit= $ML/" \ # REMOVE THE FOLLOWING LINE TO CREATE THE UPDATE-ONLY SCRIPT: /etc/$PHP/cgi/php.ini > "$INIFILE" chmod 0755 "$CGIFILE" chmod 0644 "$INIFILE" [ -s $CGI/.htaccess ] || echo "Options -Indexes" > $CGI/.htaccess touch $HOME/$D/.htaccess if grep -q ’^Options’ $HOME/$D/.htaccess; then grep -q ’+ExecCGI’ $HOME/$D/.htaccess || \ sed -i ’s/^Options\(.*\)/Options\1 +ExecCGI/’ $HOME/$D/.htaccess else echo "Options +ExecCGI" >> $HOME/$D/.htaccess fi grep -q ’^AddHandler[ ]\+php-cgi[ ]\+.php’ $HOME/$D/.htaccess || echo "AddHandler php-cgi .php" >> $HOME/$D/.htaccess if grep -q ’^Action[ ]\+php-cgi’ $HOME/$D/.htaccess; then sed -i "s@^Action[ ]\+php-cgi.*@Action php-cgi /cgi-bin/$PHP.cgi@" \ $HOME/$D/.htaccess else echo "Action php-cgi /cgi-bin/$PHP.cgi" >> $HOME/$D/.htaccess fi 3/ Prepare script for execution Execute the following commands into the shell. This will give you permission to execute the php-copy.sh that we just created. chmod +x php-copy.sh This calls our new shell script to copy the php.cgi and php.ini files into our cgi-bin directory. ./php-copy.sh If you get the error message: "bad interpreter: No such file or directory", there is probably an unseen problem with the formatting of the file.

58

3 Aug 2007

Drupal Handbook

Run the following command to convert it to proper Unix format before calling the script again: dos2unix php-copy.sh 4/ Test your new PHP setup Open one of your existing PHP pages in your browser to ensure that your newly-installed local copy of PHP is functioning properly. If there is a problem, go back over the prior steps and use your debugging skills and your mastery of PHP, shell scripts and Linux to get your newly-copied PHP interpreter working! Once everything works properly, go on to the next step. 5/ Create a shell script to make a fresh copy of php (for future use) cp php-copy.sh php-update.sh Open the newly-created php-update.sh script in your favorite text editor and find this line: # REMOVE THE FOLLOWING LINE TO CREATE THE UPDATE-ONLY SCRIPT: Delete that line as well as the line following it. Then save php-update.sh If you got a "bad interpreter: No such file or directory" error message when you executed ./php-copy.sh previously, remember to convert the new file to unix format by running the following command: dos2unix php-update.sh 6/ Set up a cron task to keep php up to date Type: crontab -e And then enter the following in the text editor that shows up (replacing ’myusername’ with your specific username): @weekly /home/myusername/php-update.sh This will update the php binary and config file once a week. 7/ Configure your website to use new the php.ini that we just set up Create the file ~/[your website directory]/.htaccess which contains the lines: Options +ExecCGI AddHandler php-cgi .php Action php-cgi /cgi-bin/php.cgi This is telling Apache (the webserver) to use the php.cgi and php.ini that php-update.sh copied into ~/[your website directory]/cgi-bin.

59

Drupal Handbook

3 Aug 2007

How to create a custom php.ini file when nothing else works
I recently needed to increase the memory_limit, upload_max_filesize and post_max_size values to something higher than the measly amount set by a particular webhost’s default php.ini file. This account was set up with cPanel and overriding the php.ini defaults the usual way (by adding various lines to the .htaccess or settings.php files) didn’t work at all. If you’ve had the same experience, you may find that this how-to works for you. This how-to is for any version of Drupal running on Linux and Apache. No Drupal modules are needed, but the devel module certainly helps.

1. Get and modify your custom php.ini file
It’s best to use a php.ini file that somewhat resembles the one already running on your server. You can probably find one at /usr/local/lib/php.ini or /usr/local/Zend/etc/php.ini and just copy it into your account’s web folder (it may be called "public_html" or "www" or "htdocs" -- you know the one). Edit your php.ini file and save your changes. There are handbook pages on increasing memory and upload size if you need help on the syntax.

2. Creating your CGI script
Now create a small script and put it in your cgi-bin directory. In your web folder, create another folder called "cgi-bin" if it’s not there already. Using your preferred text editor, create a file name "php.cgi" and put the following into it: #!/bin/sh exec /usr/local/cpanel/cgi-sys/php5 -c /path/to/drupal/ If you don’t have cPanel on your account, try /etc/php5 instead. In any case, replace the /path/to/drupal/ part with the full path to your Drupal installation, such as /home/youraccount/public_html/ or /home/youraccount/public_html/drupal/ Since this is a script that needs to run as an executable file, use the chmod command and type this at the command line: chmod -x php.cgi Don’t have shell access? That’s outside the scope of this how-to, but you can use an FTP program that can change permissions of files, ask your webhost to make the php.cgi script executable for you, or make it executable with some PHP code (perhaps with the devel module’s Execute PHP block).

60

3 Aug 2007

Drupal Handbook

3. Modifying your .htaccess file
Add this one line to your .htaccess file: Action application/x-httpd-php5 /cgi-bin/php.cgi This tells Apache to perform an action each time it encounters a file of file type "application/x-httpd-php5" -- if you’re using a version of PHP older than PHP5, you’ll need to change this to "application/x-httpd-php" (or upgrade to PHP5 -- ask your webhost). Finally, scroll down to the part that says "# Protect files and directories from prying eyes" and add "ini|" to the <FilesMatch> directive so it looks something like: <FilesMatch
"(\.(ini|engine|inc|info|install|module|profile|po|sh|.*sql|theme|tpl(\.p

hp)?|xtmpl)|code-style\.pl|Entries.*|Repository|Root|Tag|Template)$"> Order allow,deny </FilesMatch> Notice the "ini|" on the first line? This will prevent your custom php.ini file (and anything else ending in .ini) from being accessible to the entire world. (The character after the "ini" part is a pipe, by the way, not an L.)

4. Test your site
Load up your website and see if it works. If it does, good job! If it doesn’t, go back to step 2 or 3 and check to see what version of PHP your site is using. You can also ask your webhost for help. If you increased your post_max_size or upload_max_size, then look at your admin/settings/uploads admin page and see how big your uploads can be. If you increased your memory_limit, check phpinfo or devel module’s phpinfo() page at admin/logs/status/php

Create Drupal database using Plesk
Create the database Login and select Services » Databases This loads a page with an overview of databases. Depending on your host a database may already have been created. This is often the case with low-budget hosts, where you are limited to one database. In that case, use table prefixing. If no limits exists it is best to create a new database for Drupal via: Add New Database. Click on the name of the database you wish to use. In the overview page you’ll see all users for this database. Again, depending on your host, you need to create a new user via: Add New Database User.

61

Drupal Handbook

3 Aug 2007

If you do not have the option to create new database users, use a pre-existing one. Load the Drupal database scheme From the database users overview page click DB WebAdmin The icon is a blue stack with a monkey wrench. Note that this opens phpmyadmin in a pop-up that may be blocked by your browser. First make sure the relevant database is selected. If necessary, click Databases in the phpmyadmin start screen and then the database name. Go to the SQL screen via a small button labelled SQL in the left pane of the phpmyadmin screen. If you’ve created a new user for the Drupal database, you need to grant priviliges to the user: execute the SQL query: GRANT ALL PRIVILEGES ON databasename.* TO username@localhost IDENTIFIED BY ’password’; where ’databasename’ is the name of your database ’username@localhost’ is the username of your MySQL account ’password’ is the password required for that username This may not complete successfully; in that case you’ll have to assume / hope the user was created with the necessary privileges. To create the database layout, select the tab database/database.mysql with the database scheme. import files. Upload the file

Drupal with safe mode enabled and open basedir
This is still undergooing some changes as I’m doing more tests... But it works on a clean drupal 4.7.3 install... I haven’t tested all modules yet, so please help me out... Simply: use safe mode based on groups rather then owner and give access to my central code base for virtual hosts so that open base dir works... You need to be logged in using ssh as root... And mind you my examples are from a plesk based system... With a central code base located in /var/www/apps/drupal and the virtual hosts directory in /var/www/vhosts/{domain}.{tld}/httpdocs/ 1) create a group and a user called drupal... After -d you can put any home directory you like, but I choose the directory where my drupal code is installed... after the passwd you need to give a GOOD password for the user...

62

3 Aug 2007

Drupal Handbook

groupadd drupal useradd -d /var/www/apps/drupal -g drupal drupal passwd drupal 2) Change the owner and the group of the single code base... If you don’t have a single code base, only changing the group (chgrp) is enough chgrp drupal -R /var/www/apps/drupal chown drupal -R /var/www/apps/drupal 3) For the virtual hosts, change the group of the sites directory Also all directories under sites should be chmod to 2775: 2 puts all new subfiles created automatically into the group of the folder they are placed in (drupal in our case) + 7 for owner (root or drupal or ftpusername) + 7 for group (drupal) + 5 for guests If you have any more directories under sites, chmod them too chgrp drupal -R /var/www/vhosts/{domain}.{tld}/httpdocs/sites chmod 2775 /var/www/vhosts/{domain}.{tld}/httpdocs/sites chmod 2775 /var/www/vhosts/{domain}.{tld}/httpdocs/sites/default 4) Add the users to the group Plesk has a psaserv group don’t worry if you don’t have it... The drupal group needs the psaadm and psaftp only if you run plesk vi /etc/group psaserv:x:2523:apache,psaftp,psaadm,drupal
drupal:x:10002:drupal,apache,psaftp,psaadm,{user_of_ftp_account_of_virtual_host}

restart service apache 5) correct the tmp dir by creating a sub directory and putting the drupal group and user on it... mkdir /tmp/drupal chmod 2775 /tmp/drupal chgrp drupal /tmp/drupal ==> in admin change to /tmp/drupal 6) alter the code of file.inc so directories are made using 2775 rather then 775 find: @chmod($directory, 0775); replace: @chmod($directory, 02775); Actually my version of PHP has a bug and doesn’t put the 2!!! I have to remember to chmod myself then... 7) change your virtual host settings of httpd.conf In plesk this is done in: /var/www/vhosts/{domain}.{tld}/conf/vhost.conf Other systems might have another place for the conf which is the configuration for your httpd server.. With this code I have made sure that only the drupal directories benefit from group based safe

63

Drupal Handbook

3 Aug 2007

mode (safe_mode_gid)... all other directories still use the default safe mode Remove the second DirectoryMatch in case you want all files and folders to benefit from group based safe mode... As I have a central code base in /var/www/apps/drupal, I need to add this dir to the open basedir... and again only for the drupal directories off course... # # allow all documents below this dir access to drupal core # <DirectoryMatch "^/var/www/vhosts/{domain}.{tld}/httpdocs"> <IfModule sapi_apache2.c> php_admin_flag safe_mode on php_admin_flag safe_mode_gid on php_admin_value open_basedir "/var/www/apps/drupal:/var/www/vhosts/{domain}.{tld}/httpdocs:/tmp" </IfModule> <IfModule mod_php5.c> php_admin_flag safe_mode on php_admin_flag safe_mode_gid on php_admin_value open_basedir "/var/www/apps/drupal:/var/www/vhosts/{domain}.{tld}/httpdocs:/tmp" </IfModule> </DirectoryMatch> # # now limit for all directories below root that are not includes or modules # users want other apps installed too... so no access to drupal # <DirectoryMatch "^(/var/www/vhosts/{domain}.{tld}/httpdocs/)(?!includes/|modules/).*/"> <IfModule sapi_apache2.c> php_admin_flag safe_mode on php_admin_flag safe_mode_gid off php_admin_value open_basedir "/var/www/vhosts/{domain}.{tld}/httpdocs:/tmp" </IfModule> <IfModule mod_php5.c> php_admin_flag safe_mode on php_admin_flag safe_mode_gid off php_admin_value open_basedir "/var/www/vhosts/{domain}.{tld}/httpdocs:/tmp" </IfModule> </DirectoryMatch>

64

3 Aug 2007

Drupal Handbook

Generic Mass SQL Import into Drupal
# General Notes for Mass Import into Drupal # # The below is a template for an SQL import file to programmatically # add nodes into Drupal version 4.7.0. # # - Currently not tested on 4.7.3, but there does not seem to be any # radical changes in the Database structure that would break this. # # - You will probably need to create a separate program to parse # your existing content and create the needed looping structures # to properly create the SQL import file for you system. # # - You must follow SQL rules for data entry, see your SQL # documentation. Incorrect escaping will cause truncated fields. # # - Copyright ReasonToFreedom.com # - Personal use: Free of charge. # - Professional use: Only with USD $20 donated # to Drupal.org per domain you use it on.* # # - This header and all copyright notices must remain intact # upon any reprint/redistribution. # # - *Don’t stiff Drupal.org, if you’re using this professionally # on five domains, you can afford to send Drupal.org $100. # # ======== Set Once Vars ========== set @uid_value = 7; # Author ID (User ID) set @format = 3; # 1 => Filtered HTML | 2 => PHP code | 3 => Full HTML # ======== End Set Once Vars ========== # ======== Set Per Node Vars ========== /* set some variables to zero */ set @node_value = 0, @node_rev_vid_value = 0; # load these values as we execute. /* Set some default values */ set @title_value = ’The Title’; /* May also set entry_date_time like curr_date_time below */ set @entry_date_time = unix_timestamp(’2002-05-20 12:00:00’); # get specific date and time as number of seconds from 01/01/1970. set @url_dest = ’the_url.html’; set @teaser_value = ’<P>Teaser Para 1.</P> <P>Teaser Para 2.</P> ’; set @body_value = ’<P>Body Para 1.</P> <P>Body Para 2.</P>

65

Drupal Handbook

3 Aug 2007

<P>Body Para 3.</P> <P>Body Para, ad nauseam</P> ’; set @curr_date_time = unix_timestamp(); # get current date and time as number of seconds from 01/01/1970. START TRANSACTION; /* Increment node_nid field in sequences. */ update sequences set id = id + 1 where name = ’node_nid’; /* Get new node_nid value from sequences for later */ select @node_value := max(id) from sequences where name = ’node_nid’; /* Increment node_revisions_vid field in sequences. */ update sequences set id = id + 1 where name = ’node_revisions_vid’; /* Get node_revisions_vid value from sequences for later */ select @revisions_value := max(id) from sequences where name = ’node_revisions_vid’; COMMIT; START TRANSACTION; Insert into node (nid, type, title, uid, status, created, changed, comment, promote, moderate, sticky, vid) VALUES (@node_value, ’story’, @title_value, @uid_value, 1, @entry_date_time, @curr_date_time, 2, 1, 0, 0, @revisions_value); Insert into node_comment_statistics (nid, last_comment_timestamp, last_comment_name, last_comment_uid, comment_count) VALUES (@node_value, @curr_date_time, NULL, @uid_value, 0); Insert into node_revisions (nid, vid, uid, title, body, teaser, timestamp, format, log) VALUES (@node_value, @revisions_value, @uid_value, @title_value, @body_value, @teaser_value, @curr_date_time, @format, ""); Insert into history (uid, nid, timestamp) VALUES (@uid_value, @node_value, @curr_date_time); Insert into node_counter (nid, totalcount, daycount, timestamp) VALUES (@node_value, 1, 1, @curr_date_time); COMMIT; set @url_src = concat( "node/", @node_value ) ; Insert into url_alias (src,dst) VALUES (@url_src, @url_dest);

66

3 Aug 2007

Drupal Handbook

# ======== End Set Per Node Vars ========== # ======== Set multiple Terms per Node ========== /* set term_value and insert as many times as you need */ set @term_value = 50; Insert into term_node (nid,tid) VALUES (@node_value, @term_value); set @term_value = 48; Insert into term_node (nid,tid) VALUES (@node_value, @term_value); # ======== End Set multiple Terms per Node ========== # EOF #

DrupalCon site
design contest entry over at the DrupalCon site and become immortal in the Drupal community.

How to degrade your Drupal db from MySQL 4.1.X/5.0.X to MySQL 4.0.X
I came across this issue when was developing a site for a client. I have MySQL 5.0.X at my localhost and staging host but client’s hosting still uses MySQL 4.0.X. So here is the solution: 0. Always make backup first. 1. Drop tables "accesslog", "cache" and "watchdog" (DROP TABLE accesslog, cache, watchdog;) 2. Recreate tables from Drupal mysql dump for v4.0 CREATE TABLE accesslog ( aid int(10) NOT NULL auto_increment, sid varchar(32) NOT NULL default ’’, title varchar(255) default NULL, path varchar(255) default NULL, url varchar(255) default NULL, hostname varchar(128) default NULL, uid int(10) unsigned default ’0’, timer int(10) unsigned NOT NULL default ’0’, timestamp int(11) unsigned NOT NULL default ’0’, KEY accesslog_timestamp (timestamp), PRIMARY KEY (aid)

67

Drupal Handbook

3 Aug 2007

); CREATE TABLE cache ( cid varchar(255) NOT NULL default ’’, data longblob, expire int(11) NOT NULL default ’0’, created int(11) NOT NULL default ’0’, headers text, PRIMARY KEY (cid), INDEX expire (expire) ); CREATE TABLE watchdog ( wid int(5) NOT NULL auto_increment, uid int(10) NOT NULL default ’0’, type varchar(16) NOT NULL default ’’, message longtext NOT NULL, severity tinyint(3) unsigned NOT NULL default ’0’, link varchar(255) NOT NULL default ’’, location varchar(128) NOT NULL default ’’, referer varchar(128) NOT NULL default ’’, hostname varchar(128) NOT NULL default ’’, timestamp int(11) NOT NULL default ’0’, PRIMARY KEY (wid) ); 3. Make a dump for MySQL 4.0.X mysqldump -u root -p -h localhost --compatible=mysql40 mydatabase > mydatabase.sql 4. Upload this dump to your MySQL 4.0.X server. 5. Refresh your browser a couple of times. Enjoy!

How-To: Virtual Hosting with Drupal
Introduction
This book explaines how I’ve enabled Drupal hosting for my customers. I hope it is helpfull for other Drupal hosters...

Environment
this is the environment used to setup my drupal hosting linux RHEL 4 plesk 8.0.1 php 4.3.9 mysql 4.1.12 apache 2.0.52

68

3 Aug 2007

Drupal Handbook

drupal 4.7.x

Requirements
keep safe mode on at all times without the need for chmod 777 keep base dir restriction on at all times integrate into plesk so that backup, databases, quotas, etc keeps working drupal must run as managed application updates done once for all vhosts :: use single code base approved modules and themes available for vhosts to select from pre-activate drupal modules that enhance basic content management: SEO, security, ... eaccelerator must speed up php processing efficiently :: use single code base Each individual vhost should be able to use its own themes and modules should be accessible trough different URLs :: drupal multisite option should also be able to use other applications then drupal within the same site should experience drupal no different as if we would install drupal for each vhost seperatly Enhance security if needed on the drupal package Single code base should be included in the normal backup mechanism available in plesk

Next pages
As the book seems to order the sub pages by date, I list here the order of further reading: 1. Solution overview: http://drupal.org/node/90144 2. Prepare environment: http://drupal.org/node/90207

How-To: Virtual Hosting with Drupal :: Prepare environment Introduction
On this page I will explain some preparations of the environment like creating the drupal group, a tempory files location, application reference location, etc. Please read previous pages: Requirements: http://drupal.org/node/80472 Solution overview: http://drupal.org/node/90144

69

Drupal Handbook

3 Aug 2007

The drupal group
As we will enable the safe mode in group mode, we are in need of a system group. SSH into the server as SU (super user or root) add the group $ groupadd drupal add the apache, psaftp and psaadm users to the group the group id (10002) could be different $ vi /etc/group drupal:x:10002:apache,psaftp,psaadm

The temp directory
Also within the temp directory we need a matching group because uploaded files are temporarly saved there and then copied to the final destination. Therefore we will create a seperate directory and chmod it so that each file created their automatically receives the drupal group. The latter is achieved by addin 2000 to the chmod command. $ mkdir /tmp/drupal $ chmod 2775 /tmp/drupal $ chgrp drupal /tmp/drupal You will see an s appear instead of the x at the group part: drwxrwsr-x 2 root drupal 4096 Oct 16 15:09 drupal

The reference location
This is a directory where all symlinks are placed that point to the current version of an application. It is this location that all vhosts will reference so that they don’t depend on the current version. When switching versions, we only need to alter the symlinks at this location and all vhosts will be updated automatically. See further pages for more info. SSH into the server as SU (super user or root) $ mkdir /var/www/apps

Navigation
As the book seems to order the sub pages by date, I list here the order of further reading: Previous: Solution Overview: http://drupal.org/node/90144 Next: Single code base: Comming soon...

70

3 Aug 2007

Drupal Handbook

How-To: Virtual Hosting with Drupal :: Solution Overview Introduction
On this page I will explain in general what solutions are provided for the different requirements Please read previous Requirements page: http://drupal.org/node/80472

Safe mode
Enabling Safe Mode imposes several restrictions on PHP scripts. These restrictions are mostly concerned with file access, access to environment variables and controlling the execution of external processes. There are problems which may be encountered when this mechanism is turned on, notably when attempting to work with files owned by different users and files which have been created at runtime by the script (which will be owned by the owner of the web server process). In Plesk (and most other virtual hosts system) each vhost gets its own owner (FTP user) that is set when files are uploaded to the server. As we want a single code base located in a central place, the owner of the files within that central place will be different then the owner of the files in the vhost’s location. In order to work around these issues, a relaxed form of the file permission checking is also provided by Safe Mode. Using the php.ini directive safe_mode_gid, it is possible to relax the user ID check to a group ID check. That is, if the script has the same group ID as the file on which a file operation was requested, the operation will succeed. If the script owners and the web server are members of the same group, and all hosted files are owned by this group, the file operations will succeed regardless of user ID. Thus, we will create a group "drupal" that will cover all drupal related files accross vhosts and enable the safe_mode_gid. By doing so we will still have a more secure system then when we would disable the safe mode. Information taken from here: http://www.acunetix.com/websitesecurity/php-security-5.htm

Open Basedir
Open Basedir limits the files that can be opened by PHP to the specified directory-tree, including the file itself. This directive is NOT affected by whether Safe Mode is turned On or Off. When a script tries to open a file with, for example, fopen() or gzopen(), the location of the file is checked. When the file is outside the specified directory-tree, PHP will refuse to open it. All symbolic links are resolved, so it’s not possible to avoid this restriction with a symlink.

71

Drupal Handbook

3 Aug 2007

In Plesk (and most other virtual hosts system) each vhost gets its own open_basedir restriction that restruicts the opening of files to the httpdocs directory and the /tmp directory. As we want a single code base located in a central place, that location will not be accepted trough this restriction. Thus, we will alter the open basedir restriction so that it includes the single code base location. But as we want other applications to be installed within the same vhost, we will add the location only for directories using drupal.

Plesk integration
The plesk control panel works great as long as you keep the directory structure and security as it is provided by plesk. Therefore we need to merge the single code base and each vhost within the provided structure. The single code base will be installed as a normal vhost but limiting web access to the domain. As such a backup of the single code base can be sheduled and FTP can be enable to upload new modules and themes. Each vhost will have his own local "sites" directory and will create its database trough the plesk interface.

Managed application
As the single code base resides as a single vhost, we can upgrade the code, add modules and themes into one location. To make upgrading easier we need to make sure that each vhost that uses drupal, references one single point independend of the drupal version. We will make subdirectories per drupal version in the single code base location and have one single reference that we can switch when going to a new version. Thus their will be a symbolic link called "drupal" pointing towards a drupal version "drupal-4.7.3" and each vhost that uses drupal will have symbolic links pointing towards the "drupal" symbolic link. When we change version, we only need to change the "drupal" symbolic link once and all vhosts will be adjusted accordingly.

eAccelerator
The eAccelerator speeds up the execution of the php script by precompiling them and putting them into memory. The dissadvantage is that you need to have the memory and the more you have the more php files can be kept for fast execution. Therefore we need to limit the number of php files on the server. By using the single code base, every vhosts uses the same files and thus memory usage can be limited and all php scripts run faster.

72

3 Aug 2007

Drupal Handbook

more on eAccelerator can be found here: http://eaccelerator.net

Each individual vhost requirements
as noted above in the "Plesk Integration" part, each vhost gets his own "sites" directory that enables them to add their own modules and themes. Also as natavely available by drupal, the multisites mechanism will work for the same reason. Using symbolic links and this "sites" directory will give the user the feeling that it is a full drupal install on their system. The local "sites" directory will allow the flexability required

Navigation
As the book seems to order the sub pages by date, I list here the order of further reading: Previous: Requirements: http://drupal.org/node/80472 Next: Prepare environment: http://drupal.org/node/90207

HOWTO: copy a site to a local computer using XAMPP
Here are the steps you need to take to get a copy of a Drupal website onto your local computer for development purposes, using the XAMPP stack and a variety of tools. Many of the steps taken here have been made so that you can keep your PHP files outside the standard htdocs DocumentRoot directory of the Apache server while maintaining whatever else you have running on your XAMPP installation. 1) Install XAMPP software. This gets you Apache, MySQL and PHP all set up in a few clicks. Skip this step if you have them already set up (Drupal needs things like php and mod_rewrite in your Apache build.) 2) Download a copy of your production ’drupal’ database to your local MySQL server. If your production server has phpMyAdmin you can export your database using it and then import using your local phpMyAdmin. You may also use a program like Navicat MySQL since it handles UTF-8 data properly (unfortunately my favorite free MySQL client, SQLyog, seems to lack proper UTF-8 support). 3) Create a user on your local mysql database to match the remote connection settings and give them full permissions: % mysql> GRANT ALL PRIVILEGES ON drupal.* TO ’drupaluser’@’localhost’ IDENTIFIED BY ’drupalpassword’ WITH GRANT OPTION; FLUSH PRIVILEGES; 4) Get a copy of the production Drupal site files and folders (In my case, I use a source control system client like Perforce) and copy them to a location you want to do your work in. An example: C:/p4/atlas-drupal/drupal. I will call this location %your_drupal_files% from here out.

73

Drupal Handbook

3 Aug 2007

5) Edit %your_drupal_files%/sites/default/settings.php and change the base URL to $base_url = ’http://localhost/drupal’; You should still be able to leave the $db_url connection setting alone. 6) Edit %your_xampp_location%\apache\conf\extra\httpd-xampp.conf and add the following lines according to where your copy of drupal lives on your computer: Alias /drupal "%your_drupal_files%/" <directory "%your_drupal_files%"> AllowOverride AuthConfig FileInfo Order allow,deny Allow from all </directory> You’ll need that "FileInfo" directive if you are getting 500 errors in your Apache error log like "RewriteEngine not allowed here". You could also add these lines in standard httpd.conf if you are not using XAMPP but just plain Apache. 7) (Skip this step if you are using regular Apache and not XAMPP) Edit %your_xampp_location%\apache\conf\httpd.conf and uncomment out the line LoadModule rewrite_module modules/mod_rewrite.so You need this so Drupal can have "clean links". 8) Edit %your_drupal_files%/.htaccess and change the RewriteBase to /drupal. 9) Restart the Apache service (with the XAMPP control panel if you are using XAMPP) You now should be able to navigate to your sandbox development copy of the site via http://localhost/drupal

HOWTO: Copy site to another directory for testing
System: Apache + PHP + MySQL + Linux I had my site at, say, example.com and wanted to set up beta.example.com as a duplicate site to test some ideas. This meant duplicating the database and code to a separate database and code tree. That way I could modify beta.example.com without harming example.com. In my case I’m on a virtual-private-server (same thing as a dedicated server) and have full control over the system. If you’re on a shared hosting account the steps will be different. Unfortunately the details of how share hosting accounts are setup vary so widely, I’m not going to try and generalize the instructions for that. 1. In the DNS, create the beta.example.com subdomain. Remember it can take a little while for the DNS entries to propogate properly. 2. Duplicate the database tables ... I’m on Mac OS X and used the navicat program to do so, but you should be able to use mysqldump or other similar programs. That is, create a new database and copy the tables and data from the example.com database to the one for

74

3 Aug 2007

Drupal Handbook

3.

4. 5. 6.

beta.example.com. Make a directory for the docroot of beta.example.com, and copy the files as so: (cd example.com/ROOT; tar cf - .) | (cd beta.example.com/ROOT; tar xvf -) If you only have FTP access this is a little harder. First FTP the files to your local computer, then FTP those files into the new docroot directory. You can also edit the files on your local computer, and then re-FTP them whenever you change something. Config apache’s httpd.conf for a second VirtualHost with beta.example.com in it. Make sure the VirtualHost entry for beta.example.com preceeds the one for example.com. Make sure the docroot for beta.example.com is a different directory. Edit sites/default/settings.php and change base_url and the database URL. $base_url = ’beta.example.com’; $db_url = ’mysql://username:password@localhost/new-database’; It’s also helpful to override the site name so that the heading on the site glaringly reminds you that you’re on the BETA site: $conf = array(’site_name’ => ’BETA this sites name’);

HOWTO: Install Drupal 5.x using cPanel
Many hosting providers use a control panel to shield users from the complexity of their servers. cPanel is one of those control panels. This small guide explains how to setup Drupal with CPanel. Not everything in this guide may be applicable to your situation, because some hosting providers limit the options available to their users. The basic assumptions: you have a domain name (http://www.example.com) and want to install Drupal at the document root, (usually public_html or htdocs), where it is reachable via the URL http://example.com or http://www.example.com. In order to accomplish this, the Drupal files such as .htaccess and index.php have to be placed into your server’s document root, along with the Drupal subdirectories such as includes, modules, themes, etc. Note that other files present may be overwritten. Make backups before installing Drupal and remove files that may interfere with installation (e.g. index.php or .htaccess). If the pre-existing .htaccess file is necessary for other parts of your site, merge it with the one provided with Drupal. If you have folders with names like admin/, image/, blog/, etc., these can conflict with Drupal and stop you from accessing areas of your Drupal site. If your version of CPanel comes with Fantastico, you can use it to easily install Drupal. However, this installation does not come with update.php, a file necessary for updating your database when newer versions of modules are uploaded into your site. Upload the Drupal files and folders

75

Drupal Handbook

3 Aug 2007

Download the newest version of Drupal. Upload this to your hosting space using an FTP Program or CPanel’s built in File Manager. Using the File Manager, extract the contents of the file: click on the file’s name and then select extract in the menu that pops up on the right. This will extract the entire archive into a folder named drupal-x.x.x. You will then need to move the files out of this directory and into your document root directory (such as www or public_html). You can also extract all the files and upload them this way; however, this takes much longer. Create a database 1. 2. 3. 4. 5. Open cPanel Go to MySQL Databases Choose a databasename* for the new database and press "Add Database" Choose a username* and password for the new database user and press "Add User" Grant permissions to the user; select the username and database name, check ’ALL’ and press ’Grant permissions’

*Note: cPanel usually adds the cPanel username as a prefix to the newly created names. Install Drupal Drupal 5.x now comes with an automated installer. You no longer have to manually load the database tables -- Drupal does it for you. Go to http://www.example.com/install.php Here you will be asked for the database name, database user, and password. If you need to use this database for more than one installation of Drupal (such as with hosting packages with a limited number of MySQL databases), you may want to click on the Advanced options and select a prefix for the tables you will be creating (such as "site_" or "main_"), This will then install Drupal for you, creating and filling all needed tables in your database. Once it is complete, you can go onto your site and set up the first user. Setting up your first user account The first user in your site (often referred to as user/1) is the "super user" on your site. It is automatically granted all admin and view permissions for your site. As such, it is important to immediately register on the site, which creates the first user.

76

3 Aug 2007

Drupal Handbook

After submitting your user name and e-mail, you’ll be given the option of changing the password for the account from the one the Drupal created for you. Cron tasks Many Drupal modules (such as the search functionality) have periodic tasks that must be triggered by a cron job. To activate these tasks, call the cron page by visiting http://www.example.com/cron.php -- this will pass control to the modules and the modules will decide if and what they must do. To call cron.php periodically you need to setup a cron job. cPanel offers a way to set cronjobs via Server » Cron jobs. Carefully read the instructions on the screen; they may differ from the following example. To run cron.php every day set the Minute and Hour fields to 0 and the rest of the fields to *. The command to run is: GET http://www.example.com/cron.php > /dev/null Additional modules Drupal comes with a limited number of modules. To expand the functionality of your Drupal site, you’ll need to download and add modules to your site. View the listing of modules and download the ones you want to use. Be careful to only download those that are for Drupal 5.x, as earlier modules will not work with your site. Also, be sure to read the description, as some modules require additional modules to be installed in order for them to work.

HOWTO: Install Drupal using cPanel
Many hosting providers use a control panel to shield users from the complexity of their servers. cPanel is one of those control panels. This small guide explains how to setup Drupal with CPanel. Not everything in this guide may be applicable to your situation, because some hosting providers limit the options available to their users. The basic assumptions: you have a domain name (http://www.example.com) and want to install Drupal at the document root, (usually public_html or htdocs), where it is reachable via the URL http://example.com or http://www.example.com. In order to accomplish this, the Drupal files such as .htaccess and index.php have to be placed into your server’s document root, along with the Drupal subdirectories such as includes, modules, themes, etc.

77

Drupal Handbook

3 Aug 2007

Note that other files present may be overwritten. Make backups before installing Drupal and remove files that may interfere with installation (e.g. index.php or .htaccess). If the pre-existing .htaccess file is necessary for other parts of your site, merge it with the one provided with Drupal. Upload the Drupal files and folders The first step is to download the drupal distritbution archive "drupal-x.x.x.tar.gz" onto your local computer, and then unpack it using a program such as 7zip, WinZip, WinRAR or tar. The second step is to upload the drupal files to your server. There are three options for uploading the files, two that use cPanel’s built-in File Manager, and one that uses an FTP-client. The latter depends on FTP access provided by your host. FTP (easiest) - After unpacking the drupal archive on your local computer, upload the files and folders in the resulting drupal-x.x.x directory to the document root of your webspace. cPanels built-in File Manager, option 1 - After unpacking the drupal archive on your local computer, recompress the files and folders in the resulting drupal-x.x.x directory into a zip file or into a new tar file. The result should be that the top-level directory "drupal-x.x.x" is no longer present in this archive. Upload this new archive to the document root on the server and extract its contents. The Drupal files and folders should now be located in the document root. cPanels built-in File Manager, option 2 - Upload the entire drupal distribution archive "drupal-x.x.x.tar.gz" to the document root of the server and extract its contents. Then use File Manager to move all the files and folders in the resulting drupal-x.x.x directory to the the server’s document root. Because you need some files from the drupal archive in a later stage, it’s a good idea to decompress it locally anyway. Create a database This step may not be necessary; some hosting firms provide only one pre-made database. Before you proceed you should know: "username" - the username for connecting to the database "password" - the password for that username "databasename" - the name of the database 1. 2. 3. 4. 5. Open cPanel Go to Server » MySQL Databases Choose a databasename* for the new database and press "Add Database" Choose a username* and password for the new database user and press "Add User" Grant permissions to the user; select the username and database name, check ’ALL’ and press ’Grant permissions’

78

3 Aug 2007

Drupal Handbook

*Note: cPanel usually adds the cPanel username as a prefix to the newly created names. Create database layout 1. 2. 3. 4. 5. Open phpmyadmin (Server » PhpMyadmin) Select the newly created database Depending on the phpmyadmin version select the tab SQL or import Choose the file database/database.mysql and press ’Go’ Alternatively copy-paste the contents of database/database.mysql in the query textfield and press ’Go’

Connecting Drupal The default configuration file can be found in sites/default/settings.php. Before you can run Drupal you have to set the database URL and the base URL to the website. $db_url = ’mysql://username:password@localhost/databasename’; Set the $base_url to match your websites URL: $base_url = ’http://www.example.com’; See INSTALL.txt for more information. Modify settings.php locally, then upload the modified file. Alternatively use cPanels text-editor to change the file on the server. Make sure to delete all trailing whitespace from settings.php when using the latter option or you will encounter the infamous ’headers already sent’ warnings. Create the first account Point your webbrowser to your site (http://www.example.com/) and follow the instructions on the welcome screen. Cron tasks Many Drupal modules (such as the search functionality) have periodic tasks that must be triggered by a cron job. To activate these tasks, call the cron page by visiting http://www.example.com/cron.php -- this will pass control to the modules and the modules will decide if and what they must do. To call cron.php periodically you need to setup a cron job. cPanel offers a way to set cronjobs via Server » Cron jobs. Carefully read the instructions on the screen; they may differ from the following example. To run cron.php every day set the Minute and Hour fields to 0 and the rest of the fields to *. The command to run is: GET http://www.example.com/cron.php > /dev/null

79

Drupal Handbook

3 Aug 2007

HOWTO: Site to site transfer with phpMyAdmin and a FTP Client
Preparation: 1) Turn OFF Clean URL’s function FTP Steps: (for downloading and uploading Drupal program files) Going to assume you have one and know how to use an FTP Client. FileZilla is free and popular. This is pretty easy stuff and you probably already know most of it. If you don’t know it. DO ânotâ recommend transferring site, as first lesson with FTP’ing. NOTE: Do not delete old site until you are 200% sure new site is ok. 1. Download all the Drupal program files from OLD site, to local Hard Drive, using FTP program. (Don’t worry about mySQL files yet) 2. 3. Be sure to get .htaccess too (it’s a Hidden File that can be found by checking the View Hidden Files Box on FTP Client. 4. 5. Edit settings.php and cron scripts to reflect new site. 6. 7. FTP files to new site phpMyAdmin Steps: (for mySQL export and import) We’re going to assume you know how to use phpMyAdmin for the basic stuff. This is pretty easy stuff and you probably already know most of it. If you don’t know it. I would ânotâ recommend transferring my site, as my first lesson with phpMyAdmin NOTE: Do not delete old site until you are 200% sure new site is ok. Export: 1. Find database in phpMyAdmin 2. 3. Click the Export Tab (we’re going to do a dump of data to local hard drive) 4. 5. In the âExportâ box â check âselect allâ and be sure the radio button is checked for SQL 6.

80

3 Aug 2007

Drupal Handbook

7. Check the âStructureâ and âDataâ boxes 8. (this ensures that both the structure of the database and the tables, and the content you have on site - is with you!) Check âdrop tableâ (so that if the new site is installed already, you can install database on top of that. "drop table" simply ensures that if the table exists - it will be replaced by the one you backed up.)

Check âcomplete insertsâ ( to make sure it does not miss anything when rebuilding the site )

Check âSendâ box (this makes the data go to a file instead of the screen)

You can modify the File Name if you wish. (don’t recommend deleting anything that might be in the file name box already â just add something to it. I usually add MonthDay â Mar09)

You can check âcompressionâ if you so desire.

Click the âGOâ button and you will soon see a pop-up asking you where to save file. Importing: (with phpMyAdmin) 1. Find NEW database with phpMyAdmin 2. 3. Click the tab SQL (just like when you are adding a module) 4. 5. Go to the âOr Location of the text file:â (just like you would for adding a module) 6. 7. âBrowseâ to local hard drive and find file. 8. 9. Click âGOâ

81

Drupal Handbook

3 Aug 2007

10. 11. It’s going to take a few minutes for everything to come over. Final process: 1. Check new site and I do mean check everything, until you’re bored 2. 3. Since I usually do this stuff at night. I check everything that night and then I check once more in the morning. !Checking data is a lot faster than repairing or re-entering data :-) 4. 5. Turn Clean URL’s back on Problems you might encounter with phpMyAdmin 1. phpMyAdmin has some limitations on the size of file that can be transferred. My Host has it set to 10Mb, others might be lower or higher limits. If file is bigger than limits you have to make some choices. 2. You can save the file as âcompressedâ (but you might time out on the upload) 3. You can âEmptyâ (NOT DROP) a few of tables. Below are some the tables you might want to think about cleaning up before you make data dump. (Not in any order.) a. Aggregator Items (the data from news feeds) b. Accesslog c. Cache d. Watchdog e. Search_Index with FTP (still working on this section) NOTES: 1. If you run cron make sure to change this also in /scripts/cron-lynx.sh - so it points to cron at new site.

Import a MySQL data dump with BigDump
What is BigDump?
Importing large SQL dumps (when replicating or moving a database) can be difficult for those with only web access to the MySQL server. phpMyAdmin has certain shortcomings when importing files of more than a modest size. BigDump can be a helpful utility in such cases. From the BigDump website:

82

3 Aug 2007

Drupal Handbook

Staggered import of large and very large MySQL Dumps (like phpMyAdmin 2.x Dumps) even through the web-servers with hard runtime limit and those in safe mode. The script executes only a small part of the huge dump and restarts itself. The next session starts where the last was stopped.

Setting up BigDump
Download BigDump from http://www.ozerov.de/bigdump.php. Once downloaded you need to open the file bigdump.php in any simple text editor (or php editor) to modify the variables required for your server and database. Commencing at line 78 with "// Database configuration" you need to setup the usual variables to connect to your database (same as are required for Drupal). There is one extra piece of information which the script needs to work well and that is the name of the sql file to be used to setup the database. Tip: Make sure you upload the file containing the SQL export of your database and bigdump.php to the same directory (root is best) on your webserver. <?php // Database configuration $db_server = "localhost"; $db_name = "your_DB_name"; $db_username = "your_DB_user_name"; $db_password = "your_DB_password"; // Other Settings // Specify the dump filename to suppress the file selection dialog $filename = "the_file_you_wish_to_execute"; // Lines to be executed per one import session $linespersession = 3000; // You can specify a sleep time in milliseconds after each session // Works only if JavaScript is activated. Use to reduce server overrun $delaypersession = 0; ?> Save the file once you have set the above (best in the same folder as your sql file backup).

Uploading the sql file and bigdump.php to the webserver
Open your FTP program and open a new session connecting to your webserver root directory and the folder where the sql file and prepared bigdump.php reside on your computer. Upload both files in ASC11 mode to the webserver root directory.

83

Drupal Handbook

3 Aug 2007

Running BigDump
Once the files are uploaded you simply need to connect to the bigdump.php script by using the URL http://www.your_domain.com/bigdump.php If successfully connected bigdump will greet you with a screen like the below. BigDump: Staggered MySQL Dump Importer ver. 0.21b <a>Start Import</a> from "the_file_you_wish_to_execute.sql" "your_DB_name" at "localhost" © 2003-2005 Alexey Ozerov - BigDump Home into

If it all looks good (ie: all the relavent names are correct) then click "Start Import" and the database will be setup by running in short automated stages to prevent server timeouts. At the completion BigDump will notify you that it is finished. That’s it! You have now copied, moved, migrated, synchronized or duplicated your mySQL database. Well Done! Thanks go to markus_petrux for the original tip about BigDump

Installing Drupal behind an Actiontec GT701-WG router
The popular Actiontec GT701-WG (and possibly other routers) DSL modem/router has a peculiar behavior that affects how base_url must be set up in sites/default/settings.php. The solution is to replace the PHP code that sets base_url with some code that is available below. Here’s the scenario: you are using computer A to access and use your Drupal site, computer B is the server that is hosting the Drupal site, and both computers are plugged into a GT701 router, which in turn is linked to the Internet. Internet users can access your server from the outside by typing in www.example.com (because you set up port forwarding on the GT701). However, the GT701 will not allow you to type that address in from computer A, because the GT701 interprets such an action as a request to view the GT701’a administrative interface. Instead, you must type in the local network IP address (usually 192.168.0.xxx) of computer B to access and use your Drupal site. However, this causes a problem because base_url is used by Drupal to create all the site’s links. If base_url is set for www.example.com, you will be unable to use the site from computer A (even if you type in the local IP). If base_url is set for the local network IP address, Internet users will not be able to use the site. In other words, base_url has to be different for internal network users (computer A) and Internet users. To do this, replace the line $base_url = "http://www.example.com"; with the following PHP code:

84

3 Aug 2007

Drupal Handbook

<?php $ipaddress = getenv(REMOTE_ADDR); $local= strpos($ipaddress, ’192.168.’); if ( $local=== false ) { $base_url = "http://www.yourdomain.com"; } else { $base_url = "local network IP address"; } ?> Here, replace www.example.com with the actual URL and local network IP address with the proper IP address (something like 192.168.xxx.xxx). It is possible that your local network IP addresses do not begin with 192.168; in that case, you would need to change the code to look for the local IP range accordingly. With this setup, you can access the Drupal site using computer A by typing in Computer B’s local IP address in your browser, while Internet users can continue to access it by typing in www.example.com

Installing Drupal in a subdirectory in 4.6
If you install Drupal in a subdirectory, you need to alter the .htaccess file in Drupal’s root. Change ErrorDocument to: # Customized server error messages: ErrorDocument 404 /subdirectory/index.php Change RewriteBase to: # Modify the RewriteBase if you are using Drupal in a subdirectory and the # rewrite rules are not working properly: RewriteBase /subdirectory Remove any #’s in front of the RewriteBase line in case it’s commented out. Make sure your $base_url in conf.php is set correctly as well.

More than one Drupal site on one machine
There are several possible configurations for running multiple Drupal servers on the same hardware. You can separate them by directories or by vhosts, they can share configurations or split them or, in some cases, have a mixture, but all of these methods have at their heart the ./sites/domain_or_host_name/settings.php configuration file and the search-sequence where the Drupal program will search first for a configuration named for the current page and then to the current host before settling for the default.

85

Drupal Handbook

3 Aug 2007

General rules for multiple Drupal deployments
Each of the possible multi-drupal scenarios is discussed in more detail in the sections that follow, but the general form for the alternate configuration filename is: ./sites/<i>vhost.uri</i>/settings.php Note how the path separator (’/’) must be changed to a dot. As an example, the vhost drupal.mysite.net may have one primary drupal server at the DOCUMENT_ROOT location, but a second site may begin at DOCUMENT_ROOT/altserver. For this case, the configuration file would be ./sites/drupal.mysite.net.altserver/settings.php Within that configuration file, the most common and minimal option is to set the $db_url that specifies the host, database and login for the Drupal tables, as well as the $base_url. But you can also include assignments to override anything in the VARIABLES table. This allows you to redefine the theme, the site footer and contact email, blocks per-page limits, even the name you use for anonymous. Drupal IDs: When using multiple drupal servers on the same hardware, each new configuration will result in a new host component for the username@<i>host</i> Drupal login ID (used when logging into a foreign Drupal server). For example, if you have a directory partitioned host at drupal.mysite.net/altserver your usename to login to some other Drupal server would be USENAME@drupal.mysite.net/altserver. Prefixing Database Tables to put them in One Database If you only have one database then it is necessary to use database table prefixing. See this handbook page for details on how to achieve that.

Moving your Drupal installation to a new directory
If for instance you need to move your installation from www.mysite.com/development/ to the root directory of www.mysite.com, just follow these simple steps: Copy Files Copy the files of your Drupal installation from the old directory to your new directory. Make sure you include .htaccess. Change Path In your new directory, open the file (4.5 or earlier) includes/conf.php or (4.6) sites/default/settings.php Look for a line that begins with "$base_url = ", update this so that $base_url equals the path to your new directory. Save the file and close it.

86

3 Aug 2007

Drupal Handbook

You might need to modify the .htaccess file as well. Update Cron If you set up Cron on your old installation, make sure you update it to point to your new installation. Delete Old Directory Test that everything is working in your new installation. If so, it is now safe to delete the files in your old Drupal directory.

PCRE_UTF8 solution for VPS servers | FreeBSD
installation PROBLEMS? - PCRE_UTF8 support on VPS server accounts? Look here! I receive the same error on every page with a basic install however everything seems to be functioning otherwise fine. warning: preg_match(): Compilation failed: this version of PCRE is not compiled with PCRE_UTF8 support at offset 0 in /home/brandform/www/drupal.brandform.net/includes/unicode.inc on line 32. The solution was much more difficult to find than i had hoped so maybe this post will be useful to some others as well. I had to uninstall the pcre package and reinstall the proper one with utf-8. heres the procedure: login to server via shell, on VPS2 accounts, # su root then type password basically you want to be root user. then type: # pkg_info which will show you the installed packages. type: # pkg_delete pcre-6.4 for me it was 6.4 but yours may be different. make sure to enter the proper version of pcre displayed in pkg_info. then you want to change to the directory where your ports collection is. on FreeBSD it is: /ports/devel/pcre-utf8 so type into your shell prompt: # cd / # cd ports/devel/pcre-utf8 # make

87

Drupal Handbook

3 Aug 2007

# make install # make clean then youll want to restart the apache server... something like this: # restart_apache thats it... fixed everything for me. after over a day of pulling my hair out and almost abandoning the effort......

Known causes of PCRE server errors
In the event that you see the following error: warning: preg_match: internal pcre_fullinfo() error -3 in /SERVER_PATH/includes/common.inc on line 592. Be aware that this issue exists at the server level, outside of Drupal code. Put plainly, the error means that the server’s PCRE (Perl Compatible Regular Expression) library is not configured correctly. This error may be caused any time a Drupal module calls a PCRE function. Typically, the error appears within common.inc, but this is not always the case. Depending on the server environment, there are several different causes (including a reported bug in some versions of PHP 5). This manual page is designed to capture known instances of this bug, Known Causes An upgrade of RedHat included a bad library and required a patch. (Details to follow) Recommendations Send the content of the error to your system admin and have them debug your PHP’s PCRE module.

Redirecting specific pages to new URLs (301 redirects in Drupal)
If you are porting over an existing website to Drupal, one consideration is how you redirect the old page URLs to the appropriate pages on the Drupal version of the site. If you don’t want to create custom rewrite paths within Drupal for those nodes -- or perhaps cannot due to clean URLs or filename suffixes -- then 301 redirects are considered the best way to handle redirected pages, for they inform search engines to update their databases with the new paths. This way, you should not risk your search engine pagerank or lose site visitors with 404 "not found" errors.

88

3 Aug 2007

Drupal Handbook

However, 301 redirects cannot be done using the common approach. Yet establishing 301 redirects is quite easy, provided you have mod_rewrite enabled in your .htaccess file.

How to create 301 redirects in Drupal Apache mod_rewrite
Edit your .htaccess file in a text editor. [Note: Be sure to save the file in "UTF-8" format.] In the file, you will find the commands: # Various rewrite rules. <IfModule mod_rewrite.c> RewriteEngine on # Modify the RewriteBase if you are using Drupal in a subdirectory and # the rewrite rules are not working properly. #RewriteBase /drupal RewriteBase / Immediately after that code -- and before the Drupal-provided "Rewrite old-style URLs" commands -- add your rewrite rules using the following format: #custom redirects RewriteRule ^old/URL/path$ http://yourdomain.com/new/path [R=301,L] #end custom redirects Note the convention: The old path is simply the path off the root. The new path is the full path, including the domain. The [R=301,L] code is the 301 redirect instruction. (axbom notes: "The 301 tells browsers and spiders it is a permanent redirect, and the L ensures that no other rewrites are processed on the URL before it reaches Drupal; Hence place this code above Drupal ’s own URL rewrite, but below the command RewriteEngine on.") If you have more paths to add, insert the rewrite commands as their own line as above. For more information, see the forum thread at http://drupal.org/node/16084 [from where I drew this information]

The tolerant base URL
Note: 4.7 already has this feature built in Instead of using a hard coded domain as your $base_url in the settings.php file, you might want to use <?php $base_url = ’http’ . (isset($_SERVER[’HTTPS’]) ? $_SERVER[’HTTPS’] == ’on’ ? ’s’ : ’’ : ’’); $base_url .= ’://’ .$_SERVER[’HTTP_HOST’]; if ($dir = trim(dirname($_SERVER[’SCRIPT_NAME’]), ’\,/’)) {

89

Drupal Handbook

3 Aug 2007

$base_url .= "/$dir"; } ?> This has the advantage that whatever domain the user used to get to the site, he will maintain throughout his session. Warning Email notifcations may be issued under the domain which is used by the poster. If you access your site using http://localhost, you could send emails with that invalid URL. The only module which behaves this way today that I know of is subscription.module from Contrib.

Using .htaccess to stop page caching
If your Drupal site is being accessed on a LAN with a proxy server to cache pages, you may find that user identities become confused. A user may login under their username, but when they access another page, the proxy server sends the cached page of another user, effectively switching the identities of the user as far as Drupal is concerned. Proxy servers can be instructed to stop caching pages for a Drupal site using HTML Meta Tags and/or HTTP Headers. While using meta tags may be more convenient (one need only modify the theme header), some proxy servers only respond to instructions embedeed in the HTTP headers sent by the webserver. Apache webservers can use mod_expires to send this instruction. Assuming that mod_expires is enabled on your web server, try adding the following lines to your .htaccess file to stop the proxy server from caching Drupal pages: ExpiresActive on ExpiresDefault "access plus 0 seconds"

Linux specific guidelines
Installing PHP, MySQL and Apache under Linux
Installing MySQL shouldn’t be too much of a burden, when using a Linux distribution that can handle RPMs. All you have to do is grab the RPMs from the MySQL website. Please do note that you’ll also need the MySQL client RPM, not only the MySQL server one. Once MySQL has been installed, download Apache and PHP, and unpack them in the same directory. To install Apache together with PHP and MySQL, follow the "quick install"-instructions in the INSTALL-file located in your PHP directory. When configuring PHP do not forget to replace ’apache_1.3.x’ with your version of Apache. After the compilation process you have to set the DocumentRoot in Apache’s httpd.conf to the path of your drupal-directory. Make sure your Apache is setup to allow .htaccess files so drupal can override Apache options from within the drupal directories. Therefore, set AllowOverride to "All" instead of "None". Somewhat down httpd.conf they ask you to set Directory to whatever

90

3 Aug 2007

Drupal Handbook

you set DocumentRoot to. The last thing to do is to add index.php in IfModule mod_dir.c behind DirectoryIndex. Apache will then look for index.php in the DocumentRoot and will display it as its main page.

XAMPP for Linux Packages
The distribution for Linux systems (tested for SuSE, RedHat, Mandrake and Debian) contains: Apache, MySQL, PHP & PEAR, Perl,ProFTPD, phpMyAdmin, OpenSSL, GD, Freetype2, libjpeg, libpng, gdbm, zlib, expat, Sablotron, libxml, Ming, Webalizer, pdf class, ncurses, mod_perl, FreeTDS, gettext, mcrypt, mhash, eAccelerator, SQLite and IMAP C-Client.

Installing XAMPP in Debian Download XAMPP Latest version from the following link
http://sourceforge.net/project/showfiles.php?group_id=61776&package_id=6... At the time of writing this article XAMPP version is 1.5.3a #wget http://kent.dl.sourceforge.net/sourceforge/xampp/xampp-linux-1.5.3a.tar.... Now you should be having xampp-linux-1.5.3a.tar.gz file in your downloaded location Go to a Linux shell and login as root: $su Extract the downloaded archive file to /opt #tar xvfz xampp-linux-1.5.3a.tar.gz -C /opt XAMPP is now installed below the /opt/lampp directory.

Start XAMPP Server
To start XAMPP simply call this command: #/opt/lampp/lampp start Starting XAMPP for Linux 1.5.3a... XAMPP: Starting Apache with SSL (and PHP5)... XAMPP: Starting MySQL... XAMPP: Starting ProFTPD... XAMPP for Linux started. Test Your XAMPP Installation

91

Drupal Handbook

3 Aug 2007

OK, that was easy but how can you check that everything really works? Just type in the following URL at your favourite web browser: http://localhost XAMPP Security Configuration As mentioned before, XAMPP is not meant for production use but only for developers in a development environment. The way XAMPP is configured is to be open as possible and allowing the developer anything he/she wants. For development environments this is great but in a production environment it could be fatal. Here a list of missing security in XAMPP: The MySQL administrator (root) has no password. The MySQL daemon is accessible via network. ProFTPD uses the password "lampp" for user "nobody". PhpMyAdmin is accessible via network. Examples are accessible via network. MySQL and Apache running under the same user (nobody). To fix most of the security weaknesses simply call the following command: #/opt/lampp/lampp security It starts a small security check and makes your XAMPP installation more secure. Start And Stop Server Services start Starts XAMPP. stop Stops XAMPP. restart Stops and starts XAMPP. startapache

92

3 Aug 2007

Drupal Handbook

Starts only the Apache. startssl Starts the Apache SSL support. This command activates the SSL support permanently, e.g. if you restarts XAMPP in the future SSL will stay activated. startmysql Starts only the MySQL database. startftp Starts the ProFTPD server. Via FTP you can upload files for your web server (user "nobody", password "lampp"). This command activates the ProFTPD permanently, e.g. if you restarts XAMPP in the future FTP will stay activated. stopapache Stops the Apache. stopssl Stops the Apache SSL support. This command deactivates the SSL support permanently, e.g. if you restarts XAMPP in the future SSL will stay deactivated. stopmysql Stops the MySQL database. stopftp Stops the ProFTPD server. This command deactivates the ProFTPD permanently, e.g. if you restarts XAMPP in the future FTP will stay deactivated. security Starts a small security check programm. For example: To start Apache with SSL support simply type in the following command (as root): #/opt/lampp/lampp startssl You can also access your Apache server via SSL under https://localhost. Important Configuration Files And Directories opt/lampp/bin/ - The XAMPP commands home. /opt/lampp/bin/mysql calls for example the MySQL monitor.

93

Drupal Handbook

3 Aug 2007

/opt/lampp/htdocs/ - The Apache DocumentRoot directory. /opt/lampp/etc/httpd.conf - The Apache configuration file. /opt/lampp/etc/my.cnf - The MySQL configuration file. /opt/lampp/etc/php.ini - The PHP configuration file. /opt/lampp/etc/proftpd.conf - The ProFTPD configuration file. (since 0.9.5) /opt/lampp/phpmyadmin/config.inc.php - The phpMyAdmin configuration file. If you want to confiure apache2 you have to use /opt/lampp/etc/httpd.conf(If you want to change Apache DocumentRoot directory you can chage in this file).If you want to configure namebased and ip based virtual hosts check here If you want to configure proftpd check here If you want to configure mysql check here Stopping XAMPP To stop XAMPP simply call this command: #/opt/lampp/lampp stop You should now see: Stopping LAMPP 1.5.3a... LAMPP: Stopping Apache... LAMPP: Stopping MySQL... LAMPP: Stopping ProFTPD... LAMPP stopped. And XAMPP for Linux is stopped. Uninstall XAMPP From your Machine To uninstall XAMPP just type in this command #rm -rf /opt/lampp

Windows-specific guidelines
Several packages exist which install Apache, PHP, and MySQL in one easy download. These include the following:

94

3 Aug 2007

Drupal Handbook

ApacheFriends XAMPP Miniserver Foxserv PHPHome If you want to install them separately, see the guidelines below.

How to install Drupal for newbies using FTP and phpMyAdmin
There are three things to do: upload the database, get drupal ready and change "/tmp" on your drupal site.

Change "/tmp" on your drupal site.
1. Open a browser and go to your new drupal site, whatever its domain is. 2. Create a new user account. You enter a username and password and now you are the admin for your new site. Important: the first user you create has access to every administration setting on your Drupal site. 3. On the left side of your screen, there is a link, "administer." Click "administer," then "settings." 4. Scroll down to "File system settings" and in the "Temporary directory" field you will see "/tmp." Remove the "/" from in front of "tmp." So now in "Temporary directory" the field should only contain "tmp." Click "Save configuration," at the bottom of the screen.

Get Drupal ready
1. Download Drupal 2. Extract Drupal to your desktop (or wherever you like on your computer). You need to have a program like 7-zip or Winzip installed first. You will have to extract the files twice. 3. Edit conf.php. It’s in the drupal-4.5.2/includes directory after you extract the files. You have to edit two lines in this file. 4. To edit the file, you may need to load your text editor (Windows comes with Notepad and Wordpad, either of which will do fine) first then find the file by clicking the File menu, then Open. 5. Change: $db_url = "mysql://user:password@localhost/drupal"; You must replace "user" and "password" with your username and password for your phpMyAdmin login and "drupal" with your database’s name. 6. Change: $base_url = "http://www.example.com"; You must replace "example.com" with your domain name. 7. Put drupal on your server. You need an FTP program like FileZilla. Open your FTP program and navigate to the directory where your index.htm file would normally go. This is usually called public_html/ or www/ This is where you put the drupal files. The drupal files that go there are the contents of drupal-4.5.2, that you extracted. You don’t put the folder itself on the server, just the contents. That

95

Drupal Handbook

3 Aug 2007

means you are uploading six folders (database, includes, etc.) and ten files (.htaaccess, cron.php, etc.). 8. Create a new directory on your server. In your FTP program, right click on the server side, select "create directory" and name the new directory "files." You want "files" in the main directory. After you create it, you should see it in between "database" and "includes." 9. Now you open up your new directory, "files," and create a new directory inside called, "tmp." 10. Change the file attributes of both "files" and "tmp" by right clicking on them one at a time, selecting "file attributes" and entering "755" in the "numeric value" field (if you see errors on your drupal site later saying "files" and "tmp" are not writeable you have to change the file attributes to "777," which is less secure).

Upload the database
1. Login to your phpMyAdmin (on your server). 2. Click "Create new database." 3. - name it "drupal" (or whatever you like). 4. You should see "drupal" at the top of the left column. Click "drupal." 5. In the center column you should see some tabs to choose from. Click "SQL." 6. At the bottom of the box that comes up it says, "Location of the textfile:" and there’s a button that says, "Browse". Click "Browse" and navigate to the file "database.mysql." Its on your computer inside the folder you extracted, "drupal.4.5.2," inside the "database" folder. Select "database.mysql" and click "open."

HOWTO: Create an apache sandbox using Windows and Apache2Triad
One of the most useful and productive techniques for working with Drupal is to install it on your own computer. Having Drupal installed on your local computer allows you to rapidly prototype Drupal sites using any combination of contributed modules and themes, dry-run upgrade installations of Drupal without interrupting production sites, and perform any other Drupal task much more quickly by allowing you to work locally instead of remotely. This tutorial addresses a simple method of setting up a web server on your own computer that functions identically to many commercial web hosting services, however it is not intended as a tutorial for turning your computer into a web server or using it to host a site. This tutorial focuses on installing the web server software as a means of working on a copy or prototype Drupal site, i.e. the result is not part of the internet, and can’t be accessed from the internet. The advantage is that the software runs much faster on your own computer. While Drupal will work with Microsoft’s Internet Information Services (IIS), this tutorial will focus on a specific package, apache2triad, available for download from sourceforge.net. Though all that is needed to run Drupal is a web browser, apache, PHP4 (4.3.3) or higher and mySQL, apache2triad comes with a variety of other features that will not be covered in this tutorial.

96

3 Aug 2007

Drupal Handbook

Best of all, however, apache2triad requires no additional configuration in order to set up and install Drupal, making it an ideal choice for novice web site creators wishing to learn to set up and use a Drupal site with only very modest skills and almost no previous experience. Tools needed to complete this tutorial: A web browser. An archive program capable of extracting .tar and .gz files, such as 7-Zip. An FTP client like coreFTP (optional).

Before you begin
Apache2Triad comes in three different configurations; a legacy version for Windows 9x systems, and PHP4 and PHP5 versions for Windows XP. If you intend to work on a copy of Drupal that you plan to transfer to a production server provided by your web hosting service, you may wish to find out which versions of PHP and MySQL are installed. If your web hosting service is currently providing PHP/MySQL 4.x, you may wish to download the corresponding version of Apache2Triad, in order to avoid compatibility issues. If so, you may also wish to inquire your hosts’ timetable for upgrading PHP and MySQL since 4.x versions are no longer supported by their respective development teams. As of this writing, the following versions of Apache2Triad were available for download from Sourceforge: Edge (Apache2.2 PHP5 MySQL5) v1.5.4 95.8MB space required 348.7MB Stable (Apache2.0 PHP4 MySQL4) v1.4.4 75.3MB (somewhere between "edge" and "legacy") Legacy for Win9X (limited Apache2.0 PHP4 MySQL4) v1.2.3 48.0MB space required 200.3MB While each version of Apache2Triad shown has been tested with various versions of Drupal in recent years, this tutorial focuses on using the "edge" version as installed under Windows XP.

Installing Apache2Triad
1) Download the version of Apache2Triad that best suits your needs. 2) Double-click the icon from the file you downloaded. This opens a small configuration window to begin the Apache2Triad installation. Leave the default settings as they are and click the button labeled "next". 3) The next dialog window allows you to set the destination folder, which for most people will be "C:\apache2triad", but it works equally well installed wherever you like (provided there is room available, see space requirements above). It is recommended that Apache2Triad be installed at the "root level" of the drive chosen, for example, "C:\apache2triad" as opposed to "C:\Program Files\apache2triad\", as this will save you typing later on. 4) The next dialog asks you to set a password of no less than eight characters. It will be important to know this password as you will need it later on. Select an eight character password (ideally one easily remembered), write it down, then click the button labeled "next", then the button labeled "I Agree" on the following dialog to complete the license agreement and begin the installation. 5) After the files have been installed to the directory of your choice, a dialog will open that alerts you that post configuration is needed. Click the button labeled "OK" to continue. Several

97

Drupal Handbook

3 Aug 2007

windows will open and close as the installer automatically configures most options for you, eventually stopping at a CMD window asking you to type your password from step 4. Do so now and press the "enter" key; post-configuration will complete itself, and at last open a window requesting that you reboot, which is necessary to start apache, php and mysql as Windows services. Note that depending on how Windows is configured for your computer, you may notice that there is now a "user" account named apache2triad; ignore this and log on with your regular account.

Installing Drupal
1) Obtain a copy of Drupal 4.6x, 4.7.x or 5.0 (cvs) from drupal.org as well as any contributed modules or themes you wish to use. 2) Use your archive program to extract any files from step 1; note that because the files are stored in both .gz and .tar formats, it may be necessary to extract them twice. You may wish to create a directory named DrupalX, where ’X’ is the version of Drupal, and unarchive your files to this location in order to stay organized; by copying the files you wish to use instead of using the originals, it is safe to move the archived versions to the recycle bin if you like. 3) Browse to the location you installed Apache2Triad and open it’s folder, then look for the folder labeled "htdocs". This folder is where you will place your Drupal files in order to access them through apache and your web browser. You may wish to place a shortcut to htdocs on your desktop, or create a shortcut in a toolbar with bookmarks and other shortcuts to tools. See the Support and Help Center under the Start Menu for details about how to accomplish these tasks. 4) For purposes of this tutorial, Drupal was extracted to drupal-4.7.3 and drupal-cvs in order to illustrate their installation. Note that the installation procedure for Drupal 4.6.9 is identical to the one for Drupal 4.7.3. Note that in doing so, Drupal is being installed to a sub directory and follows installation procedure accordingly. If Drupal were to be installed at the "document root" level of the server, the files inside the drupal-x folder extracted themselves would be place in the htdocs folder inside the Apache2Triad installation. In this tutorial, the whole folder is placed in htdocs (for simpler organization) and this affects how Drupal will be configured in later steps. Note that you may also use the folder name of your choice, such as the sub directory used on your web hosting server, "sandbox" or anything else that makes sense for your project. Copy the folder you have created (or the files inside it to htdocs, if you want to install to the "document root") now. 5) Open your favorite web browser, select the text in the address bar and type: http://localhost/phpmyadmin/ This will load the PHPMyAdmin logon page, which will ask for a username and password; the username is "root" and the password is whatever you selected when Apache2Triad was installed. Enter these now. 6) This will load the PHPMyAdmin main page. At this stage of this tutorial, it is useful to provide a brief introduction to PHPMyAdmin, which is also discussed in the Drupal handbook

98

3 Aug 2007

Drupal Handbook

section How to install Drupal for newbies using FTP and phpMyAdmin. For intents and purposes, PHPMyAdmin is a tool used to create, backup and restore MySQL databases. Although it has considerably more sophisticated features, this tutorial focuses only on those needed to complete a given task. 7) Select a database name and type it into the text field labeled "create database", then click the button labeled "create". The next steps vary depending on whether 5.0 or 4.7.x or earlier is being installed. If you are installing 5.0 from scratch, you may skip the next step. For purposes of this tutorial, databases named drupal-4.7.3 and drupal-cvs were created (if creating multiple databases, click the ’home’ button to the left of the PHPMyAdmin page to return to the database creation page). Minimize your browser (we’ll come back to it, later) before moving on to the next step. 8) Open your htdocs folder and look for the folder labeled "sites" if you installed Drupal to your document root, or inside the Drupal folder you created earlier, if you are installing Drupal 4.7.x or earlier. Here it is necessary to open the settings.php file and specify the installation options described in the INSTALL.TXT file that came with Drupal. Note that if you require multiple Drupal installations to use the same copy of Drupal, you should modify the settings.php file according to your configuration requirements. For single-version Drupal sites, the settings.php file you’ll want to use is in the folder labeled "default". Right-click the settings.php file with your mouse, select "open with" from the context menu, and select "notepad" from the application list. Depending on how you have Drupal configured, your settings.php file entries will vary, however the entry: $db_url = ’mysql://root:password@localhost/drupal-4.7.3’ will use "root" in place of the username and the password you selected when installing Apache2Triad. Don’t forget to set the entry for $base_url if you did not install Drupal to document root to the folder name you installed Drupal to. For example: $base_url = ’http://localhost/drupal-4.7.3’; // NO trailing slash! IMPORTANT "localhost" must be substituted for "www.example.com" in order to work on your local machine. For those working on copies of Drupal that will be hosted on production servers, it is handy to keep two copies of your settings.php entries, one for local use and one for remote use. This way, you can switch between configurations just by commenting or uncommenting the appropriate lines, for example: # Remote setting: # $base_url = ’http://www.example.com/drupal-4.7.3’; // NO trailing slash! # Local setting: $base_url = ’http://localhost/drupal-4.7.3’; // NO trailing slash! Once your settings.php file’s entries are correct, restore your browser window and locate the PHPMyAdmin page tab labeled "import" and click the button labeled "browse". For Drupal 4.7.x and earlier, the database that will be imported will be in the database folder, which will be in htdocs under the Apache2Triad installation you created earlier. Browse to that folder and select the appropriate sql file: database.mysql for Drupal 4.6.x, database.4.0.mysql for Drupal 4.7.x and

99

Drupal Handbook

3 Aug 2007

MySQL4 (Apache2Triad "stable" installation), and database.4.1.mysql for PHP5. Note that it is a good practice not to mix MySQL 4 and MySQL 5 databases in order to avoid potential compatibility conflicts. Click the "Go" button on the MySQL database to import the database you’ve selected. 9) The next step will depend on where you installed Drupal in your htdocs folder. Select the text of your address bar in your web browser and type: http://localhost/drupal-cvs/ substituting "drupal-cvs" for the folder name you used in htdocs or omitting it if you installed to document root. If you are installing Drupal 5.x, this will open the Database configuration page for your new site, which will prompt you for a database name (the one you created with PHPMyAdmin earlier), a username (root) and a password (the one you created when you installed Apache2Triad). Enter these now: if your Drupal installation uses a database prefix, select the advanced option and enter the prefix at this time. Select the appropriate radio button, depending on if you are installing the MySQL or PGSQL version of the database (most likely MySQL). Click the "save configuration" button and your installation is complete. You will be taken to the welcome screen where you will create the first user logon for your new site. Drupal 4.7.x users will be taken directly to the welcome page to create the first user logon directly.

Importing and exporting Drupal databases updated with PHPMyAdmin
There are certain circumstances when you may wish to work on a site that is a copy of one running on a production server, backup the database, and perform other tasks specific to making changes to your databases. This section of the tutorial focuses on using PHPMyAdmin to do so. If PHPMyAdmin is not available on your hosting provider’s server for you to use, you may be able to install it yourself if it is unavailable; check with your hosting service to find out what your options are if you are unsure. Because any possible task is going to entail some permutation of exporting, copying and/or importing databases from one a remote server to your personal computer, this section of our tutorial focuses on two basic operations within PHPMyAdmin that have tabs labeled accordingly; "import" and "export".

To export a database with PHPMyAdmin
1) Using your web browser, browse to the PHPMyAdmin location of the server where the database you wish to export resides. For example: http://www.example.com/phpmyadmin/ for a remote database and http://localhost/phpmyadmin/ for a database hosted on your Apache2Triad installation. Select the name of the database you wish to export from the combo box on the left side of the page and you will be taken to that database’s main operations page. Next, click the tab labeled "Export" and you will be taken to the Export database page. 2) Fill out the sections of the form located on the Export database page as follows:

100

3 Aug 2007

Drupal Handbook

a) Click the link marked "select all" in the group labeled "Export" to select all of the tables in the database for export. The radio button selected below should be "SQL". b) Select the check box labeled "add DROP TABLE" in the group labeled "Structure". The check boxes labeled "Add AUTO_INCREMENT value" and "Enclose table and field names with backquotes" should be selected as well as the checkbox next to "Structure", leave them as they are if already selected or set if needed. IMPORTANT Selecting "add DROP TABLE" means that if the copy of the database created is later imported to another Drupal installation, the tables in the imported copy will overwrite them if they exist in the target database. You should be careful to keep track of your databases, and make sure you only import and export the correct databases for your task. c) Under the group labeled "Data" select the check box marked "Complete inserts". The checkbox labeled "Use hexadecimal for binary fields" may be selected (select it if not) and the combo box labeled "Export type:" should be set to "INSERT" (select if needed). d) Put a check in the box in the "Save as file" group, then type a name for the database and click the button labeled "Go". Note if a radio button other than "None" is enabled in the group "compression". Uncompressed databases may be larger, but are sometimes easier to work with. e) Select a location to save your database to (preferably something easy to remember, like the database folder of your Drupal installation in htdocs, for example).

To import a database with PHPMyAdmin
1) Using your web browser, browse to the PHPMyAdmin location of the server where the database you wish to import resides. For example: http://www.example.com/phpmyadmin/ for a remote database and http://localhost/phpmyadmin/ for a database hosted on your Apache2Triad installation. Here you will either need to select an existing database name in the combo box on the left side of the PHPMyAdmin page, or create a new one. Note that if you are setting up a database on a remotely hosted site, your host may have prohibitions on the creation of MySQL databases that require they be created outside of PHPMyAdmin by means of a control panel or other mechanism; check with your web hosting service for specific details of their requirements. 2) One you have selected or created the appropriate database name, select the tab labeled "Import" on the PHPMyAdmin page to be taken to the import page. 3) Find the control group in the Import page form labeled "Location of the text file" and click the button labeled "Browse", following the resulting dialogs to select the database file of your choice. IMPORTANT If you are importing a database that you exported using the instructions in this tutorial, remember, the tables of the imported database will overwrite any that exist in the database you are importing to, overwriting them. Therefore it is important to double-check that the database you are selecting and the target you are importing to are correct before proceeding. If uncertain, you should back up the target database before importing a new one into it.

101

Drupal Handbook

3 Aug 2007

4) Click the button labeled "Go" to import your new database.

Using bigdump.php to deal with large databases
While bigdump.php is not included with Apache2Triad, it is a useful tool that greatly simplified working with large databases and Drupal. Used correctly, it can greatly speed importing large databases under Apache2Triad, and will also assist in importing large databases hosted on remote servers where restrictions are placed on the size of databases that may be imported. This is done by breaking up one big import operation into several small ones, reducing load on the computer and avoiding import file size limitations. 1) Download a copy of bigdump.php, unzip the file, and open the file "bigdump.php" by right clicking it with your mouse, selecting "Open with" from the context menu and then "Notepad" from the list of applications. 2) Find the following section of the file: // Database configuration $db_server = ’localhost’; $db_name = ’drupal’; $db_username = ’root’; $db_password = ’password’; The entries should be as shown above, substituting the correct values depending on where the database that is to be imported is located. Close this file and save a copy of it to your desktop or somewhere it will be easily remembered. 3) If you are using bigdump to import a database into your Apache2Triad installation, you should place a copy of the file you just edited in your htdocs folder along with a copy of the database you intend to support. If you are importing the database to a remotely hosted Drupal installation, you will need to transfer copies of the database and the bigdump.php file you edited to your server. 4) Open your web browser, select the text in the address bar, and type: http://localhost/path-to-my-drupal-folder/bigdump.php if you are importing to Apache2Triad and http://www.example.com/path-to-my-drupal-folder/bigdump.php 5) Bigdump.php should run unattended after it has run, and will inform you of it’s success when the database has been completely installed. 6) If you are importing to a remote database, you should delete the bigdump.php file for security purposes with your ftp program or other utility as suggested in the bigdump.php documentation, and you may wish to remove the old database at this time as well, to free up server space.

Installing Apache (with PHP) on Windows
As of this writing, the current version of Apache is 2.2.4 and PHP is 5.2.2.

102

3 Aug 2007

Drupal Handbook

1. Download the Apache Windows MSI Installer from Apache.org 2. Download the PHP Windows Zip Package from PHP.net. The first step to getting Drupal running on your Windows machine is to set up the Apache web server by running the Apache MSI installer. The following steps will walk you through the installation: 1. 2. 3. 4. 5. 6. Select Next Select "I accept the terms in the license agreement" Select Next Fill in your server information if it is known. A typical setup will use the "for All Users, on Port 80, as a Service" option. If this is being setup as a test machine, you may use localhost as the Network Domain and the Server Name. Select Next. Select the Typical Setup Choose a Destination Folder for the Installer to place the program files into. Note: the default Apache Installer location is C:\Program Files\Apache Software Foundation\Apache2.2. Because of the spaces in the directory name, using this folder may cause cgi and php scripts to not find the paths correctly. Select Finish If a Firewall is enabled, make sure that port 80 is unblocked and open. To test if the Apache server is running, open up http:\\localhost in a browser. A plain black and white page should come up that reads "It Works!"

7. 8. 9.

Configuring Apache: 1. Using a text editor such as Notepad, open the httpd.conf file. This file is found in the /conf sub-directory under the directory that was set up during installation. Alternatively, a shortcut may be found in the start menu under the Apache HTTP Server folder. 2. Note: Windows based systems uses backslashes \ and Unix based systems use slashes / for paths. In the Apache configuration files, slashes / should be used in path names. 3. Change the DocumentRoot to point to the location of the root document folder. In the default httpd.conf file, this is found on line 149 and if the defaults were used during the installation, it would point to "C:/Program Files/Apache Software Foundation/Apache2.2/htdocs". Note: Wrapping the path name in quotes will escape out any spaces that are used. 4. Change the Directory path to match the one used in the previous step. This is found on line 177 of the default httpd.conf file. 5. Add to index.php to the DirectoryIndex. This is found on line 212 of the default httpd.conf file. 6. Append the following lines to the end of the httpd.conf file: LoadModule php5_module "c:/php/php5apache2_2.dll" AddType application/x-httpd-php .php PHPIniDir "C:/php" 7. Save and Close

103

Drupal Handbook

3 Aug 2007

Installing PHP: 1. Unzip the PHP files to C:\php 2. Copy c:\php\php-ini-recommended.ini and rename itc:\php\php.ini 3. Uncomment the Windows include_path on line 506 Note: In the PHP.ini file, semicolons are used to denote that something is commented out. To uncomment a line, simply remove the semicolon. 4. Update the doc_rootto match the one that was set up in the httpd.conf file on line 513. Note: The PHP INI files uses the Windows style backslash \ for path names. 5. Update the extension_diron line 520 to "C:\php\ext" 6. Uncomment php_gd2.dll extension on line 637. 7. Uncomment mysql.dll extension on line 651. 8. Update the sessions.save_pathto the Windows temporary files directory (i.e. C:\Temp). 9. The PHP directory needs to be added to the Path Environment Variables 1. Open the Control Panel 2. Open System > Advanced > Environment Variables 3. Append ;C:\php to the end of the Path System Variables list and Click OK. 10. Restart Apache 11. To test PHP on Apache, go to the root directory (i.e. C:\Program Files\Apache Software Foundation\Apache2.2#92;htdocs) and create a new php file in it. In this file, use PHP’s phpinfo() function to see the server’s configuration information. For example: <html> <body> <?php phpinfo() ?> </body> </html> Open this file in a browser (i.e. http:\\localhost\filename.htm). Alternative Options: Bundled Packages Apache2Triad Apache Friends - XAMPP

Installing MySQL on Windows
1. After downloading the latest stable release version of MySQL, locate the setup.exe, and execute it. When prompted choose custom install. 2. Choose a path to install it. I recommend keeping to the default, which is c:\mysql. 3. Select all components, and continue until done. 4. Go to the MySQL folder, and start winmysqladmin.exe 5. Choose a username and password for yourself. 6. In the console, click on the my.ini tab, and choose "create shortcut in startmenu" option. 7. In the my.ini tab, also chck that all the configurable options are correct in accordance to your computer. 8. Close the admin console and restart it. If admin program runs with a green light, everything fine.

104

3 Aug 2007

Drupal Handbook

Installing PHP4 on Windows
After obtaining the latest stable release of PHP, extract the archive to c:\php or something similar. Copy php.ini-optimized to php.ini Make the following modifications: Change include_path to ’’.’’ Change sendmail_from to ’’your@email.address’’ Change SMTP to ’your.smtp.mail.service’ If you don’t know your smtp server, use the same configuration as your email client uses. Change session.save_path to a temporary folder (’’drive:pathtotemp’’) and make sure the temporary folder exists. Change doc_root to your preferred work folder (’’drive:pathtofiles’’). Make sure it exists and is the same folder your specified in the Apache setup procedure. Set register_globals to equal "On" Save the changes, and copy the php.ini file to your Windows directory. Create a basic php file, for example test.php which contains the following: <?PHP phpinfo(); ?> and save it in your work folder. Open your web browser, and type in: http://localhost/test.php. If you get the PHP information page, then everything is set up correctly. If not, just go over the settings again for PHP to make sure everything is ok.

Drupal 4.7 on Windows/IIS Requires PHP in ISAPI mode
When installing Drupal version 4.7 and later on Windows servers running IIS rather than Apache, PHP must be run in ISAPI rather than CGI mode. A relatively obscure bug in IIS discards PHP session information when the PHP script that sets the session also redirects to another page. In Drupal 4.7 and later, the user login screen automatically redirects to the home page on a successful login. The IIS bug is triggered, preventing the new session data from being sent to the user’s browser, and making it impossible for users to log in. As the bug only affects IIS when PHP is running in CGI mode, switching to ISAPI mode will solve the problem.

Installing PostgreSQL on Windows
Postgres is easily installed and administered on Windows. See PostgreSQL on Windows for the options you have.

105

Drupal Handbook

3 Aug 2007

As of this writing, the apparently easiest choice for PostgreSQL on Windows is "UltraSQL by PeerDirect" mentioned at above link. It is available from here. See the README file enclosed in the download and Installing the PeerDirect PostgreSQL beta for Windows for more instructions. After completing installation, the username for your DB is your windows login name and there is no password. You might want to install phpPgSQL in order to admin your database. It will save you frustation at the command line. A more complete list of all known PostgreSQL GUI tools is available at PostgreSQL GUI’s Go ahead and create your database tables via phpPgSQL or via the command line as described here.

Multiple Drupal Sites under Windows
One troublesome area in Drupal-on-Apache/Windows is multiple Drupal sites. Nowhere is this documented as being possible to do using a single code base. The weakness is in the fact Drupal uses symbolic links to point to the directory where Drupal’s code resides. In Linux, this is easy by creating a symbolic link to Drupal’s root directory: \Drupal\Site1 -> \Drupal \Drupal\Site2 -> \Drupal In Windows, this isn’t that easy. Shortcuts in Windows are not usable except when browsing the file system. What not many people know, is that Windows DOES support symbolic links. What Windows doesn’t have is a built in capability to build symbolic links. That’s where a 3rd party utility is required. I use Junction by Sysinternals. Using the tool is similar to the ln command in Linux. c:\> junction.exe c:\drupal\Site c:\drupal Will make a link to c:\drupal from c:\drupal\site Using this, AND the directions located elsewhere on this site regarding the strutcure of the drupal\sites directories, you can make an attempt at getting multiple drupal sites running under Windows.

Running multiple sites on a local PC (localhost) from a single codebase, using Windows
Here’s how to get mutltiple sites working on localhost using Windows XP. This should work with Drupal 4.6.x and assumes that you have PHP, Apache, MySQL, phpMyAdmin and Drupal all installed and working. There are four stages to go through, but it’s not difficult: 1. Set up your databases, one for each website 2. Set up each website in Drupal 3. Edit the virtual host settings in Apache 4. Update the Windows hosts file

106

3 Aug 2007

Drupal Handbook

In the following example we will add a local site"http://testsite1" in addition to the default site. We’ll assume Drupal is installed in c:/www (and that your web root is set to c:/www in the apache confic file). Databases ========= Firstly we will set up a new database for ’testsite1’ 1. Open your phpMyAdmin page 2. Type a name for your database in the ’create database’ textbox (’testsite1’ is as good as anything) then click the create button. You should get a message to say your database is created. 3. Next we need to add the necessary tables. Click the ’sql’ tab, then use the browse option to navigate to the ’includes’ folder of your Drupal installation, e.g. c:/www/drupal-4.6.3/includes. Select the file ’database.mysql.inc’ then ’go’. 4. phpMyAdmin will run the script and install the necessary tables. Drupal ====== 1. Make a copy of the folder /sites/default and call it /sites/testsite1. i.e. you should now have two folders in your sites folder, default and testsite1. 2. Open file sites/testsite1/settings.php using notepad. Edit the $db_url line to match the database defined in the previous steps: $db_url = "mysql://username:password@localhost/database"; where ’username’, ’password’, ’localhost’ and ’database’ are the username, password, host and database name for your set up. 3. Set $base_url to match the address to your Drupal site: $base_url = "http://testsite1"; 4. Save the file. Apache ====== 1. Open the apache config file ’http.conf’ (it’s in the apache/conf folder in Apache 1. I think it has moved somewhere else in Apache2) 2. Scroll to the end of the file, where you will find the virtual hosting setup. Assuming your websites are all located in the folder c:/www then add the following lines (edit the paths as necessary)

107

Drupal Handbook

3 Aug 2007

NameVirtualHost 127.0.0.1:80 <VirtualHost 127.0.0.1:80> DocumentRoot "C:/www/" ServerName localhost </VirtualHost> <VirtualHost testsite1> DocumentRoot "C:/www/Drupal-4.6.3" ServerName testsite1 </VirtualHost> There are lots of other things you can add into your VHost settings - see the Apache documentation. Windows ======= We now need to tell Windows that the domain ’testsite1’ is hosted locally, i.e. not to look on the Internet for it. Open the ’hosts’ file with notepad. It can usually be found in c:/windows/system32/drivers/etc Edit the end of the file to read: 127.0.0.1 localhost 127.0.0.1 testsite1 Save the file. Apache, again ========= OK, that’s (almost) it. All that is left is to restart the Apache webserver. You could reboot your computer but a better way is to open a command prompt window (a DOS window as we used to call it) and type ’net stop apache’. When the service has stopped, restart it using ’net start apache’ Now when you open your favourite browser and enter ’http://testsite1’ you should see your shiny new Drupal site, just waiting to be customised. You can add as many sites as you need by following the process above.

Untar
When you download Drupal packages you will need to decompress the files. Drupal packages are double compressed ’tar’ and ’gz’. To untar packages in Windows several programs are recommended.

108

3 Aug 2007

Drupal Handbook

7zip Winzip Winrar Winace

Installing Drupal on Windows
[this page used to contain verbose windows installation guidelines. they got removed because they were a) just a copy of the general installation guidelines, b) misleading ("start by extracting the archive to the PHP working folder"), and c) we don’t want to maintain redundant documentation. this page should only contain windows specific guidelines that differ significantly from the general guidelines. preferably, latter would be put so generally that we don’t need anything here (eg. don’t rely on "wget" and "tar" etc.)]

PostgreSQL specific guidelines
1. Create a PostgreSQL database for your site. createdb -U <i>username</i> -W <i>dbname</i>where username is the owner of the database (this user must have permission to create databases) and dbname is the name of your database. You will be prompted for that user’s password. On success, the following is displayed: CREATE DATABASE . The user must also have the correct PSQL Grant privileges to use the database correctly. 2. Once you have a proper database, dump the required tables into your database: psql -U username -W dbname < database/database.pgsqlYou will be prompted for your database password. You should see a progress report as the tables are created. All has gone well if there are no lines marked "Error:" printed to the screen. 3. Set the database options in includes/conf.php so Drupal can access the database you have created. Edit the following line in includes/conf.php: $db_url = "pgsql://username:password@hostname/dbname";

ERROR: DB connect failed
You may need to update pg_hba.conf file, to support access for loopback connections: host drupal drupal 127.0.0.1 255.255.255.255 password When getting this type of error, it may help to look into apache error log. Postgresql 7.3.4 does not enable tcp/ip sockets per default, so you have to either enable it by uncommenting: tcpip_socket = true port = 5432

109

Drupal Handbook

3 Aug 2007

in postgresql.conf, which may not be a good solution for security concerned people, or enable unix domain sockets: $db_url = "pgsql://admin:password@unix(/tmp)/drupal" /tmp works on a slackware 9.0 Linux 2.4.21, no commas needed.

ERROR: language "plpgsql" does not exist
If you get an error about plpgsql being an invalid language, you just need to install by running the following at the command line: createlang plpgsql drupal (substitute your database name for "drupal") Then go back and rerun the final part of the database.pgsql file - where the "greatest" function is created.

ERROR: null value in column "uid" violates not-null constraint
Try the following to fix: psql -U drupalDbOwner -d drupalDbName -ec "alter table sessions alter uid set default 0;"

PostgreSQL support in Drupal 4.7.x
The PostgreSQL support in Drupal 4.7.x has improved dramatically. This page lists remarks and points to remember when installing and using Drupal 4.7.x with PostgreSQL database. The installation instructions, specific for PostgreSQL, are in INSTALL.pgsql.txt file PL/pgSQL is no longer required for Drupal working You should not use schema as a $db_prefix. For example, use foo_, but not foo.. If you use schema prefix, you will run into errors when upgrading to the next stable release (e.g. from 4.7.x to 4.8.x). The errors are easy to fix, but it’s impossibile to support both foo_ and foo. type prefixes

Drupal 4.5 and PGSQL 8 configuration
The exact order of commands I used to get drupal working on PostgreSQL 8.0.0 beta[345]. Differences to the (excellent) supplied documentation: Create the db user first createdb -O instead of -U. This sets the owner of the new database to the user, but that user need not have create database permissions. Remember the createlang command as pointed out (thank goodness!) by another user

110

3 Aug 2007

Drupal Handbook

psql expects -U instead of -u. Use -f to load the file. 1) Create a new database user (I used "drupal"). As the postgres user: postgres$ createuser --pwprompt Enter name of user to add: drupal Enter password for new user: Enter it again: Shall the new user be allowed to create databases? (y/n) n Shall the new user be allowed to create more new users? (y/n) n 2) Create the new drupal database owned by the user created in 1) above As the postgres user: postgres$ createdb -O drupal drupal 3) Add the plpgsql language to the database As the postgres user: postgres$ createlang plpgsql drupal 4) Finally, read in the supplied database.pgsql file. As root postgres user: postgres$ psql -U drupal -d drupal -f database/database.pgsql 5) Set $db_url as mentioned in above documentation.

Installing contributed modules
Once you have the Drupal core files installed, you can begin adding third-party contributed modules to extend or alter Drupal’s behavior. The basic instructions are as follows: Download the module, extract the files, upload the resulting folder, and enable the module in administer > site building > modules (version 5.x) or administer > modules (version 4.7 or under). The detailed instructions are: 1. Download the module. Make sure the version of the module matches your version of Drupal. Note that modules labeled "CVS" are in a development stage. They may be written for a previous/current/future version of Drupal, and they are considered unstable and should be handled with care. 2. Extract the files. When you first get the module, it will appear in a compressed file format

111

Drupal Handbook

3 Aug 2007

such as ’tar.gz’. On Windows, use a program like WinZip to extract it. On the Mac, you can use Stuffit Expander. To extract the file using the Unix command line: tar -zxvf modulename-drupalversionnumber.tar.gz You should see a list of files extracted into a folder. 3. Upload the folder. FTP your files to the desired modules folder in your Drupal installation. Since the /modules/ folder is typically reserved for Drupal core modules, as of version 5.x you should create a sites/all/modules/ directory and put uploaded modules there. This will also make it easier to update your Drupal site later on. For version 4.7 and below, put contributed modules into /sites/example.com/modules/ (multi-site setup) or /sites/default/modules/ (single site setup) 4. Read the directions. If the module has an installation file (usually INSTALL.txt and/or README.txt), read it for specific instructions. There are modules that require special treatment, and even modules that depend on other downloaded files to function properly. Sometimes the readme filename has no .txt extension. When you try to double-click on it, your computer doesn’t know what program to use. In that case, open Notepad (or your favorite text editor) first, and then open the file using Notepad’s ’open’ command. 5. Enable the module. Version 5.x users go to administer > site building > modules while 4.7 or prior use administer > modules. Check the ’Enabled’ box next to the module and then click the ’Save Configuration’ button at the bottom. NOTE: If you’re upgrading an existing module you’ll need to browse to your update page at www.example.com/update.php and click on ’run the database upgrade script’. 4.6 USERS: As of 4.7, modules have an .install file so that any database tables which the module requires are created automatically when the module is enabled. If the new module doesn’t have one, look for modulename.mysql and/or modulename.pgsql. If you see those, the module isn’t using .install files yet, and you need to read step 6 of the 4.6 instructions. If there are none of those files, the module doesn’t affect the database. 6. Set file permissions. Some modules will require you change permissions or settings to get them working. Permissions and settings info may be in the instructions that came with the module. Usually, go to administer > users > access control. Scroll down to see if the module appears in the list and, if it does, give the appropriate permissions to roles. 7. Adjust settings. In 5.x, settings are with the module. In 4.7 and prior, go to administer > settings and see if the name of the module you just installed is in the list. If it is, click the module name and configure as appropriate. 8. If you run into problems, search the forums. If your problem hasn’t already been addressed, post a question and someonw will try to help you out. Note: To keep up-to-date on any issues and fixes related to your newly installed module(s), you can create a user account (if you haven’t done so all ready) and then subscribe to each module you are using. Note: You can have only one copy of a module with the same name in each Drupal site.

112

3 Aug 2007

Drupal Handbook

HOWTO: Install glossary module
I just finished installing the Glossary module in three Drupal 4.7x websites, so I thought I’d write out some basic steps here:

Where is the Glossary?
One of the first things to try to understand is that, although we will install a "Glossary Module", all the glossary content is actually entered and created in "Administer>Categories*" as entries in a Vocabulary. Although Taxonomy Vocabularies are quite powerful, and contain many other uses (many of which I don’t yet understand or I’m not yet aware of), this article only explains Vocabularies as they relate to the Glossary Module. The Glossary Module takes the Vocabulary entries and turns them into one or more Glossaries. Each time you create a new "Vocabulary", you are creating (the potential for) a new Glossary. (The Vocabulary terms are only turned into Glossaries when chosen in the "Administer>Input Formats" section.) (More about this later below.) *Note: Although the Glossary content is entered through "Administer>Categories>Vocabularies" , don’t get this confused with the optional, but different, Category Module, which adds it’s own "Administer>Categories" menu listing.

What is the purpose of the Glossary Module, and what does it do?
Creates Glossary Page(s), the Glossary Module creates a glossary page of all your terms, with the definitions. You may create one or multiple glossaries. Terms Identified:, on any page on your website, whenever you use any of the words in the glossary, those words will be identified on each page. You can choose whether the words will be identified by being underlined (with a broken line), or using a superscript letter (or word), such as the superscript letter "i", like this i (You can actually type in any letter or word that you want), or by using a small icon by the word. (You can also chose whatever icon you like)(see instructions below) Definitions Available on "Hover", whenever the visitor "hovers" the mouse pointer over any one of the identified terms, the definition will "pop up" in a small box for about 6 seconds. This way the definitions of all the words in your glossary will be readily available every time you use any of those words. Instantly Go to Glossary. If you click on the underlined word, or one of the identifiers (the superscript "i" or the small icon), you will immediately be taken to the full glossary page. Full Page Definitions, you can attach full page (or multiple pages) of descriptions to any, or all, of the glossary terms. (see instructions for this at the bottom). If you have attached any full pages to any glossary term, the pop up definition will still work, but when you click on the word, you will be taken to the full page descriptions instead of to the glossary page. If you have multiple pages attached to the glossary term, then you will be shown the teasers of all the definition pages. You can then choose to look at any of those pages.

113

Drupal Handbook

3 Aug 2007

Installing the Glossary Module
More detailed instructions (for some of the following steps) can be found in the Glossary Readme file. 1. First download the Glossary Module from http://drupal.org/project/glossary onto your computer.(Some website control panels allow you to upload an archived file; zip, tar, etc. and then unarchive it after the file is on your website in a folder. If this is the case, then just upload the Glossary Module tar or zip file to your website. Otherwise, unzip the file on your computer, then ftp the whole folder to you website folder.) Using either a ftp program, such as FileZilla, or from your website control panel: file manager, upload the folder/files to (mywebsite.com/drupal/modules)

Configuring the Glossary
1. On your Drupal website, go to "Administer>Modules" and enable the glossary module and save the new configuration. Go to Administer>Categories: Add one or more Vocabularies. You might give the vocabularies names that will encompass all your terms. For example, since I do upholstery, I might name one of my Vocabularies "Upholstery Terms" , then add some terms. Go to Administer>Input Formats: Choose one of the input formats, for example chose âFiltered HTMLâ, At the right side, under "Operations", click on âconfigureâ. This will take you to the "’Full HTML’ input format" page. Under the âViewâ tab (which is the default), under âFilters,â enable the "Glossary filter", At the bottom of the page, click âSave Configurationâ. After it is saved, you will be on the same page. Now, at the top of the page, click on the âconfigureâ tab. Click on âGlossary Filterâ which will open up some choices. In the âSelect Vocabularyâ box, click on the vocabulary term(s) that you created in Administer>Categories. Next, do you want all the terms of your glossary to show on one page? (This would be suitable for small glossaries) If not, click in the box by "Show glossary across many smaller pages" The next choice is "Match Type". I haven’t figured that one out yet, so I leave it alone on "Word". Chose whether you want your glossary terms to be case sensitive or insensitive. I usually chose case insensitive, since I want all the tems to show up, whether capitalized or not. Next, do you want all the terms on any given webpage to be identified as being in the glossary, or do you only want the first term on any page identified? Chose Replace Matches: "Only The First Match" or "All Matches". Under "Indicator Settings", you now make choise about how you want your terms identified on the website pages. Under "Term Indicator" Choose "superscript", "icon", or "replace with acronym link": Superscript:If you want a superscript letter (or word) by each word, like this i or this term Icon: A default icon is installed with Drupal. the icon will follow the term in place of the

114

3 Aug 2007

Drupal Handbook

superscript. If you want to choose a different icon, upload it somewhere on your website, such as your picture gallery, or a file, copy the URL to your chosen icon, and enter that URL into the Glossary Icon URL: text box. Underline: If you’d rather have all you terms underlined (only with a broken line), then choose "replace with acronym link" in the Term Indicator box. When you are finished with all of your choices, click on âsave configurationâ Glossary Administration: Finally, Choose which type of user(s) that you want to be able to administer the glossary, such as all "authenticated users" or only members in a "specific user role", or just the "administrator(s)". To make this choice, go to "Administer>Access Control>Permissions. Scroll down to "glossary module" and enable your chosen user role(s). Your Glossary Module should be working now. Go back to "Administer>Categories>Vocabularies" to enter your glossary/vocabulary terms. I would suggest that you keep your terms down to one brief paragraph. This paragraph will display all through the website whenever a user’s mouse pointer "hovers" over the indicated word; it will only display for about 6 seconds. Keep your paragraph down to about 6 seconds of comfortable reading. (Yes, a user can go back to the indicated word and get the definition to pop up again, but why should they have to? You can put more detailed definitions or explanations on other page(s), which can be connected to any glossary/vocabulary term(s).)

Adding Full Page Definitions
Do you want to allow any registered user to add full page definitions to the glossary, or do you want only specific persons to have this ability? This is controlled through the "Administration>Input Formats". If you want every authenticated user to be able to add full pages to the glossary, then you would enable the glossary with each of the input formats available to those users. However, if you only want specific users to have that abililty, Use or create an input format that only those users, or type of users, will be using. .............>>> More to be added here later <<< .................

Adding Glossary To Menus
This part (below) needs to be written better, more later. 1. To create additional glossary entries, go to Administer>Categories (as you did above) and enter more. (when your create Vocabulary (in Administer>Categories above), menu items and blocks are created for them, but not enabled.) If you want your Vocabulary to be on the website menu, go to Administer>Menus and enable them. If you want your Vocabulary to have its own menu block, go to Administer>Blocks and enable them. Stephen Winters Winters Sewing Winters Sewing: Upholstery Information Website

115

Drupal Handbook

3 Aug 2007

Kingwood Bible: Community Website

Leech - automating content addition
The Leech module is an amazing module that automagically adds content to your site. Once its set up it will read RSS feeds and "leech" the articles from the originating site and each article as a node on your drupal site. This is how you set up leech (4.7.x-1.6 as of 3/3/2007).: Enable the following 2 modules: 1. leech node_template (which comes with leech) next, according to modules/leech/README.txt you have to do the following: 1. create a story called "template story" and in the body of the story, put any place holder like "template node". Under publishing options disabled "Published" 2. After creating the story, you will find the node now has a new tab called "template". Click on that and then on the button named "create" 3. Next go to admin/settings/content-types and enable leech using the template created above. and save 4. The final and most important part of the leech puzzle is from http://drupal.org/node/116859. which says you have to create a PAGE for each RSS feed. When you create content/page you will now find there is a new option called leech. put in your rss feed’s url and wait for like 10 to 30 seconds. the advanced options will fill up with the data for your feed. Give your new leech feed a name and save. I don’t believe any body would want this new leech feed posted to their front page so uncheck that option from under publish. 5. once saved, there is still no data, depending on how often you set your leech module to check for updates (dependent on cron) you will either have to wait for the next cronjob or click on leech data now and VOILA! NEW STORIES! NB. its supposedly possible to use other node types and even CCK but i havent tried and the above is exactly what i need

Relationships between modules
This is a start to explain how similar or related modules are related and why you would use one vs another. Internationalization - Locale (core), i18n also known as Internationalization, and Translation

116

3 Aug 2007

Drupal Handbook

http://drupal.org/project/locale - provides multiple translations of strings generated by drupal - now part of the core code of drupal, critical if you want the site in something other than english http://drupal.org/project/i18n - provides a mechnanism to define multiple a single piece of content in multiple languages. - requires locale module - only use this if you want your site in English AND french http://drupal.org/node/12875 - translation module which allows for people to switch between node content in other languages - must require locale and i18n module - designed to make it easier to produce sites in both english AND french Module Comparisons - http://drupal.org/project/scheduler vs http://drupal.org/project/event (applied to nodes) - http://drupal.org/node/19813 vs taxonomy

Installing new modules (Drupal 4.6 or older)
After installing Drupal, you have the option of installing extra modules to extend or alter Drupal’s behavior. In brief. Download the module, extract, upload the folder into your Drupal modules folder, run the mysql file if necessary, and enable the module in administer » modules. 1. Download the new module. Make sure the version of the module is compatible with your version of Drupal. Also note that modules labeled CVS are considered unstable and should be handled with care. Often, CVS modules work only with the CVS version of Drupal. They may be in draft form, or be in the midst of active development. 2. Extract the module. When you first get the module, it will probably come in a compressed file format such as tar.gz. On Windows, use a program like WinZip to extract it. On the Mac, you can use Stuffit Expander. To extract the file using the Unix command line: tar -zxvf modulename-4.5.tar.gz You should see a list of files extracted in to a folder. 3. When you’ve extracted the file, upload the files via FTP to a folder inside the modules/ folder of your Drupal installation. 4. Read the installation file (usually INSTALL.txt and/or README.txt). Sometimes the installation file has no extension, so when you try to click on it, your computer doesn’t know what program to use. In that case, open Notepad (or your favorite text editor) first, and then open the file into it. 5. There are modules that modify the database. You can generally tell if there is a modulename.mysql and/or modulename.pgsql file included with the module. If you

117

Drupal Handbook

3 Aug 2007

do have to modify the database, see the next few steps. If you do not, please skip to step 7. 6. If you have to modify the database to get your module running, you will need to add tables to the database you made when you installed Drupal. Instructions given here are for MySQL. Using phpMyAdmin: If you have phpmyadmin, log in and go to your drupal database. If you have it, but do not know how to access it, please contact your host. Click on the tab that says ’SQL’ You should see a text area labeled ’Run SQL query/queries on database yourdrupaldatabase’. Underneath, it says ’Or Location of the textfile:’ Click browse, and find the modulename.mysql that came with the module. Click go. Unless your instructions for the module says anything else, that should be all you have to do to the database. Using the Unix command line: Run the following command. mysql -u username -ppassword database_name < modulename.mysql Replace ’username’ with your MySQL username, ’password’ (but keep the -p before it) with your MySQL password, ’database_name’ with the database Drupal uses, and ’modulename.mysql’ with the SQL file that the module comes with. You can generally find this out from settings.php in either the sites/default folder or the sites/sitedomain.com folder, replacing sitedomain.com for the domain that hosts Drupal.) 7. For most modules, all that is left is to activate it! To activate your module, you need to click administer » modules, check the box next to your new module name, and click on ’Save configuration’ at the end. 8. Some modules will require you change permissions or settings to get them working as you like them. Permissions and settings info may be in the instructions that came with the module. If not: 9. 1. Click administer » access control. Scroll down to see if the module appears in the list and, if it does, give the appropriate permissions to roles. 2. Click administer » settings and see if the name of the module you just installed is in the list. If it is, click the module name and configure as appropriate. 10. If you still run into the problems, search the forums. If your problem hasn’t already been addressed, post a new post. Note: To keep up to date on any issues and fixes you can create a user account (if you haven’t done so all ready) and subscribe to each module you are using. Note: You can have only one copy of a module with the same name in an Drupal installation.

Multi-site installation and set-up
Instructions on multi-site configuration (also known as "multisite" and "single code base" installations) can be found within the installation instructions.

118

3 Aug 2007

Drupal Handbook

Here are some useful links: Search results 4.6 Multi-Site from single code base Multi-Site .htaccess configuration multi-site, single installation, shared db, single sign on. is this possible? Automatic Multi-site registration Using Multi-Site Multihosting Off Single Codebase Multisite and symlinks doesn’t work Sharing tables between installations

10 Minute Multisite Install & Configuration
Multisite 10 minute Install: Server: LAMP SSH/Telenet Client: PuTTY Must have root access to your server. If website in question is an addon domain, i.e., addon.mydomain.tld, then substitute "www" for "addon" in steps below. For list of Linux commands http://www.ss64.com/bash/ Here we go: [login via PuTTY] Get to location where Drupal core will be located: [/]# cd /var/www Upload Drupal core: "x.x" should be replaced with the version of Drupal you’re installing, e.g. "5.1" [/var/www]# wget http://ftp.osuosl.org/pub/drupal/files/projects/drupal-x.x.tar.gz Unpack Drupal core: [/var/www]# tar -zxvf drupal-5.1.tar.gz Move contents of Drupal core (including .htaccess) to html: visit: http://www.oreillynet.com/linux/cmd/ or

119

Drupal Handbook

3 Aug 2007

[/var/www]# mv drupal-x.x/* drupal-x.x/.htaccess /var/www/html Clean-up: [/var/www]# rm drupal-x.x.tar.gz [/var/www]# rm drupal-5.1 Create the files directory per Drupal instructions and change permissions (will change permission again after install): [/var/www]# cd html [/var/www/html]# mkdir files [/var/www/html]# chmod 777 files Make directories that will hold custom and contributes modules and themes: [/var/www/html]# cd sites/all [/var/www/html/sites/all]# mkdir modules [/var/www/html/sites/all]# mkdir themes [/var/www/html/sites/all]# cd modules [/var/www/html/sites/all/modules]# mkdir custom [/var/www/html/sites/all/modules]# mkdir contrib [/var/www/html/sites/all/modules]# cd ../ [/var/www/html/sites/all]# cd themes [/var/www/html/sites/all/themes]# mkdir custom [/var/www/html/sites/all/themes]# mkdir contrib Create directory "www.mydomain.tld": [/var/www/html/sites/all/themes]# cd ../ [/var/www/html/sites/all]# cd ../ [/var/www/html/sites]# mkdir www.mydomain.com Change permission of "settings.php" per Drupal instructions and copy "settings.php" in default to www.mydomain.tld: [/var/www/html/sites]# cd default [/var/www/html/sites/default]# chmod 777 settings.php [/var/www/html/sites/default]# cd ../ [/var/www/html/sites]# cp -rp sites/default sites/www.mydomain.tld Create database and user with permissions: [/var/www/html/sites]# mysql mysql> CREATE DATABASE wwwmydomaintld_drupal; mysql> GRANT ALL PRIVILEGES ON wwwmydomaintld_drupal.* TO ’wwwmydomaintld_myusername’@’localhost’ IDENTIFIED BY ’mypassword’;

120

3 Aug 2007

Drupal Handbook

mysql> \q Go back to PuTTY to chmod on settings.php in www.mydomain.tld: [/var/www/html/sites]# cd www.mydomain.tld [/var/www/html/sites/www.mydomain.tld]# chmod 755 settings.php [/var/www/html/sites/www.mydomain.tld]# logout What next?: Make changes to "settings.php" in www.mydomain.tld? I’ve read that it’s not necessary to make changes to setting.php. Make changes to "httpd.conf" in /usr/local/apache/conf? I’ve been using WHM to create accounts, putting Drupal in public_html and having no problems. But when it comes to parting from the WHM abstraction and getting multisite set-up correctly this is the end of the proverbial road for me. Could use help...: 1. Help making improvements to steps articulated above 2. Help with next steps so that I/we can get on to grander things, like creating modules, custom themes, profiles, (and maybe - just maybe - spend some time working on business strategy :-)

Access all multisites with www. only [.htaccess]
The default .htaccess RewriteRule to redirect every multisite.com to www.multisite.com does not work properly. If you have problems with that too, just leave the two lines uncommented, and ADD THE FOLLOWING 3 LINES FOR EVERY MULTISITE you set up: RewriteCond %{HTTP_HOST} mysite\.com$ [NC] RewriteCond %{HTTP_HOST} !^www\. mysite\.com$ [NC] RewriteRule ^(.*)$ http://www.mysite.com/$1 [L,R=301] (Thanks to Florian!)

Drupal as a library
Short introduction on how to share drupal with all users on a shared server (without having troubles with file-permissions). Note: it is still possible to use the Multisite option of drupal.

121

Drupal Handbook

3 Aug 2007

example server’s file-structure: /path/to/phplibraries/drupal (chmod 644) /home/ user1/ (example.com) lib (symbolic link => /path/to/phplibraries/) public_html/ main/ files/ includes (symbolic link => /home/user1/lib/drupal/includes) misc (symbolic link => /home/user1/lib/drupal/misc) modules (symbolic link => /home/user1/lib/drupal/modules) profiles (symbolic link => /home/user1/lib/drupal/profiles) sites/ all (symbolic link => /home/user1/lib/drupal/sites/all) default (symbolic link => /home/user1/lib/drupal/sites/default) example.com/ settings.php themes (symbolic link => /home/user1/lib/drupal/themes) .htaccess (copy from drupal/.htaccess) cron.php (copy from drupal/cron.php) index.php (copy from drupal/index.php) install.php (copy from drupal/install.php) robots.txt (copy from drupal/robots.txt) update.php (copy from drupal/update.php) xmlrpc.php (copy from drupal/xmlrpc.php) .htaccess (1) user2/ (example2.com) (same as user1) user3/ (example3.com) (same as user1) etc... .htaccess (1) this isn’t neccessary but it keeps public_hml/ clean when several sites are maintained by one user. When only one site is maintained the contents of the main/ directory could be moved to public_html/ itself Options +FollowSymLinks DirectoryIndex index.php <IfModule mod_rewrite.c> RewriteEngine on

122

3 Aug 2007

Drupal Handbook

RewriteCond %{REQUEST_FILENAME} RewriteCond %{HTTP_HOST} RewriteRule ^(.*) </IfModule>

!-f ^example\.com$ [NC] main/$1 [L,QSA]

Multi-site setup in 5.x using CPanel
After some searching around, I found out how to do multi-site setup using CPanel. 1. Create your initial Drupal site at www.yourdomain.com. Drupal 5.x makes this very easy to do, as it will automatically install the database for you -- all you have to do is input the database information. 2. Create a folder in the sites/ folder that matches the subdomain you want to create (so for site1.yourdomain.com, the folder name would be site1.yourdomain.com). 3. Duplicate the settings.php file from the default folder and place it in your newly created folder from step 2. 4. Edit the settings.php file you just placed in the site1.yourdomain.com folder so that it points to the correct database. 5. In CPanel, set up the subdomain. For the above example of site1.yourdomain.com, a folder named site1 will be automatically created by CPanel. 6. Delete the folder that was created. 7. Use the following example to create and upload a php file onto your site. An easy way to do this is to use Notepad, pasting in the text below, editing as necessary, and then saving as multisite.php. Afterwards, upload via FTP or CPanel’s File Manager. <?php symlink( ’/home/username/public_html/’, ’site1’ ); ?> 8. Go to the location of the www.yourdomain.com/multisite.php) php file in your browser (such as

This will create a symlink, allowing your subdomain to work properly. 9. Go to your subdomain. Drupal will install the tables necessary to run the new site. 10. You’re all set to use the new site. If you run into any problems, or have questions, use the contact form attached to my user account here to contact me.

123

Drupal Handbook

3 Aug 2007

Multi-Site, Single Codebase, Shared Database, Shared Sign-on 4.6
I used this option, having a network of interrelated sites. While each site has its own domain, offers its own theme and own primary (homepage) content, the sites are essentially related and needed to share user registration accounts and forums. With a shared database, they also share information, e.g. the site which offers reviews can also display news headlines in a sidebar; the site which offers classified ads can offer reviews in a sidebar; etc. An unintended consequence of this approach is that savvy users can effectively navigate any and all content from any and all sites (once they understand breadcrumbs and drupal-specific navigation), so they get, essentially, whatever content they want in whatever theme they want.

Apache (http) Configuration
All domains will point to one document root. That cannot be emphasized enough. When using virtual hosting, do not create a separate virtual domain for each site -- only for the first site. When using a control panel such as cPanel or Ensim, create only the first domain. In the first domain’s alias area, list all the additional domains and subdomains to be used. Your virtual hosting entries should end up like this: ServerName www.firsthost.com ServerAlias firsthost.com ServerAlias secondhost.com www.secondhost.com ServerAlias thirdhost.com www.thirdhost.com forums.thirdhost.com etc... DocumentRoot /home/virtual/whatever/var/www/html etc... Any request for any of the domains will all run to /home/virtual/whatever/var/www/html for response. This is the desired result.

Download and Placement
The code base should sit in the DocumentRoot defined above. Download the tar ball for the latest stable version (4.6 as of this writing) and open it in the doc root. Note: all remaining commands assume you are sitting in your doc root, so go there. wget http://drupal.org/files/projects/drupal-x.x.x.tar.gz tar -zxvf drupal-x.x.x.tar.gz mv drupal-x.x.x/* . mv drupal-x.x.x/.htaccess . Check ownership and permissions - if you’ve downloaded directly, they’re likely to be very wrong. Security note of caution: I typically go through and change permissions to 444 (read-only) for all .php, .gif, .jpg and .css files. In drupal, that’ll also mean .module files. You’ll

124

3 Aug 2007

Drupal Handbook

have trouble editing these files, but that’s the point. It’s easier to change permissions temporarily on a file you want to hack than it is to fix a break-in. chown -R siteX:siteX . chmod -R 444 *.php *.gif *.jpg *.css *.tar *.module

SQL Setup
There are two ways to do this: on the command line and via a control panel. Some control panels (Ensim, for example) require that you create new databases through their interface (so they can limit a site to a set number of databases). If you can create new databases through the command line, do it like in the install file mysqladmin -u user -p create Name mysql -u user -p GRANT ALL PRIVILEGES ON Name.* ’password’; flush privileges;

TO

user@localhost

IDENTIFIED

BY

I substituted Name for ’drupal’ in the instructions -- really, name your database something other than ’drupal.’ Helps to prevent hacking if the attacker isn’t intimately familiar with the site configuration. Even if you call it mysite_drupal, that’s something. I also have no idea why the installation instructions suggest permissions for ’nobody,’ so I changed that to the database user. If you don’t have a database user setup for this site, setup an SQL user with its own unique password. phpMyAdmin makes it easy to do this. If you have to create databases via your control panel, open it and go to the SQL page. Create a new, empty database associated with the correct host and call it what you will (see notes above about calling it ’drupal.’ Most systems create a database user for each site; if yours doesn’t, create that user and give it permissions for the database you just created. Just because you have to create the database via the control panel doesn’t mean you have to fill it that way. You can now return to the command line and setup the database structure. mysql -u user -p Name < database/database.mysql chmod 000 database/database.* Technically, you’re done after the first line, but I like to lock up all setup files once I’m finished with them. This prevents someone else from trying to reset my system to hack in and prevents me from erasing my database in a fat-fingered typing accident.

125

Drupal Handbook

3 Aug 2007

Individual Site Configuration & Theming
Now, to the individual site information. Drupal will parse the http request and provide the correct content based on the domain name and settings files. You’ll need one directory for each domain name and one settings file for each. You can link aliases together. In the example below, Drupal will load this settings.php file for calls to http://firsthost.com and http://www.firsthost.com. mkdir sites/firsthost.com cp sites/default/settings.php sites/firsthost.com ln -s sites/firsthost.com sites/www.firsthost.com Now, edit sites/firsthost.com/settings.php and enter the following values (using the SQL values above for user, password and database Name). This allows the site to connect up to the database created above, and to create links to itself correctly. $db_url = ’mysql://user:password@localhost/Name; $base_url = ’http://firsthost.com’; (or www.firsthost.com depending on preference) And add the following lines (using site values). This overrides any theme or database settings to provide unique values for this site. Things you may want to override include the individual site’s name, slogan, and theme. Also, you can use site_frontpage to set a default module. In the case below, we’ve chosen ’node’ (generic stories) as the home page for this site. $conf = array( ’site_name’ => ’Name of the First Site’, ’site_slogan’ => ’My Original Drupal Site’, ’site_frontpage’ => ’node’, ’theme_default’ => ’pushbutton’, ’anonymous’ => ’Visitor’ ); Now, repeat from the ’mkdir’ command for each new site. Some things will remain the same. The configuration variables will change. In the example below, we’ve changed the homepage to the book module and the theme to bluemarine. When Drupal parses a request for this second site, it will present those options. $conf = array( ’site_name’ => ’Name of the Second Site’, ’site_slogan’ => ’The We Love Drupal Fan Site’, ’site_frontpage’ => ’book’, ’theme_default’ => ’bluemarine’, ’anonymous’ => ’Dude’ );

126

3 Aug 2007

Drupal Handbook

You have working multisites. Call up the first domain, setup your administrative user and run with it. Keep in mind that sites/default is the settings.php file which will be used if Drupal doesn’t recognize the http call, so you might want to set that one up to run with your default site ... or set it up to notify you if someone tries it.

Some things which can be improved:
- I have yet to try to use the FOAF module ( http://drupal.org/project/foaf ) to automate logins from one domain to the other. At the present time, users must login separately to each site, even though they use the same account info. - I don’t use the statistics module, so I can’t say what it does, but it can be difficult to get individual domain info out of the Apache logs. Unless you do some fancy configuration, you get one combined log. - Note that to use different databases (completely different Drupal sites) with the same code files, you can still follow the above instructions, creating a separate database and user for each one. Then, point each settings.php file to the appropriate database instead of pointing them all to the same one. Keywords: multisite multi-site multi site, multihost multi-host, host, sharing code, one codebase, site configuration, step by step

Multi-Site, Single Codebase, Shared Database, Shared Sign-on 5.x
This document is written with assumptions that you have: installed Drupal 5 before access to your server via ssh / telnet access to MySQL database / you can setup your own MySQL database In this example, I will setup two sites using: Drupal 5 One database on MySQL Linux-based server Also: Website’s url is: www.example.com Drupal is installed in: /var/www/drupal Names of sites are: âsite_1’ and âsite_2’ These sites will share session and user-related tables so once users login to one of the sites, they can view the other site without logging in. User roles and profiles are also shared among the two sites.

127

Drupal Handbook

3 Aug 2007

1. Prepare database and database user 1.1. create a database and user
In this example, I will use: DB name: drupal_db DB username: druser Password: twosites Access right: SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES

2. create and modify site configuration 2.1. duplicate settings folder
Duplicate a folder contains site config information under drupal/sites/ dru@/var/www/drupal/sites: cp âR default/ www.example.com.site_1 dru@/var/www/drupal/sites: cp âR default/ www.example.com.site_2

2.2. Modify config files 2.2.1. provide DB connection detail
Open settings.php in a folder under www.example.com/site_1. Go to line 93 (or somewhere around there) and you should find a line that goes: $db_url = ’mysql://username:password@localhost/databasename’; change this line with your DB name, DB user and password. It will look like: $db_url = ’mysql://druser:twosites@localhost/drupal_db’;

2.2.2. set prefixes for table names
just below the line we just changed above, there is a line that goes like: $db_prefix=’’; Since we want to share a database among two sites but not completely, we decide which tables to share / not to share. This can be done by adding prefixes to table names. An example given below is for sharing user-related tables, sequences (this table is a âcounter’ of users, nodes and other stuff) and session information. $db_prefix = array( ’default’ => ’site_1_’, ’users’ => ’shared_’, ’sessions’ => ’shared_’, ’role’ => ’shared_’, ’authmap’ => ’shared_’,

128

3 Aug 2007

Drupal Handbook

’sequences’ => ’shared_’, ’profile_fields’ => ’shared_’, ’profile_values’ => ’shared_’, ’users_roles’ => ’shared_’, ); the second line that goes: ’default’ => ’site_1_’, this means tables that are not shared with other sites will have a prefix âsite_1_’. So for example, table name ânode’ will be âsite_1_node’. Now, when you finish editing this file, open and edit drupal/sites/www.example.com.site_2/settings.php. This time, you enter the exact same information for the database connection. So the line around 93 should look like: $db_url = ’mysql://druser:twosites@localhost/drupal_db’; Then, you add an array of prefixes, which will look like: $db_prefix = array( ’default’ => ’site_2_’, ’users’ => ’shared_’, ’sessions’ => ’shared_’, ’role’ => ’shared_’, ’authmap’ => ’shared_’, ’sequences’ => ’shared_’, ’profile_fields’ => ’shared_’, ’profile_values’ => ’shared_’, ’users_roles’ => ’shared_’, ); notice a prefix in the second line is now âsite_2_’. At the installation, all tables will have this prefix except for the ones that are specifically given a prefix âshared_’.

3. create static links
In order to access site_1 and site_2 from web browser, you have to make static links to drupal directory. In the directory /var/www/drupal, enter the following commands: ln -s drupal site_1 ln -s drupal site_2 now access âwww.example.com/site_1’ (and âsite_2’). If you see a drupalicon and a message like âUnable to select database’, go back to 2.2.1 of this manual and check if you have all details correct, including a single-quotation and semicolon. If you see hundreds of messages like âWarning: Table ’continuu_test.access’ doesn’t exist’, you are almost there. While this may look scary or makes you think you have done something wrong, it is just saying that it cannot find tables Drupal needs to have access to. This is simply because we have not yet finished installing Drupal. All the necessary tables will be created in the

129

Drupal Handbook

3 Aug 2007

next step, which is described below.

4. install drupal
Since we have entered information for database connection, we can run the install script (install.php) straight away, instead of giving all the detail to installation wizard. From your web browser, just access: http://www.example.com/site_1/install.php http://www.example.com/site_2/install.php Installation should complete within a second (or two). If you fail to install: read the error message and find out what is wrong (wrong DB name, username or password, etc.) make sure $db_url (around line 93 in settings.php) ends with a quotation mark and semicolon. ( â; ) If you have two separate Drupal sites and are thinking about merging them with above method, I would recommend you not to do it. Yes, it is not impossible. You can rename tables and modify values in sequence table and so on, but i tried it and had a hell of a hard time... If you have sites already setup, using CAS or other authentication services is more appropriate than merging.

Multiple domains or vhosts using different databases
Apache supports both IP- and name-based virtual hosts (vhosts). While running more than one engine (by using vhosts) can be very useful for development and testing purpose, it might even be more interesting for hosting companies. Therefore, we tried to support vhosts in the best possible way in order to make the life of any administrator easier. We do so by making it possible to run an unlimited amount of vhosts on the same physical source tree, though by using different configuration files. Moreover, you can setup multiple configuration files in your includes-directory. $ ls -l sites/*/*.php -rw-rw-r-1 drupal drupal sites/www.example1.com/settings.php -rw-rw-r-1 drupal drupal sites/www.example2.com/settings.php The only thing left to be done is to setup the corresponding vhosts in your Apache configuration file. Note that the DocumentRoot points to the same source tree twice: NameVirtualHost 127.0.0.1 DocumentRoot /home/www/drupal ServerName www.example1.com DocumentRoot /home/www/drupal ServerName www.example2.com

130

3 Aug 2007

Drupal Handbook

Remember that as of Drupal 4.6, you can have site specific modules and themes as well. Just create a directory under the sites/www.example1.com called ’modules’ and place the site specific modules. The same applies to themes as well. Consult the INSTALL.txt that came with your Drupal installation for more details.

Sharing Drupal tables between databases using MySQL5 Views
Note: The more Drupalish way to achieve this is through advanced table prefixing. The docs are in this handbook. Problem: You’d like to share some data between two different drupal websites without changing any Drupal code or otherwise having to lift much of a finger. But you don’t want to share information unless it meets certain requirements (for example, only users labeled "foo" in somedatabase.sometable) For our example, we’ll use the users table. Solution: Use MySQL5 Views (http://dev.mysql.com/doc/refman/5.0/en/views.html) Our "master" users table resides in a database called "master". The database of the site that will have restricted access to our masters users table is called "banana". Assumming you’re starting with a fresh instance of the Drupal schema in your database "banana", do this: mysql> use banana; mysql> drop table users; mysql> CREATE VIEW users AS mysql> SELECT * mysql> FROM master.users mysql> WHERE uid IN ( mysql> SELECT uid mysql> FROM somedatabase.sometable mysql> WHERE uid = 0 mysql> OR label = ’foo’ mysql> ) Drupal will use banana.users just as it would a normal users table. No other modifications are necessary. Now only "foo" users will be included in the users table for your banana website. Note: Drupal has a dependency that is not really documented. Every users table must have an entry that contains uid=0. It’s a "stub" entry that Drupal needs to function properly. A workaround for this dependency is to include "user 0" in the results set that defines your view. See, wasn’t that easy?

131

Drupal Handbook

3 Aug 2007

Multiple domains using the same database
If you want to host multiple domains (or subdomains) on top of the same database (e.g. http://example.com/ and http://www.example.com/), simply use symbolic links to setup the required configuration files: $ ln -s sites/example.com sites/www.example.com $ ls -l sites -rw-rw-r-1 drupal drupal sites/example.com lrwxrwxrrx 1 drupal drupal sites/www.example.com sites/example.com

->

If your installation isn’t in the root folder then you need to specify the path to the Drupal installation. For example if the URL to your installation is http://www.example.com/drupal/ you would use sites/www.example.com.drupal with a settings.php file in it. If you want cookies to be shared between two sites, you will need to set the value of PHP’s session.cookie_domain correctly. In the case above, set it to ".example.com". You can do this through Drupal’s .htaccess file.

Same codebase, completely different content and users
This document assumes the following: You want to create more than one Drupal site using the same codebase (the same basic set of Drupal files, uploaded into one location). You know how to install mysql tables in your database. You know how to set up subdomains/folders/other domains that you want to use. You have already downloaded Drupal 4.7, and set up one MAIN site. This document contains instructions on how to create completely separate Drupal site, with different configurations, users and content. Nothing is shared between the installations except the codebase. Some definitions: codebase: the basic set of Drupal files, included in the .tar.gz file. the stuff that makes Drupal work. database: a collection of tables that stores data. Affected files: settings.php (sites/default/...)

132

3 Aug 2007

Drupal Handbook

database.mysql For this example, we will assume the following: www.example.com: the MAIN site, where the codebase has already been uploaded, and settings.php has been properly configured. sub1.example.com; www.example.com/sub2; www.subexample.com : the other sites we will create. 1. Create the following folders in your sites directory: sites/sub1.example.com/ sites/www.example.com.sub2/ sites/www.sub3example.com/ Copy the settings.php file from sites/default into each of the above folders. 2. There are different database files (inside the database folder). Select the one that is appropriate for your database version. Copy it to each of the folders you made in step 1. This is OPTIONAL, but it will help you keep things straight. 3. Decide on SEPARATE PREFIXES for each site. Below is what we will use for the example: site database prefix sub1.example.com sub1_ www.example.com,sub2 sub2_ www.sub3example.com sub3_ 4. Configure your settings.php for each site. This code MUST BE CHANGED FOR EACH SITE: $db_url = ’mysql://username:password@localhost/databasename’; Note; if you are using the same database as the MAIN site, the $db_url is the same.

133

Drupal Handbook

3 Aug 2007

OPTIONAL: # $base_url = ’http://www.example.com’; // NO trailing slash! # # # # # $conf = array( ’site_name’ => ’My Drupal site’, ’theme_default’ => ’pushbutton’, ’anonymous’ => ’Visitor’ );

For sub1.example.com, the settings would be: $db_prefix = ’sub1_’; $base_url = ’http://sub1.example.com’; $conf = array( ’site_name’ => ’My SUB1 Drupal Site’, ’theme_default’ => ’pushbutton’, ’anonymous’ => ’Visitor’ ); For www.example.com/sub2, the settings would be: $db_prefix = ’sub2_’; $base_url = ’http://www.example.com/sub2’; $conf = array( ’site_name’ => ’My SUB2 Drupal Site’, ’theme_default’ => ’fancy’, ’anonymous’ => ’Anonymous’ ); For www.sub3example.com, the settings would be: $db_prefix = ’sub3_’; $base_url = ’http://www.sub3example.com’; $conf = array( ’site_name’ => ’My SUB3 Drupal Site’, ’theme_default’ => ’marvin’, ’anonymous’ => ’Guests’ ); 6. Upload the modified settings.php files in their respective folders. 7. Open the database file you copied into each sites folder. Find the following (don’t forget the SPACE at the end!!!): CREATE TABLE INSERT INTO

134

3 Aug 2007

Drupal Handbook

Replace each ’create table’ and ’insert into’ with ’create table dbprefix_’ and ’insert into dbprefix_’ For sub1.example.com: CREATE TABLE >> CREATE TABLE sub1_ INSERT INTO >> INSERT INTO sub1_ 8. Upload the modified mysql files into the database you specified in your settings.php. 9. Voila!

Setup of /sites directory for multi-site
Drupal’s multi-site hosting capability is built in with any installation. This is great news for users who run numerous web sites from a single hosting account. A single Drupal installation can be used to run multiple domains, which makes it much easier to manage and maintain the code base. Even if you are dealing with only one domain, the multi-site capability may be valuable by providing the ability to run a separate domain or sub-domain for a development version. This page describes the set-up of the /sites directory for multi-sites. The single-site basics are discussed at Basic /sites directory setup. With version 5.x, the intended location for all non-core elements of a Drupal installation is in a separate /sites directory inside the Drupal installation. Directory /drupal/sites/all (used by all sites) Contents /modules /themes

/drupal/sites/default /files (used when there is no /sites/example.com directory) settings.php /files /module /themes /tmp settings.php /files /module /themes /tmp settings.php

/drupal/sites/example1.com

/drupal/sites/example2.com

135

Drupal Handbook

3 Aug 2007

The intended best practice configuration is to create a /sites/example.com directory for each domain. It should contain a site-specific settings.php file and /files directory. Configure Drupal site settings to specify ’File System Directory’ of ’sites/example.com/files’ instead of the default ’files’. It’s possible to do this with an existing web site, but moving file uploads around can cause a lot of confusion if there are already URLs pointing to the old locations. Domain specific modules and themes should also be placed in /sites/example.com/modules and /sites/example.com/themes respectively. Contributed modules and additional themes which are for use by all domains in a multi-site installation should be placed in /sites/all/modules and /sites/all/themes. Note that there shouldn’t be a /sites/all/files or /sites/all/settings.php. The /sites/default directory should contain /files and settings.php, for use if the /sites/example.com directory doesn’t exist for a domain. In addition to multiple sites, such as www.example1.com and www.example2.com, sub domains are also easily set up. Adding sub3.example2.com and sub3.example2.com/site4, the directory structure for these four sites would be: /drupal/sites/all/modules /drupal/sites/all/themes /drupal/sites/default/files /drupal/sites/default/settings.php /drupal/sites/example1.com/files /drupal/sites/example1.com/modules /drupal/sites/example1.com/settings.php /drupal/sites/example1.com/themes /drupal/sites/example1.com/tmp /drupal/sites/example2.com/files /drupal/sites/example2.com/modules /drupal/sites/example2.com/themes /drupal/sites/example2.com/tmp /drupal/sites/example2.com/settings.php /drupal/sites/sub3.example2.com/files /drupal/sites/sub3.example2.com/modules /drupal/sites/sub3.example2.com/settings.php /drupal/sites/sub3.example2.com/themes /drupal/sites/sub3.example2.com/tmp /drupal/sites/sub3.example2.com.site4/files /drupal/sites/sub3.example2.com.site4/modules /drupal/sites/sub3.example2.com.site4/settings.php /drupal/sites/sub3.example2.com.site4/themes /drupal/sites/sub3.example2.com.site4/tmp

136

3 Aug 2007

Drupal Handbook

Once you’ve done this, the file structure of your site will be cleanly organized: The main Drupal directory will contain only the standard ’core’ files. All of your custom themes, add-ons, settings, and so on will be in /sites/example.com, /sites/all, or /sites/default. /sites/default/settings.php and /files will be used if there is no /sites/example.com directory. /sites/all/modules and /themes will be available to all sites. Backing up the /sites directory and your Drupal database will give you everything you need to restore the site in the event of a crash, or to move to a new server. Adding a domain is easy: just copy the /sites/default directory to /sites/example5.com Symbolic links can be used for several purposes: Even if using default settings, a good option is to use links from /sites/example.com directory to point to the /sites/default directory. That way, if the settings and /files are ever changed from the default and actually placed in /sites/example.com, their location does not ’move’ and no links are broken. Links could also be used to point the /sites/default directory to your primary site. A /files directory could easily be shared across two domains without being shared across the remaining domains. A non-domain-name path for /files can be setup. If it is possible that the domain name might change (say, from a development name), then you can set up a link from /drupal/sites/moniker to /drupal/sites/example.com, where ’moniker’ is a short version of the site name that will remain constant even if /example.com changes. Although the /sites/default directory could contain a /modules and /themes directory, these elements should usually be placed in /sites/all or /sites/example.com. Similarly, although contributed modules could be placed in /drupal/modules as was the practice in version 4.7, this is not recommended. Multi-site directory setup for sub-domains, including non-standard ports, is described in the installation instructions (INSTALL.txt). See multidomain for a contributed module that allows spanning one site across multiple domains, so that specific content types appear on specific domains or sub-domains. Version 4.6 and 4.7: Best practice for multi-site set-up under version 4.6 and 4.7 is similar to 5.x. The primary difference is that there is no /sites/all directory. Instead, /modules and /themes that are available for all domains are kept in /drupal/modules and /drupal/themes.

Installing new themes
Once you get Drupal installed and you start to come to terms with it you will probably want to customize the way it looks.

137

Drupal Handbook

3 Aug 2007

There are several themes which you can download from the Drupal web site which should get you started. Installing a new theme is very straightforward: 1. Download a new theme package. Note that themes for different Drupal versions are not compatible, version 4.4 themes do not work with Drupal 4.5 and reverse. 2. Read any README or INSTALL files in the package to find out if there are any special steps needed for this theme. 3. Check to see if you have the required theme engine to be able to display your theme. Theme engine files go in a folder in themes/engines in your Drupal directory. 4. Upload the contents of the theme package to a new directory in the themes directory in your Drupal site. For example; in 4.7 you place your theme in themes/box_grey. in 5.0 you place your themes in /sites/all/themes/box_grey 5. Click administer » themes and enable the new theme (Drupal will auto-detect its presence). 6. Edit your user preferences and select the new theme. If you want it to be the default theme for all users, check the default box in the themes administration page. Note: You can see a variety of themes on themes.drupal.org. Some of these themes shown there are available for download from Drupal.org and others are merely samples.

138

3 Aug 2007

Drupal Handbook

Basic site configuration
Drupal is an extremely flexible platform that provides you with many options for changing how your site looks, how users interact with it, and the kinds of information you wish to display. Although there are many configuration options, Drupal works well "out of the box" and there is very little initial configuration to perform. As your site evolves and your demands grow, Drupal makes it easy for you to dramatically alter its look and add to its functionality. Best of all, because it is released under the GNU General Public License, Drupal is infinitely customizable and lets you tailor it to your specific needs. You will want to start your configuration with your drupal site’s basic settings can be found on the settings page, which you can reach by clicking administer » settings in the navigation block. You must be logged in and have permission to access this page. After you change the settings, don’t forget to click "Save configuration" at the bottom of the page. The information you enter here is stored in Drupal’s database to help Drupal decide how to prepare and serve your pages. Keep in mind that the settings on this page are only basic configuration settings. There are many other places to configure Drupal. These are discussed in the appropriate sections of this handbook. Much of the configuration information can be found in the modules help file or in the modules section of the handbook. For more advanced configuration then an out of the box modules provide, see the Customization and theming handbook. A lot of the information you are asked to supply on the settings page is self-explanatory and there are brief help messages below each setting to guide you. Note that the "Slogan," "Mission," and "Footer message" may or may not be immediately visible, depending on the theme you are using. If you are new to Drupal, we recommend supplying all the information for these boxes. If you decide that you don’t need or like how Drupal uses them, you can change it later (see the handbook section on configuring themes for more on this).

Settings
Below are links to provide you with explanations and tips for some of the more technical settings on the "settings" page. If you just want to get Drupal up and running, you can safely ignore these settings. You’ll always be able to come back and experiment with them later. The one possible exception to this is the "file system settings" which you may wish to set now. For more information on the "File system settings," click its link below. This link can also help you resolve issues with errors that often appear at the top of the "settings" page after Drupal is freshly installed. You can configure your sites basic settings at administer >> settings.

139

Drupal Handbook

3 Aug 2007

General settings
The General settings area is where you configure some basic information for your site. Name: this is where you set the name displayed for your site. E-mail address: A valid e-mail address for this website, used by the auto-mailer during registration, new password requests, notifications, etc. You can set this to a real email address that people can reply to or to something generic no-reply@example.com that is outbound only. The email server that your site uses is set in the php.ini file and not by Drupal. Slogan: The slogan of this website. Some themes display a slogan when available. It will also by displayed in the title bar of your sites visitor web browser. Mission: Your site’s mission statement or focus. Your mission statement is enabled in your theme settings and requires that the theme support it’s display. Footer: This text will be displayed at the bottom of each page. Useful for adding a copyright notice to your pages. HTML formating can be used in the mission and the footer areas. Anonymous user: Users who interact with your site without being logged in are labeled as "Anonymous" by default. Drupal gives you the option to change this to something different (e.g. "Anonymous coward"). The name you give anonymous users is used by Drupal when creating bylines for posts which typically reads something like, "Posted by Anonymous on January 1, 2006".

Default front page
This setting gives you control over what Drupal-generated content a user sees when they visit your Drupal installation’s root directory. For example, you might have created a node with a large collection of links to act as a table of contents to the different sections of your site and you want this directory to be what users see first. This setting tells Drupal which URL users should be redirected to. It’s important to note that the URL is relative to the directory your Drupal installation is in. So, instead of "http://www.example.com/node/83" or "http://www.example.com/drupal_installation_directory/node/83," you need only type "node/83". For those not using clean URLs, note that there is no need to type in "?q=" before typing the URL.

140

3 Aug 2007

Drupal Handbook

By default, the "Default front page" is set to "node," which simply displays articles that have been "Promoted to front page." Note that when you change the "Default front page" to something other than "node", nodes that are "Promoted to front page" will no longer appear on the front page. They can however, still be viewed by visiting the relative URL path "node". If you enter a value in here that is not a valid Drupal path, the user will be confronted with a "Page not found" error. You cannot redirect users to any web documents (e.g. a static HTML page) not created by your Drupal site.

Examples
Problem 1: You want a particular node to be the first page user’s see when they visit http://www.example.com (we are assuming Drupal is installed in the site’s root directory). Solution: Determine the id number of the node you wish to have Drupal redirect users to. One way to determine the node’s id number is to visit the node and look at the number after the last slash in your browser’s address bar. This is your node’s id number. Now set the "Default front page" to "node/id#". So, assuming your node’s id is "83," you would type "node/83". Problem 2: You want user blogs to be the front page. Solution: Set the "Default front page" to "blog". Problem 3: You want content from a single category to appear on the front page Solution: Determine the category’s id number. You can determine the id number by going to administer » categories. Roll the mouse on top of the "edit term" link next to the category to reveal the URL in your browser’s status bar (usually located at the bottom of your browser’s window). The number after the last slash in the URL is the category’s id number. Now set the "Default front page" to "taxonomy/term/id#". If your category’s id number is "5" for example, you’d write "taxonomy/term/5".

Clean URLs
By default, Drupal passes path arguments to itself via its internally generated URLs. This results in URLs that look like the following: "http://www.example.com/?q=node/83." This can make URLs hard to read and it also stops many search engines, like Google, from indexing the pages with these URLs. You can tell Drupal to use "clean URLs", eliminating the "?q=" in internal URLs. Note that this works only for Apache servers which have the LoadModule rewrite_module configured and mod_rewrite enabled in httpd.conf configuration file.

141

Drupal Handbook

3 Aug 2007

There are two ways to enable URL rewrites in Apache. If there is complete control of the Apache webserver clean URLs should be enabled in the httpd.conf as this has better performance and security. Warning. Enabling "Clean URLs" if your server is not properly configured can make it difficult to navigate back to administration pages to undo your mistake. If you find yourself in this situation, you can return to the administrative settings page by typing in the URL in the ’non-clean’ form: http://www.example.com/?q=admin/settings. Enabling clean URLs involves three steps: 1. Enable mod_rewrite for Apache. Please talk to your web host or consult the Apache documentation for mod_rewrite to get more information on how to do this. At a minimum, this will involve making sure that mod_rewrite is enabled for your installation of Apache. It will have to be either compiled-in or made available as a loadable module. Generally speaking, you can tell Apache to load the module by including LoadModule rewrite_module modules/mod_rewrite.so AddModule mod_rewrite.c in your Apache configuration file. Be sure to uncomment AddModule mod_rewrite.c. Note that this may not be the case for all distributions of *nix operating systems. Consult your distribution’s documentation that came packaged with your Apache software. We also recommend disabling multiviews in Apache as they conflict with clean URLs. 2. Edit your Apache configuration files for your site: the configuration information may be found in httpd.conf, a virtual-host-specific file, or in an .htaccess file in your Drupal installation directory. You can find this file usually in /etc/httpd/conf/httpd.conf. You may use find /etc -name httpd to find the file if it is located else where in your Unix system. The main configuration option which may need to be changed for your site is the RewriteBase. For example, if your Apache DocumentRoot is /var/www/ (i.e., /var/www/index.html is what is displayed when you point your browser at http://www.example.com/) and your Drupal installation is installed in the subdirectory /var/www/mysite/, then the RewriteBase should be set to /mysite. In some configurations setting RewriteBase / will allow mod rewrite to work. If you don’t use the .htaccess that comes with Drupal you’ll need to add some rewrite rules into your apache directory directive. Consult the .htaccess file in Drupal for examples of rules.

142

3 Aug 2007

Drupal Handbook

<Directory /var/www/example.com> RewriteEngine on RewriteBase / RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.php?q=$1 [L,QSA] </Directory> You will also need to set the Allow Override settings in httpd.conf so that local .htaccess commands will be run for you site. If you are changing the .htaccess file in the Drupal distribution you want to set it to AllowOverride All to ensure rewrites are enabled. Read "Behind the scenes with Apache’s .htacces for a thorough review of .htaccess.Here are samples of Apache 2 directives. 3. You should ensure your Drupal site has the path module enabled and the correct permissions set in order to create custom URLs. You can enable the path module in administer >> modules. You can then set permissions to administer URL aliases and create URL aliases. Enable clean URLs on your administration >> settings page. First, see if you can go to the settings page on your site using clean URLs: type in the URL http://www.example.com/admin/settings (where www.example.com is replaced by your hostname). If you get no errors and get to the same page you would have gotten to by clicking on "administer" then "settings" , then you know that you have setup the ReWriteRule rules successfully and can then click the Yes checkbox for "Clean URLs:" . If you have problem you can read the instructions to unset clean URLs. If you If you still have problems with clean URLs you can set the Drupal Settings.php $conf[’clean_url’]=1;. Note: The standard Drupal installation contains a sample .htaccess file which supports clean URLs. It is easy to miss copying this file, because of the leading "dot". Note Regarding MultiViews: The Apache webserver supports a feature called "MultiViews" (more generally: "Content Negotiation"), which allows navigation to your pages without the need for file extensions. For instance, if you had a file called "evaluation.txt", a MultiViews-enabled site could access this file with the URL "example.com/evaluation". While MultiViews can be a handy feature when used knowingly, they can cause problems when Drupal’s Clean URLs are enabled. Unless you know what you’re doing, you should consider disabling MultiViews if you plan to use the clean URLs feature of Drupal. Be aware that there’s a good chance that MultiViews is already disabled, however; it’s not enabled in a default Apache installation. Consult the Apache documentation for further information about MultiViews.

.htaccess for clean urls on specific shared hosts
zorroposada posted this .htaccess file, the use of which then allowed clean urls to be enabled when using several hosts like 1and1.com, mediatemple.net, ehostpros.com, ehosting.ca

143

Drupal Handbook

3 Aug 2007

bobdonohue reported that this .htaccess file worked on dotster. This code was taken from the boost.module and modified just a little bit. There is no guarantee this will work for you though. Instructions: Create a text file, copy and paste the code below and save it as .htaccess Upload the file and put it in the public_html directory of your site. Modify "RewriteBase subdirectory "example." /" in line 68 to "RewriteBase /example" if your site is in

# # Apache/PHP/Drupal settings: # # Protect files and directories from prying eyes. <FilesMatch
"(\.(engine|inc|install|module|sh|.*sql|theme|tpl(\.php)?|xtmpl)|code-style\.pl|Entries.*|Repository|Root)$">

Order deny,allow Deny from all </FilesMatch> # Set some options. Options -Indexes Options +FollowSymLinks # Customized error messages. ErrorDocument 404 /index.php # Set the default handler. DirectoryIndex index.php # Override PHP settings. More in sites/default/settings.php # but the following cannot be changed at runtime. # PHP 4, Apache 1 <IfModule mod_php4.c> php_value magic_quotes_gpc 0 php_value register_globals 0 php_value session.auto_start 0 </IfModule> # PHP 4, Apache 2 <IfModule sapi_apache2.c> php_value magic_quotes_gpc 0 php_value register_globals 0 php_value session.auto_start 0 </IfModule> # PHP 5, Apache 1 and 2 <IfModule mod_php5.c> php_value magic_quotes_gpc 0

144

3 Aug 2007

Drupal Handbook

php_value register_globals 0 php_value session.auto_start 0 </IfModule> # Reduce the time dynamically generated pages are cache-able. <IfModule mod_expires.c> ExpiresByType text/html A1 </IfModule> # Various rewrite rules. <IfModule mod_rewrite.c> RewriteEngine on # If your site can be accessed both with and without the prefix www. # you can use one of the following settings to force user to use only one option: # # If you want the site to be accessed WITH the www. only, adapt and uncomment the following: # RewriteCond %{HTTP_HOST} !^www\.example\.com$ [NC] # RewriteRule .* http://www.example.com/ [L,R=301] # # If you want the site to be accessed only WITHOUT the www. , adapt and uncomment the following: # RewriteCond %{HTTP_HOST} !^example\.com$ [NC] # RewriteRule .* http://example.com/ [L,R=301] # Modify the RewriteBase if you are using Drupal in a subdirectory and # the rewrite rules are not working properly. RewriteBase / # Rewrite old-style URLs of the form ’node.php?id=x’. #RewriteCond %{REQUEST_FILENAME} !-f #RewriteCond %{REQUEST_FILENAME} !-d #RewriteCond %{QUERY_STRING} ^id=([^&]+)$ #RewriteRule node.php index.php?q=node/view/%1 [L] # Rewrite old-style URLs of the form ’module.php?mod=x’. #RewriteCond %{REQUEST_FILENAME} !-f #RewriteCond %{REQUEST_FILENAME} !-d #RewriteCond %{QUERY_STRING} ^mod=([^&]+)$ #RewriteRule module.php index.php?q=%1 [L] # Rewrite rules for static page caching provided by the Boost module # BOOST START <IfModule mod_mime.c> AddCharset utf-8 .html </IfModule> RewriteCond %{REQUEST_URI} !^/cache RewriteCond %{REQUEST_URI} !^/user/login RewriteCond %{REQUEST_URI} !^/admin RewriteCond %{HTTP_COOKIE} !DRUPAL_UID RewriteCond %{REQUEST_METHOD} ^GET$

145

Drupal Handbook

3 Aug 2007

RewriteCond %{QUERY_STRING} ^$ RewriteCond %{DOCUMENT_ROOT}/cache/%{SERVER_NAME}/0/%{REQUEST_URI} -d RewriteCond %{DOCUMENT_ROOT}/cache/%{SERVER_NAME}/0/%{REQUEST_URI}/index.html -f RewriteRule ^(.*)$ cache/%{SERVER_NAME}/0/$1/index.html [L] RewriteCond %{REQUEST_URI} !^/cache RewriteCond %{REQUEST_URI} !^/user/login RewriteCond %{REQUEST_URI} !^/admin RewriteCond %{HTTP_COOKIE} !DRUPAL_UID RewriteCond %{REQUEST_METHOD} ^GET$ RewriteCond %{QUERY_STRING} ^$ RewriteCond %{DOCUMENT_ROOT}/cache/%{SERVER_NAME}/0/%{REQUEST_URI}.html -f RewriteRule ^(.*)$ cache/%{SERVER_NAME}/0/$1.html [L] # BOOST END # Rewrite current-style URLs of the form ’index.php?q=x’. RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.php?q=$1 [L,QSA] </IfModule> # $Id: boosted.txt,v 1.4 2006/12/05 10:39:19 arto Exp $

403 Permission denied error
So you’ve tried every advice above but still get the 403, "You don’t have permission to access", error when testing for clean urls. This is how I solved it after many tedious hours of googling.... Apparently there’s an option called Multiview in apache which enables the server to look for files without an extension in the parent directory of the directory you specified, if it can’t find the directory. So if you type www.mysite.com/admin/settings and it can’t find the directory it looks for a file named settings.(some extension) in www.mysite.com/admin, however if you also have directory browsing turned of and it can’t find a file it will report it as you trying to find a file in www.mysite.com/admin which you don’t have a permission to view or doesn’t exist i.e. the 403 error. To solve this you either turn of diretory browsing in your .htaccess file by writing: Options +Indexes instead of Options -Indexes However if you don’t feel like having directory browsing on, I guess most people do, you just turn of Multiviews like this under the other options in your .htaccess file:

146

3 Aug 2007

Drupal Handbook

Options -MultiViews

A mod_rewrite bug causing occasional corruption of the query string
It seems that using mod_rewrite to set or modify the query string can corrupt it. One case where it certainly fails is if the URL has %2B (a urlencoded "+" character) in it. As a demonstration, try searching for the string "alice + bob". You can see on http://drupal.org/search/node/alice+%2B+bob that the rewrite rules change the %2B to a space, while on http://drupal.org/?q=search/node/alice+%2B+bob it work correctly without clean URLs. The reason I am posting it here as a warning and not as a bug report is that it’s not a Drupal issue, but a mod_rewrite issue. (It would be worth a bug report for mod_rewrite, but they have such bug reporting guidelines that require a few hours’ work to follow...)

Apache 2 configuration of clean URLs on Debian
If you’re running Apache2 on Debian stable, in order to install the rewrite module you simply need to: # a2enmod rewrite then restart the webserver: # /etc/init.d/apache2 restart then edit either /etc/apache2/sites-enabled/drupal or to your .htaccess and ensure it looks something like this: # # Apache/PHP/site settings: # # Protect files and directories from prying eyes: <Files ~
"(\.(conf|inc|module|pl|sh|sql|theme|engine|xtmpl)|Entries|Repositories|Root|scripts|updates)$">

order deny,allow deny from all </Files> # Set some options Options -Indexes Options +FollowSymLinks # Customized server error messages: ErrorDocument 404 /index.php # Set the default handler to index.php: DirectoryIndex index.php # Overload PHP variables: <IfModule sapi_apache2.c>

147

Drupal Handbook

3 Aug 2007

# If you are using Apache 2, you have to use <IfModule sapi_apache2.c> # instead of <IfModule mod_php4.c>. php_value register_globals 0 php_value track_vars 1 php_value short_open_tag 1 php_value magic_quotes_gpc 0 php_value magic_quotes_runtime 0 php_value magic_quotes_sybase 0 php_value arg_separator.output "&amp;" php_value session.cache_expire 200000 php_value session.gc_maxlifetime 200000 php_value session.cookie_lifetime 2000000 php_value session.auto_start 0 php_value session.save_handler user php_value session.cache_limiter none php_value allow_call_time_pass_reference On </IfModule> # Various rewrite rules <IfModule mod_rewrite.c> RewriteEngine on Options All # Modify the RewriteBase if you are using Drupal in a subdirectory and the # rewrite rules are not working properly: RewriteBase /drupal # Rewrite old-style URLS of the form ’node.php?id=x’: RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{QUERY_STRING} ^id=([^&]+)$ RewriteRule node.php index.php?q=node/view/%1 [L] # Rewrite old-style URLs of the form ’module.php?mod=x’: RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{QUERY_STRING} ^mod=([^&]+)$ RewriteRule module.php index.php?q=%1 [L] # Rewrite URLs of the form ’index.php?q=x’: RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.php?q=$1 [L,QSA] </IfModule> # $Id: .htaccess,v 1.58 2004/10/09 20:41:49 dries Exp $ This is because the debian package installs the drupal "sites-enabled" virtual host, result being that drupal is accessed from http://yourhost.com/drupal, hence the need to uncomment RewriteBase. Change it to the base that corresponds to your system.

148

3 Aug 2007

Drupal Handbook

ref: http://www.debian-administration.org/articles/136 http://drupal.org/node/14322 -Sean K. O’Brien CTO Colley Graphics, LLC http://www.colleygraphics.com

Apache 2 on Ubuntu
Two methods here:

Editing apache2.conf
First thing to do is make sure you have apache up and running: /etc/init.d/apache2 start Then you have to enabled the rewrite module(mod_rewrite). You no longer have to do the: LoadModule rewrite_module modules/mod_rewrite.so AddModule mod_rewrite.c It’s now as easy as: a2enmod rewrite To disable this module it’s just: a2dismod rewrite with Apache version 2, the httpd.conf has been depreciated and the new file is located at: /etc/apache2/apache2.conf in this file you need to add your directory and the allow override to give access to your drupal site. so look for a section in your apache2.conf that has Directory tags and just add another section: <Directory /var/www/drupal_website_install> AllowOverride all </Directory> *keep in mind that my website is in a subdirectory (drupal_website_install) and so you may need to edit the above to reflect this. By this I mean if i go into my webbrowser I need to go to http://localhost/drupal_website_install/ After you edit you apache2.conf as listed above you need to restart the server by: /etc/init.d/apache2 restart

149

Drupal Handbook

3 Aug 2007

If you are having problems with getting your rewrite to work you can always use logging. To do that add this to the end of you apache2.conf: RewriteLog "/var/log/apache2/rewrite.log" RewriteLogLevel 3 Level 0 is no logging Level 9 is log everything You can pick the level to determine the amount of output you need. ***Security Warning: Make sure to take the log code out, disable it, or put the log file in a directory that can’t be read by normal users (as shown above) otherwise it can result in a security breach.*** hopefulley this helps some people and saves them the time that I spent trying to get it working.

Editing apache2/sites-available
My configuration: drupal 5.x apache 2.2 mysql 5.0 debian/ubuntu server install drupal path: /www/drupal/sites/site1...site2 I have root access to my server. First, from the linux command line, I enabled the rewrite module for apache like this: a2enmod rewrite Next I restarted Apache: sudo /etc/init.d/apache2 restart Then I reloaded Apache config files: sudo /etc/init.d/apache2 reload Finally, I changed the file located at: /etc/apache2/sites-available/default (in the sites-available directory, you should see as many files as you have websites enabled. One is named default and the others should reflect the names of your additional sites if you are running virtual hosts. If you have only a single site, it will most likely be named default. You can open these files in an editor such as nano and make changes.)

150

3 Aug 2007

Drupal Handbook

change this directive in the file(s) found in sites-available: AllowOverride None to AllowOverride All Save this file and then restart apache as we did above. Now browse to your site with your browser, login, click administer, find "Clean URLs" and browse to that page, run the test for "Clean URLs" buried in the paragraph explaining "clean Urls". If your setup is like mine, you should now have Clean URLs in drupal.

Clean URL Support in Abyss
This clean URL implementation has been tested on Abyss X1, one which has a properly set Custom Error Page 404 to any arbitrary file that, for this purpose, will be referenced as "/url_rewrite.php". Due to the generalized design of this solution, this method could theoretically work on virtually any webserver that can redirect missing URI location onto a php resource. The method described here works only on webservers with a singular host configuration. One esoteric requirement is for the webserver to pass the server variable REQUEST_URI containing the value of the original resource requested. For more information on configuring Abyss X1 for this purpose, please visit this Aprelium forum resource. This solution could be rendered academic if Aprelium finally decides to implement URL rewrite in Abyss internally. This method is useful for Abyss webservers version 2.3.2 and most other versions prior to this specific release. Another drawback is that the URL rewrite becomes only invisible to the machine but is always visible to the human. The idea is to pass (or redirect) the missing URI location on the HTTP-404 handler "/url_rewrite.php". For illustrative examples, let’s look at the following scenarios: 1. http://www.example.com/node/add => "/node/add" not found, pass to 404 handler "/url_rewrite.php" => "/url_rewrite.php" determines "/index.php?q=node/add" exists and serves that instead. 2. http://www.example.com/admin/settings => "/admin/settings" not found, pass to 404 handler "/url_rewrite.php" => "/url_rewrite.php" determines "/index.php?q=admin/settings" exists and serves that instead. 3. http://www.example.com/no_exist/location => "/no_exist/location" not found, pass to 404 handler "/url_rewrite.php" => "/url_rewrite.php" determines "/index.php?q=no_exist/location" exists and serves that instead but lets Drupal display the proper "page not found" informational message. Here are the steps in letting this method apply to your setup.

151

Drupal Handbook

3 Aug 2007

1. Create the following file and save it as "/url_rewrite.php". <?php /* Add in this array the list of (old path => new path) pairs */ $redirection = array( ’^(.*)$’ => ’index.php?q=$1’ ); if (!file_exists($_SERVER["REQUEST_URI"])) /* Get the URI and trim leading slashes */ $uri = ltrim($_SERVER["REQUEST_URI"], "/"); { foreach ($redirection as $key => $value) { if (eregi($key, $uri)) { /* Convert the replacement string syntax - $1 -> \1 */ /* and perform the substitution */ $uri = str_replace("index.php","",substr($uri,0)); $new_uri = str_replace("?","&",$uri); $new_uri = "/index.php?q=".$new_uri; $new_uri = str_replace("%26","&",$new_uri); break; } } } if (isset($new_uri)) { header("Status: 307"); header("Location: $new_uri"); exit; } ?> <!-- Your 404 error page --> <HTML> <HEAD> <TITLE>Not Found</TITLE> </HEAD> <BODY> The object <tt><?php echo $uri; ?></tt> is not available. </BODY> </HTML> 2. In the Abyss web console, enter the Custom Error Pages, add a 404 Status Code entry with the Associated URL value "/url_rewrite.php". Click OK and restart the Abyss webserver. 3. Test for functionality by querying your website directly with URI’s such as: http://www.example.com/admin/settings http://www.example.com/node/add

152

3 Aug 2007

Drupal Handbook

If the redirection works properly, proceed to the next steps. If the redirection would not work, check if the steps above have been strictly followed. Modify only those things that you have absolute knowledge of. 4. Log on to your website and log on to your "/admin/settings" page. Under General Settings section, enable Clean URLs. If the Clean URLs option is grayed out, add the line "$conf[’clean_url’] = 1;" in your settings.php, then repeat this step. Don’t forget to click the "Save configuration" button. 5. If things do not work out, completely remove the line "$conf[’clean_url’] = 1;" from your settings.php. And browse to your http://www.example.com/index.php?q=admin/settings page to disable Clean URLs properly.

Clean URL support in XAMPP
Clean URLs do not work out of the box on XAMPP 1.5.x with PHP4 due to a problem in Apache’s module load order; mod_rewrite will not work properly. To remedy this edit the file [path_to_xampp]/apache/conf/httpd.conf. Move the line LoadModule rewrite_module modules/mod_rewrite.so to just above or below #LoadModule cache_module modules/mod_cache.so You also have to set AllowOverride All for the directory Drupal is in. Do this in httpd.conf or extra/httpd-xampp.conf Always restart Apache or changes to its configuration files won’t have an effect. If Drupal is not installed in the document root, the next thing you’ll have to do is to modify the file .htaccess, that comes with Drupal. Remove the commentsign (#) in front of RewriteBase and, if necessary, modify the path: RewriteBase /drupal Finally, in Drupal go to administer » settings (admin/settings) and click the "Enabled" option for Clean URLs and save the settings.

Clean URLs in Mac OS X Server
For Mac OS X Server 10.4 (Tiger Server) and most likely previous versions as well, do not make changes to /etc/httpd/httpd.conf expecting the AllowOverride All directive to work. The correct file to add the AllowOverride All directive is in the directory /etc/httpd/sites/. In that directory are the virtual host configuration files. Each virtual server has a configuration file in that directory so it is in those files that you must enable AllowOverride All. If you only have one web server on your server configured, then the file you want to modify is /etc/httpd/sites/0000_any_80_.conf.

153

Drupal Handbook

3 Aug 2007

Clean URLs with different webservers
Microsoft Internet Services Server
Windows ISS MySQL PHP(WIMP)-Tips for Configuring Drupal on WIMP

Lighttpd
For those who have stepped up a notch in performance and moved from Apache to Lighttpd, you can use the following configuration for Lighty’s mod_rewrite module: url.rewrite-final = ( "^/system/test/(.*)$" => "/index.php?q=system/test/$1", "^/([^.?]*)\?(.*)$" => "/index.php?q=$1&$2", "^/([^.?]*)$" => "/index.php?q=$1" ) The first line ensures that Drupal’s clean URL check (when saving Settings) succeeds (Drupal makes an HTTP request for a path of the form /system/test/yLgnwqqUu5cWnvPi4Hrz.png). It’s a special case that must be handled separately (read on for the reason). The two following lines let Drupal handle any URL that doesn’t contain a dot. This is significant because we can assume, fairly confidently, that addresses like /node/add are Drupal URLs, but addresses such as /themes/bluemarine/style.css are physical files. So the above configuration will work for all cases where this assumption holds true; if there are exceptions to the rule, they can be manually added to the rewrite configuration. See also the related discussion at http://drupal.org/node/20766 I just successfully set up lighttpd 1.4.8 with php4 via fastcgi using those rules above. As per lighttpd documentation I also set up /etc/php4/cgi/php.ini to have that cgi fix. Then I added those rewrite rules for corresponding virtual_host. Ubuntu breezy’s php4-cgi package bougyman’s lighttpd package (see http://www.lighttpd.net/download/ for details)

Clean URLs with Easyphp.
To get that the clear URLs works in Easyphp 1.8 you have to join the httpd.conf file and change this two lines: #LoadModule rewrite_module modules/mod_rewrite.so and #AddModule mod_rewrite.c

154

3 Aug 2007

Drupal Handbook

and leave like this in the same line. LoadModule rewrite_module modules/mod_rewrite.so y AddModule mod_rewrite.c and Re-start the server. Easyphp have the mod_rewrite within. If there is any problem tell me. Oskar Calvo.

Example Clean URL configuration of httpd.conf for performance
This was tested and applies to FC4/php5/Apache 2.0.54. Enabling .htaccess in Apache requires more work on the part of the server. A full explanation can be found here: http://www.serverwatch.com/tutorials/article.php/3436911 Suffice it to say that it is in your interest to not use .htaccess files and even disable them if you are concerned about squeezing more performance out of apache. I moved the rewrite rules (all of the sample .htaccess file really) to /etc/httpd/conf/drupal.conf. Then for each virtual host, one can add the line: Include conf/drupal.conf The rewrite rules change slightly: # Rewrite current-style URLs of the form ’index.php?q=x’. RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ /index.php?q=$1 [L,QSA] Note that I added %{DOCUMENT_ROOT} and a leading slash in front of index.php -- because I have index.php installed in my document root. If you install it in another directory, you will want to give the relative path to it from document root with the leading slash. Important: If you forget the leading slash (more specifically, forget to give the relative path with leading slash), Apache will give you a "400 Bad Request" error. This is better. But we still have a problem where every request will check for the existence of a file and a directory before we apply the rewrite rule. The OS may be able to cache some of that information, but it would still be better to avoid the two file-system checks in the first place.

155

Drupal Handbook

3 Aug 2007

There are some directories that we should not rewrite. And there are certain extensions that we should not rewrite. Using this information, we can update the rewrite rule to send everything to index.php that does not fall into this category. The first rule excludes the directories "files", "misc", and "uploads". The second rule excludes the extensions you see. Add more if you have other extensions in your directory that should not get passed to index.php. RewriteCond %{REQUEST_FILENAME} !^/$ RewriteCond %{REQUEST_FILENAME} !^/(files|misc|uploads)(/.*)? RewriteCond %{REQUEST_FILENAME} !\.(php|ico|png|jpg|gif|css|js|html?)(\W.*)? RewriteRule ^(.*)$ /index.php?q=$1 [L,QSA]

Existing URLs for server overwrite Drupal paths
If your server has existing paths like /admin then you can either move your Drupal instance to a subdirectory like /home/admin or you can create a virtual link to ?=admin.

IIS CleanURLs using some of the available ISAPI filters.
There is a free version called ISAPI_Rewrite Lite that should get clean URLs working for IIS. Install that and insert these rewrite rules. # Accept a unchanged. RewriteRule # Make URLs RewriteRule RewriteRule RewriteRule url with the following extensions and pass them through (.*.gif|.*.png|.*.jpg|.*.pdf|.*.js|.*.css) $1 [I,L] sane /index.php.* $0 [I,L] /(.*)\?(.*) /index.php\?q=$1&$2 [I,L] /(.*) /index.php\?q=$1 [I,L]

Next, add the following line to the end of your settings.php file for your site: $conf[’clean_url’] = 1;

Translating Apache’s rewrite rules
RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d In plain English: If the REQUEST_FILENAME variable does not exist (not an existing file and not an existing directory) then apply the rule: RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]" After much research this exact functionalty does not appear to exist in any ISAPI module for IIS. I think the following solution will help solve this issue. It probably works with most "ISAPI rewrite" modules (they just need the "stop the rewriting process" option).

156

3 Aug 2007

Drupal Handbook

With this approach you basically revert the "Apache Rewrite" logic. First define rules for known files/folders (like /themes/ ..etc..). Have those "matching rules" exit, so rules processing stops before going to the next rule. With mod_rewrite.dll you can do that with the option [l]. Here is what my rules file looks (so far) like (using mod_rewrite.dll): RewriteRule ^/index.php\?q\=(.*)$ /index.php?q=$1 [l] RewriteRule ^/themes/(.*)$ /themes/$1 [l] RewriteRule ^/misc/(.*)$ /misc/$1 [l] RewriteRule ^/(.*)$ /index.php?q=$1 [l] Remember, you have to add an "exiting" rule for all known folders/files before hitting the final rule. The first rule is to avoid recursion and exit immediatly if the URL already has index.php?q=. To better understand the Apache rules here are the definitions of the main options: ’last|L’ (last rule) Stop the rewriting process here and don’t apply any more rewriting rules. Use this flag to prevent the currently rewritten URL from being rewritten further by following rules. ’qsappend|QSA’ (query string append) This flag forces the rewriting engine to append a query string part in the substitution string to the existing one instead of replacing it. Use this when you want to add more data to the query string via a rewrite rule. REQUEST_FILENAME The full local filesystem path to the file or script matching the request. ’-d’ (is directory) Treats the TestString as a pathname and tests if it exists and is a directory. ’-f’ (is regular file) Treats the TestString as a pathname and tests if it exists and is a regular file. Note: Getting Apache running on MS Windows is not that bad (I had been delaying it for years). In reality it’s a matter of a few hours to get going. http://www.sitebuddy.com aims to save you time in that endeavor.

Pathauto and Localizer
I was looking for a way to include node language into pathauto recognizable variables, this is how I managed to do it, you will be able to use [locale] in your nodes path. In your pathauto_node.inc you need to add these lines: This one is shown in the pathauto config <?php function node_pathauto($op) { switch ($op) {

157

Drupal Handbook

3 Aug 2007

case ’settings’: $settings[’bulkdescr’] = ?> ... <?php // LOCAL ADDON t(’[locale]’) => t(’The locale used for this node.’), ?> These will be loading the data <?php function node_get_placeholders($node) { ?> ... <?php // LOCAL ADDON $result = db_query("SELECT locale FROM nid=’%d’", $node->nid); $nodelocale = db_fetch_object($result); $placeholders[t(’[locale]’)] = pathauto_cleanstring($nodelocale->locale); ?> Hope this helps someone !

{localizernode}

WHERE

Setting up clean URLs above web document root on virtual private servers
To set up clean URLs above web document root on virtual private servers, you need to change a setting in httpd.conf. (default setting) Options FollowSymLinks AllowOverride None Change it to Options FollowSymLinks AllowOverride All None of the other changes discussed in this section of the handbook were necessary (and in fact had to be undone). The hosting provide said this does not provide any security issues (no guarantees).

158

3 Aug 2007

Drupal Handbook

reboot vps after making change
This is excellent advice. I installed a test site at /var/www/test. My live site is at /var/www/html. The live site worked fine. In the test site i went to set clean url’s and got an apache error. This fixed it. One minor note. I had to reset the vps before the changes took affect. With my hosting company this is simply a menu selection in their control panel, so if you have this setup and make the change and it does not work. Ask your provider to reset your Virtual Private Server. This is simular to stopping and starting Apache on a Windows install.

Using Clean URLs with IIS
Drupal can display brief, pretty URLs like those at drupal.org. For Apache sites, mod_rewrite powers this feature. For IIS, you will use a custom error handler for this. You probably want to disable logging in IIS, since every page view is considered an error using this technique. make sure your Drupal is working well without clean urls enabled. open your Internet Services Manager or MMC and browse to the root directory of the web site where you installed Drupal. You cannot just browse to a subdirectory if you happenned to install to a subdirectory. right click and select properties -> custom errors tab set the HTTP Error 404 and 405 lines to MessageType=URL, URL=/index.php. If you are using Drupal in a subdirectory, prepend your subdir before /index.php paste the following code into the bottom of settings.php file, which is usually located under sites/default/. the first two lines should be edited. If you aren’t using a subdirectory, set $sub_directory to "". then set $active=1 and enjoy! <?php // CONFIGURATION $sub_dir = "/41/"; // enter a subdirectory, if any. otherwise, use "" $active = 0; // set to 1 if using clean URLS with IIS // CODE if ($active && strstr($_SERVER["QUERY_STRING"], ";")) { $qs = explode(";", $_SERVER["QUERY_STRING"]); $url = array_pop($qs); $parts = parse_url($url); unset($_GET, $_SERVER[’QUERY_STRING’]); // remove cruft added by IIS if ($sub_dir) { $parts["path"] = substr($parts["path"], strlen($sub_dir)); } $_GET["q"] = trim($parts["path"], "/");

159

Drupal Handbook

3 Aug 2007

$_SERVER["REQUEST_URI"] = $parts["path"]; if ($parts["query"]) { $_SERVER["REQUEST_URI"] .= ’?’. $parts["query"]; $_SERVER["QUERY_STRING"] = $parts["query"]; $_SERVER["ARGV"] = array($parts["query"]); parse_str($parts[’query’], $arr); $_GET = array_merge($_GET, $arr); $_REQUEST = array_merge($_REQUEST, $arr); } } ?> at this point, you should be able to request clean url pages and receive a proper page in response. for example, request the page /node/1 and hopefully you will see your first node shown. you should not use the q= syntax; use the clean url syntax. if you get an IIS error, you have a problem. please fix redo the above and then retest. browse to index.php?q=admin/system, enable clean URLS, and press Submit. you may get a php error if your php error reporting in your php.ini file is set to high. Try this setting in your php.ini file error_reporting = E_ALL & ~E_NOTICE Note: This method seems to work for IIS5 but not IIS6. Check this thread for some approaches using ISAPI_Rewrite.

Alternate method
Alternatively, you can use ISAPI Rewrite by Helicon software to add mod_rewrite-like functionality to IIS: www.isapirewrite.com

set your sites 403 and 404 Error pages
Drupal’s page error messages are meant to be direct and to the point. If you want page error messages that are a little more user-friendly, Drupal allows you to customize them. Just follow these steps: 1. Create two nodes, one for each kind of page error (403 and 404). 2. Determine the id number of the node you wish to have Drupal redirect users to. One way to determine the node’s id number is to visit the node and look at the number after the last slash in your browser’s address bar. This is your node’s id number. 3. Now enter the paths to your nodes into the appropriate boxes. For example, if the node id number for 403 error codes is "83," you would type "node/83" into the "Default 403 (access denied) page" setting.

160

3 Aug 2007

Drupal Handbook

Because you are creating nodes for this, they will show up in the tracker and popular content blocks and anywhere else real nodes would show up. If this isn’t acceptable, there is a contributed module called Custom Error that avoids this problem.

Configure your sites error reporting
Where Drupal, PHP and SQL errors are logged. On a production server it is recommended that errors are only written to the error log. On a test server it can be helpful to write logs to the screen. By default, errors are displayed to the screen. You should change this to ’Write errors only to log’ only for your production site. You can tell Drupal to automatically discard error log entries older than the age you specify. This requires a crontab (yoursite.com/cron.php) to be set up. See step 6 of the install.txt for example of setup.

Cache support
Busy Drupal sites may want to consider caching their pages to lighten the load on their server and speed up page generation times. Normally, every time you visit a Drupal page, Drupal makes dozens of queries to the database to pull out the data needed to generate the HTML that your web-browser renders. On a large site with many modules installed or with lots of content on a page, the number of queries per page could rise into the hundreds. Usually, you don’t notice all the work Drupal does because computers are very fast and Drupal is very efficient. However, on very busy sites with many hundreds or thousands of page views per minute, the amount of work required to serve each page may start to slowing the server to a crawl. Busy sites can reduce the work required to generate pages by enabling Drupal’s page cache. With the cache turned on, Drupal stores all the HTML code for any page visited by an anonymous user directly into the database. When another request for the same page comes along, Drupal knows to fetch this page out of the database rather than re-generating it from scratch. The result is that hundreds of queries are replaced with one single query, thereby significantly lightening the load on the web server.

Primary and secondary links
General Information:
In versions 4.6 and below, primary and secondary links were handled in the theme administration. As of 4.7, primary and secondary links have been incorporated into the menu system. To have primary and secondary links in your theme, you make them menu items. A fresh Drupal 4.7 install comes with an empty menu called "Primary Links" that is set to be used to display both

161

Drupal Handbook

3 Aug 2007

the primary and secondary links.

Setting Up Your Primary and Secondary Links:
There are two configuration screens that deal with these links: On admin >> settings >> menu you choose which menu is used for the primary links and which for the secondary links. If you have added items to the default "Primary Links" menu and they are not showing up, check to make sure the option on this page hasn’t been changed to "No Primary Links". On admin >> menu you will find the default "Primary Links" menu and you should add your links to that. You can also create a menu to hold the secondary links or create a different menu for the primary links. Be sure to change the options on admin >> settings >> menu to use the correct menu(s).

Theming Your Link Menus
You can display your links in two ways: 1) You can add the menu block to a region just like any other menu. 2) You can insert this code where you want the links to show up: <?php if (isset($primary_links)) { ?><div id="primary"><?php print theme(’links’, $primary_links) ?></div><?php } ?> <?php if (isset($secondary_links)) { ?><div id="secondary"><?php print theme(’links’, $secondary_links) ?></div><?php } ?> You can then use CSS to theme your DIVs however you like.

Set length of trimmed posts and # of posts on front page
admin >> settings >> post Here you can set the number of posts on main page and the length of trimmed posts. You also set whether previewing posts is optional or required.

URL Alias Optimization
Drupal 6.0 implements a new feature to enhance site-performance: a whitelist/blacklist for URL alias lookups. Database queries to find url aliases created by the path module are among the most frequent in many Drupal installations. The performance setting allows administrators to either define paths which will no be looked up (blacklist), or paths which will (whitelist). Similar to the block visibility settings, you can use the * wildcard to define ranges of URLs.

162

3 Aug 2007

Drupal Handbook

The blacklist comes with a set of useful default urls. For many sites, enabling the blacklist will reduce the number of overall queries to the database without degrading any functionality. However, if you make extensive use of URL aliases, you should think about what settings work best for you. If you have a small number of aliases, setting them up as a whitelist may be even better.

File system settings
Drupal provides configuration settings to control whether, and how, users and administrators can upload files for use by Drupal. Note: Unconfigured or improperly configured Drupal installations may display one or more error message at the top of the "settings" page, indicating that either the "Temporary directory" or "File system path" directories do not exist and/or their permissions are not set properly. Simply create these directories and set their permissions so that Drupal can write and read from the directory. If you are unsure about where or how to create these directories or how to change their permissions, contact your web hosting service or software documentation for further assistance.

Download method
Download settings are configured in Administer >> Settings >> File system There are two possible settings for download method: Public and Private. Set to Public if you don’t care if any user, even anonymous users, can download the files uploaded by other users. Set to Private if you wish to restrict the ability of some users to download files uploaded by other users. Please note that if you set your download method as private, you should set your "files" directory to be outside the document root for your drupal installation (i.e. not in your_drupal_site/files or your_drupal/site/sites/all/files). The private download method also has performance implications which you may want to consider. If you change your settings at a later date, all download urls will change, therefore it’s best to plan ahead when you set your drupal site up and think carefully about whether you’ll need to restrict file downloads. If that’s the case we strongly recommend setting the file download method to private when you first create your site to avoid broken links later on. If your download method is set as private, all users will still be able to download files until you set otherwise.

163

Drupal Handbook

3 Aug 2007

Path settings
File system path By default, this is set to "files". We recommend leaving this setting alone. Temporary directory By default this is set to "/tmp" which is the temporary directory common in GNU/Linux distributions. If you are using a Windows or other kind of server, we recommend setting it to "tmp" (no slash). Drupal will automatically create the temporary directory as a subdirectoy of the "File system path." If it does not due to permissions or other configuration issue’s, you can create the file manually.

Date and time settings
Drupal allows you to configure how dates and times are formatted and displayed. When making the format settings, you should probably consider the culture of your target audience. Below are suggested configurations for the "Default time zone" and "Configurable time zones" options. For sites where most users live in a small geographic region: Set the "Default time zone" to the time zone of the region and disable configurable time zones. For sites where most users live a region that spans a few time zones: Set the "Default time zone" to the time zone usually considered to be the "standard" time zone and disable configurable time zones. For example, in the United States, you’d set your site’s time to the timezone that corresponds to Eastern Standard Time. For sites where users are likely to be scattered across the globe: Set the "Default time zone" to the time zone to GMT (+0000) and enable configurable time zones.

Customizing the interface
When launching a new drupal site, here are some things you can do to personalize the design and architecture of your drupal site. Choose a Theme. The look and feel of Drupal is primarily controlled by the theme you have applied to your site. A site can even have multiple themes. A good first step is to go to administer > themes and set a new theme as your default. You can find more themes on the download page after the list of modules. Once you download a new theme you will need to install it on your system. Create your own Theme.

164

3 Aug 2007

Drupal Handbook

Many Drupal sites will need a more unique look than these pre-built themes can offer. Therefore, many developers will want to write their own themes. Theme development requires a working knowledge of HTML/CSS and possibly some rudimentary PHP depending on the complexity of your theme. Customize the Navigation. The menus that are displayed on the top and bottom of the page are configured in administer > themes. Select the configure tab and scroll down to Menu Settings. The primary and secondary links can be defined here, using straight HTML. If the primary links are left blank your navigation will be created based on your installed modules. Each theme has an individual configuration page (listed at the top of the global settings page) as well. Unfortunately, in Drupal 4.6 and previous using PHPTemplate your navigation must be defined in that theme’s individual theme area. In 4.7 PHPTemplate engine is incorporated into the Drupal core and the Primary and Secondary links are now part of the menu system. Mention of this can be found here. Customize Text Strings You can also change the text strings throughout drupal using the locale feature, which was designed for running drupal in different languages, you can personalize almost all of the text in drupal. In fact, you can replace a string like "create blog entry" with html markup such as references to graphics.

Customizing user login
In the default setup the Drupal login block is always displayed unless a user is logged in. This may not always be desirable. For example, if you are using Drupal to create a site that has a very small number of people actually logging into the system to create or edit content, then you probably don’t want a large portion of your screen real-estate taken up with a login block that doesn’t relate to them. This also confuses the majority of your users that will not have the option to login. To disable the login block: 1. Goto the block configuration (administer » blocks) 2. Deselect the check box for User login in the Enabled column Your regular content editors and administrators can still login to the site by directly accessing the login page, http://www.example.com/?q=user. If you are using clean URLs you may also use http://www.example.com/user, but remember that the ?q=user version will always work whether you have clean URLs enabled or not.

165

Drupal Handbook

3 Aug 2007

You can also create more customized login blocks. You can create name and email filter rules in admin >> access control >> account rules. Set up username and e-mail address access rules for new accounts. If a username or email address for a new account matches any deny rule, but not an allow rule, then the new account will not be allowed to be created.

Beginner’s guide for Cron on a shared hosting provider
This guide is excerpted from the original article on ThemeBot.com: Time to talk about Cron - a beginner’s guide If you have downloaded and installed Drupal 5, you will notice that there is an error in the administrative log when you first sign in with your administrative account. One or more problems were detected with your Drupal installation. Check the status report for more information. When you look at the status report you can go ahead and click the link "run cron manually" and this will remove the error. However, you will eventually want to set up a Cron job to do this. Having the Cron maintenance run regularly on an automatic schedule is important for keeping your site indexed. If this is not done, new content that is added will not be included in search results. Cron can also perform other tasks in Drupal, such as cleaning up log files. Also, some of the contributed modules require that Cron maintenance is run regularly. With the Drupal 5 installation package, there is a script included for Cron and it is called cron.php. This file is located in the root directory of your Drupal installation. You can actually run Cron maintenance by entering, for example, the URL "http://www.yourwebsite.com/cron.php" into a web browser. But we want to get this done automatically, so we need to call on the help of the Lynx browser. Lynx is a text browser that is often installed on servers. You will need to contact your hosting provider to make sure that they have Lynx installed (most probably do). Once you know that Lynx is installed, you will need to find the configuration panel for setting up a Cron job in your hosting account. The first thing to do is enter the command. The following example is the command I use to make Lynx run cron.php: lynx -source http://www.yourwebsite.com/cron.php You may need to adjust this command depending on your hosting provider.

166

3 Aug 2007

Drupal Handbook

The next step is to decide on a schedule to have this Cron job run. Running Cron does use system resources, so you don’t want to have it running every minute if you don’t need to. It is up to you to decide on an appropriate schedule for having each Cron job run. Understanding the format for entering a schedule can take a little getting used to. Here is a quick rundown on scheduling options that can be entered: Minute â any integer from 00 to 59 (specifies the minute the job will be run on) Hour â any integer from 0 to 23 (specifies the hour the job will be run on) Day â any integer from 1 to 31 (must be a valid day if a month is specified) Month â any integer from 1 to 12 Weekday â any integer from 0 to 7, where 0 or 7 represents Sunday The asterik (*) specifies that the task should be run every time for any sub-constraint. This statement doesn’t even make sense to me so let’s just have a look at the examples to figure it out. You can also use the command */ to have jobs run every interval. Here the examples to help you get the hang of it. Run cron.php task every 30 minutes: */30 * * * * lynx -source http://www.yourwebsite.com/cron.php Run cron.php task once a week at 1:00 am every saturday (you can see that saturday is represented by 0): 00 1 * * 0 lynx -source http://www.yourwebsite.com/cron.php Run cron.php task on the first day of every month at 12:00 am (midnight) : 00 0 01 * * lynx -source http://www.yourwebsite.com/cron.php I hope this is helpful for beginners who have installed Drupal and are wondering how to setup Cron.

Check your filters
Drupal input filters are a little known but powerful feature. They can give a site administrator a lot of control over the input of their site. Some contributed modules add filters here to control content display and link behavior. In the Navigation menu, select administer / input formats. (?q=admin/filters)

167

Drupal Handbook

3 Aug 2007

Configure user registration
Configure the user registration options for your site (?q=admin/user/configure). The three options for your Drupal based site are listed here. Only site administrators can create new user accounts. Visitors can create accounts and no administrator approval is required. Visitors can create accounts but administrator approval is required. If you allow user registration, take the time to customize the message to something appropriate to your site and community. User picture support is also enabled/disabled here and relies on the theme to have support for it. These settings can be found in admin >> users >> configure in Drupal 4.6. These settings can be found in admin >> settings >> users in Drupal 4.7. Some sites may want to establish rules for user names, or block registration from certain email domains. This can be done through the Account Rules tab in admin >> access control(?q=admin/access/rules). Set up username and e-mail address access rules for new accounts. If a username or email address for a new account matches any deny rule, but not an allow rule, then the new account will not be allowed to be created. There is allowance for wildcards as well. %: Matches any number of characters, even zero characters. _: Matches exactly one character. For example a rule of %- :would prevent any user names ending in a dash w_rd :would prevent any combination or w any 2nd character and rd %: Matches any number of characters, even zero characters. _: Matches exactly one character. There is also a checking tool to check the effect of your rules.

Creating a menu structure
Drupal comes with a menu module that allows you to create infinitely nested menu trees. You can activate this module at administer > modules if you can’t see the menu item labeled "menu" in the "administer" menu.

168

3 Aug 2007

Drupal Handbook

A screencast of building a basic site navigation system using menu module is also available for Drupal 4.7 users.

Creating a menu
1. To add a new menu, go to the menu module’s page at administer > menus. Click on "add menu" and supply a title for your new navigation. If it is the main navigation, simply call it "Main navigation" or "Default menu" or whatever you find appropriate. 2. Now that you have created your menu, enable it on the administer > blocks page checking the "Enabled" checkbox after the menu name that you entered in step one. You can also change the region and the weight of the menu. This affects where the menu is placed on the page. For a detailed description of what are blocks and how to use them, consult the block module’s handbook page. After having enabled the block, you should see an empty section on the side that has the title you supplied for the menu. 3. Create menu entries. This can be done by going back to the menu module’s page and clicking on "create menu item". Now you can enter a title for the new menu item, supply a short description, define its path (for a detailed description on paths or url aliases, consult the path.module’s handbook page). Select the parent for the menu item. That means, you can select under which navigation item your new menu item is filed. Selecting the item with the same title as your menu’s title means that the new item is a top level item. Select the weight. This defines at which position the menu item is. A lower weight means that the item "floats" above items with "heavier" weight. You can also create multiple menu items for one node. This allows you to find the node on more than one place. But generally your visitors get only confused if they can find the same content on multiple places, so use this feature carefully and only when it’s appropriate.

Simplifying the workflow
In Drupal version 4.6.x, always having to go to the menu module page is sometimes annoying if you just want to quickly add a page to your site. For this purpose, the Menu-on-the-fly module has been created. It adds a section on every create content that allows you to create a new menu item along with the node quasi on the fly (as the module’s name indicates). This functionality is built into the core menu module in 4.7.x

Helping search engines and robots.txt
Drupal by itself is very search engine friendly. For example it is not uncommon for Drupal based sites to have have a Google ranking of 5 or higher (out of 10) where using the same content on another CMS would score much lower.

169

Drupal Handbook

3 Aug 2007

Still, you can make Drupal even more search engine friendly by changing some default parameters. There are several Drupal settings you can tweak to make Drupal even more search engine friendly. 1. First of all you might want to enable friendly URL’s 2. Then, make sure that you get rid of the session ID in the URL by changing the .htaccess if you are using version 4.5.x. On 4.6, session IDs in URLs are disabled by default. 3. Optionally, use URL aliasing for some or all nodes. You can use the pathauto module to automatically create aliases for new nodes.

Controlling what gets indexed -- the robots.txt file
The robots.txt file is the mechanism almost all search engines use to allow website administrators to tell the bots what they would like indexed. A robots.txt is included with Drupal 5.x. Drupal 4.x does not come with a robots.txt file. By adding this file to the root of your (virtual) webserver, you can quide the search engines’ "bots" through your site or forbid indexing parts of your site. See for an example the file for drupal.org itself at http://drupal.org/robots.txt. If you want to have a robots.txt file, please follow the instructions below. For more details check http://www.robotstxt.org Create a file with the content as shown below and call it "robots.txt" # small robots.txt # more information about this file can be found at # http://www.robotstxt.org/wc/robots.html # lines beginning with the pund ("#") sign are comments and can be deleted. # if case your drupal site is in a directory # lower than your docroot (e.g. /drupal) # please add this before the /-es below # to stop a polite robot indexing an exampledir # add a line like (delte the #’s) # user-agent: polite-bot # Disallow: /exampledir/ # a list of know bots can be found at # http://www.robotstxt.org/wc/active/html/index.html # see http://www.sxw.org.uk/computing/robots/check.html # for syntax checking User-agent: * Crawl-Delay: 10 Disallow: /aggregator Disallow: /tracker Disallow: /comment/reply

170

3 Aug 2007

Drupal Handbook

Disallow: Disallow: Disallow: Disallow: Disallow:

/node/add /user /files /search /book/print

This file tells indexing robots that they should avoid pages that contain content for users only, for example the search page, or the ’Add a comment’ forms for nodes. Many robots obey the "Crawl-delay:" parameter. Since Drupal sites seem to be popular with search engines and lots of people have more aggresive bots than visitors at their site, it might be wise to slow down the robots by adding a robots.txt line like this: User-Agent: * Crawl-Delay: 10 Here 10 is the delay in seconds between page requests. Both "Slurp" (The robot that is indexing for yahoo and altaVista) and the Microsoft robots for the MSN sites obey this parameter. Googlebot does not use the "crawl-delay" parameter yet but will likely do so in an upcoming version. Change the file as you wish and save it. Now upload it to your webserver and make sure it is in the root of the (virtual) webserver. If you have installed Drupal in a subdirectory (for example /drupal), then change the URL’s in the robots.txt file but place the file in the root of the webserver, not in the root of your drupal instalation. Now watch the robots visit your site and after some time, monitor your log files ("referrer log") to see how many visitors came from a search engine.

Add ’Disallow: /node/’ if your setup has aliases for all nodes
If your Drupal setup has aliases for all nodes (mostly happens when you use path and pathauto both) then add Disallow: /node/ to your robots.txt. Nodes with aliases are accessible from 2 URIs: the default URI and the aliased URI. Search engine bots will discover both over a period of time and this might lead to penalisation for duplicate content as well as twice as much crawling as is really required. I learnt this the hard way. It is best to do this when the site is new.

Selective Bot Crawling
here’s a copy of my robots.txt file: # AllTheWeb User-agent: fast-webcrawler Crawl-Delay: 10 Disallow: /aggregator

171

Drupal Handbook

3 Aug 2007

Disallow: /tracker Disallow: /comment/reply Disallow: /node/add Disallow: /user Disallow: /files Disallow: /search Disallow: /book/print Disallow: /admin Disallow: /cron.php Disallow: /xmlrpc.php Disallow: /database/ Disallow: /images/ Disallow: /includes/ Disallow: /modules/ Disallow: /scripts/ Disallow: /themes/ Disallow: /email_disclaimer Disallow: /privacy_policy Disallow: */add/ # AltaVista User-agent: scooter Crawl-Delay: 10 Disallow: /aggregator Disallow: /tracker Disallow: /comment/reply Disallow: /node/add Disallow: /user Disallow: /files Disallow: /search Disallow: /book/print Disallow: /admin Disallow: /cron.php Disallow: /xmlrpc.php Disallow: /database/ Disallow: /images/ Disallow: /includes/ Disallow: /modules/ Disallow: /scripts/ Disallow: /themes/ Disallow: /email_disclaimer Disallow: /privacy_policy Disallow: */add/ # Googlebot User-agent: googlebot Crawl-Delay: 10 Disallow: /aggregator Disallow: /tracker

172

3 Aug 2007

Drupal Handbook

Disallow: /comment/reply Disallow: /node/add Disallow: /user Disallow: /files Disallow: /search Disallow: /book/print Disallow: /admin Disallow: /cron.php Disallow: /xmlrpc.php Disallow: /database/ Disallow: /images/ Disallow: /includes/ Disallow: /modules/ Disallow: /scripts/ Disallow: /themes/ Disallow: /email_disclaimer Disallow: /privacy_policy Disallow: */add/ # Looksmart User-agent: wisenutbot Crawl-Delay: 10 Disallow: /aggregator Disallow: /tracker Disallow: /comment/reply Disallow: /node/add Disallow: /user Disallow: /files Disallow: /search Disallow: /book/print Disallow: /admin Disallow: /cron.php Disallow: /xmlrpc.php Disallow: /database/ Disallow: /images/ Disallow: /includes/ Disallow: /modules/ Disallow: /scripts/ Disallow: /themes/ Disallow: /email_disclaimer Disallow: /privacy_policy Disallow: */add/ User-agent: zyborg Crawl-Delay: 10 Disallow: /aggregator Disallow: /tracker Disallow: /comment/reply Disallow: /node/add

173

Drupal Handbook

3 Aug 2007

Disallow: /user Disallow: /files Disallow: /search Disallow: /book/print Disallow: /admin Disallow: /cron.php Disallow: /xmlrpc.php Disallow: /database/ Disallow: /images/ Disallow: /includes/ Disallow: /modules/ Disallow: /scripts/ Disallow: /themes/ Disallow: /email_disclaimer Disallow: /privacy_policy Disallow: */add/ # MSN User-agent: msnbot Crawl-Delay: 10 Disallow: /aggregator Disallow: /tracker Disallow: /comment/reply Disallow: /node/add Disallow: /user Disallow: /files Disallow: /search Disallow: /book/print Disallow: /admin Disallow: /cron.php Disallow: /xmlrpc.php Disallow: /database/ Disallow: /images/ Disallow: /includes/ Disallow: /modules/ Disallow: /scripts/ Disallow: /themes/ Disallow: /email_disclaimer Disallow: /privacy_policy Disallow: */add/ # Yahoo Vertical Crawler User-agent: yahoo-verticalcrawler Crawl-Delay: 10 Disallow: /aggregator Disallow: /tracker Disallow: /comment/reply Disallow: /node/add Disallow: /user

174

3 Aug 2007

Drupal Handbook

Disallow: /files Disallow: /search Disallow: /book/print Disallow: /admin Disallow: /cron.php Disallow: /xmlrpc.php Disallow: /database/ Disallow: /images/ Disallow: /includes/ Disallow: /modules/ Disallow: /scripts/ Disallow: /themes/ Disallow: /email_disclaimer Disallow: /privacy_policy Disallow: */add/ # Exclude every other bot (hopefully) User-agent: * Disallow: / ... this way, it blocks every bot, except the ones i listed. a much more logical approach, methinks. also, a little off-topic, but don’t forget to Disable PHP’s session use_trans_sid for cleaner search engine listings.

Increase upload size in your php.ini
Drupal’s limits on upload file size are determined by your server’s PHP settings. The default values for PHP will restrict you to a maximum 2 MB upload file size. Drupal 4.7.x and above calculates and displays the maximum file size that you can set in the settings page for the upload module based on two PHP settings, ’post_max_size’ and ’upload_max_filesize’. Since ’post_max_size’ is the limit for all the content of your post, potentially including multiple uploaded files, the upload module limits the size of a single attachment to be 50% of post_max_size, or 100% of upload_max_filesize, whichever is smaller. The default PHP values are 2 MB for upload_max_filesize, and 8 MB for post_max_size. Depending on your host, changing these two PHP variables can be done in a number of places with the most likely being php.ini or .htaccess (depending on your hosting situation). For example, to increase the limit on uploaded files to 10 MB: Add the below to the relevant php.ini file (recommended, if you have access). Note that for some hosts this is a system-wide setting. However, for hosts running PHP as a CGI script with suexec (for example) you may be able to put these directives in a php.ini file in your Drupal root directory.

175

Drupal Handbook

3 Aug 2007

upload_max_filesize = 10M ; post_max_size = 20M ; Add the below to your .htaccess file in the you Drupal root directory. php_value upload_max_filesize 10M php_value post_max_size 20M The PHP documentation states that the memory_limit setting also affects file uploading. Generally speaking, memory_limit should be larger than post_max_size. If this is an issue, see the page on how to Increase memory in your php.ini

Need images etc? - check Filtered HTML
As you start creating content like a story or an article, it’s easy to overlook "input formats" where there are options for filters like Full HTML or Filtered HTML. But these are very important; and the well-meaning Filtered HTML can trip up many a Drupal newbie: certainly caught me out, and had me searching for solution. The Filters remove HTML that isn’t listed as acceptable, as website code is processed for previews or actual views, to safeguard your site from potential harm. Can set the site’s default filter, plus decide which user groups have permission to use certain filters. For me, as plenty of others, an apparently weird early problem was that I added an image to my text, but couldn’t see it in Preview or web pages. The reason: I’d left "input format" in default mode, which uses Filtered HTML. And this, by default, is so enthusiastic in stripping out potentially dangerous HTML that it also removes <img> tags. Result: no images! One solution is to use Full HTML, so Drupal’s bodyguards stand down, and all HTML code entered is allowed on actual site. This, though, is unwise if you’ll have untrusted users contributing to the site. It’s better, then, to permit <img> and perhaps a few other HTML tags in Filtered HTML for untrusted users (if you’re site superuser, can use Full HTML as needed). Or, better still, create one or more new Filters: which, you’ll find, can include other filters. Creating a Filter (site configuration - input formats - add filters), you’ll see that you have the option to include existing main filters, such as Filtered HTML and - depending on modules things like a filter for menalto Gallery, and inline images filter from Image Assist. But, in Drupal 5 at least, you can’t see the HTML tags in your custom filter. To see these, save your Custom Filter. Then, choose "configure" from the list of key filters, and then configure again. Now, you can revise the list of tags. At least add <img>. But since the default Filtered HTML seems like some latterday Ebeneezer Scrooge of the website world, can also add more. As I type this, Drupal site notes: Allowed HTML tags: <h1> <h2> <h3> <h4> <h5> <h6>

176

3 Aug 2007

Drupal Handbook

<em> <strong> <code> <del> <blockquote> <q> <sub> <p> <br> <ul> <ol> <li> <dl> <dt> <dd> <a> <b> <u> <i> <sup> There’s a post on TINYMCE - http://drupal.org/node/59769 - suggesting that use: <quote><a> <em> <strong> <u> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <img> <p> <sub> <sup> <strike> <blockquote> <hr> <br></quote> for fckeditor, a suggested list (posted by someone helping me with Filtered HTML troubles) is: <a> <em> <strong> <small> <sup> <sub> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd> <h1> <h2> <h3> <h4> <img> <br> <br/> <p> <div> <span> <b> <i> <font> <color> You’ll want to leave option "strip disallowed tags". It may be useful to create extra Filters, for finer control on users and HTML they can input. For instance, if someone will be writing and editing articles, could allow them a wide range of tags. (If you have, say, a user group "writers n editors", might create Filtered HTML for Editors.) But for folk who register and can just add comments, post to forum, could have tighter list. This, perhaps, could obviate need for BBcode, albeit a few fckeditor style buttons would be more user-friendly than listing of code tags. Note that the input formats are stored as you save text etc. So if you change filter you want to be used as default for your site, won’t affect saved pages.

Set default content options - Stop automatic promotion to the front page
Configure the default content workflow suitable for your site. Out of the box, Drupal modules are set to promote to the front page. While this is desirable in many instances, it is not something you always want. The administration menu has changed in 4.7, so the config screen for this has moved. In 4.6 and older: Go to the Administer > Content Select the Configure tab and then the Content Types sub tab. In 4.7: Go to Admin > Settings > Content-types In 5.x Go to Administer > Content Management > Content-types Click on the configure for the node type in question and change the default workflow options to something suitable for your site. If you add or enable modules such as CCK that create additional node types, you will need to revisit these settings. Remember that.

177

Drupal Handbook

3 Aug 2007

Show/hide ’Submitted by’ on posts
Set appropriate post information for your site. In 5.x: In (Administer > Site building > themes), select the "configure" tab, then "Global settings." Select the appropriate "Display post information on" that are right for your site. Available options will be determined by the installed modules on your site. Other options can be configured on the individual theme’s configuration page. In 4.7 and before: In (administer > themes) (URL: ?q=admin/themes/settings) menu, select the "configure tab" and "Global settings" sub-tab. Select the appropriate options for your site in the "Display post information" menu.

Blocks
Blocks are the boxes visible in the sidebar(s) of your Drupal website. Most of the blocks that you will see (e.g., recent forum topics) are generated on-the-fly by various Drupal modules, but you can also create your own blocks. Whether, and where, a given block will appear on a page depends on both the theme enabled and on administrative block settings. Block settings are controlled from the block administration screen, which you can reach by clicking administer » blocks. From this screen, you will be able to control whether each block is enabled where it will be placed on the page, and which pages it should appear on.

Block configuration
Whether a block appears on a page depends on a number of factors. First, the block must be enabled by checking its "enabled" box on the block management page; Second, the block’s custom visibility settings must permit the block to be displayed for a given user. You can configure a block to appear always; to be displayed by default unless disabled by individual user preferences, or to be disabled by default but visible if enabled by individual users. Individual users can select or disable optional blocks from their "my account" page; Next, whether the block appears on pages for a given section of the site can be configured by the administrator by setting the block’s path; The block can be configured to appear only for certain content types; Finally, if the throttle module has been enabled, and the block has its throttle box checked on the block management page, then it will only appear if the site’s traffic is below a given threshold.

178

3 Aug 2007

Drupal Handbook

Once you have configured a block to appear as required on specific pages and in the correct column, you may wish to adjust the block’s weight to position the block vertically within its column. A block’s weight is set via a pull-down selector on the block management page. Heavier blocks (those with a more positive weight) "sink" to the bottom of a column, while lighter blocks "float" towards the top. More infomration can be found in the modules section of the handbook on block

Restricting blocks to certain pages
Below the Page Specific Visibility Options options, you will see a large text box. On each line, you can specify which pages that block will appear on -- or not appear on, depending on what you selected above. The following are some annotated examples. They all assume that you choose the second option above; if you chose the first option, blocks will appear on all pages other than what you specify below. You’re welcome to add more than one listing, each separated by lines. (Note that you cannot specify pages on which blocks appear as well as pages on which blocks do not appear. It is either one or the other.) <front> node/42 Specifies that the block appears on the front page. Specifies that the block will appear on the item with the node ID of 42.

aggregator Specifies that the block appears on just the aggregator. Specifies that all URLs that start with blog/ will show the block. Note: if you want the block(s) to also appear on the main blog page, you need to add blog (that is, without the trailing slash) as well.

blog/*

Some users have reported they receive the error "warning: Delimiter must not be alphanumeric or backslash in [your drupal install] modules/block.module on line 354." if they do not surround their paths in <> like <node/42> Another example, if you have HTML, Javascript or PHP blocks you don’t think are necessary for administrators to see, you can select "Show on every page except the listed pages." and use the following wildcard for the block: admin/* Administrators can select which content type blocks appear on as well. This can be found under "Content specific visibility settings" after clicking the "configure" link for an individual block. Choose which content type blocks appear on by checking the box next to that content type. You can use content type-specific blocks in conjunction with the above restrictions based on URLs.

179

Drupal Handbook

3 Aug 2007

Examples of using PHP for visibility combined can be found in the PHP Snippets section of the Handbook in the article Overview Approach to Block Visibility

Preventing a block from appearing in Drupal 4.5
I’m baffled....I have reviewed the Drupal guide on the site and read through numerous postings from the archive of this list, and have tediously tested many alternate paths. I currently have this path (which works) <^(?!event)> it used to to keep certain blocks off the month view of the calendar. I want to add to that string something that does not display a block on a specific page (e.g. node/635) I tried <^(node/635)|^(?!event)> (did not work) <(^node/635)|^(?!event)> (did not work) I’m not sure I am using the vertical bar | correctly. I had trouble finding examples of multiple paths. I am also not specifying the node/635 correctly, as I could not get to work even when I removed the second part ^(?!event) Thanks, Andrew Hi Andrew, I can empathize with your situation! This is one of the most powerful, but also one of the most difficult, aspects of the block mechanism in Drupal. Both power and difficultly spring from the same source - regular expression syntax. There are entire books on the subject, so please don’t feel stupid! It really is pretty heavy going. You’ll want to place the entire regular expression in angle brackets, as in your examples. The caret (^) anchors your regular expression to the start of a line, that is, the part of the URL immediately following the hostname.

180

3 Aug 2007

Drupal Handbook

Hence <^node> will match http://www.example.com/node, http://www.example.com/node/foo, and http://www.example.com/node/123, if your server is www.example.com. If you omit this and type <node> for example, your regular expression will match http://www.example.com/node, but also http://www.example.com/nodessert, http://www.example.com/blog/how_to_delete_a_node, etc. OK so far? As you have perceived, parentheses group sub-expressions (sort of in the same way that parentheses group sub-expressions in arithmetic, or even in written communication, as in this example!). The ’pipe’ operator (|) is used to separate alternatives. Read it as ’or’. So, <^(foo)|(bar)> can be read as ’match foo or bar at the start of the line’. The expression (?!...) is called a negative look-ahead operator. It says to match only if the subexpression following the ?! does not match from the point where the ?! is evaluated (matched) So <^foo(?!(t))> matches http://www.example.com/fool and http://www.example.com/fooze but not http://www.example.com/foot, or http://www.example.com/football. One more thing - letters and numbers ’match themselves’, but obviously certain other special characters have special meaning (e.g., we’ve already seen that ^,?, !, | and parentheses are treated specially). These are called metacharacters. To match a metacharacter you need to ’escape’ it, by preceding it with a ’\’ (backslash). So, to match the pattern ’foo?!’ you’d have to type <foo\?\!>. Now, we can put all of the pieces together. Just as in arithmetic, or in writing compound sentences, you can create long expressions by combining short ones. Regular expressions can be combined by simply catenating them:<foo> matches ’foo’, and <bar> matches ’bar’; catenate them to get <foobar> matching ’foobar’. You can also combine by alternation: <(foo)|(bar)> matches foo or bar. You can specify that a subexpressions matches zero or more times by following it with an asterisk: <(foo)*t> matches ’t’, foot, foofoot, foofoofoot, and so on. (I’ve omitted the server part of the URL for brevity) On to your example: <^(?!(node\/635)|(event))> matches (at the beginning of the line) anything that doesn’t match the subexpression following ?!, namely, node/635, or event. I’ve escaped the slash - I don’t know if this is necessary (but it doesn’t hurt - any regular character when escaped just matches itself)

181

Drupal Handbook

3 Aug 2007

If you’re beginning to love this stuff, there’s hundreds of more pages of fun examples in various books and on other websites (for example at http://www.php.net). Just search for ’regular expression’ or PCRE (perl compatible regular expressions) Hope this helps, Djun

Custom blocks
A custom block contains content supplied by you (as opposed to being generated by a module). Custom content may be either static (i.e., HTML) or dynamic (PHP generated content). Virtually all of the functionality of Drupal is accessible from within a PHP content block. The flexibility of blocks provides an extremely powerful way to customize your Drupal website. You can create a custom block via the block management screen (click on administer » blocks). Select the new tab and complete the form. Each custom block has a title, a description, and a body. The content within the body can be as long as you wish. Note: In Drupal 4.6, the title of the block is used as its identifier in the database table. Therefore you can only have one custom block without a title (this issue has been fixed in newer Drupal versions). One workaround for this is to enter a title such as this: <!--title of custom block-->. This satisfies Drupal’s need for a block title but the comment markers (<!-- ... -->) prevent it from being displayed.

Increase memory in your php.ini
While Drupal core will run with 8 MB of memory configured for your server, you may need to increase this depending on how may modules you use on your site. In Drupal 4.7.x and below, when you go into ?q=admin/modules, you may experience a blank screen. This is caused by Drupal loading all the modules of your site into memory, whether you have them turned on or not. If you get a blank screen here, you have two choices; increase your allocated memory for PHP or delete unused modules. In Drupal 5.x and above, this problem has been fixed, and the modules page no longer loads all modules. If you are still getting out of memory problems, you should either reduce the number of modules used or increase your allocated memory for PHP. Depending on your host, this can be done in a number of places with the most likely being php.ini or htaccess depending on your hosting situation.

182

3 Aug 2007

Drupal Handbook

Add for example: memory_limit = 12M to your php.ini file (recommended, if you have access) ini_set(’memory_limit’, ’12M’); to your sites/default/settings.php file php_value memory_limit 12M to your .htaccess file in the Drupal root You will need to experiment with the value that is right for you.

Database table prefix (and sharing tables across instances)
Some web hosts limit their customers to one database. Thus, no duplicate table names are possible. In order to assure that these admins can still use Drupal, and even use multiple installations of Drupal, Drupal offers table prefixing. In order to use this feature, you must currently edit the script database/database.x in order to create tables prefixed by the string of your choice. If you are adding contributed modules you will need to also modify INSERT and REPLACE statements to have a prefix as well. For example, change all statements from the format of CREATE TABLE access INSERT INTO system VALUES (’modules/filter.module’,’filter’,’module’,’’,1,0,0); Becomes, CREATE TABLE dr1_access INSERT INTO dr1_system VALUES (’modules/filter.module’,’filter’,’module’,’’,1,0,0); Then use dr1_ (for example) as value of $db_prefix in your sites/example.com/settings.php file. You can also use the prefix.sh in the scripts subdirectory of your Drupal install to do this automatically. You can then update several sites in one swoop with a (bash shell) command-line like for F in ’’ prefix1 prefix2; do \ for S in ‘find ./modules --name \*mysql‘; do \ scripts/dbprefix.sh $F < $S | grep -v DROP |\ mysql -h DBHOST -u DBUSER -pPASSWD DATABASE; \ done; done NOTE:that not all scripts end in mysql, but you get the idea; the ’’ prefix tells the script to run with no prefix at all, ie a straight cat - command that just lets me process all my sites together. Here is a PHP script that creates all of the database tables for all sites in /drupal/sites/*. It works for DRUPAL-4-6. See the Database Table Creation script issue for more info.

183

Drupal Handbook

3 Aug 2007

If you want to share users across multiple sites, you’ll need to use a $db_prefix along these lines: <?php $db_prefix = array( ’default’ => ’authmap’ => ’profile_fields’ => ’profile_values’ => ’role’ => ’sequences’ => ’sessions’ => ’users’ => ’users_roles’ => ’users_uid_seq’ => ); ?>

’thissite_’, ’shared_’, ’shared_’, ’shared_’, ’shared_’, ’shared_’, ’shared_’, ’shared_’, ’shared_’, ’shared_’, // for pgsql

See the sharing tables and sharing tables across databases sections.

Share tables across instances
Table prefixing may be optionally applied to some tables and not others. This has the effect that multiple Drupal installations can share common tables. One interesting application for this is to share the taxonomy tables (vocabularies, term_data). Another interesting use is to share users across Drupal installations. In order to use this capability, create two drupal installs in same DB using different database prefixes. In this example, one is prefixed ’master_’ and the other ’slave1_’. Then edit the conf.php file of ’slave1_’ so that it points some tables to the ’master_’. For sharing users, add the following: $db_prefix = array( "default" => "slave1_", // the prefix for tables that are not shared. "users" => "master_", "sessions" => "master_", "authmap" => "master_", "sequences" => "master_" "profile_fields" => "master_", "profile_values" => "master_", ); Note: The actual tables that you will share depends on your installation. However, the following tables contain data that is highly site specific and therefore should not be shared:

184

3 Aug 2007

Drupal Handbook

cache variable There is a limitation in that you can only explicitly specify which tables will be shared and not the other way round. The following may fail (however a recently deleted comment on this page by marcob suggests this has been fixed: $db_prefix = array( // Be careful of this setup. ’default’ = ’primary_’, ’cache’ = ’slave1_’, ’node’ = ’slave1_’, ’system’ = ’slave1_’, // etc... );

Setup tip for Drupal 5
For Drupal 5+, an easy way to get started with table sharing across instances is to run the installer twice using the same database - it will create the prefixed tables and handle all the initial INSERTS (as with the ’system’ and ’menu’ tables, etc) for all your different prefixes.

Using schema prefixes with PostgreSQL
This page discusses usage of PostgreSQL schemas for prefixes. "Normal" prefixes can be used in the same way as in MySQL, so they won’t be discussed here. PostgreSQL has something called ’schemas’ (http://www.postgresql.org/docs/current/static/ddl-schemas.html). They can be very handy sometimes, but if you don’t know what they are, you probably don’t actually need them and can stop reading here. Schemas can be used as prefixes within Drupal. That is, with a multisite setup, each site can reside in its own schema, and shared tables can reside in a "shared" schema (or even in the public schema). There is one annoyance: the upgrade will fail. This is unfortunate, but nothing can be done as the "normal" (not schema) and schema prefixes are just incompatibile. If you are interested in the details, please see http://drupal.org/node/40034. But, don’t worry. This can be easily fixed by changing the update script (update.php and updates.inc) a bit. The problem lies in the CREATE [UNIQUE] INDEX and ALTER TABLE ... DROP/ADD CONSTRAINT statesments. When schema prefixes are used, queries like this are executed: CREATE INDEX prefix.search_total_word_idx ON prefix.search_total(word) ALTER TABLE prefix.boxes DROP CONSTRAINT prefix.boxes_title_key

185

Drupal Handbook

3 Aug 2007

ALTER TABLE test.contact UNIQUE (category)

ADD

CONSTRAINT

test.contact_category_key

The prefix must be removed from the index and constraint name--that is they must be changed to: CREATE INDEX search_total_word_idx ON prefix.search_total(word) ALTER TABLE prefix.boxes DROP CONSTRAINT boxes_title_key ALTER TABLE test.contact ADD CONSTRAINT contact_category_key (category)

UNIQUE

You can easily search for CREATE INDEX, CREATE UNIQUE INDEX and ADD/DROP CONSTRAINT statements and remove the {} from index/constraint names. The best way is to run a test upgrade. You’ll see a list of failed queries and it will be easier for you to change them. Another remark: you can’t use prefix.sh to prefix the tables, it will produce incorrect CREATE [UNIQUE] INDEX queries. This, also, can be easily fixed, by changing: s/^CREATE INDEX \(.*\) ON /CREATE INDEX $PREFIX\\1 ON $PREFIX/; s/^CREATE UNIQUE INDEX \(.*\) ON /CREATE UNIQUE INDEX $PREFIX\\1 ON $PREFIX/; to: s/^CREATE INDEX \(.*\) ON /CREATE INDEX \\1 ON $PREFIX/; s/^CREATE UNIQUE INDEX \(.*\) ON /CREATE UNIQUE INDEX \\1 ON $PREFIX/; An alternate approach Here’s what you need to do if you want to solve it this way: 1. Add the following at the top of your database.pgsql file: CREATE SCHEMA schemaname; SET search_path TO schemaname; 2. Edit drupal/includes/database.pgsql.inc, replacing the function db_connect() with: <?php function db_connect($url) { $url = parse_url($url); $db_and_schema = explode(".",substr($url[’path’], 1)); $conn_string = ’ user=’. $url[’user’] .’ dbname=’. $db_and_schema[’0’] .’ password=’. $url[’pass’] . ’ host=’ . strtr($url[’host’],’+’,’/’); $conn_string .= isset($url[’port’]) ? ’ port=’ . $url[’port’] : ’’; $connection = pg_connect($conn_string) or die(pg_last_error()); if(!empty($db_and_schema[’1’])) pg_query(’SET search_path TO

186

3 Aug 2007

Drupal Handbook

’.$db_and_schema[’1’]); return $connection; } ?> 3. Finally, use a db_url akin to such in your settings.php file(s): $db_url = ’pgsql://user:password@+tmp/dbname.schemaname’; Not thoroughly tested, but works for me (on 4.6.3). This also fixes the inability to specify a Unix socket as the host - the +tmp gets replaced with /tmp for pg_connect().

Define shared variables for all sites
When you create a multi-site installation, an important table to duplicate is the variable table. However, by duplicating this table, you will also duplicate some variables that you might prefer not to. To force a set value for these variables, for all of your websites, you can do the following. First, you will probably have a settings.php file for each site in your installation, like sites/example.com/settings.php. Edit each file and add the following to the end. include_once (’./sites/default/shared_variables.php’); Now, in the default directory, add a file called sites/default/shared_variables.php containing the following. <?php /** * These variables are fixed for all sites that have this line of * code in their settings.php file: * * include_once (’./sites/default/shared_variables.php’); */ $conf = array( ’site_name’ => ’All these sites are belong to us.’, ’theme_default’ => ’pushbutton’, ’anonymous’ => ’Visitor’ ); The element names (eg. ’site_name’) correspond to a variable in the variable table. So no matter how many copies of the variable table that you need, each site in your multi-site installation will defer to the variables that you define in the $conf array in your shared_variables.php file.

187

Drupal Handbook

3 Aug 2007

The disadvantage is that these variables cannot be edited via the Drupal admin pages.

188

3 Aug 2007

Drupal Handbook

Drupal Cookbook (for New Drupallers)
Purpose
I am one of the many Drupal "newbies" who seemed overwhelmed at first. Well, I still am. But I have learned a lot in my first month with Drupal. I’m even answering question in the forums (actually, I think it’s fora.) With some encouragement from other newbies, I decided to start on writing down what I’m doing to build my sites. (Shoot, at my age, I can’t rely on my memory, I have to write it down.) Yes, that’s plural. As of this writing I have three sites in production, plus a test site for playing around.

Background
The basis of this book is going to be my efforts to build new test sites on my PC, running Windows. Hopefully by the time I get to that point in this book, I’ll have figured out how to transfer the developed sites onto the remote production servers. Pretty much all of this is directly appicable to building a site directly on a web server.

Myths
It is a pure myth that you have to know how to program (especially in php) to use Drupal. It doesn’t hurt to have some basic knowledge of php, HTML, and CSS, but it is not required. Here are some good resources for you: W3 Schools - for virtually everything Internet-related. The Official PHP Site - the full php implementation. PHP Builder - some tutorials and code ready-to-use. Now, to be honest, I have used HTML in this book, and tweaked the CSS on my site a little bit. But I have not used one line of php code. Another common myth is that your learning curve for Drupal is going to be steep and it will take you months, or even years, to get a web site up and running. Hogwash! I had my first, largely static, web site with 36 pages up in less than a week after I installed my first copy of Drupal. Then, because my hosting provider pulled the plug, I got my group’s site up in the time it took to get the domain name transferred (about 5 days). That was after about 16 days from starting with Drupal. That site had a lot of static content, but also required a taxonomy-based access control module, a fancier theme, meta tags, photo albums, and a calendar - and it all had to work right away!

189

Drupal Handbook

3 Aug 2007

You can do it! Yes, YOU.

Using the Drupal Web Site
There are a few things you need to know before you post anything on the Drupal web site: Search to see if the subject has already been covered. If it has, then recreating the subject will probably get you negative comments. If you don’t understand the responses (I certainly identify with that feeling), don’t hesitate to say "I’m a newbie, can you say this in easier to understand terms?" You need to get a few basic terms right or you will be flamed. Node: This is, in simple terms, a unit your content. It may, for example, be a "page," "story," "book page," or "blog entry." Theme: This is the way your site is displayed (or rendered) to the end-user. Block: This is a "container" for pieces of content on your displayed page. For example, your navigation menu and log-in are blocks. You may also have "Recent posts," "Sponsor links," or "Who’s online." Try to completely describe the situation. For example, if a page is not showing up correctly, it could be a browser problem, so make sure you tell the reader what browser you’re using. Always mention which release of Drupal you’re using (4.7.x, 5.x, etc).

Typing Convention
Throughout this site, as well as the Drupal site, you will see things like Administer>>Access control>>User management>>Roles. This means click on "Administer" in the navigation menu, then "Access control," then "User management," and then "Roles." I will occasionally refer to "production" or "live" sites. These terms are pretty much interchangeable. The latter term is more modern and accepted in reference to web sites and means the site that your end-users interact with. The former term is largely synonymous but is a more "traditional" data processing term.

Some Preliminary Advice
This is from a post by ebrad on March 26, 2007, with some minor editing. I don’t know if I could call my sites "great;" it’s taken about 9 months to really get a good understanding of how to use Drupal and its modules. This doesn’t include learning the API or writing my own modules. These are some recommendations I would have given myself before I began with Drupal:

190

3 Aug 2007

Drupal Handbook

Never try anything for the first time on a live site. Use a test site that uses the same modules and same data (different database). I keep 2 tests sites going at all times. Don’t try to make the "perfect site" on your first shot. Muddle through for a while until you understand a better way. Stressing over the perfect solution will slow you down. Stay away from Views, Category, CCK, and Organic Groups modules until you at least have a little experience under your belt. These modules require a good bit of understanding to master and it might discourage you if you try to dive in too fast. However, over time you will come to realize that these are some of the most powerful and flexible modules out there. [Nancy’s note: also stay away from access control (security) modules until later. They can really destroy your site if you don’t know what you’re doing.] Customize one of the default themes before creating your own, the Theme Developer’s Guide in the handbook is a big help. When you run into a problem with a module, make sure to read the "readme," then do several searches with different terms, only rarely have my problems not already been answered in the forums or in an issues queue. To make a site really successful, make it work for the users, not against them. Once you have the basic site set up, get your friends, family, or anyone who will talk to you to look at your site and give honest feedback, or do user testing for a more formal approach (I run a company Intranet and I do user testing every couple of months). Help out in the forums when you can. It’s surprising how explaining something to someone else helps you understand it yourself. Go easy on what I call "gadgets" such as useless blocks, images, and graphics that clutter the page. I prefer simplicity and I only place something on the page if it is needed. This of course depends on your application Good Luck!

Drupal Is Supposed to be Easy?
Drupal is very powerful and flexible. That means it must have a significant degree of complexity. Do you think the folks at Myspace don’t have their terminology or managed to roll out that site in a day? I don’t know who told you Drupal was easy, but many people make it harder than it has to be by thinking they need to understand everything at once. Terminology is necessary in order to properly convey what one is trying to say or ask. If you talk about "that box-like thingy on the right side of my screen" you could be referring to many things. Contrast that with "the Author Information block in the right sidebar" - now you are precise and everyone knows exactly what you mean. You’ve told them what it is, where it is, and even how it got there and part of how you’ve styled it. Start by trying to understand the basic parts of Drupal, don’t try to understand everything at once. For example, it is imperative that you know what a node is (look in my book). Then understand what content types are. Learn the basic parts of the rendered page (header, footer, left and right sidebars, and the center, or content areas). Check out the administration pages so you have some idea where things are, even if you don’t understand them all today.

191

Drupal Handbook

3 Aug 2007

It’s all fine and good to have "Myspace" as your target, but you are one person with a new tool. The people that put that together are many and using tools that they already were familiar with. (BTW, I find Myspace to be rather illogical.) Just start by getting something up and visible. Then celebrate that you’ve done that. Now you’re ready to move on to more wonderful things, but do it one step at a time. Don’t add tons of modules right away; get comfortable with what you have. Add modules one at a time and get familiar with them - one at a time. As for making Drupal easier and more logical, you’re welcome to submit feature requests or explain why something is not done in the most logical manner. But don’t demand it, or threaten to abandon Drupal if you don’t get it your way. And certainly don’t resort to name calling or derogatory comments.

A. Getting Started
Assuming that you want to build a site on your PC (with Windows), I suggest a visit to DeveloperSide.net to download their package. Hey - there’s no need to re-invent the wheel! This package has already integrated the following things: Apache 2.2 HTTP Server MySQL 5.0 Database PHP 5.2 and Perl 5.8 Scripting Languages GUI WAMP-stack Controller Dynamic DNS Client Tomcat Servlet/JSP Container mod_aspdotnet ASP.NET Host Interface OpenSSL Cryptography Toolkit mod_security Web Application Firewall phpMyAdmin MySQL Administration Joomla Drupal WordPress MediaWiki phpBB Don’t ask me what all of those mean, because I have no idea. Did I need them all? I doubt it. But disk space is cheap, and the key thing I looked at was that it had Drupal 5.0 (the latest release) integrated. I followed their instructions, which built me a working system! Yay! I don’t remember if it was automatic or not, but you will find it useful to have the "Web-Developer Controller" icon on your desk top.

192

3 Aug 2007

Drupal Handbook

The only "fly in the ointment" was that when I went to the Drupal web site to start pulling my modules and themes, there was a big announcement on the front page saying that 5.1 had been released and was highly recommended. What’s a girl to do? Do I stick with 5.0 any way, or try to update it to 5.1? Well, in for a penny, in for a pound. I downloaded 5.1. I then unzipped it (using WinZip). Of course, that created a directory called "Drupal-5.1," but the other software I had installed was looking for a directory called "Drupal." Well, by getting Apache and its services shut down, I managed to rename the two directories so that 5.1 was now called "Drupal." It worked! I now had a running 5.1 system! And it was all fairly painless and straight-forward. [Well, you know the plot will thicken, don’t you?] But at least I’m not as afraid to install a new release of Drupal any more.

B. Basic Configuration
Whether you run one site or several, there are some basic things you should do right now. Here’s what I do right off the bat; the advantage to doing it in the "root" database is that when I make copies for my other sites this has already been done. I’d give you a link to something on the Drupal site, but I never found anything like this. 1. Go to Administer>>User management>>Roles and create an "administrator" role. 2. Go to Administer>>User management>>Users and create a user entry for yourself. This allows you to test the site by changing your role to meet your needs. 3. Go to Administer>>User management>>Access control and allow the "administrator" role to do everything. 4. While you’re there, go ahead and set what the "authenticated users" (logged in) and "anonymous user" (not logged in) can do, such as using your contact form. This is not engraved in stone; you can change it any time you want. 5. Go to the Administer>>Site configuration>>Site information page and, near the bottom, set the "Default front page" to "node." As long as you’re on this page, set basic defaults for the other fields. I don’t know about everyone, but I don’t like, when I visit a site, being called "Anonymous" so I change the designation to "Visitor." 6. If there are any modules (core or contributed) that you use on all sites, go ahead and enable them now ((Administer>>Site building>>Modules). For example, you will probably use "Page" on all sites, and maybe "Story." I am finding more and more uses for "Book." 7. I do recommend turning on (enabling) the "Path" core module so you can use "normal" names for your pages. If you want to use the contact form to email anyone from the site, be sure to enable the "Contact" module.

193

Drupal Handbook

3 Aug 2007

8. The same goes for themes. There are a few things I recommend that you do in all your databases, so this is a good time to do it: Turn on "CLEAN URLS" to make your site more user friendly. Go to Administer>>Site configuration>>Clean URLs. At the bottom of the verbiage there is a link to run the "Clean URLs Test." If it passes, then the "Enable" radio button will un-dim. Click on that. (If the URLs stop working for some reason here are instructions to unset clean URLs.) In order for me to create any kind of content, I go to Administer>>Site configuration>>Input formats and set "Full HTML" as the default until I get the site ready to go live. Then I still allow administrators (like my other ID) to use that format. Do this now and you will avoid a very common problem with building your site. I don’t like having "Promoted to front page" as a default for content, so I go to Administer>>Content management>>Content types and turn that off - in each format. While you’re there, decide on your default comment mode. Go to Administer>>Content management>>Comments>>Settings and set the comments to be entered on a "separate page" and make sure that "Preview comment" is set to "Required." Now, let’s turn on the Contact form so your users can send you a message. Go to Administer>>Site building>>Menus and locate the "Contact" item. Click on the "enable" link. Remember that later on you will want to go to Administer>>Site building>>Contact form and finish setting that up.

C. Creating Multiple Sites On Your Local Computer
Need another test site? Here’s how to do it the "easy" way. [Hint: if you want several test sites, make a list right now. Read these instructions all the way through. Now you can do some of the steps in bulk to save some time.] Why create extra sites? In addition to my having several sites running already, I had some ideas in the back of my head, not the least of which being a site where I could document everything I do (like this book). I also had some idea for other sites that I might put up in the future. So before you totally pooh-pooh the idea, give it a few minute’s thought. And you can always change your mind later; it just might be a bit messier then. At the very least, I would create a "working" site other than my "root" site. This makes it easier to start all over again if you get totally out of control later on. This may look like a long process, but it’s deceiving because I spell it out in detail. It is expanded and updated from the post "Running multiple sites on a local PC (localhost) from a single codebase, using Windows." For more details on the "official&quot. stance on the sites directories, read Setup of /sites directory for multi-site.

194

3 Aug 2007

Drupal Handbook

Open phpMyAdmin (using "other" in Web-Developer Controller) start bulk loop 1 On the left, select the Drupal51 database. This is the one that was created by the package installation. Click on "Operations" Scroll down to "Copy Database to:" Enter the new database name. Verify that the radio buttons are clicked for: Structure and data CREATE DATABASE before copying Switch to copied database Click on the Go button just below this area. When the copy is complete, click on "SQL". In the "Run SQL query/queries on database" box, enter: GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES ON databasename.* TO ’admin’@’localhost’ IDENTIFIED BY ’superpw’; FLUSH PRIVILEGES; admin is what I call my administrative role (this is the "super-user" name); superpw is the password for this user (I tend to use the same one for all my databases to make it easy). Hint: I created and saved this in c:/www/drupal/grant.txt so I could copy and paste. Change databasename to the new database’s name. end bulk loop 1 Close phpMyAdmin. Go to the www/Drupal/sites directory. start bulk loop 2 Copy one of the site folders (e.g. default) and name it for your new site. Open the directory, then open the settings.php file in Notepad. Change the $base_db and $base_url lines. The $base_db line should have the name of the database you just created. The $base_url will be how you want to access the site. Close the file. If you are going to have site-specific modules or themes, go ahead and create directories in this site to hold them (named "modules" and "themes"). end bulk loop 2 Navigate to the /www/Apache22/conf folder. Locate and open the "httpd.conf" file (Hint: I always make a copy of things I’m about to change, just in case I mess up.)

195

Drupal Handbook

3 Aug 2007

I did notice that my version of Apache sets index.html ahead of index.php, so don’t have an index.html in your directory.

Find the line that says "# Virtual hosts." Remove the "#" from the next line. This allows you to make all your other changes in a separate, and less dangerous file. Save it. Navigate to the /www/Apache22/conf/extra folder. Open the httpd-vhosts.conf file. At the bottom of the existing list, comment out ("#") the examples. start bulk loop 3 At the bottom of the existing list, enter: <VirtualHost *:80> DocumentRoot /www/drupal/ ServerName databasename </VirtualHost> Change databasename to the new database’s name. end bulk loop 3 Close the file. Navigate to the /windows/system32/drivers/etc folder. Open the Hosts file with Notepad. Hint: these two steps can be done by using "other" in Web-Developer Controller. start bulk loop 4 Add a line that says: 127.0.0.1 databasename Change databasename to the new database’s name. end bulk loop 4 Close the file. Go back to Web-Developer Controller. Click on Apache2 (top left). Click the Stop Service button. Wait for it to change to "stopped." Click the Start Service button Wait for it to say "running." Go for it. You can now start the browser and enter http://databasename.

196

3 Aug 2007

Drupal Handbook

For more details on directories for multiple sites, see Setup of /sites directory for multi-site.

D. Error Pages
Occasionally, a user may do something that confuses Drupal, such as typing a wrong page name or trying to access content they shouldn’t. These will generate 404 and 403 errors, respectively. A recent SEO newsletter, they mentioned the value of letting Drupal handle these errors: Your unique 404 error page should look like a regular page of your site. It should include your site’s header, footer and navigation bar so that the site visitor can easily click on another area of your site. The content of this unique 404 error page should contain text explaining that the page selected is no longer available along with contact information so the site visitor has the option of emailing or calling your company. This was one of those "Duh" moments for me. How obvious it is that you should make it easy for the user to get "back into" your site. The same more or less goes for the "access denied" (403) error message. Let them know they did a no-no and try to explain why. Just go to "Create content" and select "Page." I title them "Access Denied" and "Page Not Found" but you can call them whatever makes sense to you and your users. When you submit them, note the node ids. Then go to Administer >> Site Configuration >> Error Handling and enter "node/nnn" in the appropriate boxes.

Page Not Found
Here’s the HTML for my 404 page: <p>Sorry! The page you were looking for no longer exists. We redesigned our site and many of the pages have changed.</p> <p>&nbsp;</p> <p>If you are unable to find something on our new site or have a question about our site or services feel free to <a href="/contact">contact us</a>.</p> <p>&nbsp;</p> <p>--Webmistress</p>

Access Denied
Here’s the HTML for my 403 page: <p>We’re sorry, but you must have permission to view the page you requested.</p> <p>&nbsp;</p> <p>If you are already a registered member of this site, please try <a

197

Drupal Handbook

3 Aug 2007

href="user">logging in</a>.</p> <p>&nbsp;</p> <p>If you are not a member, you need to <a href="/join_us">join us</a>.</p> <p>&nbsp;</p> <p>If you have any questions about our site or group, please feel free to <a href="/contact">contact us</a>.</p> <p>&nbsp;</p> <p>--Webmistress</p> Don’t worry that you haven’t created the "join_us" page yet. This is an advantage to having URL Alias support (the Path module) enabled. Just add to your to-do list to create this page when you get to the "Creating Content" step a few chapters later in this book.

E. Accessing Your Test Site(s)
Okay, great, now we have all that software installed. But how do we use it? First, open the "Web-Developer Controller" that you put on the desk top. Look at the top left. You want to see, and should, if Apache and MySQL are running. If they are, you’re just about ready. If not, select Apache, then click on the "Start Service" button. Within a few seconds it should change to "Running." Now select "MySQL" and start it. Fabulous, we have the software ready for us. Now let’s get us ready. Fire up your favorite browser. In the Address field type in http://localhost/drupal/ to access your "root" database. Since you’ve done everything right, you’re now into your Drupal database. Congratulations! Now the work begins.

F. Adding Modules and Themes
Let me first say that a newbie shouldn’t worry a lot about adding modules and themes at first. Work on the basics of your site first, then worry about add-ons. Themes are largely a matter of taste. For example, I have no idea why anyone would use a "fixed width" theme, but lots of people do. One nice thing about themes are they are pretty much independent of your content (later on you can look at the many submissions that are dependent on content). Contributed modules are ways to add or extend functionality of your site. The only module I, personally, consider necessary is the Nodewords (a.k.a Meta Tags) module; in my opinion, it should be promoted to "core" status. This one allows you to add the "content," "keywords," and "robots" meta tags to your pages. This is useful if you’re interested in your search engine rankings. You will also find that many contributed modules also require the Views module; I go ahead and make that a standard one for my sites.

198

3 Aug 2007

Drupal Handbook

Now, if you experiment with different themes and modules, as I know you will, despite my suggestions, you should also look at the Update Status and Site Documentation modules to make sure you are current and to document and clean up the mess your experimentation will make.

Installation
Installing a module or theme is pretty much the same until you get to enabling them. Now keep in mind that I use a Windows based PC (development) and Linux servers (on my live sites). 1. Go to the Drupal site and click on the "Downloads" tab. Then select either "Modules" or "Themes" depending on what you’re after. 2. Locate the module or theme you want. 3. I always click on "Find out more" and read the stuff again. This gives you the chance to see if there is support for your release of Drupal. You can also look at pending bugs and feature requests - it might change your mind. 4. Download the proper release. (I put them in a Drupal folder in "My Downloads.") 5. Unzip the downloaded file (I use WinZip). It may tell you that there is only one file in the zipped file; click "yes" or "OK." 6. Extract the code to to your Drupal/sites/sitename/modules or themes folder. If you are not running multiple sites, this would be Drupal/sites/all/modules or themes. 7. That’s it! Now you need to enable it.

Modules
Modules
You enable a module at Administer>>Site building>>Modules. The non-core modules are listed farther down. With 5.x, they now show you some of the inter-module dependencies. I turn them on and "Save configuration" in order of the dependencies. For example, "Views UI" requires "Views", so I turn on "Views" first, save the configuration, then turn on "Views UI." and save again. Ah, now the real work begins. Go to Administer>>User management>>Access control to select who can use the features of the new module. If the module introduced new content types, go to Administer>>Content management>>Content types and configure them. Don’t forget this may also affect your "Input formats" (Administer>>Site configuration>>Input formats) and "Categories" (or taxonomy, Administer>>Content management>>Categories); you’ll have to check those too. Okay, now you can start using the new module.

199

Drupal Handbook

3 Aug 2007

This Site
My documentation site is a relatively "vanilla" implementation of Drupal. Core Modules Enabled Blog Book Comment Contact Help Menu Path
pieces of code. description.

Contributed Modules in Use Codefilter - Provides tags for automatically escaping and formatting large Meta Tags (Nodewords) - Allows users to add meta tags, eg keywords or Site Documentation - Documents and cleans up your configuration.

To get some idea of what modules are available, check these links: module handbook and contributed modules handbook.

Themes
Themes
You enable a theme at Administer>>Site building>>Themes If it has never been enabled on this site, you will have to check the "enable" box and then click the "Save configuration" button at the bottom. To set up how the theme works, click on the "Configure" link (not the tab at the top). Fill in the fields. Save the configuration. Don’t leave the page yet.

Logo and Favorite Icon
Now use that "Configure" tab I prefer to do this part under the "Global Settings" but it can be done theme-by-theme if you prefer. The "Default Logo" is that little picture (usually) in the upper left corner of the page. For example, on the "Bluemarine" theme, it’s the Drupal logo.

200

3 Aug 2007

Drupal Handbook

If you want to change it, here’s how: 1. First, find out what size it is because you’ll want your own logo to be about the same. (If you are comfortable with HTML and CSS you can also edit the theme’s code to accommodate your logo rather than resizing the image. How to edit theme code is not covered in this beginner’s guide.) 2. Theme Name Width Height Bluemarine Chameleon Garland Minelli Pushbutton Fancy 48 49 64 64 144 80 55 57 73 73 63 80

3. Under "Logo image settings" either type in the path to your logo, or upload it from your PC. 4. Note: Neither one of those options turns off the "Use default logo" radio button. You must select the correct radio button yourself. 5. The "Shortcut icon" (a.k.a. the favorite icon, or "favicon.ico") is the same way. If you want to change this, you must specifically say, "Hey, Drupal, I’m changing this." Now you click the "Save configuration" button. If you did this in "Global settings" it affects all themes (assuming they behave properly); if you did it for a single theme, then only that theme is changed. For a list of all available themes, check Themes. HINT: Going to make a few (or a lot) of changes to a standard theme? Think about copying it over to your /sites/sitename/themes/ folder and renaming it. Then you can do anything you want and still be able to undo it easily by recopying. If the changes ae a bit bigger, think about contributing it back to the community (with your name, of course).

G. Creating Content
"Wow, I’ve done all this and I still don’t have any content on my site!" Well, let’s fix that.

201

Drupal Handbook

3 Aug 2007

First, let me explain that the page your visitor sees first upon entering your site is usually called the "home" page. Drupal calls this the "front" page, much like a newspaper. This page is special to Drupal. I know you’re in a hurry, but read about both "pages" and "stories" before you decide which to use to create your front (home) page.

Content Types Page
Drupal says, "If you want to add a static page, like a contact page or an about page, use a page." If you’re used to building web sites with HTML, this is what you’ve done in the past. In general a "page" is going to stand on its own and will probably have a menu entry. You may also later add it into a book. When I created my first two sites (based on former static HTML sites, I made the front page a "page;" I have since changed to a "story."

Story
Drupal says, "Stories are articles in their simplest form: they have a title, a teaser and a body, but can be extended by other modules. The teaser is part of the body too. Stories may be used as a personal blog or for news articles." Why they say to use it for a blog, I have no idea; they supply a blogging module as part of the core support. Okay, you’ve seen the Drupal site and noticed that there are "pieces" all over the place. Look at the front page; you’ll see several announcements with space between them - those are "stories." I have now switched my sites to use stories on the front page. The "welcome" message is one story. I have an announcement story node that any of my admins can edit. If you want to have weather or cartoons, a story is a good idea. Another use is if you are on a net ring - put the ring links into a story.

Book Page
Drupal says, "A book is a collaborative writing effort: users can collaborate writing the pages of the book, positioning the pages in the right order, and reviewing or modifying pages previously written. So when you have some information to share or when you read a page of the book and you didn’t like it, or if you think a certain page could have been written better, you can do something about it." Another way to use a book is to collect related information together. A book has its own navigation, so it can also be used to de-clutter your menu.

202

3 Aug 2007

Drupal Handbook

Blog Entry
You probably already know what a blog is, but just in case: A blog is a diary, collection of thoughts, or other time-ordered content.

So have you decided what kind of content you want? No, okay, just start with a page; it’s easy. As you go create your content, be thinking about the menu as well.

G1. Creating a Page
A page is probably the simplest content, other than maybe a blog. Click on "Create content" in the menu, then select what kind. The title and body are pretty self-explanatory. Below these are a number of collapsible fields. "Input format" controls what you can put into the page; I’m assuming you are the "super-user" (user/1), so give yourself the priviledge of "Full HTML." If you have Nodewords installed, the next section is "Meta Tags." It’s pretty well documented. I have no idea why you’d use the "Log message" but I’m sure someone has a reason. Hopefully, you already set your default "Comment settings" but the front page rarely deserves comments, so you can disable them. If you turned on the "Path" core module, you’ll have URL path settings next. You can enter a "normal" name here rather than being required to use "node/2" when you refer to it later on. Hint: if you are converting a site that was static pages, you might want to go ahead and add ".htm" or ".html" to the name so that the search engines will continue to find the page. "Menu settings" is the next section. "Title" is what will show in the menu normally. "Description" will show when the user hovers the cursor over the menu item. "Parent item" allows you to create multi-level menus that collapse and expand. "Weight" allows you to set a relative position within the menu; unfortunately, some Drupal core items are hard-coded at 0. Chances are you won’t need "Authoring information" unless you want to attribute the page to someone else. The other use for this section is to control the page or story order when they are based on the time and date it was created. Finally, "Publishing options," which you set defaults for earlier, right? You want the page "Published" so it will show up. If this is your "Welcome" page, you’ll want it "Promoted to front page." "Submit" it.

203

Drupal Handbook

3 Aug 2007

Congratulations, you now have some content on your site!

G2. Creating a Story
Most of what goes for a page is also true for a story. You can largely consider the two types to be interchangeable, and it is goodness to have at least two content types because conflicts can arise in the way content types are used (for example, taxonomy "collisions"). Stories have a "teaser" or opening statement intended to grab the reader’s attention. The length of the teaser is set in one of two ways: In Administer>>Content management>>Post settings. The default there is 600 characters. You can change that. By specifically identifying a break point with ‘‘< !--break-->’’ in your content (before the default limit; leave out the space). Note: You may see some places that tell you to use ‘‘<break>’’ to set a teaser point. This was originally changed in 5.0 and created a considerable controversy, so it was backed out. A story probably shouldn’t have a menu entry. If you use the general "convention" that a "page" is for static or generated content that stands alone, and "story" is for collections of related content (e.g. RSS feeds, newsletter articles, press releases, etc.), then a story is usually going to be displayed with other stories, so which one would be the menu item? Generally the menu for a set of stories will be a description of how they are selected for display. You may want to promote the story to the front page. For your ‘‘Welcome’’ message, you probably also want to make it ‘‘Sticky at top of lists.’’ Alternatively, you can give it a lighter ‘‘weight’’ so it "floats" up the list.

What’s a Teaser?
This is from a post by zoon_unit on January 10, 2007. A ‘‘teaser’’ is essentially a snippet of text designed to tell the user the content of a post without reading the entire post. Since most writers have embraced the common journalistic style of explaining the nature of an article in the first paragraph, teasers work well for most articles. Here’s what happens: 1. A node contains an entire article. 2. Drupal’s ‘‘teaser’’ function, ‘‘node_teaser,’’ strips the first x number of characters from the article and makes it available as content. The exact length is determined by the value set in Drupal’s Administer » Content management >> Post settings. 3. So, you list a bunch of articles on a page. You want the articles to display only a snippet of text from the full article, so that you can fit a bunch of articles on a page without requiring the user to page down through tons of text. If the user likes the ‘‘teaser’’ content of the article, they will click on the article’s title and see the full content of the article on its own

204

3 Aug 2007

Drupal Handbook

page. In a sense, teasers function like summaries of an article, except that the software decides where to cut off the text. If you want to determine where a teaser article ends, you can insert the comment tag to instruct Drupal exactly where to fashion the break between full text and teaser text. NOTE: There is a bug in the core Node module. Check the issue status. It is a simple change (can be done manually) and must be applied in order for some modules to render teasers correctly. By the way, you might want to add your own experience to that bug report in order to increase its attention by the developers.

G3. Creating a Book Page
Generally, I only create one book page for each book. This is the first one, usually the introduction. All other pages will be added as "Child pages" (to be accurate, child pages will still have the "book page" content type set for them). In addition to the things I said about pages, a book page has a "Parent." For the first page, this will be "<top-level>." If you use "Add child page" the "Parent." selection should be already filled in with the book’s name. If you create another book page, you would need to make sure you properly select which book or page teh new one is to be made a child of. The top page of the book probably deserves a menu entry. The rest do not, unless they are really special. Remember, a book has its own navigation. You are currently reading a "book."

G4. Creating a Blog entry
Blog entries are a little different. Assuming you enabled the "Blog" module, you should see a "My blog" entry in your navigation menu. When you click on that, there will be a "Post new blog entry" link on that page. If the blog is a diary, you probably want to use the date for the title. If it’s a collection of thought, give it a meaningful title. Type in the content of the entry. Your blog will always show the most recent entries on the beginning page when visitors view it.

205

Drupal Handbook

3 Aug 2007

H. Custom Blocks
I’m not going to say a lot about custom blocks. But I will show you some really simple ones to give you a flavor. There’s a lot I still don’t know about custom blocks, and that fills many posts on the Drupal web site. One good starting point is: Blocks.

Address
A business or support group should always let people know how to contact them. One easy thing is to include your mailing address on your pages. This is about the easiest kind of block to start with. 1. Go to Administer>>Site building>>Blocks. I should already be sitting on your default theme, but if not, select the right one. 2. Click on the "Add block" tab. 3. Fill in the "Description" and "Body." Here’s a sample body: 4. My company name<br>123 Main St.<br>Mytown, State Zip<br>USA<br>(123) 456-7890 5. Save the block. 6. For some strange reason, you now need to "Configure" the block to add the block’s name and placement. 7. Add the name. 8. Determine whether users can turn to block on or off. Then which roles can see it; leave this with no selections to allow everyone to see it. Then choose which pages it will be shown on; I show the address on all pages. 9. Save the block. 10. Now you’re back on the block list. Locate the block you just created. Select its location; I like the address in the left sidebar. You can use the "Weight" parameter to set its position with in the selected area; again, I like the address at the bottom, so I use a heavier weight. 11. Click on the "Save blocks" button. That wasn’t so bad was it?

Last Updated
It is fairly common practice, especially on a group site to let the visitors know when the site was last updated. This example requires you, the webmaster or administrator (sometimes called the "super user") to maintain the block. There are ways to automate it, but I leave that until we are all farther along in our Drupal education. I followed pretty much the same process for the address block, giving this one a slightly heavier weight to sink it to the bottom. <address>Feb. 12, 2007 - NEW</address><br> <small>Best viewed in a full window with Internet Explorer 5.5 or

206

3 Aug 2007

Drupal Handbook

higher. Tested with IE6, Netscape 8, and Firefox 2.</small> The main difference is that I wanted it only on the home (front) page. So under "Page specific visibility settings," I clicked on the "Show only on the listed pages" radio button, and entered <front> in the pages box. Okay, now you’re an "expert" on blocks.

I. Working with the Menu
Introduction
This will not be an exhaustive piece on the subject of menus. My main point will be to start you on building your menu and giving you a flavor for how it works. A more complete guide to menus can be found at Creating a menu structure. As we all know the menu, or navigation system, can make or break a web site. It must be easy to follow, often referred to as "intuitive." It must be complete, yet compact. There is a lot of content on the Drupal site on menus. Most newbies have trouble understanding it all. I’ve been using Drupal for just over a month as I write this and I still have a long way to go on completely understanding menus. For beginners it can be very confusing to understand the difference between menus and categories. The menu is a navigation system and categories is a system to order content data. So menus is to arrive at content and categories to order it. Initially to understand Drupal well, you have to see these as two separate things. With a menu you can point directly to a node, like a page or a story, but you can also point to a term in a category, which would show you a summary list of stories or pages.

How To Menu
Drupal offers three primary ways, which may be combined, to provide your users with site navigation. 1. Textual menu - this is the "standard" line-by-line type of menu, like what you see on most sites, including mine. It can be enhanced in a few ways, such as using a CSS or separate book navigation (as I have done here). 2. Tabbed menu - becoming more popular because it’s a little more "gee-whiz" in its presentation. It is debatable as to whether it is any more effective for your visitors. In Drupal, it is divided into "Primary" (the tabs you always see) and "Secondary" (the part that drops down, or slides out). Not all themes support secondary links. 3. Books - Books are organized separately from menus, but have their own navigation, which you can see on this site. See my section Creating a Book Page.

207

Drupal Handbook

3 Aug 2007

Textual Menu
The textual navigation is the easiest to understand. As a matter of fact, I still don’t understand how to make the "secondary" part of tabbed navigation work the way a lot of people think it should (drop down). You may see the terms "primary links" and "secondary links" in many posts. This is one area where I find the Drupal documentation confusing (at best). While they sounded great, and I am now using them, they may not be the best thing for someone just starting out. Stick to the standard "Navigation" menu until you have a better feel; you can always go back and change this later. For the most part, the "standard" menu is best built as you create content, but may require a little tweaking as you see how it lays out. When you create a page, story, blog, or book page, one of the fields that you may (should) fill in before submitting, is the menu entry (if the node is to have one). You have the "title" (what is to appear in the menu as people see it) and a "description" (what they will see if they hover the cursor over that entry). I rarely worry about the "weight" until I see how it shows up in the menu. At that point, you can either go back and edit the content you created or go to Administer >> Site building >> Menus and edit it there. Okay, that was the easy part. Now let’s say you want this particular content listed in the menu as a child of some other page. No problem! Let’s say you have a subject’s introductory page already listed in the menu, for example "Family History." The page you’re creating is "1860-1899." When you build the menu entry, you’ll notice a selection box labeled "Parent Item." Scroll down the list until you find "Family History." Now when you submit this page, it will be a child of "Family History," making that item an expandable menu item. You just created a hierarchical menu!

Tabbed Menu
In those themes that support this technique, the "Primary" seems to get built automatically as you build the "Navigation" menu, unless you specify a different menu set. I have no idea yet how to make drop down "secondary" links part work - I think it requires a separate module. I do know how to make the secondary links appear in a block, if they exist. I like the way that works, but it may not be for everyone.

Books
The book "menu" is built automatically for you. The only thing you have to worry about is the order of the entries (hint: weight).

208

3 Aug 2007

Drupal Handbook

The only "complicated" part is turning on the book navigation block, which is done at Administer >> Site building >> Blocks. All you really need to do is to tell Drupal which region to place it in and its relative weight. You can get fancy, if you want, with your style sheets.

More
Later you might consider using the taxonomy_menu module. It will add to your confusion, but it will be good when there are frequent changes in your vocabularies. It will make the difference between menu and categories almost completely disappear, because it allows you to make vocabularies appear as a menu. This way menus will be generated automatically. If you want hierarchical drop down menus, the nice_menus module might come in handy.

I2. The Contact Form
For something as simple as a contact form, this is one of the most complicated things to get set up and operating.

Set Up
First, the contact module must be enabled. Go to Administer >> Site building >> Modules and locate it in the list of core modules. Click the check box and go to the bottom to save the change. Go to Administer >> Site building >> Contact form. Here you can set up the "Categories" - or recipient name/office. [Don’t confuse this with taxonomy categories.] For example, email for the Sales Department might be given a category of "Sales." The email address that the form is sent to may be sales@mycompany.com. If you want a reply automatically sent to the person sending the contact email, you can specify that here. Don’t worry if you don’t know them all right away, you can come back and change this at any time. Click the "Submit button." Now click on the "Settings" tab. Here you can limit how many contact emails an individual may send in an hour -- this helps limit spamming. You may also turn on personal contact forms here; this allows users to contact each other. Click on the "Save configuration" button.

Make It Accessible
To me this step seems totally unnecessary, but I suppose that some people want it.

209

Drupal Handbook

3 Aug 2007

Go to Administer >> User management >> Access control, locate the "Contact module" entry and enable it for the roles you want to be able to use Contact. Save your changes. The menu link (next step) will not be visible to any one not having access.

Add "Contact" to the Menu
Go to Administer >> Site building >> Menus. Under "Navigation," enable "Contact" as described in the instructions. Save your changes.

Using It In Content
To add a link to a content page use <a href="/contact">Contact Us</a>. Unfortunately, this does not give you the capability to specify which contact to send it to. Fortunately, there is help! Check out the Contact List module. Need a customized contact form? Check the WebForm Module. A recent change to the Contact_List module allows you to use these two modules together.

J. URL Aliases
"URL" is an abbreviation of "Universal Resource Locater." It is a fancy way of saying "my page’s address (or name) on the web." It is the "name" by which a browser identifies a page to display. We’ve all seen advertisements that say "Check us out at abcxyz.com." Well, abcxyz.com is a URL for the home page of their web site (well, sort of - there is an implied add-on to that, such as index.html). By default, Drupal calls your content "nodes" and identifies them by their position in your database. So your page on "The History of the Macadamia Nut - Part 1" might be known as "node/167." That’s all fine and well for Drupal, because it understands that. But your visitor really doesn’t care where the page is in the database; all they want to do is find the page again, or know what the entry in their bookmarks list is. So Drupal has a feature called "URL Alias" that allows you to provide a more understandable name to the content. As far as browsers, servers, and search engines go, it is totally unnecessary. But for humans, it is nearly mandatory. This is why I tell people to always turn on the Path core module, which supports URL Aliasing. (I will mention another module shortly, called Pathauto.) So, just before you submit that exhaustive treatise on macadamia history, and if you have the Path module enabled (I told you that you’d want it), then you’ll see a section on the edit page that says "URL path settings." So let’s say you want your visitors to see it as http://www.mysite.com/MacadamiaHistory.htm. In the URL field, you enter MacadamiaHistory.htm.

210

3 Aug 2007

Drupal Handbook

Now, some people will argue that putting that ".htm" on the end is not necessary. That’s absolutely true. But then it’s not necessary to do any of this. My opinion is that if you want your visitors to see a "normal" name, it should look like a normal WEB name. Web pages have some kind of type, such as ".htm" so we should too. But it’s your preference. Oops, forgot to do this before you submitted the page? Not to worry - Drupal to the rescue! First, visit the page you created. In your browser’s address field, you’ll see its URL. On the end it will probably say "node/xxx" where xxx is some number. Write down that number. Now go to Administer>>Site building>>URL Aliases. There’s an "Add Alias" tab at the top. In the top box (sorry, they seem to have dropped a label in 5.1), enter "node/xxx" from above. In the second box, enter "MacadamiaHistory.htm". Now go back and visit that page and look at your browser’s URL field. If your site is going to have lots of content, particularly user-submitted content, you might want to looks at the PathAuto module. Not only will this module automatically generate URL aliases for new content (according to rules you can set up), but can even go back and change aliases in bulk.

K. Moving Entire Drupal Site with Databases
Start with Moving entire Drupal site with databases This might help too: Backing Up Your Database I know the "official" process is to load the "tar" file to the host and unpack it. As an alternative, one can copy the code directly from your test site on your PC. I’ve tried uploading code from my machine twice with disastrous effects. (Okay, so I was born blonde!) So, I’ve worked out my own process that works. [By the way, this also reduces the bandwidth usage for those who might be running short on that.] What has always worked for me is to install Drupal with cPanel/Fantastico (I know there are some people out here who will speak ill of Fantastico, but it has always done me right). Now, to be fair, one needs to understand what Fantastico can and cannot do. Fantastico only supports core functions. It does not support custom themes, contributed modules, or custom code (outside of content). Fantastico does not use "update.php" (as a matter of fact, doesn’t even load it), so it is not a good idea to use it to upgrade your installation. As long as you understand this, you’re much less likely to have problems. Make sure that the correct versions of modules and themes are working on your test site.

211

Drupal Handbook

3 Aug 2007

Here’s my process: (by the way, this should pretty much work for changing hosts as well) 1. Keep a pencil and paper handy to write down what changes you have to make. You can use this if you need to restart, or to think about changes to your site that slow down moving to new releases. 2. Use phpMyAdmin (on some hosts, it’s hidden under MySql) to back up your live database. If you have a site that is actively receiving new content, you may have to put the site into maintenance mode to prevent losing new content. 3. It would also be a good idea to back up your test database, just in case... 4. Import the database into your test site. 5. Download any pictures you’ve uploaded and any folders that are created by the modules you have installed. 6. If your live site and test site are not at the same version, you will need to run "update.php." 7. Open your browser to your test site. Don’t panic if everything looks strange, or even blank. In the URL bar, append "update.php" and press Enter. If it says you don’t have the access rights, don’t worry. Using Notepad or similar text editor, open "update.php". Near the top, you will see: // Enforce access checking? $access_check = TRUE; Change it to FALSE and save it. Try "update.php" again. If you have any errors listed, search the Drupal site for fixes. There’s a good chance that someone else has had the problem. If it appears to be a new error, post a request for help. Take your site out of maintenance mode and plan to start over when it’s fixed. Change $access_check back to TRUE. If you had a custom theme, you probably need to re-enable it for the site to look right. Now check out all your module settings. They’ll probably be okay. Look through your content, especially the front page. Make sure your menus are correct. Check out any content that uses custom code, especially if you are changing Drupal versions. Does everything check out? Good, you’ve done all the real work. Now the easy(er) part. Okay, now it’s time to do the damage. For me, the rest of this takes less than 15 minutes, so the outage to your users is minimal. If your current site was installed with Fantastico, delete the current installation. If not, then you have to manually remove all the folders. Now tell Fantastico to install the current version. Leave the directory field blank to put it in your "root" directory (probably "public_html"). The userid and password you supply will be your "super user" (user/1). When it is done, I always tell it to email me the installation summary.

8. 9. 10. 11.

212

3 Aug 2007

Drupal Handbook

12. If you have any customized themes, non-core modules, or pictures, upload them (FTP) to the correct places on the server. 13. If there were pictures or module-related folders, upload them now. 14. When that’s done, use phpMyAdmin on your test site and create a back up. 15. Then go to your cPanel again and invoke phpMyAdmin. When you get there, select your Drupal database and then "Import." There’s a section to locate the back up on your local computer (Browse). Find it, and then Click on the "Go" button. 16. If you have a customized theme, go to Administer>>Site Configuration>>Themes and enable it. [Hint: Do not panic if your site looks weird at first. Remember you can always login with http://www.mywebsite.com/?q=user (yes, "user," not your ID.] 17. If your test and live directories are not identical, you may need to update IMG links, etc. 18. You should be in business. 19. One more little bit of business if you used Fantastico: go to the main Drupal directory on your PC and copy (FTP) the update.php script to your server. I don’t know why they leave it out, other than they don’t use it. You may need it later.

Backup Process with phpMyAdmin

Backup Process with phpMyAdmin
The screen shots here are from phpMyAdmin 2.9.2, which I have on my local computer. My web hosts have 2.9.0.2 and look very similar. They certainly produce exchangeable results. 1. 2. Log into phpMyAdmin on your server. 3.

4. name of your database - or your Drupal database if you have several databases.

Select

the

213

Drupal Handbook

3 Aug 2007

5.

6. 7. 8.

The next screen will show you all the tables inside your Drupal database. Ignore those, and click the "Export" tab on the top set of tabs.

214

3 Aug 2007

Drupal Handbook

9.

Look at the left box at the top of the Export section. All the tables in the database you selected are in that box.

If you have other programs that use the database, then choose only those tables that correspond to your Drupal installation. If you only have Drupal installed, in the left column, click "Select All." 10. Ensure that the SQL button is selected too. 11. 12. In the Structure section tick the following boxes: Structure, "Add DROP TABLE," "Add AUTO_INCREMENT," and "Enclose table and field names with backquotes." 13.

215

Drupal Handbook

3 Aug 2007

14. In the DATA section leave the boxes inside this section unticked, but make sure to keep the check box next to the "DATA" heading checked. 15. 16. Tick the "Save as file" option, and leave the template name alone. 17. 18. For now, select "None" for compression. 19. 20. Now click "Go" and you should be prompted for a file to download. Save the file to your computer. Depending on the database size, this may take a few moments. 21. You have now backed up your database! (Not so bad, was it?) Once that download is complete, you may check the "zipped" option, click "Go", and download the next file. If you want, you can download a backup in each of the compression formats. Your choice.

L. Moving Stuff to Your Web Site
Occasionally, you need to update something other than your content (database), like the style sheets, or new code levels. FTP stands for File Transfer Protocol. It is pretty much the standard way to move stuff (files, code, style sheets, etc.) to your site. This is not how you will create content; that goes into the Drupal database. Now, the postings on the Drupal site will tell you to get a fancy FTP program. If you are at least on Windows 2000, there is absolutely no need. You can do it with Windows itself and it will look just like another older and you can drag and drop. I find this process to be easier if you use Internet Explorer than some of the other browsers. In your "Address" bar for your browser, enter ftp:username:password@ftp.domain.com where username is your user name at your site (not Drupal), password is the password for that username, domain.com is your site’s domain name (without "www"). This will take you to your site. In Linux, you’ll probably have to click into the "public_html" folder to get to your Drupal stuff. Then just navigate to the correct folders from there.

M. Setting Up Cron
I could not get a decent answer from the Drupal site on setting up the Cron jobs that it keeps complaining about. Nor would my hosting support people help ("That’s a user problem...").

216

3 Aug 2007

Drupal Handbook

My hosting provider does not allow me to have Shell access (probably a wise move). But they do provide the more-or-less-standard cPanel function. On my version, the "Cron" entry is in the lower left. I also had WebCalendar installed on one of my sites. When I went to cPanel, I noticed that WebCalendar had a command already set up. Modifying it a bit, this is what I came up with to put in:
cd ’/home/username/public_html/’ ; php -q ’cron.php’;

Note that username is my host’s user ID for domain management and my Drupal installation is in my "root" folder (actually "public_html"). This worked for getting Cron run, but did generate some error messages. I was happy that Cron ran, but a bit concerned about those messages. So I did some searching on the Drupal site and came up with several posts of the same messages, but no solutions. So I posted again. This time someone saw it through. They suggested using WGET, but I don’t have shell access. But I did, for some reason, check the "Advanced" mode on cPanel again. I noticed that there was now a helpful hint there (of course in a small font). It said to use GET http://nanwich.info/cron.php (obviously, use your own URL). I did and the error messages went away and Cron is working great! For Cron jobs another possibility is http://drupal.org/project/poormanscron For every page view, this module checks to see if the last Cron run was more than 1 hour ago (this period is configurable). If so, the Cron hooks are executed, and Drupal is happy. These Cron hooks fire after all HTML is returned to the browser, so the user who kicks off the Cron jobs should not notice any delay.

N. Categories (Taxonomy)
You will see a lot of posts on the Drupal site about creating and using a Taxonomy (or "vocabulary" and "terms"). Most of those posts will be over your head - many are still way over my head. While it is true that the more content you have the more obvious the need for a taxonomy becomes, there is certainly no reason why a smaller website that has things to classify can’t use it. For example, I run a web site for a group that has members submit articles for a monthly newsletter. They wanted a way to organize it so that they could go back and review it by date or topic. So I created two vocabularies, one for the issue date and one for the topic. Now they can, with one click, read all the book reports, movie reviews, or humorous articles. And, every month when they submit new articles, they automatically show up in those lists.

217

Drupal Handbook

3 Aug 2007

Another use is to categorize collections of FAQs, which I do on another site. They had, at the time I set it up, three hard-coded HTML pages with different types of FAQs; no one wanted to touch them. I installed the FAQ module (which is great), and set up the three terms in a single vocabulary. That allowed them to actually grow their FAQ library to now contain six categories, and it is trivial for them to maintain it. But to try to help you get a slightly better idea of how to use them, I’ll use a case study here. The Recipe module is probably a good example. On one of my sites, in order to foster a bit more "community" feel and encourage visits to my site, I decided to add a group cookbook (a real one, not like this book). The recipe module does that. It didn’t take me very long to realize that entering a bunch of recipes without any organization would get messy pretty quick. Well, recipes fall into several categories: Appetizers, Entrées, Desserts, etc. So let’s set up those things as a "vocabulary" with which we can organize the recipes. 1. Go to Administer>>Content management>>Categories and click on the "Add vocabulary" tab. 2. Enter the name, for example "Recipes." Then a "Description" like "Our community cookbook." 3. Select the type of content this applies to. The Recipe module introduces a "recipe" type. 4. I selected a "single" hierarchy. Later on, if the number of contributions gets large, I can always add sub-categories (like "Beef," "Poultry," and "Pork") and change to multiple level hierarchy. 5. I then selected "Required" to force the users to choose a category for any recipe they enter. That’s it for the "vocabulary," so click on the "Submit" button. You’ll go back to the Categories list. You should see your new vocabulary listed. Towards the right, you’ll see a link to "add terms." Click on it. 1. 2. 3. 4. 5. Since this is a single level hierarchy, the "Parent" should say "<root>." In "Term name" enter your first term, such as "Appetizers." Enter a "Description" such as "Things for before the meal." Don’t worry about the rest yet, just click the "Submit" button. Keep adding the rest of your terms ("Salads," "Soups," "Side dishes," etc.

Now when a user goes to Create content and selects "Recipe," they will be required to choose one of these categories for it. And if they go to the "Cookbook" menu item they’ll see a list of categories that they can browse. That wasn’t as complicated as all those posts sound like, was it? For another example, I run a web site for a group that has members submit articles for a monthly newsletter. They wanted a way to organize it so that they could go back and review it by date or topic. So I created two vocabularies, one for the issue date and one for the topic. Now they can, with one click, read all the book reports, movie reviews, or humorous articles. And, every month

218

3 Aug 2007

Drupal Handbook

when they submit new articles, they automatically show up in those lists. [By the way this was done with a custom content module that is easily adapted to other uses. It is available through me.] Another use is to categorize collections of FAQs, which I do on another site. They had, at the time I set it up, three hard-coded HTML pages with different types of FAQs; no one wanted to touch them. I installed the FAQ module (which is great), and set up the three terms in a single vocabulary. That allowed them to actually grow their FAQ library to now contain six categories, and it is trivial for them to maintain it. Some newbies swear by these articles: Drupal and the New Paradigm and The Power of Drupal Categories

O. Common Problems
There are some problems we all seem to "find;" this section documents a few of them. [Remember to always search before posting on the forums.] Tables messed up, images not showing, other "strange" problems with HTML - I think every Drupal user finds this problem. Drupal defaults to filtered HTML; that is, only certain tags are allowed. Further, that input format also breaks long lines of text. The fix is real easy: switch to the "Full HTML" input format. I make that the default for administrators (like me). Note that you may still want the URL Filter and Code Filter modules turned on for this input format; they are not defaults. Help, I turned on Site Maintenance, now I can’t login! - About 3 out of 4 Drupal users have done this to themselves (including me). You can still log in with http://www.example.com/?q=user. Note that "user" is exactly that - do not put your username there. I don’t want anonymous users to see "Create content." - "Create content" is actually a child menu item of "Content" which is usually disabled. Go to your menus administration screen and enable the "Content" parent above "Create Content." Then you will see a "Reset" link appear. Click on that. Once again, "Content" will be disabled, but "Create content" will not be shown to anyone who does not have the access permissions to do so (especially anonymous users). Also read the handbook section Troubleshooting FAQ

P. Links and IMG
Yes, you can link between pages in Drupal. It’s the same as not having Drupal, except the name may be weird if you’re not using the Path module (URL Aliasing).

219

Drupal Handbook

3 Aug 2007

The biggest mistake people make is not knowing that there needs to be a leading slash ("/"). Omitting this will probably cause a "404:Page not found" error and, depending on which browser you’re using, additional problems, like being logged out. My home page on this site is node #4, so a link to it would look like this: <a href="/node/4"&gt;Home</a>, but with URL Aliasing turned on, I can also code it like this: <a href="/home">Home</a> The picture on the "Accessing Your Site" page is created with this tag: <img src="/files/pictures/Docs/WDP.jpg" align="right" hspace=1>

Q. Additional Tips and Tricks
This section gives you some ideas for improving your site or making life easier for you.

Q1. Tracking Module Status
A "site" you might want to build on your PC is a "catch-all" site for monitoring module and theme status with the Update Status module. This module will check with the Drupal site and let you know if newer releases of your modules are available. Before you pooh-pooh this idea, let me suggest this additional tip: Many people eventually find that they need (want) to patch, tweak, or otherwise modify modules or themes. If you create a "catch-all" site, you can place unmodified code here so that you always have a "clean" copy to fall back on. You can then copy it to the correct site before changing it. Now, not only do you have the fall-back plan, but you get the added advantage of knowing if it needs to be updated.

Q2. Making Multiple Site Maintenance a Bit Easier
A lot of people don’t realize that there browser home page does not have to be out on the web somewhere. It can be right on your computer.

220

3 Aug 2007

Drupal Handbook

Here’s part of my home page. As you can see, I have links for all my maintenance tasks (cPanel, FTP, etc.) included, so I don’t have to keep looking them up. I also included links to my test sites, so they are easy to get to as well.

Q3. Controlling User Log In
How do I disable "Create New Account?"
It’s in Administer » User management >> User settings. Click the radio button that says: Only site administrators can create new user accounts.

How do I disable User Log In entirely, and how would I get in if I do?
First, you can go to Administer » Site building >> Blocks and change the "Region" setting for the "User Login" block to <none>. Now your user login block will disappear. In order for you to login, I offer two techniques: Enter http://www.myexample.com/user (or, if you don’t use Clean URLs, http://www.myexample.com/?q=user). Yes, it is the word "user" -- not your user ID. Go to your Site information settings and stick a "login" link in the footer. <a href="/user">login</a> I do this on several sites.

221

Drupal Handbook

3 Aug 2007

R. Keeping Your Local and Remote Sites Synchronized
The point of a test site is to have a place to experiment or develop new content without impacting your users or giving away your latest gee-whiz before its time. But it is also important to make sure that you always have a good working version of your live site on your test site. Let’s ignore, for the moment, that in an "ideal" world you will have a staging site which is always identical to the live site and nothing goes live without being staged. There are two basic techniques for keeping your sites synchronized: Manually making sure that the content of the two sites are the same. Frequent uploads or downloads of database back ups. The first technique is quite time consuming and it’s difficult to keep user comments on your test site. It also relies on your memory to know what’s been changed, unless you update both sites at the same time. If there are things that are dependent on other things (sorry for the technical terminology), you have to be careful that you update them in the right order so that your random visitor doesn’t break something. The second technique allows for user comments to be downloaded to your test site. From there they can be incorporated into the content and deleted, or left as is. You just have to be careful that you don’t lose new, experimental, or incomplete content that hasn’t been put onto the production site yet. Which is better? I can’t answer that question for you. You need to weigh the risks and benefits and decide that for yourself. Personally, at my age and with my memory, the second technique is probably better for me, at the risk of losing something not yet uploaded. I also have the bad habit of updating things on the live site and not bring the change back to my test site. More to come

S. More Reading
Now that you’re a Drupal expert, there are some additional topics you might find useful: Adding Hidden Site Design Notes - how to put design or maintenance notes on your site that only admins can see. Core modules - what the many core modules do. Contributed modules - a starter list to get you to the right modules, if you need them. Site recipes - collection of tricks and techniques. Multi-site Installation Site configuration challenge: corporate brochure - many ways to get to a "Corporate Brochure" type site. Best practices guidelines - a guide to doing the right things. My favorite module or theme is outdated. What next? -- it happens!

222

3 Aug 2007

Drupal Handbook

PHP and Javascript snippets -- useful code to use as is or adapt to your own needs. SQL snippets -- database stuff. CSS Tips, Tricks, and Techniques Theme developer’s guide Special cases How to write automated tests The Road to Drupal Hell -- this should be required reading for anyone who wants to do something not in the core Drupal. Using Drupal in an Academic Environment

T. Glossary
Okay, "Glossary" may not be the best description for this section. I’m trying to explain terms in a [over-]simplified way so that the beginning Drupaller can get her/his arms around Drupal. You might also want to look at the handbook section on Basic Terminology. A node is a container for stuff (sorry for the technical term). Some of that stuff is the content you create. Drupal itself creates a few nodes for its own stuff. A module is a way to extend the functionality of Drupal. It is usually a lot of programmed code (usually in php) and, usually, a style sheet (CSS). For example, if you want to include meta tags to describe your content, you would add on the "Nodewords" module (also known as "Meta Tags"). A theme is a means of manipulating and describing how you want your content displayed to your visitors. This includes elements such as your header, icons, block layout, etc. It also includes programming and style sheets. A server is (generally) a computer that provides services to the Internet. These services may be things like running the database or managing the gathering and dissemination of information. A browser is the "program" that you use to display content from the Internet. In reality, it is usually a set of programs, not a single one; it is also a set of tables (e.g. settings) that are used to control its display. Examples are Internet Explorer, Netscape, and Firefox. This operates on the client, or user, side of the presentation. HyperText Markup Language (HTML) is the standardized language of the web. It has its own "vocabulary," consisting of tags, elements, and descriptors. A tag is the basic component and is used to say, "The following content is to be displayed according to these rules." An example of a tag is a level one heading (<H1>). Most tags can have additional information to tell the browser more specifically how you want it to render the content. This specification is called an element.

223

Drupal Handbook

3 Aug 2007

Most elements require more information to make them work, this is the descriptor, which really should be called "value." For example, if you want that heading centered, you would use the "align" element and give it a descriptor (value) of "center." So , completely constructed it would look like this: <H1 ALIGN="CENTER">. A Taxonomy is a way of characterizing stuff. It can be used for grouping, selecting, and protecting stuff. Many people who are new to Drupal think this is a very difficult subject (admittedly, we can make it so), however, virtually all of us had an introduction to taxonomy in school: classifying living creatures (i.e. the Linnaean taxonomy). In that taxonomy, we classified living things according to kingdoms (plant or animal), phylum, class, and so on, down to genus and species. In reality there is an additional classification below species; sub-species (animals) or varietal (plants). [Oh, yeah, I vaguely remember that! That’s a taxonomy?] In Drupal, the highest level of taxonomy description is the "vocabulary;" it is used for defining the terms, or tags, that actually end up on your stuff to be used for the various purposes. In the above example, think of "Living things" as the vocabulary. Each vocabulary has one or more "terms" that are used to tag (i.e. define, or describe) your stuff. Terms may be hierarchical; that is they may exist in levels. Genus and species would be hierarchical terms. The vocabulary is assigned to input types (e.g. stories, recipes); terms are assigned to a given piece of content (e.g. "Groundbreaking Research on Macadamia Nut Yields" or "My Fabulous Macadamia Brittle"). Notice that I said "terms" - plural - because an individual node may have more than one term associated with it; for example, the "Research" news article may be assigned to "Nuts," "Trees," and "Harvesting." It could then be viewed through any of those terms (or keywords). Breadcrumbs is a term borrowed from Hansel and Gretel, who left crumbs of bread along their path so they could find their way back out of the forest. In current computer parlance, it refers to the section, usually near the top of the page, that shows the path you followed to locate the current page. For example, it might show Home > Macadamia Nuts > Current Events > News Articles, meaning that you started at the home page, clicked on "Macadamia Nuts" in the menu, then selected "Current Events" in the sub-menu, and finally selected, "News Articles." A database is a container for containers. It is a collection of related "tables" that are generally used for a single application (such as Drupal). A table is a collection of data used for a specific purpose within that application, such as identifying users. Within a table, each individual grouping of data is referred to as a row (or in traditional terms, a "record"). Each row is identified by one or more keys that allow easy retrieving of the row. Each row is then broken down into columns (often called fields, although this is more appropriate for forms on which the data is displayed). A column holds a specific piece of information for the row, such as a user name or country. Now, just to complicate things a bit, some times we describe the collection of item-related table rows with a collective term. One such term is "node." For example, information about a page on your site may exist in several tables; yet we describe all of this as a "node."

224

3 Aug 2007

Drupal Handbook

Still confused? Let’s try to relate this to an example you’re probably familiar with. Let’s relate this to your windows computer. Your [hard] disk (or disc) is sort of like a database; it is a collection of your data. On that disk, you have folders; they are analogous to tables within a database. Inside those folders, you have documents or programs; these relate to rows. Within the document (e.g. a Word document), you have paragraphs; these are much like columns. Okay, let’s add to the analogy a little. Word or Lotus 1-2-3 would be your theme, as they describe and manipulate the content before it is displayed to you. It’s a bit of a stretch for several reasons, but you can then think of Windows itself as your browser, since it is responsible for the final rendering of the content to you. Does that help a little? The Structured Query Language (SQL) is a standard specification for how database engines locate data that you want. An example might be SELECT country FROM user_profile WHERE username = "Nancy"; this would get the value from the column "country" in the "user_profile" table using column "username" as the key.

225

Drupal Handbook

3 Aug 2007

Taking your site live
Once you’ve got your Drupal installation set up just the way you want it, there are a few final considerations before you unleash it on the world.

Moving from a temporary location
It’s likely that you’ve put Drupal in a subfolder on your server, so it doesn’t interfere with your existing website while you get it set up. So you have www.example.com showing your old site, www.example.com/drupal showing drupal, and you want www.example.com to show off your new site to the world. There are two ways you can go about this:

Moving Drupal
As of version 5, moving the Drupal base folder shouldn’t pose any problems. For older versions, some settings may need to be changed so Drupal can find everything. See this forum thread for more details.

Redirecting your server
Alternatively, you can leave Drupal where it is in a subfolder, and just have your webserver fool everyone into thinking that folder is www.example.com. With Apache, you need to add the following to the .htaccess in the root folder (or create an .htaccess file if there isn’t one there): RewriteEngine on # # stuff to let through (ignore) #RewriteCond %{REQUEST_URI} "/folder1/" [OR] #RewriteCond %{REQUEST_URI} "/folder2/" RewriteRule (.*) drupal/$1 [L] Use the RewriteCond rules to let through URLS without modification (for example, you might have other subfolders you still want accessible). Replace ’drupal’ with the name of the folder Drupal is in. You also need to modify the settings.php file for your site. By default, this is at sites/default/settings.php. Uncomment (or change) the line that sets $base_url, and set it to the URL you want browsers to see as the base for your site: $base_url = ’http://www.example.com’;

226

3 Aug 2007

Drupal Handbook

In other words, ensure that this does not include the drupal subdirectory. This changes the links that Drupal generates so they point to the correct location.

Excluding paths from Drupal
It may be that your site is made up components other than Drupal, or that you have an archive version of your old site you want to be browsable. Drupal in a root folder takes over all URLs; Drupal in a subfolder fooled into thinking it’s root likewise. Either way, the .htaccess file in the root folder needs to be changed to let through the paths to files or folders you Drupal to ignore. In the case where Drupal is in the root folder, here’s what you need to to: 1. In the your webserver root’s .htaccess file, find the section marked with the comment ’# Various rewrite rules.’ 2. Below ’RewriteEngine on’ but before any other rules, add lines in the following form: RewriteRule /folder - [L] # a subfolder Drupal should ignore RewriteRule /file.html - [L] # a file in root Drupal should ignore This page is a work in progress. Please suggest other tasks it should cover.

227

Drupal Handbook

3 Aug 2007

Core modules
The pages below give help for the modules that come with Drupal. When you install Drupal, these modules are automatically installed. To make use of a module, first make sure it’s enabled at administer >> site building >> modules. (Some modules automatically are.) Then set the right permissions for it at administer >> user management >> access control. You can further extend the features of Drupal by using "contributed modules." A list of help pages for contributed modules is available at the contributed modules page. If you would like to add a module help page, follow the authoring guidelines. The site maintainers can create and update pages for you.

Aggregator: publishing syndicated content
The news aggregator is a powerful on-site RSS news reader that can gather fresh content from news sites and weblogs around the web and make it available from your site. Users can view the latest news chronologically in the main news aggregator display or by source. You can add, edit, and delete feeds and choose how often to check each individual feed for updated news. You can also tag individual feeds with categories, offering selective grouping of some feeds into separate displays. Listings of the latest news for individual sources or categorized sources can be enabled as blocks for display in the sidebar through the block administration page. The news aggregator requires cron to check for the latest news from the sites to which you have subscribed. Drupal also provides a machine-readable OPML file of all of your subscribed feeds. You can administer your list of news feeds administer >> aggregator. add a new feed administer >> aggregator >> add feed. add a new category administer >> aggregator >> add category. configure global settings for the news aggregator administer >> settings >> aggregator. control access to the aggregator module through access permissions administer >> access control >> permissions. set permissions to access new feeds for user roles such as anonymous users at administer >> access control >> permissions. view the aggregator page. run your cron job manually at your sites cron page. read about configuring cron jobs.

228

3 Aug 2007

Drupal Handbook

Old page
Thousands of web sites, especially news sites and weblogs, syndicate their most recent site content for others to display. The syndicated content always includes titles, also known as headlines, for the newest published stories. Each headline acts as a direct link to the stories on the remote site. Along with the headline, most sites typically provide either the first few paragraphs of the story or a short summary. Many individuals use client-based news aggregators on their personal computer to aggregate content, such as FeedDemon (for Windows), NetNewsWire (for Macs) and AmphetaDesk (Windows, Mac and Linux). Drupal also has a news aggregator built in as a standard feature. With it, you can subscribe to feeds from other sites and display their content for your site users. Simply enable the aggregator module in administer » modules, then click administer » aggregator and enter the feeds that you choose.

Open aggregator links in new browser window
Many people would like to keep users on their site. In order to have users open links in a new browser window instead of leaving your site you can modify two theme functions: aggregator_page_item and aggregator_block_item. An alternative approach would be to modify the output directly. Here is a sample of code target=\"_blank\">$feed->link\n"; that could be used: $output .= "link\"

User Aggregator:user submitted feeds
http://drupal.org/node/30865 User Aggregator allows users to add a syndication feed to a site’s aggregator via their user profile. Features: Site administrator can set - visible and default categories that will be assigned to user entered feeds. Default categories do not have to be visible - default refresh interval for user entered feeds - option to show on account setup - allow users to select single or multiple categories Users can select or unselect visible categories User entered feeds go to a pending table for administrative review

229

Drupal Handbook

3 Aug 2007

What do I need to subscribe to a feed?
The standard method of syndication is using the XML-based RSS format. RSS stands for Really Simple Syndication, RDF Site Summary, or Rich Site Summary, depending on whom you talk to. To syndicate a site’s content, obtain the full URL of the RSS page providing syndication. Common file tags for RSS pages are .rss, .xml and .rdf. Example: http://slashdot.org/slashdot.rdf. Most weblog sites that offer syndication will have an obvious link on the main page. Often you need only look for a red XML button, such as the one Drupal uses for site syndication. Some sites do not make their RSS feeds as easy to find. Or maybe you want to find a number of feeds on a given topic, without extensively searching the web. In that case, try an RSS syndication directory such as Syndic8. To learn much more about RSS, here are some good introductions: Mark Pilgrim’s What is RSS WebReference.com’s The Evolution of RSS NOTE: Enable your site’s XML syndication button by turning on the Syndicate block in administer » blocks.

Configuring news feeds
To subscribe to an RSS feed on another site, click administer » aggregator. Once there, select the add feed tab at the top of the aggregator administration page. Drupal will then ask for the following: Title -- The text entered here will be used in your news aggregator, within the administration configuration section, and as title for the news feed block. As a general rule, use the web site name from which the feed originates. URL -- Here you’ll enter the fully-qualified URL for the feed for the site you want to subscribe to. Update interval -- The update interval is how often Drupal will automatically access the RSS URL for the site for fresh content. The 1 hour default is typically a good minimum to use. Accessing another site’s RSS page more frequently can be considered impolite because it requires the other site’s server to handle your automatic requests. To take advantage of this feature, note that cron.php must be configured to have your feeds updated regularly. Otherwise, you’ll have to manually update feeds one at a time within the news aggregation administration (administer » aggregator) section. Once you submit your new feed, check to see if it is working properly. Select update items on the main news aggregation page. If you do not see any items listed for that feed, edit the feed and make sure that the URL was entered correctly.

230

3 Aug 2007

Drupal Handbook

Filter feeds by keyword, time, by summary
To filter by keyword: http://drupal.org/node/13047 Filtering by time and by summary to be added.

Creating categories in the aggregator
1. Go to administer » aggregator then click on the add category tab. 2. Add a title to the category, then a description. 3. If you wish to have a block of the last x items from that category, select the number of items in "Latest items block". To place the block on your sidebar, go to administer » blocks and look for the category you just created. Now every time you add a feed, you can select a category which the items will automatically appear under. Alternatively, you can tag individual items in your aggregator to appear in a category.

Tagging individual items in the aggregator
1. To get to the categorization screen, in your sidebar navigation, click news aggregator 2. Here you have two options: 1. click categories, then the category you wish to look at, then the categorize tab. 2. click sources, then the feed source you with to look at, then the categorize tab. 3. You will be presented with a list of items to categorize, plus to the right, the categories which you can assign to each item. If you have the multiple-select option enabled in the aggregator configuration, you can select more than one category for an item by holding down CTRL (PC) or CMD (Mac) and clicking on each category.

Using the news aggregator
The news aggregator has a number of ways that it displays your subscribed content: Latest News -- Displays all incoming content in the order received with The title of the original post. The name of the source, which acts as a link to an individual feed page, listing information about that feed and incoming content for that feed only. A description, the first few paragraphs or summary of the originating post (if any). The list of categories that the feed (or feed item) belongs to, with a link to each category. News by Source: Organizes incoming content by feed, displaying titles which link to the originating post. Also has an icon which acts as blog it link. News by Topic: Organizes incoming content by bundles, displaying titles which link to the originating post. Also has an icon which acts as blog it link.

231

Drupal Handbook

3 Aug 2007

News Sources: Displays an alphabetical listing of all subscribed feeds and a description. The title acts as a link to an individual feed page, listing information about that feed and incoming content for that feed only.

RSS feed blocks
In addition to providing subscribed content through the news aggregator, Drupal automatically can create a block for every feed as well as every category, though the administrator can choose whether or not a feed or category gets its own blocks by configuring the individual feeds and categories. Enable any or all of the blocks using block management by clicking administer » blocks.

Block: controlling content in the sidebars
Blocks are the boxes of related/grouped data that are visible in the left and/or right sidebar(s) of your web site. They can also be placed anywhere on your page using regions. These are usually generated automatically by modules (e.g. recent forum topics), but administrators can also create their own defined blocks. The sidebar each block appears in depends on both which theme you are using (some are left-only, some right, some both), and on the settings in block management. The block management screen lets you specify the vertical sort-order of the blocks within a sidebar. You do this by assigning a weight to each block. Lighter blocks (smaller weight) "float up" towards the top of the sidebar. Heavier ones "sink down" towards the bottom of it. The block management screen also provides checkboxes and a configure link for customizing the visibility of individual blocks. A block’s visibility depends on: The Enabled checkbox. Disabled blocks are never shown. The Throttle checkbox. Throttled blocks are hidden during high server loads. Page specific visibility settings. Individual blocks can be configured to only show/hide on certain pages. You can also show/hide blocks based on the result of a PHP snippit. Custom visibility settings. Individual blocks can be configured so that users decide whether to show/hide certain blocks. Its function. Dynamic blocks (such as those defined by modules) may be empty on certain pages and will not be shown.

Module blocks
Module blocks are available when modules are enabled. These blocks can be administered in block administration.

232

3 Aug 2007

Drupal Handbook

Administrator defined blocks
An administrator defined block contains content supplied by the administrator. Each admin-defined block consists of a title, a description, and a body which can be as long as you wish. The Drupal engine will render the content of the block. Note: Blocks are configured per theme so if you use multiple themes on a site you will need to enable and configure blocks for each theme. You can enable throttle and configure blocks at administer >> block. add a block at administer >> block >> add block.

Blog: a blog for every user
The blog module allows registered users to maintain an online weblog (commonly known as a blog), often referred to as an online journal or diary. Blogs are made up of individual posts that are time stamped and are typically viewed by date as you would a diary. Blogs often contain links to webpages users have read and/or agree/disagree with. The blog module adds a user blogs navigation link to the main navigation menu (the link must be enabled), which takes any visitor to a page that displays the most recent blog entries from all the users on the site. The navigation menu has a create content link (which takes you to a page with a link to a submission form) and a my blog link (which displays your blog entries as other people will see them). The blog module also creates a recent blog posts block that can be enabled. You can read your blog via your user profile at my account. post a blog at create content >> personal blog entry. administer blog at administer >> settings >> content types >> blog entry. administer blog api at administer >> settings >> blogapi. enable the "recent blog posts" block at administer >> blocks to show the 10 most recent blog posts.

HOWTO: Configure user blogs
To implement user blogs on your Drupal site, turn on the blog module and enable permissions: 1. Go to administer » modules and check the box in the status column to the right of blog. 2. Under administer » access control, check the edit own blog box for each role you wish to maintain blogs.

233

Drupal Handbook

3 Aug 2007

Aftewards, once logged in, each user with the permission to maintain a blog will be able to click create content » personal blog entry and will see my blog (which displays blog entries as other people will see them) in the user navigation block. At the top of each individual blog post, the original blog author will find an edit tab. To add instructions for users on creating their blogs and set workflow options such as published, promoted to the front page, etc.: 1. Select administer » content » configure » content type, then the "configure" link next to "personal blog entry 2. Enter your instructions in the available text field. 3. Set workflow options. 4. Use the Minimum number of words in a blog entry setting to specify a minimum length for all blog posts.

Most recent blog post block
Note that the block displaying "recent blog posts" cannot be easily customized to display fewer than 10 items. You have to modify the source code, the number is hard wired. There is a forum discussion on this limitation. See: http://drupal.org/node/15635

Navigate throught categories inside a blog
It’s very useful knowing how to make the general taxonomy system fits with the needings of a multiblog site. If in our web there are many blogs independent, but the share the same vocabulary, there would be a problem when navigate using taxonomy links in a post. There a interesting post titled "Blogs categories" very useful: http://drupal.org/node/20260 . I’ll write here the code to make a term link go to a view with two arguments (the user id, and the term id). Soon.

What is a blog or weblog?
Drupal’s blog module allows all registered users to maintain a personal weblog on site. Blogs are easily- and frequently-updated websites usually written in an informal and conversational style. They are ordered reverse-chronologically (that is, the most recent entry is at the top) and have archives of past entries. Each individual entry has a permanentâthat is to say, stableâURL linking directly to that item. Blogs typically have comments for each entry so that readers can participate in the discussion, and they usually have RSS feed to be syndicated elsewhere or read in an desktop aggregator. Each entry usually contains one idea, with a link to the source of the original item being discussed. Blogs can be (and are) written about any subject, from daily personal life to technology to politics to knitting to sports to a company’s products.

234

3 Aug 2007

Drupal Handbook

From a more practical standpoint, blogs can be seen as a means of personal knowledge publishing, a place for researchers or enthusiasts to build and share knowledge about their interests. Or in project oriented sites, as a workspace for project members to post ideas for commenting by others in a group. For a more complete definition of blogging with links to resources and examples, see George Siemens’ The Art of Blogging - Part 1 and The Art of Blogging - Part 2.

Making user blogs more accessible
Drupal provides a number of ways to make user blog posts accessible. You’ll need to decide which ones work best for how your Drupal site is configured: A link in the navigation bar: After activating the blog module, most Drupal themes will include a Blogs link in the header navigation bar. The user blog listing contains the most recent blog posts by all site users. If the site is using xtemplate, you’ll need to create the link yourself. Go to site configuration » themes » xtemplate and add in the HTML to create the URL (to find the URL, switch your site theme momentarily to Marvin and the link will be present in the navigation header). Making user blog listings the default home page: Click administer » settings and type in the word "blog" (without quotes) for Default front page. Promoting individual blog posts: If "node" is the Default front page setting, administrators can elect to promote any user blog posts to the front page. Click onto the blog post you want to promote, then the edit tab and then check Promoted to Front Page. Promoting individual blog posts automatically: Click administer » content » configure » content type, then the "configure" link next to "personal blog entry, and check the Promoted front page box in the "Default options" group. (This will work if "node" is the Default front page in administer » settings. Links to recently-updated blogs on the sidebar: Drupal also makes available a Most recent blogs block under administer » blocks.

Additional features
Blog it: Users with blogs will see a "blog it" link in the form of a linked image i.e. when viewing posts in the news aggregator. Other news listings, such as RSS blocks, will have an icon in place of the textual blog it link. When the blog it option is selected, the user will be taken to the blog entry form, with the title, a link to the item, and a link to the source already entered in the text input field, ready for the user to add explanation. User Blog RSS syndication: each individual user blog has their own RSS feed, allowing other sites to syndicate their content or allowing readers to read the individual blog in an aggregator. To find the RSS feed for a user, view their personal blog (in their personal information, which you can get to by clicking on their username, select view recent blog entries). Then look for the XML icon at the bottom of their blog page.

235

Drupal Handbook

3 Aug 2007

BlogApi: post from blog tools
The blog API module enables a post to be posted to a site via external GUI applications. Many users perfer to use external tools to improve their ability to read and post responses in a customized way. The blog api provides users the freedom to use the blogging tools they want but still have the blogging server of choice. When this module is enabled and configured you can use a variety of programs to create and publish posts from your desktop. Blog API module supports several XML-RPC based blogging APIs such as the Blogger API, MetaWeblog API, and most of the Movable Type API. For more information on using software with the BlogAPI, see the Creating New Content section of the End User Guide. This module also allows site administrators to configure which content types can be posted via the external applications. So, for instance, users can post forum topics as well as blog posts. Where supported, the external applications will display each content type as a separate "blog". You can view the XML-RPC page. administer >> settings >> blogapi.

Book: structured document publishing
A book is a set of pages tied together in sequence, perhaps with chapters, sections, subsections, and so on. You can use books for manuals, site resource guides, Frequently Asked Questions (FAQs), or whatever you’d like. Users who have permission can create a book and write, review, modify, or rearrange the pages. Many users can work together on a book. You can allow or disallow collaboration, to whatever extent you want. At the bottom of book pages, Drupal automatically provides links for moving to the previous page and the next, and a link labeled up that leads to the level above in the structure. A contents page is also automatically created. You can provide your users a menu that helps them find their way around inside your books. You do this by enabling the book navigation block on the blocks page (administer >> blocks). (Users will see the menu only when viewing the book.) Apart from this, you can also add a books link to any of your menus. This link will take users to a list of your books. You add the link by enabling the books menu item on the menus page (administer >> menus). You’ll find this item there under "Navigation." You can also add this link to any menu you want. (Click "add menu item," and when you fill in the "path" field on the dialogue page just enter "book.")

236

3 Aug 2007

Drupal Handbook

The "books" link takes users to your books. The "book navigation" block helps users move around inside your books. You can also let users generate a printer-friendly display of a book page and all its subsections. They do this by selecting the link for printer-friendly version at the bottom of any book page. On the books administration page (administer >> content >> books), administrators can view a list of all the books on your site. For each book there’s a link to an outline, from which to edit or delete pages or sections, change their titles, or change their weight (thus putting them in a different order). When you edit a page or section, you can also move it to a different level in the hierarchy by changing the "parent" to which it belongs. So you can move things around however you like. You can also check for orphan pages (pages that have become disconnected from the rest of the book). On the access control page (administer >> access control) you can assign to users with various roles the permission to create book pages, to create new books, and to edit their own book pages or the pages of others. When users you allow create a post of the type Book page, Drupal automatically prompts them to add their page at the level of their choice in a book, or to start a new book (by defining its "parent" as "top-level"). You can also give permission to outline posts in books. Users with this permission can take any other type of existing content on your site and add it to a book. When viewing a post they’ll see an outline tab, and by clicking it they’ll come to an interface that lets them move the post into a book. You can: create new book pages: create content >> book page. administer individual books (choose a book from list): administer >> content >> books. set workflow and other global book settings at administer >> settings >> content types >> book page. enable the book navigation block: administer >> block. control who can create, edit, and maintain book pages at administer >> access control.

Customising the book navigation menu
By default, the navigation menu block for a book appears only on pages that are part of the book hierarchy- that is, the top-level book page (www.example.com/books/book-name) and its child pages (www.example.com/books/book-name/child-page). This is because the code in the block is not an actual menu- it just simulates a menu, and so will never appear on the menu page at ..admin/menu.

237

Drupal Handbook

3 Aug 2007

This means that you can’t make the book navigation block appear permanently on the front page (if you are using the book module to create a static hierarchical structure for example), or in any other place on the site except the book pages. This seems like a major limitation, but fortunately a snippet is available that will create a book navigation menu that can be placed anywhere on your site and not just when navigating a book.

Maintaining a FAQ using a collaborative book
Collaborative books let you easily set up a Frequently Asked Questions (FAQ) section on your web site. The main benefit is that you don’t have to write all the questions/answers by yourself let the community do it for you! In order to set up the FAQ, you have to create a new book which will hold all your content. To do so, 1. 2. 3. 4. 5. 6. Click on the create content » book page link. Give it a thoughtful title. A title like "Estonia Travel - FAQ" is nice. Set the Parent to <top-level> to make this page the beginning of a new book Add in the text of the book page into the Body textarea. Leave the log message blank for now. Use the weight field to position this book in the list on the book module page.

After you have submitted this book page, you are ready to begin filling up your book with questions that are frequently asked. Creating new pages for your FAQ. The process for creating new pages in your FAQ is very similar to above. When choosing the Parent option, select the FAQ book page that you already created to add it to the book. Adding existing non-book pages to your FAQ. Whenever you come across a post which you want to include in your FAQ, 1. Click on the outline tab at the top of the page. 2. Place the relevant post wherever is most appropriate in your book by selecting a Parent. Notes: Books are quite flexible. They can have sections like Flying to Estonia, Eating in Estonia and so on. As you get more experienced with the book module, you can reorganize posts in your book so that it stays organized. Any comments attached to those relevant posts which you designate as book pages will also be transported into your book. This is a great feature, since much wisdom is shared via comments. Remember that all future comments and edits will automatically be reflected in your book. You may wish to edit the title of posts when adding them to your FAQ. Clear titles improve navigability enormously.

238

3 Aug 2007

Drupal Handbook

Book pages may come from any content type (blog, story, page, etc.). If you are creating a post solely for inclusion in your book, then use the create content » book page link. If you don’t see the edit link or outline tab , then you probably have insufficient permissions.

Categories (taxonomy): A way to organize your content
The categories module lets you classify content into categories and subcategories, thus organizing the content on your site. For example, you could classify music by genre: classical, jazz, rock. And you might further classify "classical" into concertos, sonatas, symphonies, and so on. When your users create new content, you can let them classify it (or even require them to do so) right when they create it. When users view a post to which a category has been assigned, along with the post your theme will generally show the name of the category (or categories) to which the post belongs. Each category’s name appears as a link. And clicking on that link will bring users to a page showing the other posts of the same category. You can enable the categories module on the modules page (administer >> site building >> modules). The categories module is also sometimes called the taxonomy module. Taxonomy means "division into ordered groups or categories." Taxonomy also refers to the science or principles of classification. In the language of taxonomy, groups of categories are called "vocabularies," and the categories themselves are called "terms." With the categories module you can define groups ("vocabularies") of categories ("terms") by which to classify content. Each vocabulary consists of a set of terms. You can have as many vocabularies as you want and for each create as many terms as you want. You can order your terms into hierarchies. You can also have "free vocabularies," in which users creating new content don’t have to classify it with terms from a "controlled vocabuary," one you’ve defined. Instead they can freely define their own terms, or "tags." (This is sometimes called "free tagging.") When you create a term, you can also tie it to related terms. (Think of "See also" in a dictionary.) You can allow users to classify each piece of content they create--each story, blog item, or whatever--using one term or many. For simple implementations, you might create a set of categories without subcategories (like Slashdot’s "sections"). For more complex implementations, you might use subcategories too, thus organizing things into a hierarchy.

239

Drupal Handbook

3 Aug 2007

To further organize your site, you can have groups of categories intersect. For example, intersecting your musical genres you might have a set of categories indicating times: seventeenth century, eighteenth century (perhaps with subcategories like "early eighteenth century" and "late eighteenth century"). So, using our "genre" vocabulary we might call an item by the term "sonata," and using our "times" vocabulary we might call it by the term "early eighteenth century." If we add a vocabulary for "composers," we might categorize the item three ways--as an "early-eighteenth-century" "sonata" by "Bach"--and locate it by any of these three terms. Working with vocabularies On the categories page (administer >> content management >> categories) you can create, view and manage your categories. You’ll see a list of the vocabularies you’ve created, and you can edit each one. You can add new vocabularies, using the add vocabulary tab at the top of the page. Or you can edit an existing vocabulary by clicking the edit vocabulary link next to its name (in the "Operations" column). You choose a name for your vocabulary. You can give each one a description, which modules may use in different ways. (For example, when users hover over a link that displays this vocabulary, they may see your description.) You can tie your vocabulary to particular "content types"--"story," "book page," or whatever. Then when users create content of a particular type, they’ll see a list of your vocabulary terms that go with it. Users can then categorize their post by choosing from the list. (You can also give your vocabulary a help text to help your users choose.) You can make choices about the hierarchies for your vocabularies. If you want all the terms to be on only one level, choose "disabled." To allow your terms to have one (but only one) level of terms below them, choose "single." And if you want to allow still further levels, choose "multiple." You can allow "related terms." If you allow "free tagging," when your users create content they can make up their own terms as they go along, instead of having to choose from a list. By choosing "multiple select," you can allow your users to put a post into more than one category at once by tagging it with more than one vocabulary term. Also, if you like, you can require that when your users create content of a certain "content type" they assign at least one of this vocabulary’s terms. You can decide the order in which your vocabulary will appear in lists by assigning to it a "weight." Finally, if you like you can delete the vocabulary altogether, thereby also deleting all its terms. Working with terms To view or manage the terms of each vocabulary, click on its list terms link. On the list terms page you can edit each term by clicking the edit link. Now, on the edit term page you have several kinds of choices.

240

3 Aug 2007

Drupal Handbook

If you’ve allowed this vocabulary to have a hierarchy, you can put the term in its place in the hierarchy by choosing the term’s "parent." You can select from this vocabulary one or more terms with which you’d like your term to be related. (You can select multiple terms by using the standard conventions of your operating system, like shift-click and control-click.) You assign your term a name. (You have to do it. There’s no such thing as a "nameless term.") You can list synonyms for your term. (In taxonomy lingo, you’re creating for your vocabulary a "thesaurus.") You can decide the order in which your term will appear in lists by assigning it a "weight." Or, finally, if you like you can delete a term altogether. To add new terms to your vocabulary, click its add terms link. (The list terms page also has an add terms link that does the same thing.) When you add new terms you have the same options as when you edit them. Using categories in menus The menus on your site can call for items that match specific taxonomy terms--that is, terms you’ve named your categories. Here’s how. When you create a new term, Drupal assigns it a number. And you can call up all the items categorized under that term by calling for its number. To see your term’s number, go to the categories page, choose list terms for the category to which your term belongs, and now hover over your term’s name in the list. You’ll see the number. Now, on the menus page (administer >> site building >> menus) you can create a menu item for your term. Select add item, and when you fill in the path field you add your category like this: taxonomy/term/1 If your category "sonatas" is term 1, this would call for all the nodes of that category. If your category "Bach" is term 2, you could call for only those sonatas written by Bach: taxonomy/term/1,2 Or if Brahms is term 3 and you want to call for everything that has to do with either Bach or Brahms, you’d do it this way: taxonomy/term/2+3 Several contributed modules make powerful use of the categories (taxonomy) module, exploiting and extending what it can do.

241

Drupal Handbook

3 Aug 2007

You can enable the categories module at administer >> site building >> modules. administer categories at administer >> content management >> categories. decide who else can administer categories at administer >> user management >> access control. add a vocabulary at administer >> content management >> categories >> add vocabulary.

Modules that do more with categories
Categorization is useful for three main purposes on a website. Manage categories: Challenges include user’s ability to suggest new categories, sharing common categories across sites, and re-organizing categories. Taxonomy_otf Taxonomy_xml Organizing content by category: Challenges include understanding hierarchies, getting users to apply categories, automatic default categorization by node type or other, automatic defaults, pulling or subscribing to content that is automatically categorized. Action_feed Taxonomy_defaults Taxonomy_image Taxonomy_multi_edit Taxonomy_redirect Taxonomy_similar-not stable Taxonomy_theme Inserting Taxonomy Images into nodes Seperating free tagging from categories Use categories for navigation: Challenges include menus, blocks, layouts, lists of titles and teasers. Taxonomy_association Taxonomy_block Taxonomy_browser Taxonomy_context Taxonomy_dhtml Taxonomy_hide Taxonomy_html Taxonomy_links Taxonomy_menu Taxonomy_ticker Related_nodes

242

3 Aug 2007

Drupal Handbook

Action_feed-you to receive and classify incoming e-mails from many organizations taxonomy_assoc The taxonomy_assoc module lets you display a node - along with the usual node listing for that term - when you view a taxonomy term. The node can be used instead of (or as well as) the description that taxonomy_context outputs. Unlike raw descriptions, however, nodes can be commented on, can have filters applied to them, and can be used in a number of other ways. taxonomy_block This is a simple module to create blocks based on taxonomy. It displays listings of recently posted nodes based on taxonomy definitions. You can create as many blocks as you like. taxonomy_browser Think of this as a ’build your own category view’ page. Users select the terms they want to see, and are redirected to the right URL (e.g. taxonomy/term/3,4,5), which displays the matching content. taxonomy_context The taxonomy_context module enables you to display several useful types of information drawn from taxonomy terms. By default in Drupal, when you bring up a taxonomy term you get a list of "node" (stories, static pages, books, etc.) associated with that term--but nothing to describe the term itself. But for organizational websites one often wants to display information like a title and description of the current section. So this module includes several methods for displaying information about taxonomy terms: * breadcrumbs * the current term * listings of sub-terms of the current term taxonomy_defaults This module provides the ability to set default taxonomy terms per node type. taxonomy_dhtml A page listing recent nodes on your site, organized by taxonomy term. Also provides a block for each vocabulary, listing terms and their node counts. Finally, a box is exported to the syndication.module main page. taxonomy_hide This module enables to setup list of vacabularies which terms will not be listed in reference term list during node view. It enables also grouping terms by vocabulary as well. taxonomy_html This module adds an HTML representations of site’s taxonomy. This is useful for enabling users to browse your site according to topics of their own interest ... Specifically, this module an Overview page listing all terms and vocabularies. Node counts for each term are also shown beside each term link or in a help tip (aka title attribute). taxonomy_image The taxonomy_image module allows site administrators to associate images with taxonomy terms. With the association created, an admin can then make a call to ’taxonomy_image_display()’ from their theme or other PHP code to display the appropriate image. The module allows the admin to create a one-to-one term-to-image relationship. With image display recursion, it is also possible to create a many-to-one relationship. This is useful if creating taxonomy hierarchies in which an entire tree of terms will use the same image. With recursion enabled, you only need to associate an image with the tree parent, and all children will automatically inherit the same image. taxonomy_menu The taxonomy menu module adds links to the navigation menu for taxonomy terms. This is useful when the community is focused on creating content that is organized in a taxonomy. The taxonomy menu administration interface allows taxonomy terms to be enabled

243

Drupal Handbook

3 Aug 2007

to show in the navigation menu. You can also select whether a term’s descendents subterms are displayed. taxonomy_multi_edit A mass category editor. quickly manage the taxonomy terms associated with your nodes. taxonomy_otf This module provides a mechanism for adding taxonomy terms on-the-fly. Users who are granted permission can specify new categories while creating or editing their post. taxonomy_redirect This module allows the administrator to change the destination of Taxonomy Term links. Ordinarily these links go to taxonomy/term/TERMID but that is not always desirable. Using this module, you could redirect these links to custom content, or content generated by the Views module. Due to the way the taxonomy module handles these redirects, they are available only on a by-vocabulary basis; you cannot redirect them for individual terms. taxonomy_similar taxonomy_similar will display a "similar tags" screen anytime content has been created or updated with tags from a "Free tagging" vocabulary. taxonomy_theme The taxonomy_theme module allows you to change the theme on a given node based on the value of a taxonomy term for that node. taxonomy_ticker Provides a block displaying titles of nodes in a scrolling news ticker. taxonomy_xml This module makes it possible to import and export vocabularies and taxonomy terms via XML. It requires taxonomy.module. Taxonomy_links It looks up the taxonomies associated with the node, and then picks up all the link entries associated with nodes belonging to those taxonomies. Inserting Taxonomy Images into nodes These snippets allow you to insert Taxonomy images into your nodes, when using the taxonomy_image.module. Separate ’free tagging’ terms from normal taxonomy termsseparates Free tagging terms from normal ones for separate theming. Related_nodesuses taxonomy terms to find lists of nodes similar to the currently displayed one.

Content Management System comparison focused on Taxonomy
This paper that compares Drupal with other CMS and why the taxonomy module sets it apart.

Taxonomy - some guidelines for effective design of taxonomies
(I wrote this as a comment and was told to make it a page, so I have). In most small sites taxonomy is obvious, but in larger sites, especially those where the expertise of the readership may not be that of the authors, taxonomy design can make the difference between a site being good or bad. VIEWS Module - with it’s powerful taxonomy based Filters - makes taxonomy design even more important than before.

244

3 Aug 2007

Drupal Handbook

General Rules 1) Unless a Vocab is well known to all anticipated users, and alphabetical (e.g. Countries of the World), try and keep them below 30-40 Terms. 2) If your Vocab has Parent-Child structures, think about dividing it up because it’s likely to be going to get too big, and is probably badly designed. Example (sort from an online arts shop) - Traditional Arts Single Select Europe -Lapp -Sami -Celtic Australia -Aboriginal This represented the way the shop classified their items. But as such it prevents some clients saying "show me European Art". Multiple Select is an option but much better to have two Vocabs - one for Region and one for Culture, make them both multi and a collector could say "What have you got which is Lapp, or Celtic or Chinese?" 3) Too Many Terms "Perfect" taxonomies are always too complex and you need to fight to make them more manageable. (Esp if you have just cut up a few Parent Child vocabs into several smaller ones each...) The advantage of VIEWS is that the multiple taxonomy terms start to build context, and that can be captured by views. There are not many sites that ever need to show more than 3-4 filters to users, even if there are 5-6 more hidden ones . Plus building them into structure adds even more granularity. Eg a site for ALL the small towns of America, where people are interested in their little towns stuff, using Book for basic structure:Top level - States - 50 items Off each State - Counties Off each County - settlements Click the named settlement and a get a VIEWS screen with filters for News, Culture, Announcements.

245

Drupal Handbook

3 Aug 2007

(Hidden filters in the Views filter by State/County/Settlement) Highly non scary - any users can use that to get what they need. 4) Clients are not experts on taxonomy, not even their own Taxonomy is a communications issue and if there is a budget for the site it’s always worth running it past an outsider - but note that they will need to get to understand the purpose of the site and also to an extent the jargon of the subject. This normally requires a least one decent face to face meeting to force the client to decide what is important, and what can be cut out. (Trust me, these decisions will have to be made, and if they are not, then people are probably not thinking carefully enough.) 5) Taxonomy creates Legacy issues - SO GET IT RIGHT Once you have a load of tagged data, it’s hard to make changes to taxonomy structures (apart from adding terms) without rendering existing nodes much harder to find. Trust me, NO ONE will go back and edit existing data, not in real life, unless there is massive funding for that purpose. 6) Taxonomy is trial and error. It should be the first thing you do on a site, but by adding test data you’ll find flaws, and refine and eventually go live with something that works. In between times you solved the CSS and templating... I once spent 3 days testing different ways to classify cars for one site - the makes/models complexity of past 20 years is a nightmare, and which there are several ways ot do it, all of which work, some are more userfriendly than others! Hope this helps. Ian Dickson - community specialist with a sideline in taxonomy because its the buidling block for EFFECTIVE social software... .

Taxonomy Garden: Managing Categories
Manage categories: Challenges include user’s ability to suggest new categories, sharing common categories across sites, and re-organizing categories. Taxonomy_otf Taxonomy_xml Taxonomy On The Fly

246

3 Aug 2007

Drupal Handbook

This module provides a mechanism for adding taxonomy terms on-the-fly. Users who are granted permission can specify new categories while creating or editing their post.

Taxonomy XML This module makes it possible to import and export vocabularies and taxonomy terms via XML.

Taxonomy Garden: Navigation by category
Challenges include menu’s, blocks, layouts, lists of titles and teasers. Taxonomy_association Taxonomy_block Taxonomy_browser Taxonomy_context Taxonomy_dhtml Taxonomy_hide Taxonomy_html Taxonomy_links Taxonomy_menu Taxonomy_ticker Related_nodes

247

Drupal Handbook

3 Aug 2007

Taxonomy Association The taxonomy_assoc module lets you display a node - along with the usual node listing for that term - when you view a taxonomy term.

The node can be used instead of (or as well as) the description that taxonomy_context outputs. Unlike raw descriptions, however, nodes can be commented on, can have filters applied to them, and can be used in a number of other ways. Taxonomy association allows you to assign terms to nodes as seen in the picture below.

248

3 Aug 2007

Drupal Handbook

Taxonomy block This is a simple module to create blocks based on taxonomy. It displays listings of recently posted nodes based on taxonomy definitions. You can create as many blocks as you like.

249

Drupal Handbook

3 Aug 2007

Taxonomy browser Think of this as a ’build your own category view’ page. Users select the terms they want to see, and are redirected to the right URL (e.g. taxonomy/term/3,4,5), which displays the matching content.

250

3 Aug 2007

Drupal Handbook

Taxonomy context The taxonomy_context module enables you to display several useful types of information drawn from taxonomy terms. By default in Drupal, when you bring up a taxonomy term you get a list of "node" (stories, static pages, books, etc.) associated with that term--but nothing to describe the term itself. But for organizational websites one often wants to display information like a title and description of the current section. So this module includes several methods for displaying information about taxonomy terms: breadcrumbs the current term listings of sub-terms of the current term

251

Drupal Handbook

3 Aug 2007

Taxonomy dhtml A page listing recent nodes on your site, organized by taxonomy term. Also provides a block for each vocabulary, listing terms and their node counts. Finally, a box is exported to the syndication.module main page.

252

3 Aug 2007

Drupal Handbook

Taxonomy hide This module enables to setup list of vacabularies which terms will not be listed in reference term list during node view. It enables also grouping terms by vocabulary as well.

Taxonomy menu The taxonomy menu module adds links to the navigation menu for taxonomy terms. This is useful when the community is focused on creating content that is organized in a taxonomy. The taxonomy menu administration interface allows taxonomy terms to be enabled to show in the navigation menu. You can also select whether a term’s descendents subterms are displayed.

253

Drupal Handbook

3 Aug 2007

Taxonomy ticker Provides a block displaying titles of nodes in a scrolling news ticker.

Taxonomy Garden: Organize content by category
Challenges include understanding hierarchies, getting users to apply categories, automatic default categorization by node type or other, automatic defaults, pulling or subscribing to content that is automatically categorized. Action_feed Taxonomy_defaults Taxonomy_image Taxonomy_multi_edit Taxonomy_redirect Taxonomy_similar-not stable

254

3 Aug 2007

Drupal Handbook

Taxonomy_theme Inserting Taxonomy Images into nodes Seperating free tagging from categories Taxonomy multi-edit Edit the taxonomy designations of multiple nodes at once, without having to select each node individually. Simplifies changing a large number of nodes from one taxonomy classification. In admin/categories, a tab is added to "assign categories." Every node with at least one taxonomy designation is displayed in a table, with the first column being and the remaining columns being the available categories.

255

Drupal Handbook

3 Aug 2007

Taxonomy_image Attach an image to each node in specified taxonomies based on terms. Child terms can have parent images if no images are designed for child terms. In admin/settings/taxonomy_image, admins can set the basic settings for the module. In admin/categories an additional tab is added to allow users to upload one image per taxonomy term. After inserting appropriate function calls to display_taxonomy_image() in the theme, images will be displayed with nodes.

256

3 Aug 2007

Drupal Handbook

Taxonomy_theme In one taxonomy, each term can be mapped to a theme that will display when the node is display on its own. In an admin/settings submenu, the module can be enabled or disabled. One taxonomy can be selected. Each term can be mapped to a theme. If it is not mapped, it gets the site default theme.

257

Drupal Handbook

3 Aug 2007

Views The views module is a query building module that can display a listing or table of results. Views can include filters to limit results by a variety of criteria. This module does not specifically organize nodes, but allows retrieval of pre-categorized nodes. In admin/views, users can create a view entering appropriate values into a form. The form has the following subsections: display, block, table, URL, arguments, filters, and sorting. If a URL is specified, a menu item can be added for later retrieval. The view can be stored for later use, or use by other modules. Views can be displayed directly as well.

258

3 Aug 2007

Drupal Handbook

Taxonomy_default This module automatically tags posts for which the taxonomy is not activated (in the categories admin section). For posts where the taxonomy is active, the tags are simply preselected. In admin/settings/taxonomy_defaults, a section is created for each content type. Each content type can set preselected tags in any vocabulary. For enabled vocabularies, the word "active" is not italicized. For non-enabled vocabularies, the word active is italicized. When entering a node, in-active vocabularies are not shown, but the term(s) are automatically added to nodes. For active vocabularies, the terms are pre-selected. In either case, the terms are visible when the node is rendered.

259

Drupal Handbook

3 Aug 2007

The taxonomy module for Drupal 4.x
The taxonomy module is one of the most popular features because users often want to create categories to organize content by type. Users also use categories to help in site navigation. The taxonomy module can automatically classify new content, which is very useful for organizing content on-the-fly. A simple example would be organizing a list of music reviews by musical genre. Taxonomy is also the study of classification. The taxonomy module allows you to define vocabularies (sets of categories) which are used to classify content. The module supports hierarchical classification and association between terms, allowing for truly flexible information retrieval and classification. The taxonomy module allows multiple lists of categories for classification (controlled vocabularies) and offers the possibility of creating thesauri (controlled vocabularies that indicate the relationship of terms) and taxonomies (controlled vocabularies where relationships are indicated hierarchically). To delete a term choose edit term. To delete a vocabulary, and all its terms, choose edit vocabulary.

260

3 Aug 2007

Drupal Handbook

A controlled vocabulary is a set of terms to use for describing content (known as descriptors in indexing lingo). Drupal allows you to tag each piece of content (blog, story, etc.) using one or many of these terms. For simple implementations, you might create a set of categories without subcategories, similar to Slashdot’s sections. For more complex implementations, you might create a hierarchical list of categories. Sites can also use folksonomies. By checking the "Free tagging" option when creating a vocabularly, users can create and enter their own tags for their content. You can add a vocabulary at administer >> categories >> add vocabulary. administer categories at administer >> categories.

Understanding categories for new users
Drupal’s Category, also known as ’Taxonomy’, system can sound daunting, but it doesn’t have to be. When all the fancy language is stripped away, Taxonomy is about one thing: organizing your site by attaching descriptive terms to each piece of content. Those terms might describe what section of your site a particular page belongs to. They might describe what topics are discussed in a given blog post, or what region of the country a photograph was taken in. These terms are organized in separate ’Vocabularies’ so that recipe ingredients don’t get mixed up with cities in Texas when you’re trying to find out what travel-logs were written in Houston, or what soups use potatos. Setting up these Vocabularies, and the descriptive terms that belong to them, is the first step in organizing your Drupal site. There are different kinds of vocabularies, and understanding how they differ can help you decide the best way to categorize your content. 1. Lists of pre-defined terms -- a ’flat’ vocabulary 2. Hierarchies of pre-defined terms -- a ’tree’ vocabulary 3. Buckets full of terms -- a ’free-tagging’ vocabulary For example, let’s say you’re setting up a photo portfolio, and using Taxonomy to keep things organized. First, you might create a ’flat’ vocabulary for basic organization called ’Photo Type.’ To that vocabulary, you would add the terms ’Portrait,’ ’Stop-Action,’ ’Landscape,’ and so on. Next, to keep track of where the photographs were taken, you might create a hierarchial vocabulary called ’Location.’ To it, you could add terms like ’Europe’ and ’United States.’ In a hierarchial vocabulary, each of those terms can also have sub-terms like ’France’ and ’Illinois.’ This makes it possible to tag a photo once with the term ’London’ and retrieve it later with a broader request like ’Show me all the photos taken in Great Britain.’ Finally, to capture notes about each photograph that would be hard to plan in advance, you could add a ’free tagging’ vocabulary called ’Keywords.’ Rather than defining the terms in advance, a free tagging vocabulary lets you enter in new terms each time you post a piece of content. If two pieces of content share a term, they’yer automatically connected to each other.

261

Drupal Handbook

3 Aug 2007

With those three vocabularies in place, any new photograph you post to your site can be quickly categorized. Whenever you post a new image, Drupal offers you a list of the available terms in the ’Photo Type’ and ’Location vocabularies AND a place to type in terms for your ’Keywords’ vocabulary. When posting a photo of your brother’s wedding, you might select a Photo Type of ’Portrait,’ a Location of ’Paris’ (if that’s where he was married, naturally!) and type in ’wedding’ and ’brother’ as keywords. If you’re used to other CMS or blogging systems, these different vocabulary types might be familiar as ’categories’ or ’sections’ or ’keywords.’ It’s important to note that nothing requires you to use these different Drupal vocabularies, and different kinds of content can use different vocabularies when it makes sense. News articles and Images might share ’Keywords’, but ’Photo Type’ obviously only makes sense for one. Mixing and matching these techniques in Drupal allows you to create the organizational system that best suits your needs. Getting used to it can be tricky at first, but if you take the time to think through your site’s organization, the results are worth it.

Using taxonomy to organize content
http://drupal.org/node/73694 --> http://digitalsolutions.ph/couchkamotereviews/power_drupal_categories --> http://drupal.org/node/118525 --> Drupal Taxonomy: the power to organize and reorganize Adapted from benc’s http://digitalsolutions.ph/couchkamotereviews/power_drupal_categories The Drupal Taxonomy module (and the contributed module Categories) is one of its most powerful features. Combined with its hooks, Drupal allows administrators to organize and reorganize content easily, giving more flexibility for knowledge sharing in an organization that continuously discovers better ways to share knowledge. This tutorial has two purposes: In particular: To show content managers and web developers how web content can be organized and reorganized by using Drupal’s taxonomy module. In general: To show the power of Drupal for rapid organization and reorganization and dynamic taxonomy management; these are qualities that make Drupal a good tool to facilitate knowledge sharing.

262

3 Aug 2007

Drupal Handbook

System requirements: You need an installation of Drupal 4.7 with admin permissions. Basic terminology: Taxonomy: The name of Drupal’s core (included) module for classification. Category: The label used in the Administer area for configuring taxonomy. Also, the name of a contributed (add-on) module for classification. Vocabulary: A group of taxonomy terms. Term: A label (of a taxonomy vocabulary) that can be applied to an item. Labels, Tags: other words that are sometimes loosely applied to mean the same thing as "Term." Scenario: Starting a news web site You have been asked to create a web site for a news company. They want to organize web content according to the topic of the story. The topics are Politics, Technology, Business, and Lifestyle. Stories may be about just one topic, or they may be about more than one. For instance, a story may be about both technology and business. Step 1: Plan your content structure. How will you organize content in the web site? In our scenario, our client wants to categorize stories as Politics, Technology, Business, and Lifestyle. Step 2: Create a vocabulary. After logging in to Drupal, go to (administer > categories) and click the "add vocabulary" tab. In the add vocabulary screen, type "Topic" as the Vocabulary name. Next, you need to tell Drupal that the vocabulary "Topic" will be used by the Story content type. To do this, check the story checkbox under Type. This step is called binding a vocabulary to a content type. Next, click the checkbox called Multiple select. This allows selecting more than one taxonomy term for each story. At this point, you will see many other options. Ignore them for now and play around with them later. Step 3: Add terms under your vocabulary. We now need to tell Drupal what labels are available under the Topic vocabulary. To the right of the categories screen, click add terms. In the screen that follows, type a Term name (e.g.: Politics) and click submit. Repeat this for each of the terms under Topic. You can now review your vocabulary. To the right of your Topic, click list terms. You will see something like this:

263

Drupal Handbook

3 Aug 2007

Topic --Business --Lifestyle --Politics --Technology This gives you an idea of the content structure so far. Step 4: Now try it out by creating a story. In the administer menu, click create content > story. Now you see the newly created Topic tags near the top of the form. Type a Title, choose Technology as the Topic, and write some text in the Body field. Click Submit. You have just uploaded content (a story) and tagged it as Technology. Upload three other stories and multi-tag them according to the plan below. (To multi-tag, just Ctrl-Click one item after another.) 1 story - Business, Technology 1 story - Lifestyle, Technology, Politics 1 story - Business, Politics Now you’re seeing a bit of the power of Drupal. Step 5: Exploit Drupal’s linking system. Now you’ll get more glimpses of Drupal’s power. Go back to the categories screen (administer > categories) and click list terms for Topic. Each of your terms is still listed and are actually links, too. Mouse over "Business" and look at the status bar of your browser; it’ll show something like www.example.com/taxonomy/term/555. (Note that the number 555 will be different in your case.) The link above tells you that "Business" is term number 555. And, get this, you can show all stories that have been tagged as Business by just invoking the link www.example.com/taxonomy/term/555 (using "taxonomy/term/555" will give the same results). Go ahead, try it on your browser. Type that link or just click on "Business" to see the stories that were tagged under Business. What does this mean? First, without having to reprogram, you can create different ways of displaying content by invoking the taxonomy term numbers. You can create a directory page for your website, similar to Yahoo, simply by creating a story, typing the topics and linking them to the term number. You can even create custom menus using this technique. You have seen how organizing content is easy in Drupal through its taxonomy module. You also saw that multi-tagging is easy to do in Drupal. Finally, you got a taste of Drupal’s power by exploiting term numbers. That’s the end of this scenario of our tutorial.

264

3 Aug 2007

Drupal Handbook

Meanwhile, you can play around with the taxonomy module further. Try out the other options and test the results by creating different stories. When you are ready, go to Scenario 2 (coming soon), which will teach you to harness more power from vocabularies. References to other beginning-level taxonomy pages (in order): Understanding categories for new users Advanced taxonomies: using hierarchies More about Taxonomy

Using vocabularies for navigation
When displaying nodes, both in teaser listings on the Drupal home pages and in full, single-node view, many Drupal themes display the categories applied to the node. If the user selects any category term, Drupal will then display a browsable listing for all nodes tagged with that term. Examine the Taxonomy URL for one such category listing. The end of the URL should look something like this: taxonomy/term/1 And another Taxonomy URL, for a different term, something like this taxonomy/term/2 Note that Taxonomy URLs always contain one or more Term IDs at the end of the URL. These numbers, 1 and 2 above, tell Drupal which categories to display. Now combine the Term ID’s above in one URL using a comma as a delimter taxonomy/term/1,2 The resulting listing represents the boolean AND operation. It includes all nodes tagged with both terms. To get a listing of nodes using either taxonomy term 1 OR 2, use a plus sign as the operator taxonomy/term/1+2 Want to combine more categories? Just add more delimeters and numbers. Know that you can use the taxonomy section in Drupal site administration to find out any Term ID. Just place the cursor over any edit term and look to the status bar at the bottom of the browser. Then substitute the new Term ID’s found there to create a different category listing. In addition to displaying Drupal nodes by category on site, Drupal has category specific RSS feeds for other sites to access your site content. See how the URL format for the RSS feed is very similar to the Taxonomy URL:

265

Drupal Handbook

3 Aug 2007

taxonomy/term/1+2/0/feed Building individual Taxonomy URL’s is not the most user friendly way to provide site users access to browseable listings. Nor do administrators necessarily want to build custom blocks for users with links to each category listing. To extend the means of accessing nodes by category, download and install the optional taxonomy_dhtml and syndication modules from the Drupal downloads page.

Vocabularies and terms
Each category group, or vocabulary, can contain multiple category entries, or terms, for tagging content. For example, a web-based discussion community might have a vocabulary Topics with terms such as Technology Politics Education Religion Sports An administrator might also choose to create multiple vocabularies for use with the same node type. Consider another vocabulary for use alongside of Topics, one which classifies nodes in another way: Content with terms News Reviews Announcements Opinions New vocabularies can also be created or added to at any time, with as few or as many terms as the administrator may need. And do not worry. Long before reaching Drupal’s limits at handling very large classification schemes, users would find large vocabularies and terms unwieldy to use and maintain. NOTE: When creating terms for a new vocabulary, administrators might want to provide users with a catchall term, such as Miscellaneous. Administrators can then review nodes tagged with Miscellaneous to see if a need exists for new terms. Once new terms are created, ambitious administrators can also update nodes with the new tag and remove the catchall category tag.

266

3 Aug 2007

Drupal Handbook

Creating a vocabulary
When setting up a vocabulary, Drupal will prompt for: Vocabulary name (Required) -- A name for this vocabulary; for example, Topics. Description (Optional) -- A description of the vocabulary (this item may be used by some modules and feeds). Types (Required) -- A vocabulary may be associated with or more node types. So, an administrator might declare that a particular vocabulary is to be associated with stories and blogs, but not book pages. If an expected node type is unavailable, check and make sure that the module for the specific node type has been activated. Hierarchy (Optional) -- Allows a tree-like taxonomy (see Using Hierarchies below). Related terms (Optional) -- Allows relationships between terms within this vocabulary. Think of these as "see also" references (this item is not used by many Drupal modules). Freetagging (Optional) -- Users create terms as they go by typing comma-separated lists of the terms they want to apply to content instead of selecting from a pre-existing list of terms. Freetagging vocabularies will present users with a text input that will autocomplete with matching terms if they exist. Multiple select (Optional) -- Allows users to categorize nodes by more than one term. Useful for cross-indexing content. Nodes may then appear on multiple taxonomy pages. Required (Optional) -- Requires a user to select a term in this vocabularly in order to submit the node. Otherwise, when creating a node, users will be offered a none option as the default for each vocabulary. Weight (Optional) -- Allows the administrator to set the priority of this vocabularly when listed with other vocabularies. When vocabularies are left with the default weight of zero, Drupal displays multiple vocabularies in alphabetical order. Increasing a vocabularies weight with respect to other vocabularies will cause it to appear after them in lists. Conversely, lighter vocabularies will float nearer the top of lists. Useful for specifying which vocabulary a user sees first when creating a node.

Creating terms
Once you have finished defining the vocabulary, you may populate it with terms. When creating a term, note that the available options may depend on what was selected for related terms, hierarchy and multiple select when creating the vocabulary: Term name (Required) -- The name for this term. Example: Technology. Description (Optional) -- Description of the term (this item may be used by some modules and feeds). Parent (Required) -- Select the term under which this term is a subset -- the branch of the hierarchy that this term belongs under (only required when heirarchy is enabled for the vocabulary). Synonyms (Optional) -- Enter synonyms for this term, one synonym per line. Synonyms can be used for variant spellings, acronyms, and other terms that have the same meaning as the added term, but which are not explicitly listed in this thesaurus, i.e. unauthorized terms (this item not used by many Drupal modules).

267

Drupal Handbook

3 Aug 2007

Weight (Optional) -- The weight is used to sort the terms of this vocabulary (see explanation of weight above).

Advanced taxonomies: using hierarchies
For many users needing simple classification schemes, the examples above may be the only structure necessary for tagging site content. For more elaborate classification needs, consider the hierarchy option when creating vocabularies. Hierarchies allow the creation of sophisticated taxonomies with categories and subcategories in a tree structure, much like Yahoo categories or subject classifications used by libraries. For example, the vocabulary Food could include the following categories and subcategories: Dairy Milk Drink Alchohol Beer Wine Pop Milk Meat Beef Chicken Lamb Spices Sugar Note that the term Milk appears within both Dairy and Drink. This is an example of multiple parents for a term. Just select both parents when creating the term Milk. Don’t forget that that the order of term siblings (e.g. Beef, Chicken, Lamb) can be controlled with the weight option.

More about Taxonomy
Taxonomy is more than just a module in Drupal. It is also the study of classification and a research area of information science in the digital age. Drupal admnistrators who want to push the limits of the Drupal taxonomy system might want to read how it applies to Drupal taxonomy module development. The taxonomy module is one of Drupal’s strongest and most popular features because it makes our lives easier and brings goodwill to all. This is because the taxonomy module allows authorized users to (1) tag content using custom labels (aka terms), and (2) automatically classify new content based on this taxonomy. This makes for truly flexible information classification and retrieval.

268

3 Aug 2007

Drupal Handbook

How is it done? There’s a technical and a storytelling explanation. Let’s begin with the technical explanation: The taxonomy module allows you to define vocabularies which are simply a collection of terms (similar to Gmail "labels" or Flickr "tags"). You can define 2 kinds of relationships between terms: * Hierarchical: indicates a parent-child (vertical) relationship like cat and dog are children of mammals) *Assocation: indicates a "similar to" (horizontal) relationship like mammals is similar to animals. Using these relationships, the taxonomy module allows multiple lists of categories for classification (or controlled vocabularies) and offers the possibility of creating thesauri (terms with horizontal relationships) and taxonomies (terms with hierarchical relationships). To delete a term choose edit term. To delete a vocabulary, and all its terms, choose edit vocabulary. {comment: The emphasized sentence actually sounds out of place here. Please suggest how it can be reorganized.} {factor next para into the main text}A controlled vocabulary is a set of terms to use for describing content (known as descriptors in indexing lingo). Drupal allows you to describe each piece of content (blog, story, etc.) using one or many of these terms. For simple implementations, you might create a set of categories without subcategories, similar to Slashdot’s sections. For more complex implementations, you might create a hierarchical list of categories. {/factor} Still confused? The story below will show some examples of what the taxonomy module can help you do: Case 1 (simple example). Abel sets up a website that contains his music reviews (posted as stories). Abel uses the taxonomy module to create two terms called Reviews and New Releases. Under Reviews, he creates the following child terms: Jazz, Folk, Classical. He then binds these terms to the story node. Now, when Abel posts each of his reviews, he gets a taxonomy dropdown box that prompts him to classify his review. If Abel classifies a review as Jazz, the story automatically gets displayed in the website’s "Jazz" category. Case 2 (intermediate example): Yoyo Ma, a classical cellist, releases an album where he combines Jazz with Classical styles. Abel now cannot decide whether to classify his album review as Jazz or Classical. Abel fires up the taxonomy module and modifies the taxonomy -- now, instead of allowing only one-to-one tagging, he allows multi-tagging. Abel now tags his review as both Jazz and Classical and everyone, including Yoyo Ma, is happy. Case 3 (complex): Abel’s music website grows and it now contains stories, blogs and forum discussions. Beth and Ching are both contributors to Abel’s site. As they post content, they are also asked to tag their contributions. {to be continued} It’s Case 3 that I am most interested in.

269

Drupal Handbook

3 Aug 2007

I’m developing a site using Drupal which will rely heavily on stories, essays, and articles submitted by a number of different users. These folks will want to just write their stuff and post it. They can use the menu navigation feature of the submission/posting process to determine to which menu (custom ones previously created by me and/or authorized moderators) the piece should be associated. [The default behavior is to list unsorted menu items in alpha order, a perfectly acceptable practice. Myself and moderators can further modify the order of menu items by assigning them weights.] So why should our contributors be further required to "classify" their material using terms I have created? Why put them (and me, who would have to spend time creating vocabularies and terms) through an unnecessary workload hassle? So far all I have read are excuses like "well, you can and it’s cool", "it will help people search for things later" (assumes an otherwise poor search facility is all that is available ), or "you either get it or you don’t". This last one being the worst response. A typical refuge of communication-impaired people who like to think themselves more powerful and wise through possession of secret knowledge. Are we expected to embrace a system simply because a system can be constructed? I picked Drupal after trying other CMS approaches because it puts forward clean, nice-looking pages fairly easily and contains a nice set of optional features (unlike Mambo and Nuke systems which seem to assume everybody screamingly wants to know what’s hot, what’s not, who’s popular, and the latest gossip). But I am not convinced Drupal developers must also buy into the theology or dialectic of the supremacy of taxonomies. Could it be something as simple as because a Drupal-type CMS is based on a database application (like MySQL), a taxonomy-based approach is the easiest way of making the system rational and more humanly understandable? Cheerily Yours, Tim O’Laguna

Creating a Block with links belonging to certain taxonomy terms
Question war_boar wrote: how to have a block of links to all terms which match taxonomy like Reviews: Anime Or Reviews: Movies without doing it manually it should be titled, Reviews and underneath all blogs or stories which matched. Answer You might want to use the Taxonomy dhtml module.

270

3 Aug 2007

Drupal Handbook

You will need to create a new Block of type=php. You will then want to paste in the code below, and customize the ’Physicians’ subject and the $tax array. $tax the list of tids that you are inetrested in. The third element, named ’operator’, can be and or or. So in your case, assuming the term ID for movies is ’3’ and the term ID admin/taxonomy/edit/term/3 for Anime is ’6’ admin/taxonomy/edit/term/6, you want: <?php // paste this code into a custom block of type=php // customize the $tax array and the $subject as needed $tax = array(3, 6); $operator = "or"; $result = taxonomy_select_nodes($tax, $operator); while ($obj = db_fetch_object($result)) { $node = node_load(array(’nid’ => $obj->nid)); $items[] = l($node->title, "node/". $node->nid); } return theme(’item_list’, $items); ?> A Block that returns the first 5 terms for a taxonomy <?php $taxo_id = 3; $sql = "SELECT node.title, node.nid FROM node INNER JOIN term_node ON node.nid = term_node.nid WHERE term_node.tid = $taxo_id LIMIT 5"; $output .= "<ul>"; $result = db_query($sql); while ($anode = db_fetch_object($result)) { $output .= "<li>".l($anode->title, "node/$anode->nid")."</li>"; } $output .= "</ul>"; return $output; ?>

Taxonomy terms on a page
I have a page with a table where each cell should list nodes that are at the intersection of two keywords. In order to accomplish this I have modified Moshe’s code slightly. Here it is: $content = "Some text"; $content .= getnodes (1,2); $content .= "Some text"; $content .= getnodes (3,4); print $content; function getnodes($id1, $id2) { $tax = array ("str_tids" => "$id1, $id2", "tids" => array ($id1, $id2), "operator" => "and");

271

Drupal Handbook

3 Aug 2007

$result = taxonomy_select_nodes(array2object($tax), 0); while ($node = db_fetch_object($result)) { $output[] = l($node->title, "node/". $node->nid); } return (theme_item_list($output)); }

Comment: allow comments on content
The comment module creates a discussion board for each post. Users can post comments to discuss a forum topic, weblog post, story, collaborative book page, etc. The ability to comment is an important part of involving members in a communtiy dialogue. An administrator can give comment permissions to user groups, and users can (optionally) edit their last comment, assuming no others have been posted since. Attached to each comment board is a control panel for customizing the way that comments are displayed. Users can control the chronological ordering of posts (newest or oldest first) and the number of posts to display on each page. Comments behave like other user submissions. Filters, smileys and HTML that work in nodes will also work with comments. The comment module provides specific features to inform site members when new comments have been posted. On sites with active commenting from users, the administrator can turn over comment moderation to the community. You can control access for various comment module functions through access permissions administer >> access control. administer comments administer >> comments >> configure. enable the recent comments block: administer >> block

Detailed comment documentation
When enabled, the Drupal comment module creates a discussion board for each Drupal node. Users can post comments to discuss a forum topic, weblog post, story, collaborative book page, etc. An administrator can give comment permissions to user groups, and users can (optionally) edit their last comment, assuming no others have been posted since.

User control of comment display
Attached to each comment board is a control panel for customizing the way that comments are displayed. Users can control the chronological ordering of posts (newest or oldest first) and the number of posts to display on each page. Additional settings include:

272

3 Aug 2007

Drupal Handbook

Threaded â Displays the posts grouped according to conversations and subconversations. Flat â Displays the posts in chronological order, with no threading whatsoever. Expanded â Displays the title and text for each post. Collapsed â Displays only the title for each post. When a user chooses save settings, the comments are then redisplayed using the user’s new choices. Administrators can set the default settings for the comment control panel, along with other comment defaults, in administer » comments » configure. NOTE: When comment moderation is enabled, users will have another control panel option to control thresholds (see below).

Additional comment configurations
Comments behave like other user submissions in Drupal. Filters, smileys and HTML that work in nodes will also work with comments. Administrators can control access to various comment module functions through administer » access control » permissions. Know that in a new Drupal installation, all comment permissions are disabled by default. The choice of which permissions to grant to which roles (groups of users) is left up to the site administrator. The following permissions: Access comments â Allows users to view comments. Administrate comments â Allows users complete control over configuring, editing and deleting all comments. Moderate comments â Allows users to rate comment postings (see more on moderation below). Post comments â Allows users to post comments into an administrator moderation queue. Post comments without approval â Allows users to directly post comments, bypassing the moderation queue.

Notification of new comments
Drupal provides specific features to inform site members when new comments have been posted. Drupal displays the total number of comments attached to each node, and tracks comments read by individual site members. Members which have logged in will see a notice accompanying nodes which contain comments they have not read. Some administrators may want to download, install and configure the notify module. Users can then request that Drupal send them an e-mail when new comments are posted (the notify module requires that cron.php be configured properly). The tracker module, disabled by default, displays all the site’s recent posts. There is a link to the recent posts page in the navigation block. This page is a useful way to browse new or updated nodes and comments. Content which the user has not yet read is tagged with a red star (this graphic depends on the current theme). Visit the comment board for any node, and Drupal will display a red "new" label beside the text of unread comments.

273

Drupal Handbook

3 Aug 2007

Comment moderation
On sites with active commenting from users, the administrator can turn over comment moderation to the community. With comment moderation, each comment is automatically assigned an initial rating. As users read comments, they can apply a vote which affects the comment rating. At the same time, users have an additional option in the control panel which allows them to set a threshold for the comments they wish to view. Those comments with ratings lower than the set threshold will not be shown. To enable moderation, the administrator must grant moderate comments permissions. Then, a number of options in administer » comments » configure must be configured.

Moderation votes
The first step is to create moderation labels which allow users to rate a comment. Go to administer » comments » configure » moderation votes. In the vote field, enter the textual labels which users will see when casting their votes. Some examples are Excellent +3 Insightful +2 Useful +1 Redundant -1 Flame -3 So that users know how their votes affect the comment, these examples include the vote value as part of the label, although that is optional. Using the weight option, you can control the order in which the votes appear to users. Setting the weight heavier (positive numbers) will make the vote label appear at the bottom of the list. Lighter (a negative number) will push it to the top. To encourage positive voting, a useful order might be higher values, positive votes, at the top, with negative votes at the bottom.

Moderator vote/values matrix
Next go to administer » comments » configure » moderation matrix. Enter the values for the vote labels for each permission role in the vote matrix. The values entered here will be used to create the rating for each comment. NOTE: Comment ratings are calculated by averaging user votes with the initial rating.

Creating comment thresholds
In administer » comments » configure » moderation thresholds, you’ll have to create some comment thresholds to make the comment rating system useful. When comment moderation is enabled and the thresholds are created, users will find another comment control panel option for selecting their thresholds. They’ll use the thresholds you enter here to filter out comments with low ratings. Consequently, you’ll probably want to create more than one threshold to give users some flexibility in filtering comments.

274

3 Aug 2007

Drupal Handbook

When creating the thresholds, note that the Minimum score is asking you for the lowest rating that a comment can have in order to be displayed. To see a common example of how thresholds work, you might visit Slashdot and view one of their comment boards associated with a story. You can reset the thresholds in their comment control panel.

Initial comment scores
Finally, you may want to enter some initial comment scores. In administer » comments » configure » moderation roles you can assign a beginning rating for all comments posted by a particular permission role. If you do not assign any initial scores, Drupal will assign a rating of 0 as the default.

Aggregator comments
Comments for aggregator items has been added to aggregator2 module.

Contact: a way for users to get in touch
The contact module helps people get in touch with one another and with you or the people running your site. Through personal contact forms users can send one another e-mail. And through site-wide contact forms users can send e-mail to the people in charge of your site. With either form, users can specify a subject, write their message, and also have a copy of their e-mail sent to their own address. Through contact forms, users allow themselves to be contacted yet keep their own e-mail addresses private. You can enable the contact module on the menus page (administer >> menus). Users (in their account settings) can turn their personal contact forms on or off. When their form is turned on, a contact tab appears in their user profile, for everyone to see. (Privileged users such as site administrators can contact even users who have turned their forms off.) When users view their own profiles they won’t see their contact tab. Only other users will see it, if it’s turned on. Your navigation menu can show a link to your site-wide contact form. Just enable the "contact" link on your menus page (administer >> menus). You can add that link to any other menu as well. (Click "add menu item," and when you fill in the "path" field on the dialogue page just enter "contact.") On the contact administration page (administer >> contact form) you can set up "categories" of site-wide contact you’d like to receive. For example, one category might be "website feedback," and another might be "product information."

275

Drupal Handbook

3 Aug 2007

For each category, you can specify whom you’d like to have receive your user’s e-mail. The mail could go to one person or many. You can also specify whether or not the user will receive an automatic reply. The settings portion of the contact administration page offers you other options. You can specify what message you’d like to show on your site-wide contact page. And you can limit how many times a user can contact you in an hour. You can view user profiles. let each user enable a personal contact form in my account. administer contact at administer >>contact.

Make your site wide contact form look prettier
Drupal ships with a sitewide contact form since version 4.7 that you can use to allow site visitors to send feedaback. As mentioned in the help text on the contact form settings page, you can also use the body area just above the form to give site visitors your postal address or share any other information. However, because you can’t specify an input format for the contact form page, the additional information you add will display without linebreaks or paragraph breaks and look pretty ugly. There is a simple workaround for this. Just put <br> and <p> tags where you want the linebreaks and paragraphs to appear and you will have a nice looking contact page. Experiment with the line break and paragraph break tags until you are satisfied with the appearance of your contact page.

Drupal: Drupal sites directory server
The Drupal module uses the XML-RPC network communication protocol to connect your site with a directory server. Enabling the Drupal module will: allow members on all sites using the Drupal module to login to your site without registering using their distributed identification and vice versa. allow members to login to any other site which uses the Drupal module, using a login name which looks much like an email address for your site: username@example.com The Drupal module administration page allows you to set the xml-rpc server page. The listing of your site in a site directory will occur shortly after your sites next cron run. You can

276

3 Aug 2007

Drupal Handbook

run your cron job manually at your sites cron page. view the XML-RPC page. administer Drupal administer >> settings >> drupal.

Old page
The "Drupal" module features a capability whereby other drupal sites may call home to report their existence. In turn, this enables a pod of Drupal sites to find, cooperate and advertise each other. Currently, the main application of this feature is the Drupal sites page. By default, fresh Drupal installations can use drupal.org as their directory server and report their existence. This reporting occurs via scheduled XML-RPC pings. Drupal administrators should simply enable this feature to get listed on the Drupal sites page. Just set your site’s name, e-mail address, slogan and mission statement on the administer » settings page. Then make sure that the field called Drupal XML-RPC server on the administer » settings » drupal page is set to http://www.drupal.org/xmlrpc.php, and enable this feature using the dropdown directly below. The listing of your site will occur shortly after your site’s next cron run. Note that cron.php should be called using the domain name which you want to have listed at drupal.org. For example, don’t kick off cron by requesting http://127.0.0.1/cron.php. Instead, use a publicly accessible domain name such as http://www.example.com/cron.php. Also note that your installation need not use drupal.org as its directory server. For example, this feature is perfectly capable of aggregating pings from all of your departmental drupal installations sites within an enterprise.

Filter: Input formats for user content
The filter module allows you to configure formats for text input for your site. For example, you may want a filter to strip out malicious HTML from users’ comments. Despite the name "filter," the module not only lets you keep out text you don’t want but also lets you enhance the text you let in. So, for example, you can use a filter to turn ordinary line breaks into HTML paragraph tags. When users create or edit content, they can choose between the input formats you make available. You can configure which formats are available to which user roles, as well as choose a default input format. You can also create new input formats. And you can configure each input format to use your choice of filters. You can

277

Drupal Handbook

3 Aug 2007

administer input format permissions and settings at administer >> input formats. add a new input format at administer >> input formats >> add input format.

Forum: create threaded discussions
The forum module lets you create threaded discussion boards, called forums, on your site. This is similar to a message board system such as phpBB. Forums are very useful because they allow community members to discuss topics with one another, and the discussions are archived for future reference. Topics, or threaded discussions, are posted to a forum. Each topic is comprised of an initial post and replies, or comments. Forum topics can have their own URLs. Multiple forums are often set up for different areas of discussion. Forums can also be placed inside other forums for a discussion area that is a subset of the parent forum, in which case they are often called child boards or forums. Containers can also be created to hold a group of forums. However, topics cannot be posted to containers, unlike a parent forums. Both containers and forums can be placed inside other containers and forums. By planning the structure of your containers and forums well, you make it easier for users to find a discussion area of interest to them. Forums module requires Taxonomy and Comments modules to be enabled. You can administer forums at administer >> forums. set workflow and other global forum settings on the forum configuration page: administer >> settings >> content types >> forum . control who can create, edit, and administer forum posts with administer >> access control or taxonomy access control. move forum topics to a different forum board using the edit tab; a copy can be left in the existing forum by selecting leave a shadow copy. enable the required comment and taxonomy modules at administer >> modules. style with flatform theme and add features with the quote, subscription, bbcode, and comment mover modules. Add private message with privatemsg module and extend user profile information with the profile module. read about the comment module at administer >> help >> comment. read about the taxonomy module at administer >> help >> taxonomy. The forum module, like Drupal itself, can be extended with different modules depending on the needs or your site. What features you choose to implement are in your control.

278

3 Aug 2007

Drupal Handbook

HOWTO: Create a forum
Users can post topics to forums. Forums can appear below other forums in a hierarchy, or can appear in containers. Click administer » forums. Click the add forum tab. Type in a forum name. Type in a forum description. This will show up below the forum name when users visit the forum section. 5. Select a parent. You can choose either a forum or a container to be a ’parent’ for a forum. If there are no containers or existing forums to choose from, you will only see <root> as the option, meaning it will be at the top of the forum hierarchy. 6. Select a weight. Higher numbers means the container will sink down in the list, lower numbers mean the container will rise up. 7. Click the "Submit" button. 1. 2. 3. 4.

HOWTO: Create forum containers
Containers are ’parents’ for forums (discussion boards); they are used to group forums. Users cannot post topics to containers; users post to the forums in the container(s). A site with only a few forum discussion boards may not need any containers. Click administer » forums. Click the add container tab. Type in a container name. Type in a container description. This will show up below the container name when users visit the forum section. 5. Select a parent. If there are no containers or existing forums to choose from, you will only see <root> as the option, meaning it will be at the top of the forum hierarchy. 6. Select a weight. Higher numbers means the container will sink down in the list, lower numbers mean the container will rise up. 7. Click the "Submit" button. 1. 2. 3. 4.

Help: context-sensitive guidance
The help module displays context-sensitive help. Administrators cannot alter the help system. But module authors can make informative use of it. And modules can make help texts available to other modules.

279

Drupal Handbook

3 Aug 2007

More about the help module
All user help should be presented using the help module. Some examples of help: The name of a module (unused, but there). The description found on the admin/system/modules page. The module’s help text, displayed on the admin/help page and through the module’s individual help link. The help for a distributed-authorization module (if applicable). The description of a post type (if applicable). The text of the help topics listed on administer >> help are maintained on drupal.org in the Drupal modules section. Additional help is often available in sub pages of that section.

Legacy: remapping of old-style URLs
The legacy module provides legacy handlers for upgrades from older installations. These handlers help automatically redirect references to pages from old installations and prevent page not found errors for your site. The legacy module handles legacy style taxonomy page, taxonomy feed, and blog feed paths. It also handles URL upgrades from Drupal 4.1. It rewrites old-style URLs to new-style URLs (clean URLs). Example Mappings: taxonomy/page/or/52,97 to taxonomy/term/52+97. taxonomy/feed/or/52,97 to taxonomy/term/52+97/0/feed. blog/feed/52 to blog/52/feed. node/view/52 to node/52. book/view/52 to node/52. user/view/52 to user/52. Legacy module has no configurable options and does not need to be enabled for new Drupal sites.

Locale: multi-language support
The locale module allows you to present your Drupal site in a language other than the default English. You can use it to set up a multi-lingual web site or replace given built-in text with text which has been customized for your site. Whenever the locale module encounters text which needs to be displayed, it tries to translate it into the currently selected language. If a translation is not available, then the string is remembered, so you can look up untranslated strings easily.

280

3 Aug 2007

Drupal Handbook

The locale module provides two options for providing translations. The first is the integrated web interface, via which you can search for untranslated strings, and specify their translations. An easier and less time-consuming method is to import existing translations for your language. These translations are available as GNU gettext Portable Object files (.po files for short). Translations for many languages are available for download from the translation page. If an existing translation does not meet your needs, the .po files are easily edited with special editing tools. The locale module’s import feature allows you to add strings from such files into your site’s database. The export functionality enables you to share your translations with others, generating Portable Object files from your site strings. You can administer localization at administer >> localization. manage strings for the localization: administer >> localization >> manage strings. add a locale language: administer >> localization >> add language. download translation files from the Drupal translations page.

Adjusting your php.ini settings for importing .po files
Gettext portable object files sometimes are big enough to require you to adjust the settings of you php.ini at least to be able to import the translated strings into your Drupal installation. For example, the es.po (Spanish localization) for Drupal 4.6.4 is a 400K+ text file containing 1800+ translated strings. You might very well need to adjust the relevant php.ini settings for this file to get imported. PHP defaults to this values: ; Maximum execution time of each script, in seconds max_execution_time = 30 ; Maximum amount of time each script may spend parsing request data max_input_time = 60 ; Maximum amount of memory a script may consume (8MB) memory_limit = 8M You’ll more likely have to adjust the memory_limit to 16M (your mileage may vary) to have the import process complete. If you’re getting a blank page with no indication that the import process has been completed (or has failed) you’re most probably having trouble with PHP’s defaults. Make sure by checking the messages in your webserver’s error log. If it’s the upload what is taking too much time go adjust max_input_time to a higher value. If it’s the time the script is taking to complete the process what’s taking too much time you’ll have to adjust max_execution_time.

281

Drupal Handbook

3 Aug 2007

There should be no need to leave this values that way once you’ve imported a big .po file. If you’re confident the new settings won’t hurt your webserver’s performance or security just leave them that way. Otherwise return them to the previous settings (even when it’s highly iikely that you’ll need to readjust them whenever you perform an upgrade or reinstall)

Editing text for translation
Translating text via the Drupal interface can be pretty tedious to say the least. This is not so much because of Drupal, but because of page reloads every time a string is updated. There is a much better way to translate strings into a different language, namely editing PO files with a PO editor, and then importing them into Drupal. A full guide on how to translate Drupal Core or modules, using the above-mentioned technique, can be found here.

How to create Drupal site in Marathi (Devnagari)
I read a few posts asking guidelines on creating a Drupal site in Marathi (Devnagari) - a language spoken in western part of India. As there is neither standard Marathi translation nor any Marathi language specifc help is available, I thought of writing a small set of steps / guidelines for creating a Drupal based website in Marathi language ( rather any Indian Language for which Unicode fonts are available) Although I have created Marathi websites using Drupal 4.7 & 5.1, this article applies to Drupal 5.1 only. To create a Drupal site in Marathi, you may follow these steps: - Install Drupal! - Create first (Admin) user account - Login as administrator to the newly created site - Go to Administer > Site Building > Modules (/admin/build/modules) - Enable Locale module - Go to Administer > Site Configuration > Localization (/admin/settings/locale) - Click on add language tab - From the drop down of languages, select Marathi & click on Add language button - On the Languages list page, you will now see mr (Marathi) as a language, enable it & make it default Now you might expect that suddenly the entire site will appear in Marathi, but nothing like this will happen! Now you will need to ’translate’ default English ’Strings’ to Marathi one by one. To do so, go to Manage Strings Tab on the localization page (admin/settings/locale/strings/search) - Enter the string / text you wish to translate to Marathi (e.g. Log in) - If the string is found, a list of all the places where this string is used in Drupal site is displayed.

282

3 Aug 2007

Drupal Handbook

- In that list, go to the row which you want to translate to Marathi, click on edit - In the next page enter your own Marathi translation of the string using unicode marathi font & save the string (e.g. Log In = यà¥à¤£à¥à¤¯à¤¾à¤à¥ नà¥à¤à¤¦ ) Follow these steps for all the labels / strings which are appearing on your site’s interface and you are done!! To avoid this painful process, there is an option of Importing a translation scheme (so we can actually import entire Marathi translation of Drupal interface in a single click). However, unfortunately, there is no standard Marathi Translation of Drupal interface available yet! So we have to wait for someone to write it or follow this string by string translation process! If you need a Marathi Transliteration Typing interface for your site (so that your users can type in Marathi using normal English keyboards), you may try a module called as UniSaraswati (http://drupal.org/project/unisaraswati) specifically written for this purpose If you need generic help about computing in Marathi, you may get it on Marathi Wikipedia http://mr.wikipedia.org You may find the examples of marathi sites created using Drupal at: www.sadha-sopa.com (Drupal 4.7) www.marathigazal.com (Drupal 5.1) www.miloonsaryajani.com (Drupal 5.1) Prasad Shirgaonkar

How to install a different language
To install a locale, simply enable the locale module. Then, go to admin/localization and import a .po file that you downloaded from http://drupal.org/project/Translations. You should select the right language code in the popup menu. That’s it ! You can now let user switch languages, or not, by activating more than one. Also, you could look in the tab "translate srtings" in the localization module. See Locale or internationalization support for more.

HOWTO: Creating a customized language set to replace Drupal terminology
1. Enable the locale module on the administer » modules page 2. administer > access control give yourself (and any other roles that should have it) permission to access locale 3. Go to the administer » localization page. 4. Select the add language tab .

283

Drupal Handbook

3 Aug 2007

5. Assuming English, create a custom language by adding en-US in the Language code text field. 6. Give your language a name, such as custom-English (be sure not to use spaces in your language name), and add the language. 7. This will return you to the main localization page. Set your new language as enabled and as the default. 8. Save the configuration. 9. Then disable the original English language set (that is, unless you would like users to be given the option to choose between the two in their account area). Now, any time you visit a page with Drupal hard-coded content, it will be added into your language set database. Once you have visited a page that you wish to change the content: 1. Go to the manage strings page (admin/locale/string/search) of the localization section. 2. Enter in the string you wish to search for. 3. Edit the result and enter your replacement text.

HOWTO: Use a customized language set to change Drupal text and terminology
Depending on your particular application, you may find that the default text or terminology used in the Drupal core or a contributed module doesn’t suit your style or need. Customizing this text with the locale module is fairly simple and is portable if you create an additional site up upgrade your version of Drupal or a contributed module. As simple examples, you might wish to change the "Search" button to say "Find", or you might wish that comments were shown as being "Posted by" rather than "Submitted by" a particular user. As a more advanced possibility, you might wish that the things described by Drupal as "forums" were instead called "bulletin boards", and that you could change this in every context where the word "forum" is used. The locale module is a well-developed system for handling this situation. While described as a system for making translations, it will also efficiently substitute your prefered terminology for the default Drupal terminology. You should first read the instructions for Creating a customized language set to replace Drupal terminology. After following the steps outlined there to create your custom language, this page is intended to provide additional step-by-step and detailed instructions for those new to Drupal. Again, before proceeding, follow the instructions in the first section at http://drupal.org/node/24593 to enable the locale module, create a customized language, and make it the default language. If you are not user #1, a user with appropriate access will need to go to the access control page at administer >> access control and enable "administer locales" for your user role.

284

3 Aug 2007

Drupal Handbook

Next, rather than searching for individual strings through the interface at administer >> localization, you’ll probably find it easier to use a template file and then import the "translated" strings. So, download the translation templates from the appropriate version of Drupal. Some contributed modules will also include a translation template in a "po" directory. In the downloaded directory of templates, you will see numerous template files ending in ".pot". The file "general.pot" contains strings that are reused in several modules. Open this in a text editor and look it over. Following through on the simple examples above, we can find these strings in the file in the following form: #: includes/locale.inc:327;346 modules/search.module:142;996 modules/system.module:1198 modules/user.module:1958 msgid "Search" msgstr "" Edit the file so as to specify a replacement text, such as: #: includes/locale.inc:327;346 modules/search.module:142;996 modules/system.module:1198 modules/user.module:1958 msgid "Search" msgstr "Find" Similarly, we can change the text shown by each comment by making a change to this entry: #: themes/engines/phptemplate/phptemplate.engine:250;273 msgid "Submitted by %a on %b." msgstr "Posted by %a on %b." Note that the text following the "#:" is for information only and does not affect the outcome of this process. From here, save your edited file somewhere handy (you might keep it together with your local copy of your customized theme). Now go back to administer->localization and choose "import" from the top tabs. Browse and choose your edited translation file, and then import it into your customized language. Voila, you should see that the name of the Search box it changed to "Find", etc. For a more sweeping change, you could open the "forum-module.pot file", and provide an alternate term every place the word "forum" is used. For example, you could edit the following entry as shown: #: modules/forum.module:51;110;216 msgid "forum topic" msgstr "bulletin board subject" Additional help and techniques for using the locale module and generating substitute text can be found in the Translator’s guide.

285

Drupal Handbook

3 Aug 2007

Note for the curious
If you look in the PHP code for a module, you’ll find (for example) in the search.module: <?php $form[’basic’][’inline’][’submit’] ’#value’ => t(’Search’)); ?> = array(’#type’ => ’submit’,

’Search’ is a t-ified string, which means it can be replaced by using the locale module.

Menu: customize site navigation
The menu module lets you customize your menus. Menus appear in blocks on your site and help visitors and users find their way around. The main menu for navigation is by default called "Navigation." On the administer menu page administrators can ’’’edit’’’ to change the title, description, parent or weight of a menu item. Under the ’’’operations’’’ column, click on ’’’enable/disable’’’ to toggle a menu item on or off. Disabled menu items are not deleted but merely made no longer visible on your site. The default menu items generated by the menu module cannot be deleted, only disabled. Use the ’’’add menu’’’ tab to submit a title for a new custom menu. Once submitted, the new menu will appear in a list toward the bottom of the administer menu page underneath the main navigation menu. Use the ’’’add menu item’’’ tab to create new links in either the navigation menu or a custom menu. Select the parent item to place the new link within an existing menu structure. For top-level menu items, choose the name of the menu in which the link is to be added. To turn off the navigation menu block, administer the block page. You can administer menus at administer >> menus. turn menus blocks on and off in the administration >> block. add a menu at administer >> menus >> add menu. add a menu item at administer >> menus >> add menu item. reset all menu customizations back to the Drupal default at administer >> menus >> reset menus.

Using named anchors with menus
Users who have tried using ânamed anchors,â also known as âjump links,â in the menu system can run into problems with them not to working. For clarification, a named anchor looks like this: <a name="anchor"></a>

286

3 Aug 2007

Drupal Handbook

The expected behavior is that when a link that points to this named anchor is clicked, the user’s browswer should jump to a to the anchor tag on the html page, making it appear at the top of the user’s browser window. This desired behavior can be accomplished by adding the following function to your theme’s template.php file: function phptemplate_menu_item_link($item, $link_item) { // Convert anchors in path to proper fragment $path = explode(’#’, $link_item[’path’], 2); $fragment = !empty($path[1]) ? $path[1] : NULL; $path = $path[0]; return l( $item[’title’], $path, !empty($item[’description’]) ? array(’title’ => $item[’description’]) : array(), !empty($item[’query’]) ? $item[’query’] : NULL, $fragment, FALSE, FALSE ); }

Node: the content
All content on a Drupal website is stored and treated as "nodes." A node is any posting, such as a page, poll, story, forum text, or blog entry. Comments are not stored as nodes but are always tied to one. Treating all content as nodes allows the flexibility of creating new types of content. It also allows you to painlessly apply new features or changes to all content. Behind the scenes, the nodes module manages these nodes. This module is what lets you list, sort through, and manage all the content on your site set norms for how all posts are displayed list and configure the "content types" for your site, and create new ones Offering "content types" is a way Drupal allows you to have different kinds of nodes for different purposes. For example, a "story" is one kind of node, a "book page" another, and a "blog entry" yet another. You can also create new content types of your own. You can

287

Drupal Handbook

3 Aug 2007

search for content at search. administer all nodes at administer >> content management >> content. administer workflow and other default settings for individual node types at administer >> content management >> content types. configure the number of nodes to display on the main page and the length of trimmed posts at administer >> content management >>post settings. set access permissions for various node types at administer >> user management >> access control.

Page: post static pages
The page module allows users to create static pages, which are the most basic type of content. Pages can be collected in books via the book module. Users should create a page if the information on the page is static. An example would be an "about" page. When a page is created, a user can set authoring information, configure publishing options, whether readers will be able to post comments. They can also select the content type of the page (e.g., full HTML, filtered HTML, php). As an administrator, you can set the publishing default for a page (in its workflow): you can specify whether a page is by default published, sent to moderation, promoted to the front page, sticky at the top of lists, and whether revisions are enabled by default. You can set the permissions that different user roles have to view, create, and edit pages. You can read the node administration help at administer >> help >> node. read the page administration help at administer >> help >> page. read the story administration help at administer >> help >> story. create a page at create content >> page. set workflow and other global page settings at administer >> settings >> content types >> page.

Difference between page and story
Many people ask what the difference is between the "page" node type and the "story" node type. In terms of basic functionality, there is no difference. However, as they are processed within Drupal as two different node types, one can theme them differently, so that page nodes and story nodes have differing looks. You can also make a distinction when using various node access modules. Note that as of Drupal 5.x a few default differences have been introduced:

288

3 Aug 2007

Drupal Handbook

A page doesn’t post author information, timestamps or comments by default. A story does post author information, timestamps or comments by default. It is still possible to configure a story and a page to be exactly the same. Drupal core now also allows administrators to edit the names of page and story to anything you want and create your own different types of content that suit the needs of a specific site.

Specify page by title
You can specify a page by using the URL format node.php?title=text

Path: readable URLs
The path module lets you create aliases for Drupal URLs. That is, instead of a technical-looking web address like www.example.com/?q=node/67, your users will see, for instance, www.example.com/?q=news. This makes more sense for your users and may help make your site show up better in internet searches. (And with Drupal’s "clean URLs" feature you can get rid of the "?q=": www.example.com/news.) Some examples of URL aliases: user/login => login image/tid/16 => store taxonomy/term/7+19+20+21 => store/products/whirlygigs node/3 => contact node/10 => products/merchandise/cups node/10 => cups node/11 => products/merchandise/coffeemakers You can use slashes however you like. So, for example, suppose a page is called www.example.com/taxonomy/term/7+19+20+21. You could also give it both of these new addresses: www.example.com/store/products/whirlygigs www.example.com/timesavers/whirlygigs You can enable the path module on the modules page (administer >> modules). Then when users with the right permissions create or edit posts, they’ll see a field for "URL path settings." That’s where they can enter an alias of their choice. On the URL aliases page (administer >> url aliases) you’ll see a list of all the URL aliases on your site. There you can edit them, and add new ones. You can assign more than one alias to a page (just use the add alias tab again for each new alias).

289

Drupal Handbook

3 Aug 2007

On the access control page (administer >> access control) you can decide who can create aliases and who can administer the list of them. The path module also lets you define many URL aliases at once. This is useful if you wish to use URLs uniformly different from those assigned by default. For example, you may want to show your URLs in a different language. To do this sort of thing, you need to dig a bit into Drupal’s source code. You can set the path for a post with the path module. add a URL alias: administer >> url aliases >> add alias. administer the list of URL aliases: administer >> url aliases. read how to configure clean URLs for your webserver. enable Clean URLS to remove the =? at administer >> settings in the General settings area. automate URL alias creation by installing and using the pathauto module.

Mass URL aliasing
Drupal also comes with user defined mass URL aliasing capabilities. You might like to see completely different URLs used by Drupal, or even URLs translated to the visitors’ native language, in which case this feature is handy. Only an administrator with access to the website source code can set up this kind of aliases. You can define a function somewhere in your code (even in settings.php), following this example: <?php // Example for Drupal 4.6.x function conf_url_rewrite($path, $mode = ’incoming’) { if ($mode == ’incoming’) { // URL coming from a client return preg_replace(’!^display/(\d+)$!’, ’node/\1’, $path); } elseif ($mode == ’outgoing’) { // URL going out to a client return preg_replace(’!^node/(\d+)$!’, ’display/\1’, $path); } } ?> <?php // Example for Drupal 4.7.x and up function custom_url_rewrite($type, $path, $original) { // This path was already aliased, skip rewriting it if ($path != $original) { return $path; } if ($type == ’source’) { // URL coming from a client return preg_replace(’!^display/(\d+)$!’, ’node/\1’, $path); } elseif ($type == ’alias’) { // URL going out to a client

290

3 Aug 2007

Drupal Handbook

return preg_replace(’!^node/(\d+)$!’, ’display/\1’, $path); } } ?> This function will shorten every node/$node_id type of URL to display/$node_id. Individual URL aliases defined on the browser interface of Drupal take precedence, so if you have a ’contact’ page alias for example, then the display/3 alias will not be effective when outgoing links are created. Incoming URLs however always work with the mass URL aliased variant. Only two modes are supposed to be supported by your custom function. You cannot only use this feature to shorten the URLs, or to translate them to you own language, but also to add completely new subURLs to an already existing module’s URL space, or to compose a bunch of existing stuff together to a common URL space. You can create a news section for example aliasing nodes and taxonomy overview pages falling under a ’news’ vocabulary, thus having news/15 and news/sections/3 instead of node/15 and taxonomy/term/3. You need extensive knowledge of Drupal’s inner workings and regular expressions though to make such advanced aliases.

Ping: notify services of changes
The ping module is useful for notifying interested sites that your site has changed. It automatically sends notifications (called "pings") to the pingomatic service to tell it that your site has changed. In turn pingomatic will ping other services such as weblogs.com, Technorati, blo.gs, BlogRolling, Feedster.com, Moreover, etc. The ping module requires cron or a similar periodic job scheduler to be enabled. You can: enable or disable the ping module at administer >> modules. run your cron job at your sites cron page. read about configuring cron jobs.

Write a custom module to ping a set of sites
If the sites that you want to notify don’t use ping-o-matic you can use the following update. Copied from here: http://drupal.org/node/29704 Replace ping.module:ping_ping with the following. Compatible with drupal 4.6.3 /** * Implementation of hook_ping(). * * Notifies pingomatic.com, blo.gs, and technorati.com of changes at this site.

291

Drupal Handbook

3 Aug 2007

*/ function ping_ping($name = ’’, $url = ’’) { $result = xmlrpc(’http://rpc.pingomatic.com’, ’weblogUpdates.ping’, $name, $url); if ($result === FALSE) { watchdog(’directory ping’, t(’Failed to notify pingomatic.com (site).’), WATCHDOG_WARNING); } else { watchdog("directory ping", t(’successfully notified pingomatic.com (site).’), WATCHDOG_NOTICE); } unset($result); $result = xmlrpc(’http://rpc.technorati.com/rpc/ping’, ’weblogUpdates.ping’, $name, $url); if ($result === FALSE) { watchdog(’directory ping’, t(’Failed to notify technorati.com (site).’), WATCHDOG_WARNING); } else { watchdog("directory ping",t(’successfully notified technorati.com (site).’), WATCHDOG_NOTICE); } unset($result); $result = xmlrpc(’http://ping.blo.gs’, ’weblogUpdates.ping’, $name, $url); if ($result === FALSE) { watchdog(’directory ping’, t(’Failed to notify blo.gs (site).’), WATCHDOG_WARNING); } else { watchdog("directory ping", t(’successfully notified blo.gs (site).’), WATCHDOG_NOTICE); } unset($result); } - David Herron - http://7gen.com/

Poll: community voting
The poll module lets you create simple polls. You ask a question, provide possible answers, and let your users vote. Drupal then keeps a running tally of the results. When you create a poll, you can also specify the "base" vote counts (how many votes an item has at the start) and decide how long the vote will run.

292

3 Aug 2007

Drupal Handbook

You can enable the polls module on the modules page (administer >> modules). The poll item in the navigation menu will take you to a page where you can see all the current polls, vote on them (if you haven’t already) and view the results. On the access control page (administer >> access control) you can decide which users have permission to vote, to see the voting results, and to create polls of their own. You can see some sample polls on Drupal.org. You can view the polls page. administer >> settings >> content types >> poll.

Profile: extending user account information
The profile module lets your users share information about themselves. You set up forms for them to fill in. Users tell about themselves by filling in your forms on the edit tab of their "My Account" page. And what each user tells will be visible to the rest of the users on your site, to the extent you choose when you design the forms. You can enable the profile module on the modules page (administer >> modules). When you set up the forms for user profiles (at administer >> settings >> profiles), you can define custom fields (for example, for name, age, and country). To do this, you can make use of fields of the following types: single-line textfield Example: You want to ask your user’s name multi-line textfield Example: You want to ask an open-ended question: "What would you most like to do to make this a better community?" checkbox Example: You want to say, "Please tick this box if you’ve ever been to Brazil." list selection Example: You want to ask, "Which of these colors do you most prefer--red, blue or green?" freeform list Example: You want to ask your user for a list--"What languages do you speak?" URL Example: You want to ask, "What is the address of your personal website?" date Example: You want to ask, "When were you born?" You can have as many fields as you want, using any of these types as many times as you want. And you can put each field into the order you want by specifying its "weight."

293

Drupal Handbook

3 Aug 2007

Each time you add a field, you are asked to specify its "category." This allows you to divide each user’s profile into more than one section. For example, you might divide the profile into two sections, one on "Community interests," the other on "Professional skills." So as you define each field, you assign it to one of these two categories. Drupal will then typically display each user’s profile page with two separate sections--one for "Community interests," another for "Professional skills"--each with its own set of information, derived from the fields you have defined and your user has filled in. You can mark a field as being required ("The user must enter a value"). And you can specify that when new users register, a field be shown for them to fill in. If both the profile module and the menu module are enabled, from the Menus page (administer >> menus) you can enable on the Navigation Menu the item User list. This will take people to a page where they can see a list of your users. A person who has permission can click on the name of any user in the list to view that user’s profile. The option to show this menu item may be disabled by default, but you can enable it. (And you can rename "User list" to whatever you wish.) You can also place a link to the User list among your site’s primary and secondary links, or on any other menu as well. (Click "add menu item," and when you fill in the "path" field on the dialogue page just enter "profile.") On the permissions page (administer >> access control) you can decide who is normally allowed to view the user profiles. (You’ll find the permissions for profiles under "user module.") In any case, the profiles are always accessible to your site administrators. Contributed modules can also deploy the fields in user profiles to do much more with them. Such modules, for example, can help community-based sites identify and organize users through their profile fields. You can view user profiles. administer profile settings: administer >> settings >> profiles.

Enabling user pictures (avatars)
Note that user pictures (or avatars) or pictures are part of the user.module, not the profile module. 1. Navigate to the administration area for user module configuration page under administer » users » configure 2. In the Pictures settings, for Picture support, select Enabled (Enable picture support.) Note: you must write in your directory name. Make sure the directory is created and make sure you have that directory has write permissions (that is, chmod to 755). Click ’save configuration’

294

3 Aug 2007

Drupal Handbook

Drupal 4.7 allows you to enable avatars at administer » settings » users (admin/settings/user).

HOWTO: Create new profile fields
1. Enable the profile module: 2. In administer » modules select in the ’Enable’ column where you see: profile | Support for configurable user profiles. 3. Create new fields or edit existing ones: 4. Navigate to the administration area: administer » settings » profiles Select a form field type under ’Add new field’ Follow onscreen instructions for configuring this field, and ’save field’.

HOWTO: Make a field part of the registration process
This information is pertaining to Drupal 4.6.3. To make a field part of the registration, perform the following steps: 1. Go to: administer >> settings >> profiles. 2. Create the profile field if it doesn’t exist yet, and as follows: 3. Under the ’add new field’ section, choose the type of field you want to create by clicking its link. Provide the particulars for the field, namely category, title, form name, explanation, weight, visibility and page title. Now check whether the field may or may not be left empty. To make it appear on the registration page, make a checkmark in the ’Visible in user registration’ checkbox. 4. Click on the ’Save field’ button. Your new field will now appear on the registration page.

Form Validation in plugin
check for $type="validate" in plugin set errors via form_set_errors() to validate the required fields in registration form

HOWTO: Create a ’country’ profile field
This page describes how to create a ’country’ field in your users’ profiles, similar to the one on Drupal.org, that lets you easily find users in any country.

295

Drupal Handbook

3 Aug 2007

1. Create a new profile field. 2. Go to the profile settings page (administer > settings > profiles ?q=admin/settings/profile) 3. Select the ’list selection’ type of form field. 4. Category (required): It can be a category you already have or a new one. (Suggested: Personal Information) Title (required): Anything is OK. (Suggested: Country) Form name (required): Anything is ok, as long as it is unique. (Suggested: profile_country) Explanation (optional): Usually, country is self explanatory, but you may want to write a note here to your users about this field. Selection options: Copy the list from the attached file here. This file is from Wikipedia (http://en.wikipedia.org/wiki/List_of_countries May 2006) Weight: Select whatever you like (this is the weight in the category selected above). Visibility: Select one of the ’Public Field’ options. Page title (required): You must put something here. (Suggested: People who live in) Check boxes: Check ’the user must enter a value’ to make this field required. Check ’visible in user registration form’ to make it part of user registration. 5. Click on ’Save field.’

CiviCRM: Tags, Profiles, Groups, advanced community member management
CiviCRM’s Profile functionality allows you to integrate and extend Drupal User screens with your contact management requirements. It also gives you tools for collecting and sharing contact information with community members and visitors. You can: configure user registration forms to include standard and custom CiviCRM fields allow users to maintain some or all of their own contact data and find other contacts with shared characteristics make a subset of CiviCRM data available for searchable listings create custom ’sign-up’ forms to collect contact information from site visitors More information: CiviCRM Quickstart - Website Integration Configuring CiviCRM Profiles

296

3 Aug 2007

Drupal Handbook

Search: an internal site search system
The search module lets users search for specific content on your site. You can search both for users and for particular words. With a regular search, if you enter more than one search term the search module will look for content that has all the terms you’ve entered. If instead you want either one term or another, join your terms with "or." If you’re looking for an exact phrase, enclose it in quotation marks. With Advanced Search you can also look for "any of these words" or "this phrase," or both, you can rule out words you don’t want, and you can choose content types within which to confine your search. You can enable the search module on the modules page (administer >> modules). Drupal’s search engine indexes the text of your site and the names of your users. You can tweak the way it does this. The search engine does its indexing at intervals you choose by setting "cron runs." Cron (which stands for chronograph) is not a part of Drupal. It’s a scheduler that resides on your server and runs tasks (called "cron jobs") at intervals, which you specify. The jobs can run weekly, daily, hourly, or whatever you like. What you want to do is schedule a "cron job" that has a browser on your server regularly visit your "cron page." For instance, if your site were www.example.com your cron page would be http://www.example.com/cron.php. (This page is automatically set up for you when you install Drupal.) Whenever such a visit occurs, the search engine will take up the work of indexing. You need to set up those cron runs before your search engine will work. For a modest personal site to which you post now and then, you might set up such a cron job to run once a day. For a more active site you’d likely want to run that job more often--perhaps every few hours or every hour. With Linux or Unix you can schedule your cron jobs by setting up what’s called a "crontab." (You might rely on helper programs like C-Panel to make setting up your cron jobs easier.) For further guidance on cron you can see Drupal’s handbook page configuring cron jobs (or, if your server is running Windows, configuring Windows cron jobs). Your hosting company may also help guide you. On your settings page for Search (administer >> settings >> search) you can limit how many items should be indexed in a single cron run. This can help keep your system from getting overloaded with work. (If you get a message that cron is timing out or PHP is running out of memory, lower the number of items to index per run.) You also have a few more search settings you can choose.

297

Drupal Handbook

3 Aug 2007

If both the search module and the menu module are enabled, from the menus page (administer >> menus) you can enable on the Navigation Menu the item Search. The option to show this menu item may be disabled by default, but you can enable it. (And you can rename "Search" to whatever you wish.) You can also place a link to Search among your site’s primary and secondary links, or on any other menu as well. (Click "add menu item," and when you fill in the "path" field on the dialogue page just enter "search.") On your blocks page (administer >> blocks) for most themes there’s also a Search form you can enable, and you can choose where you want it to display. On your access control page (administer >> access control) you can decide who can do searches and who can administer the search settings. A technical note: To use the search module the database user needs the create temporary table permission. If you seem not to have it, ask your systems administrator to make sure it’s granted to you. You can read about how your site uses cron in the administer >> help >> system. run your cron job manually at your sites cron page. read about configuring cron jobs. configure search at administer >> settings >> search.

Add searching to your custom module
In order to have a custom module be searched the module must support the search hook. Read the Drupal API for the hook_search.

Statistics: tracking referrers, page hits, etc.
The statistics module keeps track of numerous statistics of site usage. It counts how many times, and from where each of your posts is viewed. The statistics module can be used to learn many useful things about how users are interacting with each other and with your site. Statistics module features Logs show statistics for how many times the site and specific content on the site has been accessed. Referrers tells you from where visitors came from (referrer URL). Top pages shows you what’s hot, what is the most popular content on your site. Top visitors shows you the most active visitors for your site and allows you to ban abusive visitors. Recent hits displays information about the latest activity on the site.

298

3 Aug 2007

Drupal Handbook

Node count displays the number of times a node has been accessed in the node’s link section next to # comments. Configuring the statistics module Enable access log allows you to turn the access log on and off. This log is used to store data about every page accessed, such as the remote host’s IP address, where they came from (referrer), what node they’ve viewed, and their user name. Enabling the log adds one database call per page displayed by Drupal. Discard access logs older than allows you to configure how long an access log entry is saved, after which time it is deleted from the database table. To use this you need to run cron.php Enable node view counter allows you to turn on and off the node-counting functionality of this module. If it is turned on, an extra database query is added for each node displayed, which increments a counter. Display node view counters allows you to globally disable the displaying of node view counters. You can administer statistics administer >> setttings >> statistics. access statistics logs administer >> logs. view recent hits administer >> logs >> recent hits.

Story: post static pages
The story module is used to create a content post type called stories. Stories are articles in their simplest form: they have a title, a teaser and a body. Stories are typically used to post news articles or as a group blog. The story administration interface allows for complex configuration. It provides a submission form, workflow, default view permission, default edit permission, permissions for permission, and attachments. You can post a story at create content >> story. set workflow and other global story settings at administer >> settings >> content types >> story. control who can create and edit stories at administer >> access control.

System: cron and caching
The system module provides system-wide defaults for running jobs at particular times, storing (caching) web pages to improve efficiency, and performing other essential tasks. The module also keeps track of various preferences you give for how you want your system to behave.

299

Drupal Handbook

3 Aug 2007

Some of Drupal’s modules require regularly scheduled actions. The statistics module periodically cleans up logfiles. The aggregator module periodically updates feeds. Ping periodically notifies services of new content on your site. Search periodically indexes your site’s content. All of these services rely on cron. Cron (which stands for chronograph) is not a part of Drupal. It’s a scheduler that resides on your server and performs tasks (called "cron jobs") at intervals, which you specify. The jobs can run weekly, daily, hourly, or whatever you like. What you want to do is schedule a "cron job" that has a browser on your server regularly visit your "cron page." For instance, if your site were www.example.com your cron page would be http://www.example.com/cron.php. (This page is automatically set up for you when you install Drupal.) This regular visit to your cron page will help keep your system running smoothly. For a modest personal site to which you post now and then, you might set up such a cron job to run once a day. For a more active site you’d likely want to run that job more often--perhaps every few hours or every hour. With Linux or Unix you can schedule your cron jobs by setting up what’s called a "crontab." (You might rely on helper programs like C-Panel to make setting up your cron jobs easier.) For further guidance you can see Drupal’s handbook page configuring cron jobs (or, if your server is running Windows, configuring Windows cron jobs). Your hosting company may also help guide you. The system module’s caching mechanism stores dynamically generated web pages in a cache--a stockpile--and reuses them. The pages on your site, rather than being never-changing sets of text and images, are all (or nearly all) likely to use elements pulled together "on the fly" from various parts of your database. Such pages are said to be "dynamically generated." By caching such pages, the system module keeps them ready to use again, instead of having to create them again each time someone wants to view them. This way, displaying a page takes only one database query instead of several. Queries take time and system power, so caching lightens the load on your system and lets it respond more quickly. Only pages requested by anonymous users are cached. To reduce server load and save bandwidth, the system module stores and sends cached pages compressed. You can run your cron job manually at your site’s cron page. read about configuring cron jobs. administer cache settings in administer >> settings in the Cache settings area.

300

3 Aug 2007

Drupal Handbook

Configuring cron jobs
Some modules require regularly scheduled actions, such as cleaning up log files. You can make these happen automatically by using cron. Cron, which stands for chronograph, is not a part of Drupal. It’s a command scheduler that resides on your server and executes commands at intervals, specified in seconds. You can use it to control the execution of daily, weekly or monthly jobs (or anything with a period measured in seconds). These tasks are called "cron jobs." What you want to do is schedule a "cron job" that tells a web browser on your server, such as lynx or wget, to regularly visit your "cron page." For instance, if your site were www.example.com, your cron page would be http://www.example.com/cron.php. (This page is automatically set up for you when you install Drupal.) This regular visit will automatically tell Drupal to perform its periodic tasks, and this will help keep your system running smoothly. For a modest personal site to which you post now and then, you might set up such a cron job to run once a day. For a more active site you’d likely want to run that job more often--perhaps every few hours or every hour. With Linux or Unix you schedule your cron jobs by setting up what’s called a "crontab." (You might rely on helper programs like C-Panel to make setting up your cron jobs easier.) Your crontab might look like this: 45 * * * * or 45 * * * * /usr/bin/wget -O - -q http://example.com/cron.php This would have a browser (lynx or wget) visit your cron page 45 minutes after every hour. (At the start of the hour your site may receive a lot of traffic from other sites aggregating your content via RSS. So running your cron job earlier helps the job avoid that traffic.) To set up a cron job on Windows read configuring Windows cron jobs. Suppose your hosting company doesn’t allow you to set up crontab entries. You can ask the company to let you. Sometimes that’s all you need to do. You can ask someone else with access to the internet to set up an entry for you. After all, virtually any Unix/Linux machine with access to the internet can set up a crontab entry to regularly visit http://example.com/cron.php. You can use a webcron service (for example, http://www.webcron.org) to set up cron jobs through a web interface. If you can’t run cron yourself or find someone to do it for you, consider the poormanscron module. /usr/bin/lynx -source http://example.com/cron.php

301

Drupal Handbook

3 Aug 2007

Cron doesn’t guarantee your commands will run at the specified interval. But Drupal will try its best to come as close as possible. The more you visit cron.php, the more accurate cron will be. Some guidelines of a more technical nature: Take a look at the example scripts in the scripts directory. Make sure to adjust them to fit your needs. For example, the cron-lynx.sh file contains the line: /usr/bin/lynx -source http://example.com/cron.php > /dev/null 2>&1 Enter: whereis lynx from your shell to make sure lynx is located at /usr/bin/lynx (if not, adjust the path as needed). Also change http://example.com/cron.php to the location of your Drupal installation (for instance, http://www.example.com/drupal/cron.php). A good crontab line to run this cron script once every hour would be: 00 * * * * /home/www/drupal/scripts/cron-lynx.sh Note that it is essential to access cron.php using a browser on the web site’s domain; do not run it using command line PHP directly and avoid using localhost or 127.0.0.1 or some of the environment variables will not be set correctly and features may not work as expected (for example, the Drupal module). If your host doesn’t give you permission to use a browser such as wget or lynx, there is also a script in Drupal’s /scripts/ directory called cron-curl.php which uses curl instead. It’s also possible to write a simple PHP script which simulates a browser accessing your website’s cron.php (using curl, fopen, or similar), and write a cron configuration which calls that instead.

Configuring cron jobs on DreamHost
I culled this info from the Dreamhost knowledgebase: How do I set up a cron job? Via the "crontab" command from the shell. crontab -l will show you your currently set up cron jobs on the server. crontab -r will delete your current cron jobs. crontab -e will allow you to add or edit your current cron jobs by using your default text editor to edit your "crontab file". Your crontab includes all the cron jobs you’d like, with one cron entry per line. A cron entry looks like this:

302

3 Aug 2007

Drupal Handbook

45 2 * * * /home/user/script.pl The first number is the minute of the hour for the command to run on. The second number is the hour of the day for the command to run on. The third number is the day of the month for the command to run on. The fourth number is the month of the year for the command to run on. The fifth number is the day of the week for the command to run on. Here are some examples to help you learn the syntax for the numbers: 32 * * * * : will be run every hour on the 32nd minute. 12,42 * * * * : will be run twice an hour on the 12th and 42nd minutes. */15 */2 * * *: will be run at 0:00, 0:15, 0:30, 0:45, 2:00, 2:15, 2:30, ... 43 18 * * 7: will be run at 6:43pm every Sunday. You can also edit crontab on a local file. Upload it to a directory and run: crontab YourFileName It’ll replace your crontab with what’s on the text file, without having to edit it online. This is useful if you’re using a telnet client which doesn’t support ANSI control codes (such as the Windows’ one) and can’t understand what the heck is going on on the editors. In my own experience, I found that only by entering one cron command per line worked (one line each for :10, :20, :30, etc.). I could not get crontab to take the "*/15" argument, so I worked around it. Also, if you have ANY character after the last command (space, CR, whatever) the file will not take. I like this file-load approach because I have a basic command file to edit or call up again if needed. Afterwards, running crontab -l will confirm that the job did take. I hope this helps people making new installations. --

Cron Job configuration line by line
1. start your shell. 2. type crontab -l to see current jobs for site. 3. verify if lynx was set up on your server under /usr/bin 4. edit scripts/cron-lynx.sh putting in the direct address of your cron.php file. 5. create and edit a new text file cron.txt with your settings:

303

Drupal Handbook

3 Aug 2007

e.g., 55 23,5,11,17 * * * /home/accountname/public_html/drupal/scripts/cron-lynx.sh (a cron run every 11:55pm, 5:55am, 11:55am, 5:55pm) 6. import this script into crontab by typing crontab cron.txt 7. type crontab -l to see your new jobs for site. Voila, much easier than I thought!

Cronjobs without wget/lynx or curl
Some of you might have trouble getting lynx or wget to work. This may be the case if "localhost" is not permitted. Then wget, lynx or curl won’t work on the local machine. If you are not willing to depend on others to perform cronjobs and you dislike poormans cron, try this script. touch ~/scripts/cron-php.sh chmod 700 ~/scripts/cron-php.sh vi ~/scripts/cron-php.sh #!/bin/bash # # Simple cron script for those who cannot # use wget, lynx or curl because the host # closed the localhost loop. # # Usage: # - put this file in the ~/scripts dir # - add a cronjob pointing to this script # # Copyright OCS - 2006 # This script is provided under the GPL. # # v 0.1 original release # ############################# # CONFIGURATION OPTIONS ############################# # Complete local path # # Set the complete local path # to where the cron.php file # is (ie the root path) # Default is /var/www/html/ root_path=/var/www/html/ # Complete php path

304

3 Aug 2007

Drupal Handbook

# # Set the complete path # to the php parser if # different from standard parse=/usr/bin/php ############################## # END OF CONFIGURATION OPTIONS ############################## cd $root_path if [ -e "cron.php" ] then $parse cron.php if [ "$?" -ne "0" ] then echo "cron.php not parsed." else echo "cron.php has succesfully been parsed." fi else echo "cron.php not found." exit fi exit and then the crontab itself: crontab -e * * * * * ~/scripts/cron-php.sh > /dev/null 2>&1 where ~ is the directory where your drupal install is (the script defaults to /var/www/html/ but your professional hosting company will probably use /home/your.domain.tld/www

Configuring cron jobs on Windows
To setup a Windows machine to run cron.php at a specific time follow the specific instructions below. This can be useful if you are not familiar with Linux/Unix, or if your web host does not offer the ability to run cron jobs; you can run them remotely from your own computer. Note: These instructions were written for Windows XP but should be similar in other versions of Windows. Creating a Scheduled Task 1. 2. 3. 4. 5. Open Scheduler Go to Start > Programs > Accessories > System Tools > Scheduled Tasks Double-click Add Scheduled Task The Scheduled Task Wizard will appear. Click Next. Select the program to run. Choose your browser from the list (for example, Internet Explorer or Mozilla Firefox). Click Next.

305

Drupal Handbook

3 Aug 2007

6. Give the task a Name, such as Drupal Cron Job, and choose the Frequency with which to perform the task (for example, Daily)). Click Next. 7. Choose specific date and time options (this step will vary, depending on the option selected in the previous step). When finished, click Next. 8. Enter your password if prompted. Change the username if required (for example, you’d like the task to run under a user with fewer privileges security reasons). Click Next. 9. On the final page, select the checkbox Open advanced properties for this task when I click Finish and click Finish. Configuring the task 1. Go to the task’s setting page either by checking the checkbox at the end of the last step, or by double-clicking on the task. 2. In the Run box, after the text that is there now (for example, C:\PROGRA~1\MOZILL~1\firefox.exe), enter a space and then type the address to your website’s cron.php page in double quotations (for example, C:\PROGRA~1\MOZILL~1\firefox.exe http://www.example.com/cron.php 3. To set a frequency more often than Daily (for example, hourly), click the Schedule tab, then click Advanced. Here you can set options such as Repeat task, every 1 hour for 23 hours. Click Ok when finished. 4. Change the start time on the task to one minute from the current time. This will allow you to test the task and make sure that it is working. 5. When all settings have been configured to your liking, click Apply and OK (note: you may be prompted for your password) Command-line version Another way to perform the above commands is by using the schtasks (or at in Windows 2000) command from the command line. To duplicate the example above, which runs Firefox hourly to execute http://www.example.com/cron.php, open a command prompt (Start > Programs > Accessories > Command Prompt) and enter: schtasks /create /tn "Drupal Cron Job" /tr "C:\PROGRA~1\MOZILL~1\firefox.exe http://www.example.com/cron.php" hourly Enter your password if prompted. /sc

Throttle: congestion control
The throttle module provides a congestion control throttling mechanism for automatically detecting a surge in incoming traffic. If the site gets linked to by a popular website, or otherwise comes under a "Denial of Service" (DoS) attack, your webserver might become overwhelmed. This mechanism is utilized by other modules to automatically optimize their performance by temporarily disabling CPU-intensive functionality. For example, in the site theme, you might choose to disable pictures when the site is too busy (reducing bandwidth), or in modules, you

306

3 Aug 2007

Drupal Handbook

might choose to disable some complicated logic (reducing CPU utilization). The congestion control throttle can be automatically enabled when the number of anonymous users currently visiting the site exceeds the specified threshold. The congestion control throttle can be automatically enabled when the number of authenticated users currently visiting the site exceeds the specified threshold. You can enable throttle for modules at administer >> module. enable throttle for blocks at administer >> block. administer throttle at administer >> settings >> throttle.

When to use the throttle module?
The throttle is useful to sites that have limited resources and usually are not that busy. It is actually less useful to consistently high-traffic sites, as by necessity they will already have the required infrastructure to survive high loads. The throttle works well for a website that’s on a shared host with limited CPU and bandwidth, that usually only gets a handful of visitors, and then is suddenly Slashdotted. Of course, it will only help in that case if it has been enabled and properly configured.

Tracker: viewing new and updated content
The tracker module displays the most recently added or updated content to the website allowing users to see the most recent contributions. The tracker module provides user level tracking for those who like to follow the contributions of particular authors. The "recent posts" page is available via a link in the navigation menu block and contains a reverse chronological list of new and recently-updated content. The table displays the content type, the title, the author’s name, how many comments that item has received, and when it was last updated. Updates include any changes to the text, either by the original author or someone else, as well as any new comments added to an item. To use the tracker module to watch for a user’s updated content, click on that user’s profile, then the track tab. You cannot administer this module. There are no configuration options. You can view the most recent posts. view user profiles and select the track tab.

307

Drupal Handbook

3 Aug 2007

Upload: collaborate with files
The upload module allows users to upload files to the site. The ability to upload files to a site is important for members of a community who want to share work. It is also useful to administrators who want to keep uploaded files connected to a node or page. Users with the upload files permission can upload attachments. You can choose which post types can take attachments on the content types settings page. Each user role can be customized for the file size of uploads, and the dimension of image files. Note: you must first give a user role upload permissions before you can customize some of these settings. You can enable/disable uploads for individual content types at administer >> settings >> content types. administer storage location of uploaded files at administer >> settings in the File system settings area. configure file size, number of files, and other user role defaults at administer >> settings >> upload. control who can upload and view attached files at administer >> access control. The maximum upload size is controlled by your PHP environment. The standard PHP default is 2 MB. If you need to alter this, see the handbook page on how to Increase upload size in your php.ini.

User: access and management settings
The user module allows users to register, log in, and log out. Users benefit from being able to sign on because this associates content they create with their account and allows various permissions to be set for their roles. The user module supports user roles, which can be set up with fine-grained permissions allowing each role to do only what the administrator permits. Each user is assigned one or more roles. By default there are two roles: anonymous (a user who has not logged in) and authenticated (a user who has signed up and been authorized). Users can use their own name or handle and can fine tune some personal configuration settings through their individual my account page. Registered users need to authenticate by supplying either a local username and password or a remote username and password, such as a DelphiForums ID or an ID from a Drupal-powered website. A visitor accessing your website is assigned a unique ID, the so-called session ID, which is stored in a cookie. For security’s sake, the cookie does not contain personal information but acts as a key to retrieving the information stored on your server.

308

3 Aug 2007

Drupal Handbook

You can view your user page. administer users at administer >> user. create new users at administer >> user >> add user. configure user registration, user email, and user picture settings at administer >> settings >> user. allow users to select themes from their user account by enabling themes in administer >> themes. read user profile help at administer >> help >> profile. configure access permissions at administer >> access control.

Access Permissions reference
(This page is a work in progress. If you know what some of these do, please add a comment and I’ll fold it in.)

block module
administer blocks use PHP for block visibility

filter module
administer filters

menu module
administer menu

node module
access content Allows the user to view content. This should be enabled for all users, unless you want a private site. administer content types Allows the user to edit and add content types at /admin/content/types. administer nodes Allows the user to create, edit, and delete nodes of all types. This overrides all the create/edit own/edit options for specific content types below. This also exposes the ’Publishing options’ section when editing nodes, allowing users to promote content to the front page, publish and unpublish, make sticky, and create new revisions. create [TYPE] content Allows the user to create content of this type. This permission exists for page and story and each additional content type defined on the site. Overridden by the ’administer nodes’ permission.

309

Drupal Handbook

3 Aug 2007

edit own [TYPE] content Allows the user to edit content of this type that they have created. This permission exists for page and story and each additional content type defined on the site. Overridden by the ’administer nodes’ permission. edit [TYPE] content Allows the user to edit all content of this type. This permission exists for page and story and each additional content type defined on the site. Overridden by the ’administer nodes’ permission. revert revisions view revisions

path module
administer url aliases allows users the ability to administer the url aliases (modify, add, remove) create url aliases allows users to create url aliases

user module
access user profiles Can see user profiles; users without this set don’t see links on user names. administer access control Get the admin menu items Access control, Access rules, Roles added to navigation and able to make changes there. administer users Get the admin menu item Users -- can list all users, activate accounts, but NOT set roles. change own username what it says on the tin

system module
access administration pages allows users access to the admin path administer site configuration allows users to access the site configuration area of the admin panel select different theme allows users to change the theme from their profile.

Access rules (email filters)
Some of us know about a few CMS’s where the administrator can filter the incoming email registrations. For instance, you could register with your@institution.edu, but not with your@gmail.comor your@yahoo.com.Here’s how you do it:

310

3 Aug 2007

Drupal Handbook

Add an ACCESS RULE by going to ADMINISTER -> ACCESS CONTROL-> ACCESS RULES [for Drupal 4.7.4]. Then add 2 email address rules: Deny %@% (which should block everyone) and Allow %@allowed.com(which will allow people with anyone@allowed.com That’s pretty much all there is to it. Have fun with Drupal! ).

Managing access control with permissions and user roles
Roles, a way of assigning specific permissions to a group, allow you to fine tune the security, use and administration of Drupal. Users assigned to the role, or group, are granted those permissions assigned to the role. Common examples of roles used with which you may be familiar include: anonymous user, authenticated user, moderator, and administrator. By default, Drupal automatically defines two roles as a part of site installation: anonymous user -- readers of the site who are either do not have an account or are not logged in. authenticated user -- the role assigned to new accounts on a Drupal site. The anonymous user role should typically have the least access to the site of all roles. Authenticated users, because they took the time to register, might be given more permissions, such as the ability to create some types of content. If administrator approval is required for new users, or if they match certain criteria (such as having a company email address), you may be able to grant more permissions that way. The first Drupal account created on a new installation, sometimes referred to as the "root user", always has full permissions for all Drupal activities, including administration and content creation, editing and removal. More trusted users might be granted special privileges through an administrator-created role, and must be manually added to that role through the user administration interface. To create new roles: 1. Click administer >> access control >> roles tab. 2. Enter a label for the new role in the available text field at the bottom of the current list of roles. 3. Once you’ve added the role, select the permissions tab. 4. Your new role will be listed as a new column in the permission matrix. Grant permissions to the new role. 5. To add users to this role you will need to edit individual user accounts. Click administer >> users and the edit link for the user you wish to add to the role. Then you can add this user to your new role under the Roles section of the user edit page.

311

Drupal Handbook

3 Aug 2007

Note: Although all roles you create yourself receive any permissions you give to authenticated users automatically, neither roles you create yourself nor the authenticated user role receives permissions given to anonymous users. If you check any of the permissions boxes for anonymous users in the access control page, you should almost always also check the equivalent box for authenticated users to avoid odd site behavior.

Assigning permissions and users to roles
Access to almost all Drupal modules can be controlled by either enabling or disabling permissions for a given role. As a security precaution, the anonymous and authenticated users are configured with very minimal permissions during a site install. You’ll have to consider which permissions to enable. Go to the permissions administration page (administer >> access control >> permissions tab to begin enabling or disabling permissions. Consider the following descriptions of permissions: Administer -- Administer permissions, such as administer content and administer users, are usually reserved for the most trusted site users. These administration privileges grant users extensive control of the specific module(s) described by the permission title. For example, when administer permissions are granted on modules associated with specific node types, the user will be able to edit and delete all content for that node type on the entire site. Reminder: you’ll have to assign access administration pages rights to any role which also needs to configure site options in the administration menu. Access -- Permissions which grant access allow users read-only rights or general use of specific site modules, without any significant configuration privileges. Typically, these roles do not permit the creation of content. Most access permissions are safe to assign to any user role, although giving access administration should generally be reserved for the most trusted users. Create -- Allows users to create, but not necessarily edit later, the specified type of content. Generally applies to node types. Maintain -- These permissions generally enable a user to create content, as well as allowing the author of the submitted content to edit their own content. If you want to allow new site members to keep a weblog or work on the collaborative book, you’ll need to enable maintain permissions for the authenticated user.

Taxonomy_access: Restrict user roles to access specific categories only
Access to content can be restricted by category using the Taxononmy Access: http://drupal.org/project/Modules/taxonomy_access

Adjusting permissions after adding modules
Whenever a module is enabled, even if it is merely turned off and on, permissions for that module are unassigned to all roles. As a security precaution, an administrator always needs to assign permissions to roles any time a module is enabled.

312

3 Aug 2007

Drupal Handbook

User authentication
Registered users need to authenticate by supplying either a local username and password, or a remote username and password such as a jabber, Delphi, or one from another Drupal website. See distributed authentication for more information on this innovative feature. The local username and password, hashed with Message Digest 5 (MD5), are stored in your database. When you enter a password it is also hashed with MD5 and compared with what is in the database. If the hashes match, the username and password are correct. Once a user authenticated session is started, and until that session is over, the user won’t have to re-authenticate. To keep track of the individual sessions, Drupal relies on PHP’s session support. A visitor accessing your website is assigned an unique ID, the so-called session ID, which is stored in a cookie. For security’s sake, the cookie does not contain personal information but acts as a key to retrieve the information stored on your server’s side. When a visitor accesses your site, Drupal will check whether a specific session ID has been sent with the request. If this is the case, the prior saved environment is recreated.

Make a Drupal site use Basic Auth/ldap instead of the normal login block
This is a module I wrote for Drupal 5.0 to take care of authenticating, where the webserver has already done the user authentication via Basic Auth. In my case the user logged in via Basic Auth is also available as a user in Ldap so I can pull the ’cn’ name and user thier real name as thier Drupal name. Also auto populate the email address and keep the id the same as my corporate assigned user id. Enabling this module without first creating a user with admin priv with the same uid number as assigned via ldap will result in you locking yourself out of your site as the normal login block is totally bypassed by this module and becomes unavailable. To speed things up, I also added a row into the users table that directly maps to my user id obtained from basic auth. Also prevents users in large orgs with multiple John Smiths from being assigned the same account. Once again, this module totally bypasses the normal login block within Drupal substituting existing webserver based basic authentication. For those interested in doing ldap authentication WITHIN the Drupal login block, this module is not for you. Instead consider: http://drupal.org/project/ldap_integration for this. If you need to support Basic Auth, but don’t have hooks for ldap, considrer using this: http://drupal.org/project/securesite or this http://drupal.org/project/httpauth Some wierdness present. Users on first visit to site get the basic auth prompt twice, and the user shows up as logging in twice in the logs.

313

Drupal Handbook

3 Aug 2007

I also commented out the "Log out" button in my application in user.module as it doesn’t do anything other than adding extra lines into the logs after turning on this module. This module works as is for me, and perhaps it will save someone attempting to do the same thing as me some time. A good familarity with basic auth, ldap, and directly modifying the ’users’ table is probably a must. <?php /* ldap_auth module hook_init is run EVERY page load. We need to handle our own consumption of resources or spiral to death. */ function ldap_auth_init() { # if global $user has a uid already, bail as we are already logged in. global $user; if ($user->uid > 0) { return; } $user_tid=strtolower(trim($_SERVER[’LDAP_USER’])); require_once ’./includes/common.inc’; require_once ’./includes/theme.inc’; $result = db_fetch_object(db_query(’SELECT u.uid,u.name FROM {users} u WHERE u.tid = \’%s\’’,$user_tid)); # User doesn’t exist in database. Retrieve user info and add user. if (! $result->uid) { $ldap_server = ’directory.appl.yourcompany.com’; $ds=ldap_connect($ldap_server); if ($ds) { $r=ldap_bind($ds); $sr=ldap_search($ds, "o=yourcompany.com", "(uid=$user_tid)"); $info = ldap_get_entries($ds, $sr); $user_mail = $info[0][’mail’][0]; $user_name = $info[0][’cn’][0]; $user_number = trim($info[0][’personalnumber’][0]); # Use replace instead of insert to avoid errors in the event the uid has been added ahead of time, such as in the case of the administrators... db_query("REPLACE INTO {users} (uid,tid,name,mail,status,created) VALUES (%d,’%s’,’%s’,’%s’,1,%d)", $user_number,$user_tid,$user_name,$user_mail,time()); ldap_close($ds); } else { drupal_set_message(t(’Unable to contact Ldap server %name.’, array(’%name’ => check_plain($ldap_server)))); return; } } else {

314

3 Aug 2007

Drupal Handbook

# User exists in database. Set user info from there. $user_name = $result->name; $user_number = $result->uid; } # Log in, updating logs and redirecting to where the user requested, or home. Good stuff stolen from persistent login module. drupal_set_message(t(’Authenticated via Ldap. Welcome %name.’, array(’%name’ => check_plain($user_name)))); $l = array(’ldap_auth_login’ => 1,’name’ => $user_name,’uid’ => $user_number); drupal_load(’module’, ’user’); $user = user_load(array(’uid’ => $l[’uid’])); user_login_submit(’ldap_auth_login’,$l); drupal_goto(substr(drupal_get_destination(), 12)); } ?>

NTLM Authentication
NTLM is a proprietary (and not so good) protocol for deploying Single Sign On in predominantly Windows oriented networks (our company network also). NTLM sits on top of HTTP, so users who are logged on to the Windows Active Directory network can transparently log-on to web services using their Microsoft Windows credentials (and thereby having Single Sign On). Getting IIS servers working with NTLM is easy (it should be), but traditionaly Apache servers have had problems in doing this. This document explains how to get NTLM authentication working in Drupal in Linux + Apache boxes. There are various methods for getting NTLM authentication working in Apache. mod_ntlm - This is an Apache module which will add NTLM support to Apache. However, this module is not very actively maintained, and getting it compiled and running in various Apache versions ( and various distributions ) is a herculean task. To top it, the compilation throws out a lot of warnings, and one tends to feel uncomfortable with it. mod_ntlm_winbind - for boxes that have Winbind ( 1, 2 ) configured, this module can be configured to provide NTLM authentication for Apache. However, this module is still under development and is not well tested. However, for the help of people working in such unfriendly conditions, there is an excellent perl module that provides good support for NTLM authentication. Follow the steps given below for getting NTLM authentication working. 1. Install/Configure mod_perl under Apache - (and get it working of-course) 2. Download the following files for doing NTLM authentication (the following files worked for us)

315

Drupal Handbook

3 Aug 2007

For Fedora Core systems download the module from http://search.cpan.org/~speeves/Apache2-AuthenNTLM-0.02/AuthenNTLM.pm For Debian Linux systems, download the module from http://search.cpan.org/~speeves/Apache-AuthenNTLM-2.10 Install the module tar xvfz Apache*AuthenNTLM*.tgz cd Apache*AuthenNTLM* perl Makefile.PL make make test make install Edit the Apache configuration and enable KeepAlive KeepAlive On Restart your Apache server. Configure apache to do the authentication. For eg in .htaccess add. # Enable the Authentication module PerlAuthenHandler Apache2::AuthenNTLM # Do NTLM and basic authentication AuthType ntlm,basic # The name that should be displayed in the Auth box, if NTLM fails AuthName OurCompany # Ask for a valid user. require valid-user # domain pdc bdc # Domain : Your windows domain # pdc : Primary Domain Controller # bdc : Backup Domain controller. # # Note : Multiple domains can be specified. PerlAddVar ntdomain "OURDOMAIN domainpdc domainsdc" # What should be the default domain PerlSetVar defaultdomain OURDOMAIN # The user names are in the form "OURDOMAIN\user_name". Let us split it. PerlSetVar splitdomainprefix 1 # Set the debug variables PerlSetVar ntlmdebug 0 PerlSetVar ntlmauthoritative off More documentation is available in the accompanying README file in the tarball or the following link Once this is done, the domain user is populated as REMOTE_USER in the http server variables, which can be picked up by any application for doing authentication.

316

3 Aug 2007

Drupal Handbook

Now we need to enable Drupal to pick up this user id and automatically create a user. Once we have NTLM authentication working, the user id is available as REMOTE_USER. The WebServer Auth module can use this variable to automatically log the user in. Download, install, enable and configure the Webserver auth module and you should have a Drupal setup which can seamlessly integrate into Windows AD based networks.

User preferences and profiles
Each Drupal user has a profile, and a set of preferences which may be edited by clicking on the my account link. Of course, a user must be logged into reach those pages. There, users will find a page for changing their preferred time zone, language, username, e-mail address, password, theme, signature, homepage, and distributed authentication names. Changes made here take effect immediately. Also, administrators may make profile and preferences changes administer » users on behalf of their users. Module developers are provided several hooks for adding custom fields to the user view/edit pages. These hooks are described in the Developer section of the Drupal Handbook. For an example, see the jabber_user() function in /modules/jabber.module.

Using distributed authentication
Distributed authentication
One of the more tedious moments in visiting a new website is filling out the registration form. Here at drupal.org, you do not have to fill out a registration form if you are already a member of Drupal. This capability is called distributed authentication, and Drupal, the software which powers drupal.org, fully supports it. Distributed authentication enables a new user to input a username and password into the login box, and immediately be recognized, even if that user never registered at drupal.org. This works because Drupal knows how to communicate with external registration databases. For example, lets say that new user ’Joe’ is already a registered member of Delphi Forums. Drupal informs Joe on registration and login screens that he may login with his Delphi ID instead of registering with drupal.org. Joe likes that idea, and logs in with a username of joe@remote.delphiforums.com and his usual Delphi password. Drupal then contacts the remote.delphiforums.com server behind the scenes (usually using XML-RPC, HTTP POST, or SOAP) and asks: "Is the password for user Joe correct?". If Delphi replies yes, then we create a new drupal.org account for Joe and log him into it. Joe may keep on logging into drupal.org in the same manner, and he will always be logged into the same account.

Drupal
Drupal is the name of the software that powers drupal.org. There are Drupal websites all over the world, and many of them share their registration databases so that users may freely log in to any Drupal site using a single Drupal ID.

317

Drupal Handbook

3 Aug 2007

So please feel free to log in to your account here at drupal.org with a username from another Drupal site. The format of a Drupal ID is similar to an e-mail address: username@server. An example of a valid Drupal ID is mwlily@drupal.org.

Watchdog: monitor your site
The watchdog module monitors your system and records system events in a log you can review. This helps you get a quick overview of activity on your site. Since the log records events in sequence, it can also be useful for debugging site errors. The watchdog log records errors, warnings, usage data, performance data, and operational information. You can filter the entries ("Filter by message type") to view only a particular type of message. You should check the watchdog report regularly to make sure your site is working properly. You can view watchdog logs at administer >> watchdog. configure the length of time logs are archived at administer >> settings in the Error handling area.

318

3 Aug 2007

Drupal Handbook

End user guide
Welcome! This guide describes how to get started using (as opposed to administrating) a Drupal-powered web-site. This naturally includes Drupal.org, as well as most other Drupal web sites. The guide covers basic topics such as registering for an account, logging in, changing your account settings, and creating content. Drupal is a content management system. Its goal is to help users compose and present web-site content such as articles, photos, and other content types. Drupal is a "dynamic" system; rather than forcing users to specify a fixed, pre-declared arrangement of content, Drupal takes care of the details of how information is arranged and presentated, and lets users focus on the actual content to be displayed. Most of the content on a Drupal-based site (the text of this page, for example) is stored in a database. Text and images are submitted by filling in forms via a web browser. When visitors view a page, Drupal gets the relevant bits of content from the database and composes all of the components of the page in a template. This makes it easy to quickly add or change content, without requiring knowledge of HTML or other web technologies on the part of the person providing the content. Depending on the configuration of the Drupal site and the user-roles you play with respect to that site, you may be allowed to contribute or edit content. Fortunately, Drupal is designed to make this relatively easy. Very little technical knowledge is assumed. Though details may vary with a site’s configuration, the basic process involves these steps: register with the site log in by typing the user name and password supplied you in the registration step, and create content such as articles and stories This user guide will explain these steps and familiarize you with the basic information you need to use Drupal successfully. This section can also serve as a foundation for a set of instructions customized to your site’s specific needs.

Registering as a user
To add or edit content on a Drupal site, usually you have to first be registered as a user. (Sometimes the site administrator has chosen to enable "anonymous" posts of things like comments, in which case you can post them without registering.) In some cases, a site administrator will add you as a user. If so, they will send you a user name and password that you can use to log on.

319

Drupal Handbook

3 Aug 2007

Otherwise, look for a small form called âUser loginâ on the main page of the site you want to register with (usually on the right or the left of the page). Click the link that says "Create new account". The next page that comes up will generally have some information on the site’s policies for registration. After reading them, to register, enter a user name of your choice and an email address to which you have access and hit "submit". Then check your email account. Within a few minutes, you should get an automatically-generated email confirming your registration and giving you an initial password to use. Now you’re ready to log in.

Logging in
Before you can add or edit content, you usually need to log in. If you haven’t already done so, register as a user, see above (or, if applicable, request that your site administrator register you). Then hit the main page of the site you’re wishing to use and look for a "User login" form. This will typically be on the left or right side of the page (it is a "block" in Drupal talk). Enter your user name and password and hit "submit". Assuming everything’s working as planned, when the new page loads it will include a new block with your user name at the top. This is the menu you use to start entering and editing content.

Changing your account settings
Once you have registered with a Drupal-based site, you can change settings to control information about yourself and also your use and experience of a Drupal site. To see what tweaks you can make to your account, log in and then click on my account in the navigation block (that’s the one titled with your user name). Click on the edit tab. Account Settings. You may see a different collection of settings than is presented here, depending on what features have been enabled on your site. password Enter in a new password in both fields to set it. Drupal sends you a default password that is often hard to remember, so it is recommended that you change your password to something you can easily remember. block configuration The site administrator may make some blocks (chunks of content that are usually displayed in a left and/or right column) optional. You can enable and disable the display of these blocks by checking and unchecking the boxes next to them. signature If comments are enabled, you will be able to set a default signature. This will be copied into new comments for you automatically, but may still be edited. time zone Your site administrator may allow users to set their time zone. This will cause all dated content on the site to display in local time, according to the offset you enter here.

320

3 Aug 2007

Drupal Handbook

theme A "theme" is the basic look and feel of a Drupal site. Sometimes a particular site will have more than one theme installed. If the site administrator has made more than one theme available, you will be able to select what you would like the default theme to be for your account. As mentioned earlier, different site-settings will cause different fields to be displayed on your user account page. See the documentation for individual modules for instructions on how to use these additional options. Additional Information. Aside from the account settings tab, you may also see additional tabs, titled according to the information they contain. Some examples might include "Personal Information", "Workplace", etc. These are controlled by the profile module, and allows you to enter more information about yourself. Please see the profile module for more information on this.

Creating new content
Once you have logged-in, you’re ready to start posting content. At the top of your personal menu, you’ll find a link called "create content". Click this and you’ll see a list of the types of content you can create. This list reflects the privileges assigned to your user account or to the group ("role") your account is part of. There are several contributed modules which can assist with more complex content creation within this framework, such as spell checking, image embedding, and file attachment uploading.

A step-by-step example
We will assume that you have selected create content and chosen "story" as a content type. You should be looking at a form with the title "Submit story". From here, it is just a matter of filling in the form and posting it. Administrative options At the top of the form you may see some administrative options. For example, there is a box with the heading User comments. Drupal supports discussion/comments on postings--but such comments are not always appropriate. If your article is one that could be usefully commented on, keep the default settings: "Read/write". Otherwise, choose "Disabled". Title The title is straightforward enough. Try to be descriptive and catchy.

321

Drupal Handbook

3 Aug 2007

Topic: (may not be visible if you do not have categories defined) Next comes the "Topic" menu. This is the section your article will go in--or in the technical language of Drupal, its ("taxonomy categories"). This list presents all the sections available on the website, with their structure. So, choose the appropriate section or sections for your story and continue down the form to supply the body of your text. Body The "body" field is where you put the main content of the page. If you’ve typed this into a word processor or HTML editor, just copy and paste it into this field. Alternately you can just type straight in. For the most basic page, just type and leave a blank line (i.e., hit "enter" twice) at the and of each paragraph. You can optionally format your entry in friendly old HTML. But hey, if you’re a novice, don’t worry--it’s not as difficult as it sounds. Here’s a quick primer: If you want something to be bold, just enclose it in <b> or <strong> tags, like this: <b>This text is bold</b> <strong>This text is bold</strong> Note that there is always an opening tag (no forward slash) and a closing tag (a forward slash before the tag name, indicating that you are "turning it off"). To make something italic, put it in <i> or <em> tags: <i>This is in italics</i> <em>This is emphasized</em> There is considerable debate about the semantic nature of the <b></code <code><i> tags versus the <strong> and <em> tags. To put things nicely in paragraphs, enclose them in <p> tags: <p>This is a paragraph.</p> To make a bulleted list, first open a list with a <ul> tag (that stands for "unordered list"), then put each list item in <li> (yes, for "list item") tags. Don’t forget at the end to close off your list with a closing </ul> tag. Here’s how it looks: <ul> <li>This is the first bulleted item</li> <li>This is the second bulleted item</li> </ul> and

322

3 Aug 2007

Drupal Handbook

The result is displayed below: This is the first bulleted item This is the second bulleted item To add a link to you need to use the <a> (anchor) tag. <a href="http://www.example.com">Example.com</a> To add links to other pages within your Drupal site you do not need to add the full URL, you can simply refer to the node like so: <a href="/?q=node/1222">My node</a> Note the "/" at the beginning. Also the above example is using non-clean URLs. If your site has clean URLs enabled you can remove the ?q= so that you just have <a href="/node/1222">My node</a>. That wasn’t too painful, was it? Decide where you want the "teaser" (the part of the main text used in links to the article) to end. If you do nothing, Drupal will choose a breaking point for you -- but it’s better to decide yourself, to make sure the breaking point is appropriate. You do this by typing in a <!--break--> where the teaser is to end. (Your default break point is controlled by Post Settings, found in 4.7 at administer > settings > posts and in 5 at administer > content management > post settings.) And you’re set! You can preview the page you’ve prepared by hitting "Preview" (recommended, and sometimes required) or you can bravely or recklessly just go ahead and publish it by hitting "Submit".

Controlling Teaser Location
In Drupal, you can cause the teaser to end at the point of your choosing by adding the following to your content body: <!--break--> Everything above this tag will appear in the teaser (unless you place it beyond the point at which Drupal automatically breaks the content). Notes Make sure there are no spaces in the tag or it will be ignored. You can place the tag in the middle of a paragraph. The full text will not notice the tag so the paragraph will look normal, but the paragraph will be cut short in the teaser

323

Drupal Handbook

3 Aug 2007

How to add a page to the Handbook
Depending on how Drupal is configured, different users can add book pages, such as to the Documentation handbooks at drupal.org. The ability to create book pages is normally assigned to "roles" in the administration area. At drupal.org, all logged-in users have the role "authenticated user" and are allowed to add book pages. It’s very easy to add a page. When you feel like writing a piece of documentation about a topic that hasn’t already been addressed, just click on "Create content" link in the block under your user name. Then click the "Book page" link. Type away in the Body. Depending on administration settings at a web site, you may have various formatting options. Here on drupal.org, by default you will have "filtered HTML" capability. Give your page a short, descriptive Title. You will have to set the correct parent to page, select it from the Parent drop-down menu. Optionally you can add a log message to explain why you wrote the documentation. Give your page a weight. Pages with a less heavy weight will stay at the top within the parent section while pages with heavy weights will sink deeper. Then preview and finally submit.

Types of content
There are various types of content that you can post using Drupal. Many of these are organized into what are called "nodes". Basically, you can think of a node as the content of a page. This might be, for instance, an article. Content is added or updated through web page forms. So to add an article, you bring up a form, enter text into it (like the title and content of an article), and hit a button to submit the form.

Topics, categories and terms
Content on Drupal websites is usually organized using categories through a system called "taxonomy". A taxonomy has different "terms" that are used as categories for articles. When you’re adding an article, you might find a drop-down list of topics. By selecting one, you choose where on the site to categorize your article. If this seems hard to relate to, you can think of topics as being like folders on your hard drive--they help to organize content, so that you can find similar things in the same place.

Permissions
What types of content you can create or edit depends on the privileges assigned to the "role" or user group that you’re a member of. In general, to find out what you can do:

324

3 Aug 2007

Drupal Handbook

On your user menu (the collection of links that has your user name as a title), look for a link that says "create content". Click this to get a listing of the types of content you have permission to post. On a particular page, look for links at the bottom of an article. These links say things like "12 comments" (if there are comments that have been made on the article) and "read more" (if you’re looking at a short version of an article). If one of these links say "administer" or something like "edit this page", you have permissions to edit that type of content.

Moderation and the submission queue
Some Drupal sites are set up so that when you submit content it goes into a "submission queue". Content in this queue is read by other users who have a moderator role on the site. They will review the content and, if it is accepted, "publish" your contribution. Note that moderation has been removed from core as of Drupal 5 and can be accomplished with modules such as modr8.

Creating comments
Comments allow users to interact with the content on a site, to respond to an article, offer their own ideas, make additions, or supply a critique. Leaving comments When you bring up an article to read, look for comment-related links at the bottom of the article. If you’re not logged in, this might read "login or register to post comments". When you do log in, you should see something like "Add new comment". Click on the link and you’re ready to comment away. Etiquette Comments can be a great way of enriching a community site--but they can also lead to unfriendly, even harassing exchanges. As with any communication, it’s important to try to ensure that your comments are respectful and constructive. "Threaded" comments Comments on a Drupal web-site are "threaded". This means you can comment directly on an article--or you can reply to an existing comment. If you reply, your comment will be indented to show that it is part of that discussion.

Alternative ways to enter content
Drupal’s built-in form-based content editing approach is fine for many applications, but if you have a lot of text to create, or you wish to convert existing content, or if you are using a specialized content type such as a blog, it may be more convenient to use other approaches to enter content into your Drupal-based site.

325

Drupal Handbook

3 Aug 2007

Preparing your content offline suggests some ways to use familiar software on your computer to create or edit content before submitting it to Drupal. Depending on what’s available on your site, you might even be able to enter new articles without ever logging on to the site. Drupal includes functionality for "blogging"--creating "blogs" or web-based journals with the BlogAPI module. If this functionality is enabled on your site, you may be able to input and edit content using one of a number of desktop "blog" software packages. These allow you to simply type in content, hit a "post" button, and have your content automatically loaded onto your site. In fact, blogging software can be used for more than blogs--it can allow you to post content easily and quickly to almost any part of a website. Some examples of software you can use are: Examples of applications that work with Drupal from the desktop include the following: Ecto - Windows/Mac MarsEdit - Mac MS Word 2007 - Windows In addition to desktop blogging tools, other services like Flickr’s "post to blog", Firefox plugin Scribefire and Google Docs should work with your Drupal site. Before trying out one of the blogging programs, you might want to check with your site’s maintainer to make sure it accepts blog posts. The key question to ask is: "Is the BlogAPI enabled?" If the answer is yes, you’re ready to roll. If not, you could request that it be enabled to allow you quick updates.

HOWTO: Posting and editing blog entries with TextMate
Textmate is an editor for Apple Macintosh computers. The included Blogging bundle let you post and edit blog entries in your Drupal blog. As of writing to use the Blogging bundle you need to have the latest "cutting edge" release of Textmate (Version 1.5.2 (1112)). Get it by choosing "Cutting-Edge" in the TextMate menu TextMate > Preferences > Software Update and pressing "Check now". 1. Setup the Blogging bundle for your blog: Open a blank window and select Bundles > Blogging > Setup Blogs. Enter the URL of your blog. Insert your username and append xmlrpc.php to the URL, for example http://user@yourdomain/yourpath/xmlrpc.php. Save the file. Note: You are able to insert more than one blog entry. 2. Test the blog setup: Bundles > Blogging > Fetch post. TextMate will ask you for your Drupal password first time you connect to the blog. It will be saved in the keychain so you have to enter it only once. Next Textmate will present you with the last 20 blog entries you may choose from. 3. New blog entry: File > New From Template > Blogging > Weblog Post. Write your text and select Bundles > Blogging > Post To Blog to finally post the blog entry.

326

3 Aug 2007

Drupal Handbook

4. Choose Input Filter: the "Format:" header correlates to the Drupal Input Filters. Put a 3 there and the blog entry will use the third Input Filter. 5. Trimmed version (Teaser): Insert <!--break--> where you want to end the trimmed version of the blog entry. For a longer explanation have a look at the screencast at Blogging from Textmate. Problems so far: Image files: insert image files into your text by dropping them in the TextMate window. They will instantly uploaded to the blog and referenced in the text. Alas they do not appear at the blog entry, at least not at the authors blog. Taxonomy and vocabulary terms: It seems there is no way to insert vocabulary terms in the blog entry yet.

Posting and editing content with w.bloggar
w.bloggar is a gratis software for Windows designed for "blogs" (web-based journals). If you’ve confirmed that blog support is enabled, here’s some steps to get going: Download the software from http://www.wbloggar.com/ and install. Set up a new account. This is explained in the w.bloggar help files. When it comes time to set the "Blog Tool" selection, choose "MovableType" (and not "Drupal"). This is because (at time of writing) the Drupal support in w.bloggar is outdated. For "Host" put the domain of the website you’re using, then for "Path" put the rest of the address, if any, followed by "/xmlrpc.php". So if the address was "http://www.gworks.ca/site/" you would put "www.gworks.ca" for host and "site/xmlrpc.php" for Path. The "xmlrpc.php" part is the Drupal file that handles the blogging input. Now you’re ready to start posting. In doing so, you can take advantage of the text formatting functionality w.bloggar offers. When correctly set up, posting a web page from w.bloggar is as simple as opening the program, typing in some text, selecting a category (the "taxonomy term" to use) and hitting post. update It has been reported using 4.00.0193 (Mozilla version) Configuration notesâa departure from the original posting⦠In w.bloggar, I selected âDrupalâ as my blogging tool in the account setup dialog.

327

Drupal Handbook

3 Aug 2007

In Drupal, you must enable the blogger.api module. You don’t necessarily require blog module. I’m only using âstoryâ nodes, so I didn’t enable blog module. After enabling blogger.api, go to settings >> blogger.api and: check off the content type you wish to edit via the API. In my case, it’s âstoryâ. change the XML-RPC engine to âMetaWeblogâ.

Posting content with mailhandler
If the BlogAPI doesn’t meet your needs you should consider using the contrib mailhandler module to submit content.

Preparing content offline
Before posting directly to a site, you may want to start in a word processing program. Potential advantages include: Saving time online. This is a particular consideration if you’re on dial-up. Access to spell-check and other editing features. Depending on how much formatting you wish to do, you could also consider using an HTML editor. These include, for instance, the "composer" that comes with Mozilla and Netscape. Here are the steps involved: Type or copy and paste your text into the HTML editor. Apply formatting as desired (e.g., bold, italics). Bring up the HTML (encoded) view of the text. This HTML is what you’ll copy and paste into Drupal’s input form, to have formatted copy.

Editing and deleting content
To edit or delete existing content, log in and then bring up the page you wish to edit. Look on the page for an "edit" tab. Depending on your user permissions, you might see this on all pages or only on certain ones. For example, on Drupal.org, you should see the edit tab for those pages that you submitted. Clicking the edit tab will bring up a page with a form for changing the page. Here you can change the text and settings. Once you have the text and settings in a suitable form, click on the "Submit" button on the bottom of the form. Note that certain sites may be set up to require you to "Preview" the page before you can submit your changes. If you wish to delete the page (and you have appropriate permissions), click on the "delete" button near the bottom of the form. You’ll get a second chance to confirm that you wish to delete the page, or to change your mind!

328

3 Aug 2007

Drupal Handbook

Note: Because Drupal is very configurable, there may be additional ways of editing and managing content. Please check the documentation for your installation, ask the Drupal administrator, or consult with another user for details.

Search
The search facility is turned on or off by your site administrator. If it is on, you will see a box for entering your search terms and a button labelled "Search". it will be on the header of the page, or in one of the blocks on either side of the page. Like most search facilities, enter a word or words you want to search for and click the button. The wild card * performs the usual function of searching for âeverything that starts withâ Multiple words are searched as A or B, i.e. it returns pages that have one or more of the words. There is no search only for pages that have both A and B. The search engine gives greater weight to words used in headings or highlighted. It does this by assigning weights (multipliers) for scores of words inside certain HTML tags. Header h1 => 21 Header h2 => 18 Header h3 => 15 Header h4 => 12 inside a link => 10 Header h5 => 9 Header h6 => 6 underlined, bold, italics => 5 You can only search on individual words, not phrases in quotes. There is no sorting by date or other parameters. When searching for numerical data such as dates, IP addresses or version numbers, it considers a group of numerical characters separated only by punctuation characters to be one piece. This also means that searching for e.g. ’20/03/1984’ also returns results with ’20-03-1984’ in them. The dot, underscore and dash are simply removed. This allows meaningful search behaviour with acronyms and URLs. With the exception of the rules above, search considers all punctuation, marks, spacers, etc, to be a word boundary. You might also consider using Google. Start your query with "site:example.com", so you would enter site:example.com my search query or use the "Search this site" button on the Google toolbar.

329

Drupal Handbook

3 Aug 2007

Beyond the basics
Drupal is designed to support many different types of website. Many changes to a Drupal site’s functionality, appearance, and modes of interaction are easy to make via Drupal’s configuration and extension mechanisms. Drupal is highly configurable. The administrator of a site can enable different capabilities and change many settings that affect the look and functionality of a site. Drupal has a system of privileges that makes it possible to create different user roles - for instance, member, staff, partner. Each type of user can see and do different things on the site. Drupal is designed to be easily extended through modules. A module is just a fancy term for additional software you can activate or "plug in" to your web site to provide extra features and functions. For example, you might activate the poll module to let users easily create web-based polls. Some modules, called "core" modules, come pre-packaged with every Drupal installation. Third party modules, called "contributed" modules, can be downloaded separately from the Drupal website and installed on your server. The look and feel of a Drupal site can be changed through different "themes". As with modules, there are both core and contributed themes. Hence, what you see on a particular Drupal site, and what you can do there, depends to a high degree on what the site administrator(s) have chosen to present. If you require more in-depth information about changing the way in which information is presented or how its appearance may be configured, please see the Administrator’s guide at http://drupal.org/handbook and the Drupal forums.

330

3 Aug 2007

Drupal Handbook

Sports
football
“is david beckham the greatest footballer ever in england??”

331

Drupal Handbook

3 Aug 2007

Best practices guidelines
If you are going to invest in the time to setup a CMS, then you should make sure you protect your investment with some simple best practices guidelines. These guidelines are only suggestions on things that need to be considered when managing a web site or CMS. It is up to you to decide what is appropriate for you to implement for your sites. Of all the guidelines, being able to successfully backup and restore your website is probably the most important.

Back up your Drupal site
Backups are a mandatory part of running a content management system. They are your responsibility to perform regularly and flawlessly. Here’s what you need to know about backing up your Drupal site: Inquire about your ISP or web host’s backup policies. Most good web hosts have a backup plan that kicks in every 24 hours. If yours does not, it’s up to you to back up your site daily, or find a host who will. It cannot be stressed enough that if a site’s data does not exist in three places, it doesn’t exist at all. In addition to your web host’s backups, do it yourself. Periodically run a separate backup monthly, weekly, daily or whatever fits your site’s needs. Gauge the backup cycle by how much of your user’s data you can afford to loose without all the users revolting and starting a riot. Even if you tell yourself, "It’s no big deal", it is, and you do not want to lose content. Date your backups. Save each one into a directory that’s titled with the date of the backup. You do not want to be guessing which backup is the most recent one when you are trying to recover your failed site. Panic is not conducive to a good recovery process. Save a copy of each backup in a different location than your webserver. Remember, if data doesn’t exist in three places, it doesn’t exist at all. If your webserver crashes, then all the backup files might be gone too (see earlier reference to panic).

Backing up the database
Backing up and restoring a MySQL database using the command line is covered in the MySQL Reference Manual, section 5.10. Note that the Reference Manual cited is based on MyISAM tables. If you use InnoDB tables in your database, please pay particular attention to MySQL Reference Manual, section 14.2.8 Backups can also be performed with a graphical utility such as PHPmyAdmin. There’s also a FAQ on that site called "How can I backup my database or table." Another alternative solution is to install the Database Administration module. It has the option to backup the database tables from within Drupal itself. Note: Be careful with the permissions.

332

3 Aug 2007

Drupal Handbook

If you are using a database other than MySQL, that vendor’s documentation should have backup information. For a list of even more methods, consult the Handbook pages in the Upgrade Guide as well.

Backing up the core files
The root directory of your installation contains all the files that make Drupal do its magic. Sure, you *could* go get these files from Drupal.org again if you ever needed them, but having your own copies of the core files is so much faster and efficient. If you’ve edited anything in the core files for your specific website, having a copy of the core files becomes mandatory, since the site’s changelog is part of the root directory too. As a suggestion, everything in the root directory should be backed up monthly, but always back up the core files before an upgrade. It’s been said before in other sections of the Handbook, but Best Practices means that backups of the core should be a regular habit. Do this every month as suggested, and when disaster strikes, you won’t be wondering whether you’ve made any changes recently that have been lost forever.

Backing up the non-core files
Contributed modules and their associated third-party files should be backed up monthly as well. If you are adhering to the Best Practices outlined in the previous section above, your contributed modules will be part of the core files backup by default, since they exist inside a directory of the root Drupal installation. If you do not have the bandwidth or storage resources to back up your entire root directory each month, you must backup the /sites/all/modules/ (version 5.x) or the /sites/example.com/modules/ (version 4.7 and lower). Failure to do this may leave you with no clear example of which modules you had, and what versions they were. Imagine trying to restore your site right now without knowing which versions of modules to download from Drupal.org. Could you do it? There are also files that are not part of the database, the core, or the contributed modules that are important to your site. The directory you specified in Administer > Site Configuration > File System holds uploaded pictures, user’s icons, and other stuff that you don’t want to loose. If you are running your site in ’private’ file transfer mode, chances are good that this /files/ directory is not inside your root Drupal installation, and therefore won’t get backed up by the procedure outlined in "Backing Up The Core Files" above. The /sites/ directory is another one that you should take note of, since it holds lots of things relating to your site such as logos and embedded images. Custom themes are also stored here. Make sure that you back these two directories up weekly, or any changes made by your users might get lost forever. On high traffic sites, make daily backups of these two, and save the last 8 backups for safekeeping. If something goes wrong by accident, and you can bring your site back to the same way your users left it, you will have garnered their loyalty, increased word-of-mouth traffic for your site, and become their newest idol. You might even make it into their blog. Yes, backups can do this for you.

333

Drupal Handbook

3 Aug 2007

Test your backups
Document and test your backup and restore procedure before you need it. The forums and IRC chat are full of people who want help recovering from some unforeseen fatal error, and if they knew how to restore their site using the backups they’d created, they would be in business and making money rather than waiting for help from a Drupal volunteer.

Backup and restore using bash shell scripts
The two Bash shell scripts presented here work together automating the Drupal backup and restore process. They work "as is" for simple installations and can be customized for multisite or non-standard installations. The scripts have two uses: 1. Creating Drupal backups which can be restored to their original location e.g., restore from a failed upgrade attempt or recover from a disk failure 2. Staging data between Drupal configurations e.g., backup a production instance and restore to a test instance These scripts have been used successfully on and between Linux systems and on Windows systems using Cygwin.

Functional Overview
A full Drupal backup requires data backups from both the database and file system. These two backups must then be tied to each other. The backup script performs a file system backup using the tar command and a database backup using the mysqldump utility. The two backups are then combined into a single tar file. The tar is compressed and its file name includes the backup date. The restore script reverses the process by unpacking the file and database backups from the container tar file and applying them to their respective targets. The Drupal instance backed up or restored is specified by variables defined in the backup and restore scripts.

Usage notes and cautions
Detailed usage notes are provided for each script. The following points bear highlighting: The restore script has no safeguards against accidental restore. If you don’t understand how it can destroy your system you are encouraged NOT to use it. The backup script backs up every file and directory in the Drupal root directory. If you have a hosted site with subdomain websites contained in subdirectories a backup of the main website directory will include the subdomain websites. For backups this will only bloat

334

3 Aug 2007

Drupal Handbook

your backup file. For restores this could be disastrous, since you would restoring the file systems for ALL of the website. If you have this kind of configuration you must customize the tar command to make a selective backup. These scripts make no provision to lock out users while the backup or restore is in progress. This script does not understand Drupal multisite configurations The backup script requires read access to all files/directories and the restore script requires read/write access. This is sometimes a problem in hosted configurations. Because the backup and restore is done in stages enough temporary space must be available for the intermediate files Some commands used in the scripts will vary between operating systems. You may have to tailor commands for your operating system.

Site backup script
To use the script modify the variables in the Configuration block to specify the instance being backed up. The script will default the backup file name to value of tarnamebase appended with the date. The default value of tarnamebase is fullsitebackup. e.g.: fullsitebackup-2006-04-14.tgz. This name can be overridden by specifying a filename in parameter P1. The script is run using the normal Bash script invocation for your system. e.g.: $ sh fullsitebackup.sh $ bash fullsitebackup.sh You will be prompted for the database password. The backup file is placed in the same directory the script is run from. If multiple sites are hosted on the same system, create a copy of the script for each instance and rename it to reflect the backup it will perform. For example, for a site named mysite1, create a copy of fullsitebackup.sh named mysite1fullbackup.sh. You should also modify the tarnamebase variable to be more description of the site.

Usage notes and warnings:
This script backs up every file and directory in the Drupal root directory. If you have a hosted site with subdomain websites contained in subdirectories a backup of the main website directory will include the subdomain websites. For backups this will only bloat your backup file. For restores this could be disastrous, since you would restoring the file systems for ALL of the website. If you have this kind of configuration you must customize the tar command to make a selective backup. This script does not understand Drupal multisite configurations This script does not lock out users while the backup is in progress Read access is required on all files and directories (this is sometimes a problem in hosted configurations) The mysqldump utility uses the --add-drop-table option so that a restore automatically replaces tables. You may wish to modify this to add an element of safety to your restore

335

Drupal Handbook

3 Aug 2007

process. (e.g., tables must be manually dropped, script will not replace) Commands may need to be modified for your operating system (e.g., The default tar command in Solaris does not support compression) Because the backup is done in stages enough temporary space must be available to build the backup files

fullsitebackup.sh
Copy this text to a file named fullsitebackup.sh. Please ensure that special characters, such as backtick ("‘") and quotes, are saved correctly. #!/bin/bash # # fullsitebackup.sh V1.0 # # Full backup of website files and database content. # # A number of variables defining file location and database connection # information must be set before this script will run. # Files are tar’ed from the root directory of the website. All files are # saved. The MySQL database tables are dumped without a database name and # and with the option to drop and recreate the tables. # # Parameters: # tar_file_name (optional) # # Configuration # # Database connection information dbname={DB Name} # (e.g.: dbname=drupaldb) dbhost=localhost dbuser={DB Username} # (e.g.: dbuser=drupaluser) # Website Files webrootdir={Directory Path} # (e.g.: webrootdir=/home/user/public_html) # # Variables # # Default TAR Output File Base Name tarnamebase=sitebackupdatestamp=‘date +’%Y-%m-%d’‘ # Execution directory (script start point) startdir=‘pwd‘ # Temporary Directory tempdir=tmpbckdir$datestamp

336

3 Aug 2007

Drupal Handbook

# # Input Parameter Check # if test "$1" = "" then tarname=$tarnamebase$datestamp.tgz else tarname=$1 fi # # Banner # echo "" echo "fullsitebackup.sh V1.0" # # Create temporary working directory # echo " .. Setup" mkdir $tempdir echo " done" # # TAR website files # echo " .. TARing website files in $webrootdir" cd $webrootdir tar cf $startdir/$tempdir/filecontent.tar . echo " done" # # sqldump database information # echo " .. sqldump’ing database:" echo " user: $dbuser; database: $dbname; host: $dbhost" cd $startdir/$tempdir mysqldump -p --user=$dbuser --host=$dbhost --add-drop-table $dbname > dbcontent.sql echo " done" # # Create final backup file # echo " .. Creating final compressed (tgz) TAR file: $tarname" tar czf $startdir/$tarname filecontent.tar dbcontent.sql echo " done" # # Cleanup # echo " .. Clean-up" cd $startdir

337

Drupal Handbook

3 Aug 2007

rm -r $tempdir echo " done" # # Exit banner # echo " .. Full site backup complete" echo ""

Updated fullsitebackup.sh
#!/bin/bash # # fullsitebackup.sh V1.1 # # Full backup of website files and database content. # # A number of variables defining file location and database connection # information must be set before this script will run. # Files are tar’ed from the root directory of the website. All files are # saved. The MySQL database tables are dumped without a database name and # and with the option to drop and recreate the tables. # # ---------------------# March 2007 Updates # - Updated script to resolve minor path bug # - Added mysql password variable (caution - this script file is now a security risk - protect it) # - Generates temp log file # - Updated backup and restore scripts have been tested on Ubunutu Edgy server w/Drupal 5.1 # # - Enjoy! BristolGuy #----------------------# ## Parameters: # tar_file_name (optional) # # # Configuration # # Database connection information dbname="drupal" # (e.g.: dbname=drupaldb) dbhost="localhost" dbuser="" # (e.g.: dbuser=drupaluser) dbpw="" # (e.g.: dbuser password)

338

3 Aug 2007

Drupal Handbook

# Website Files webrootdir="/var/www/drupal" # (e.g.: webrootdir=/home/user/public_html) # # Variables # # Default TAR Output File Base Name tarnamebase=sitebackupdatestamp=‘date +’%m-%d-%Y’‘ # Execution directory (script start point) startdir=‘pwd‘ logfile=$startdir"/fullsite.log" # file path and name of log file to use # Temporary Directory tempdir=$datestamp # # Input Parameter Check # if test "$1" = "" then tarname=$tarnamebase$datestamp.tgz else tarname=$1 fi # # Begin logging # echo "Beginning drupal site backup using fullsitebackup.sh ..." > $logfile # # Create temporary working directory # echo " Creating temp working dir ..." >> $logfile mkdir $tempdir # # TAR website files # echo " TARing website files into $webrootdir ..." >> $logfile cd $webrootdir tar cf $startdir/$tempdir/filecontent.tar .

339

Drupal Handbook

3 Aug 2007

# # sqldump database information # echo " Dumping drupal database, using ..." >> $logfile echo " user:$dbuser; database:$dbname host:$dbhost " >> $logfile cd $startdir/$tempdir mysqldump --user=$dbuser --password=$dbpw --add-drop-table $dbname > dbcontent.sql # # Create final backup file # echo " Creating final compressed (tgz) TAR file: $tarname ..." >> $logfile tar czf $startdir/$tarname filecontent.tar dbcontent.sql # # Cleanup # echo " Removing temp dir $tempdir ..." >> $logfile cd $startdir rm -r $tempdir # # Exit banner # endtime=‘date‘ echo "Backup completed $endtime, TAR file at $tarname. " >> $logfile

Site restore script
Caution: This script has no safeguards against accidental restores. Since a restore, by definition, overwrites the existing website do NOT use this script unless you understand what it is doing. To use this script modify the variables in the Configuration block to specify the instance where the data will be restored. To restore a site run the script specifying the backup file in parameter P1. e.g.: $ sh fullsiterestore.sh fullsitebackup-2006-04-14.tgz $ bash fullsiterestore.sh fullsitebackup-2006-04-14.tgz You will be prompted for the database password and may be prompted for permission to delete a file if it is permitted read-only. If multiple websites are hosted on the same system create a copy of the script and rename it to reflect the restore it will perform. For example, for a site named mysite1, create a copy of fullsiterestore.sh named mysite1fullrestore.sh.

340

3 Aug 2007

Drupal Handbook

Usage notes and warnings:
The backup script uses the mysqldump --add-drop-table option. On a restore this allows the database tables to be removed and recreated. No prompt is given before this happens. Write access is required on all files and directories (this is sometimes a problem in hosted configurations) Enough file space must be available to allow unpacking of the backup file This script does not lock out users while the restore is in progress This script does not understand Drupal multisite configurations Commands may need to be modified for your operating system (e.g., The default tar command in Solaris does not support compression) If restoring over top of a Drupal instance that contains modules that are not in the backup there will be "orphaned" module tables. Depending on the situation, you may wish to drop and recreate the database before doing the restore. When restoring to a different server the file permissions may require updating No Drupal configuration is required if restoring a backup to the same location it was backed up from. If restoring a backup to a different location the configuration must be updated according, specifically $db_url and $base_url in settings.php. The article Creating a Test Site workflow contains information on automating this using a command line utility named sed.

fullsiterestore.sh
Copy this text to a file named fullsiterestore.sh. Please ensure that special characters, such as backtick ("‘") and quotes, are saved correctly. #!/bin/bash # # fullsiterestore.sh v1.0 # # Restore of website file and database content made with full site backup. # # A number of variables defining file location and database connection # information must be set before this script will run. # This script expects a compressed tar file (tgz) made by fullsitebackup.sh. # Website files should be in a tar file named filecontent.tar, and database # content should be in a sqldump sql file named dbcontent.sql. This script # expects the sql to drop the table before readdding the data. In other words, # it does not do any database preparation. #

341

Drupal Handbook

3 Aug 2007

# Parameters: # tar_file_name # # Configuration # # Database connection information dbname={DB Name} # (e.g.: dbname=drupaldb) dbhost=localhost dbuser={DB Username} # (e.g.: dbuser=drupaluser) # Website Files webrootdir={Directory Path} # (e.g.: webrootdir=/home/user/public_html) # # Variables # # Execution directory (script start point) startdir=‘pwd‘ # Temporary Directory datestamp=‘date +’%Y-%m-%d’‘ tempdir=tmpbckdir$datestamp # # Banner # echo "" echo "fullsiterestore.sh v1.0" # # Input Parameter Check # # If no input parameter is given, echo usage and exit if [ $# -eq 0 ] then echo " Usage: sh fullsiterestore.sh {backupfile.tgz}" echo "" exit fi tarfile=$1 # Check that the file exists if [ ! -f "$tarfile" ] then echo " Can not find file: $tarfile" echo "" exit fi # Check that the webroot directory exists if [ ! -d "$webrootdir" ] then echo " Invalid internal parameter: webrootdir"

342

3 Aug 2007

Drupal Handbook

echo " Directory: $webrootdir does not exist" echo "" exit fi # # Create temporary working directory and expand tar file # echo " .. Setup" mkdir $tempdir cd $tempdir tar xzf $startdir/$tarfile echo " done" # # Remove old website files # echo " .. removing old files from $webrootdir" rm -r $webrootdir/* echo " done" # # unTAR website files # echo " .. unTARing website files into $webrootdir" cd $webrootdir tar xf $startdir/$tempdir/filecontent.tar echo " done" # # Load database information # cd $startdir/$tempdir echo " .. loading database:" echo " user: $dbuser; database: $dbname; host: $dbhost" echo "use $dbname; source dbcontent.sql;" | mysql --user=$dbuser --host=$dbhost echo " done" # # Cleanup # echo " .. Clean-up" cd $startdir rm -r $tempdir echo " done" # # Exit banner # echo " .. Full site restore complete" echo ""

--password

343

Drupal Handbook

3 Aug 2007

Updated fullsiterestore.sh
#!/bin/bash # # fullsiterestore.sh v1.1 # # Restore of website file and database content made with full site backup. # # A number of variables defining file location and database connection # information must be set before this script will run. # This script expects a compressed tar file (tgz) made by fullsitebackup.sh. # Website files should be in a tar file named filecontent.tar, and database # content should be in a sqldump sql file named dbcontent.sql. This script # expects the sql to drop the table before readdding the data. In other words, # it does not do any database preparation. # # ---------------------# March 2007 Updates # - Updated script to resolve minor path bug # - Added mysql password variable (caution - this script file is now a security risk - protect it) # - Generates temp log file # - Updated backup and restore scripts have been tested on Ubunutu Edgy server w/Drupal 5.1 # # - Enjoy! BristolGuy #----------------------# # Parameters: # tarfile # name of backup file to restore # # # Database connection information dbname="drupal" # (e.g.: dbname=drupaldb) dbhost="localhost" # dbuser="" # (e.g.: dbuser=drupaluser) dbpw="" # database user password # Website location webrootdir="/var/www/drupal" # (e.g.: where you keep your drupal directory structure) # # Variables # Execution directory (script start point) startdir=‘pwd‘ # return of pwd() populates statdir var logfile=$startdir+"fullsite.log" # file path and name of log file to use

344

3 Aug 2007

Drupal Handbook

# Temporary Directory datestamp=‘date +’%Y-%m-%d’‘ # uses US format tempdir=$datestamp # # Begin logging # echo "Beginning drupal site restore using \’fullsiterestore.sh\’ ..." > $logfile # # Input Parameter Check # # If no input parameter is given, echo usage and exit if [ $# -eq 0 ] then echo " Usage: sh fullsiterestore.sh {backupfile.tgz}" echo "" exit fi tarfile=$1 # Check that the file exists if [ ! -f "$tarfile" ] then echo " Can not find file: $tarfile" >> $logfile echo " Exiting ..." >> $logfile exit fi # Check that the webroot directory exists if [ ! -d "$webrootdir" ] then echo " Invalid internal parameter: webrootdir" >> $logfile echo " Directory: $webrootdir does not exist" >> $logfile echo " Exiting ..." >> $logfile exit fi # # Create temporary working directory and expand tar file # echo " Creating temp working dir ..." >> $logfile mkdir $tempdir cd $tempdir echo " unTARing db and file tgz files ..." >> $logfile tar xzf $startdir/$tarfile

345

Drupal Handbook

3 Aug 2007

# # Remove old website files # echo " Removing old files from $webrootdir ..." >> $logfile rm -r $webrootdir/* # # unTAR website files # echo " unTARing website files into $webrootdir ..." >> $logfile cd $webrootdir tar xf $startdir/$tempdir/filecontent.tar # # Load database information # cd $startdir/$tempdir echo " Restoring database ..." >> $logfile echo " user: $dbuser; database: $dbname; host: $dbhost" >> $logfile echo "use $dbname; source dbcontent.sql;" | mysql --password=$dbpw --user=$dbuser --host=$dbhost # # Cleanup # echo " Cleaning up ..." >> $logfile cd $startdir sudo rm -r $tempdir # # Exit banner # endtime=‘date‘ echo "Restoration completed $endtime for $tarfile. " >> $logfile

Accounts and roles
1. Do not use the first user account for day to day stuff on your site. This account should be used for the site setup, major configuration changes and upgrades only. UID1 (User ID) has special use and purpose. 2. Set up some appropriate roles (do not forget to update these roles as you add new modules). Some role suggestions are ’site admin’, ’user admin’, ’site contributor’. What roles you need to create will depend on the type of site you have designed. Note that anyone who can administer users can grant themselves additional permissions. 3. Adding new modules often adds additonal permissions options. When adding new modules revisit your access lists to check for appropiate access for your roles.

346

3 Aug 2007

Drupal Handbook

Configuring Apache and PHP for Drupal in a Shared Environment
#### STARTING TO CLEAN UP ##### #### todo: mysql tuning section #### #### markup layout and use &gt; &lt; These are some simple guidlines for setting up Drupal in an Apache Virtual host that provides a fair amout of security for the rest of your system. Starting with php.ini: php.ini Configuration # increase php’s memory limit to avoid the white screen of death when # you add a few modules. memory_limit = 16MB Apache Virtual Host Configuration ServerName example.com #wildcard server alias helps direct all traffic to your end users site #and simplifies using drupal’s multisite configuration for subdomains. ServerAlias *.example.com # This path will vary depending on your system, If you are using debian # make sure you drop the default images alias it can be very annoying # to users on shared servers. DocumentRoot /var/www/example.com/public_html # Place the log where your end users can see them, and make sure they # are at the least readable to an end user. # # performance option: # You can move the apache logs to another partition or drive to # get some small increases in disk i/o on heavily loaded servers. # You can symlink the log files to /var/www/example.com/logs/ # to keep the persistent user interface, however it doesn’t work in # chroot environments. ErrorLog /srv/www/example.com/logs/error.log CustomLog /srv/www/example.com/logs/access.log combined

347

Drupal Handbook

3 Aug 2007

#Go ahead and give users access to manipulate their vhost to their #hearts content. AllowOverride All #Since mod_php doesn’t like yo respect su_exec, and safe_mode is just # too paranoid to be usable restrict php to the proper vhost, but a level #above the document root so users have some private file space for #.htpasswd, drupal files, backups, etc php_admin_value open_basedir /var/www/example.com #move php’s temp files into the open_basedir php_admin_value upload_tmp_dir /var/www/example.com/tmp #session.save path isn’t really necessary for drupal since it #stores sessions in the database, but for general php enabled #vhosts it keeps session data tied to each vhost. php_admin_value session.save_path /var/www/example.com/tmp //Tweaking performance my.cnf #big ol mysql.querycache(128M) (be aware of your systems memory limitations) query_cache_size = 134217728 #boost mysql max connections (min = (20*number of drupal sites)) set-variable=max_connections=512 eacclerator

Creating a Test Site workflow
Terms: prod site: the live, production website where all your web visitors go test site: a copy of your live site, at a different URL, where you can make experimental changes without affecting your prod site Drupal and its modules are in pretty constant development. So things are changing pretty fast and sometimes not completely documented. In practice, that means making a change or adding/removing a module on your prod site can have rather surprising results - surprises you’d rather your visitors didn’t have to live with. That’s why I recommend making all changes to a test site, and if they work out, promote the changes to your prod site. Here’s how I built a completely parallel site on my hosted, shared server account. First I need to mention some things about my site, so the rest of this article makes sense:

348

3 Aug 2007

Drupal Handbook

My site is called yoursite.com it’s hosted on a shared server I have shell access to my hosted files. Without shell I wouldn’t really want to attempt all this. I am allowed to have two mysql databases on my account all site files are at /home/user/public_html (there’s also an alias, /home/user/www, which points to public_html) in the above, user stands for my username, which I’m not telling you I keep my production drupal database in mysql; that db is named mydb_prod Apache is set up so that http://www.yoursite.com and http://yoursite.com will point to /home/user/public_html All of this is pretty standard stuff, but you may have to make a few changes to this process if your site is set up differently. My test/prod workflow looks generally like this: 1. 2. 3. 4. 5. 6. Make a new (empty) database, and name it mydb_test Copy your prod db into mydb_test Copy all of your prod files (from public_html) into your test directory Make three settings changes to connect the test site to the test db Make changes to your test site. (optional) replicate test site’s files and db back into the prod site to make your changes live

So how to actually do all this? Don’t worry, it’s not that hard once you have the right commands handy. Really, I do steps 1-4 in about 2 minutes. This document is long only because I wanted to be verbose enough for all skill levels! Step 0 - work with your host provider The first thing I did was ask my hosting provider to create a new directory, /home/user/test and then set up apache and their DNS servers so that http://test.yoursite.com and http://www.test.yoursite.com would point to this new test directory. It was important to ask them to make a new VirtualHost entry in the apache configurations, NOT just set up a rewrite rule. They should know what you mean by this - and they might charge you extra for it. Mine didn’t, but even if this costs you a couple of extra bucks, it’s worth it. Trust me when I say that using a rewrite rule or subdirectory of your existing site will make the rest of this much harder to do. When this is complete your directory structure will look something like: |-home |-username | |-public_html | | | |-database | |-files | |-includes | |-misc

349

Drupal Handbook

3 Aug 2007

| |-modules | |-scripts | |-sites | |-themes | |-(drupalfiles) | |-test | |(empty because we haven’t put anything here yet) /home/username could in your case be /var/www/username, or something else entirely. The point is to have a test directory which is not part of your normal html directory, and which acts as a separate site in all ways. You’ll also need a second mySQL database to house your test site’s data. Step 1 - Create an Empty Database I use the commands mysql -uuser -ppassword -e "create database mydb_test;" mysql -uuser -ppassword -e "grant all privileges on mydb_test.* to user@localhost identified by ’password’;" to create my database and set the permissions. The I broke a single mysql command into the last two lines because drupal.org wasn’t printing it all as a single line. If you are restricted from doing so, you may need to create the empty database via cPanel, Plesk, or whatever control panel your provider gives. Step 2 - Replicate the database mkdir ~/temp mysqldump -uuser -ppassword --add-drop-table mydb_prod > ~/temp/prod-db mysql -uuser -ppassword mydb_test < ~/temp/prod-db rm ~/temp/prod-db Above you see the commands I enter. You’ll need to change things user and password to your username and password; also mydb_prod should be replaced with the mySQL database name for your prod site. Knowing that, I bet you’ve already figured out that you need to replace mydb_test with the name of your newly-created test database. The first line just creates a directory to hold our temporary dump file. The second line, starting with mysqldump, is where we dump the entire prod database to a textfile. We use the --add-drop-table option because this essentially creates a script we’ll run later; this option makes sure that script will erase old data before importing new data. Note that you need to supply the proper username and password for your production database. I specify the database name mydb_prod - you will need to change this to the name of your prod site’s

350

3 Aug 2007

Drupal Handbook

database. The textfile created by this command is actually a full script which will create tables and populate them with data. The third line, starting with mysql, is where we do that. Again, be sure and replace the italicized parts with the username, password, and database name you set up in step 1. Finally I delete the dump file (~/temp/prod-db); it’s not needed anymore now that we have loaded it into mySQL. Step 3 - Copy the web files rm -rf ~/test cp -R ~/public_html/. ~/test Here I remove the test directory, then recreate it, and copy everything from ~/public_html into it. I remove the test directory and all contents because I may copy of the test site in there, and I don’t want it to pollute my fresh new exact replica of my prod site. Step 4 - Edit Settings nano ~/test/sites/default/settings.php This starts the nano editor (or use whatever you like) and loads drupal’s settings file. Here you will need to change two lines: $db_url = ’mysql://user:password@localhost/mydb_test’; $base_url = ’http://test.yoursite.com’; These lines are not together in the file. Set the database connection line, pointing to the test database you created in step one and populated in step 2. (in other words, you need to replace the words user, password, and mydb_test with information that’s correct for your test database.) The base_url line sets the URL you will point your browser at to use the site. Save the changes. Now, in your web browser, navigate to the site - it should be working fine. But I also change the Name field at administer --> settings to TEST.yoursite.com (all caps) so its easy for me to remember I am looking at the test site. Step 5 - Make your changes This is where you make you changes. Change settings, add/remove modules, muck with the code - it’s up to you. Remember you are working in a copy of your site - one that users don’t know about - so you don’t have to worry that you are creating problems for the users. Killes has written a very nice and very quick way of testing your site at node/11521 And if you don’t like the changes, or if you mess up your test site completely - no worries! Just re-do steps 2-4 to bring a new copy of your production site and database into your test environment.

351

Drupal Handbook

3 Aug 2007

Step 6 - Promoting changes to production Now that you have your test site the way you want it, you really have two choices. Method 1: You can re-make all the same changes manually on your production site. Method 2: You can basically migrate the test site into production, with a very brief outage for the users. I usually use method 2, but have been known to do it both ways. To use method 2, I’m essentially doing everything mentioned above, but this time copying the test site into the production location. So I’ll skip over it more quickly this time around: 1. mysqldump -uuser -ppassword --add-drop-table mydb_test > ~/temp/test-db mysql -uuser -ppassword mydb_prod < ~/temp/test-db rm -rf ~/temp/test-db rm -rf ~/public_html/* cp -R ~/test/. ~/public_html 2. nano ~/public_html/sites/default/settings.php (here you’ll edit the db_url and base_url to the prod-site settings) 3. Also be sure to open the prod site, navigate to administer // settings and change the name back to the way it should be for the prod site. You should probably test your site again using the Killes method linked in step 5. There are a couple of additional cleanup steps I do, once I know my site is in good shape: rm -rf ~/test/* (just cleaning out test dir for next time) rm ~/bash_history(because it has my database password in it) Remove the test database (if space is a concern)

File and directory management
These are general guidelines. 1. For Drupal 5.x only: a new feature/best practice. For a normal (single site) installation, you should put all non-core modules or themes in the sites/all/modules or sites/all/themes folders. For a multi-site installation, put modules or themes in sites/all that you wish to have available for all sites. 2. For 4.7 and prior: Create a sub directory in modules for each contributed module you install. This helps you track contributed modules vs included core modules. This is fairly important when preparing for a Drupal version upgrade and a good idea in general. For example: a module named foo.module would go in a sub directory of modules; modules/foo Be sure not to include the space if the module name is multiple words. 3. Multisite setups allow you to have a modules directory specific to the site in the sites/www.example.com/modules directory. You can still put modules in directories off

352

3 Aug 2007

Drupal Handbook

the main /modules directory if you want them available to all sites. 4. Leave the CHANGELOG.txt file in your root directory as it has the Drupal version information in it. If you manage more then one site, consider putting a version.txt file in the root of your drupal directory with the Drupal version, date and modules you are using. If you only manage a few sites you will probably remember them all, but if you set them up for other people, these reminders can help you if you are asked back to do additional work. Also, it can help the next site admin if you move on. 5. Rename update.php if you want. There are protections for it in the update script in that you have to be logged in with UID1. As of 4.7 update.php is now required for various module installations and other tasks so if you move/rename it for whatever reason do not forget to put it back to it’s original state before module installs/updates.

Other Tips
Modules that are not part of core may or may not be supported by their contributor for a Drupal version upgrade. Avoid spaces in any directory name.

Test Sites
Set up a test site using your live data. You do not want to have to ask in the forums how to save your site. You have worked hard to build it, it would be a shame to lose it. 1. Never do development or testing on your live production site. Drupal is fast and easy to install. Always test on a test site first. 2. Test that your backups work and that you know how to do a restore of your site. The test system can be your local desktop, just edit your conf.php (4.5 or earlier) file or settings.php (4.6) to localhost. You do not want to discover the hard way that you forgot a file or did not know how to do this when your site is down. 3. Test your site upgrade procedure before risking your live site and document the steps you take. Documentation aids repeating the process if necessary. Testing can be done with Simpletest. For more information on installing test sites, please see the Installing Drupal section. There are some specific examples of copying a production site to a test/development environment in the Special Cases subsection under Installation.

Version update considerations
There are several approaches to updating your site and the instructions are in the INSTALL.txt file of the Drupal download. Unless you do this often however, you may miss a few other considerations when updating from one release to the next.

353

Drupal Handbook

3 Aug 2007

1. Read the Best Practices on test sites and don’t do it first on your live site. 2. Make sure that all the contrib modules you are using have an update path or you are willing to upgrade them yourself or abandon them. 3. Create a new database and restore your live site to it, files and all. 4. Disable all contrib modules. 5. Set your site to the default theme Blue Marine (for Drupal 4.7.x) or Garland (for Drupal 5.x). Read the upgrade portion of the INSTALL.txt file Log in with UID 1. Run sitename/update.php. On the update.php page, check the schema date of the database, I generally leave it where it defaults to. Upgrade. Check for errors. Resolve all errors BEFORE proceeding. Log in check it out. Get your modules and read the install and readme files to see if there are any special upgrade instructions. Upgrade and activate modules one at a time. Test, etc. Put your own favicon.ico back. Congratulations. You can restore this to your live site. - or Follow the steps on your live site now that you are confident it will work. Start working on your theme updates and other and stuff.

Do not modify core Drupal
Do not modify Drupal core files. Doing so will complicate, make difficult or near impossible site updates due to Security and bug fixes You will make it difficult for those that come after to maintain the site You could possibly leave your site vulnerable to exploits Are there exceptions to this rule? Sure, but this is generally for specific sites or implementations by people who are extremely familiar with the Drupal code base, development practices and security model. Those who properly document their changes and practice proper revision control with their code. If you have to ask, chances are you shouldn’t.

354

3 Aug 2007

Drupal Handbook

Security
Security is an important consideration when running your web site. If you maintain your own server you should be aware of any announced vulnerabilities for your operating system, php, and web server. Be sure to follow up with the appropriate patches or updates as needed. Sign up for the security mailing list so that you can be aware of any announced vulnerabilities and how to correct them.

Test php before putting it in blocks
Drupal gives you a great deal of power and flexibility when using PHP code in blocks. Unfortunately, a stray typo character or a missing semi-colon breaks PHP. Drupal then attempts to evalate this broken code on any requested page, the PHP interpreter chokes on it and therefore your whole site is broken. Fortunately, there is a very simple and easy solution. Instead of writing and testing your code inside the administer > blocks page, go to create content and create a new story or page node. Use PHP input format, write the code, and the Preview to debug your code. When you are happy and your code is working, copy and paste the code into the block. Thank you to Heine for this tip in the #drupal-support IRC channel.

355

Drupal Handbook

3 Aug 2007

HowTo: The Advanced user’s guide
Ok, so you’ve installed Drupal and gotten it working. You’ve added a module or two, and maybe you’ve even changed the theme. Now you want to do more, and adding modules or changing the options doesn’t seem to cut it. Maybe you’ve found that things don’t look quite like you want them to, or you want there to be more functionality in a particular module. Specifically for Modules If you have problems with or questions about a specific module, there are two places to start looking: Core Modules Handbook or Contributed Modules Handbook Another place to look for issues or bugs in contributed modules is: Module downloads page. Click on "Bugs and feature requests" under your specific module to see if someone has already addressed the issue. The next place to go is to the forums. Specifically for Themes You might find that some Drupal 4.6 or earlier themes you’ve installed don’t seem to show up. If they are run by the phpTemplate Engine, you’ll need to download it and install it. If you are using Drupal 4.7 or later, you already have the phpTemplate Engine installed by default, so no worries. If you have problems with implementing and changing with specific themes, check out the Theme downloads page. Click on "Find Out More" under your specific module, and then click on "Bugs and feature requests" to see if someone has already addressed the issue. Again, the next step would be to go to the forums. The Forums Another great resource is the forums where you can ask your question to anyone, typically in the "How do I..." section. Be courteous, and please search for your answers first. Don’t be dismayed if you can’t find it right away. Chances are, someone else has already asked and answered your question, but that doesn’t mean the search will find it right away. Some people use Google to do a website search by typing in "site:www.drupal.org" in the search box. Advanced customization If your answer was not anywhere listed above, the next step may be to customize your install of Drupal by changing the code. Now, you’ve entered the realm of developing Drupal, or customizing the code to suit your needs. Look at the Contributer’s Guide to start, and you may end up with something we all can benefit from. There is a Module developer’s guide and a Theme developer’s guide. Also very helpful is the: API, or application program interface. The API is an interactive repository of information on all the functions, modules, constants, variables, etc that are used in the core Drupal code, and it’s very useful if you want to understand the relationships and purpose of different parts of Drupal. You may eventual find that your new function, module, phpcode snippet, etc. can benefit the Drupal community at large. There are several ways to do that - post it in the forums, add it to PHP page snippets, or apply for CVS (concurrent version system) access and add it there.

356

3 Aug 2007

Drupal Handbook

HowTo: enable Imagemagick for the Image module
Imagemagick is a powerful image manipulation toolkit that, unlike PHP’s default GD library, supports gif, png, and other raw file formats too. A lot of users have Imagemagick installed on their server already, and don’t even know it. If you’re using the contributed image.module in your Drupal site, and you want to access the Imagemagick already installed on your server, here’s how to do it: 1. Locate the directory where you installed the Image module. It’s most likely in /sites/default/modules/image or /sites/all/modules/image. Open the image folder and look for a file called ’image.imagemagick.inc’. Copy (don’t move) that file to /includes/. That’s a Drupal core directory, BTW. 2. After the file has been copied to your /includes/ folder on the server, surf your way to Administer > Site Configuration > Image Toolkit. There, you will find a second entry under "Select an image processing toolkit". Enable the Imagemagick library there, and click ’Save Configuration’. 3. Set the proper path to Imagemagick’s Convert binary. This is usually /usr/bin/convert, but it can be in other places too. If you installed Imagemagick on your own server, you’ll know where to look. If you’re using a hosting company who provides it as a package, ask them *after* you try and see if the default /usr/bin/convert works or not. You’re done! If there are any questions or problems relating to this HowTo, post a comment here. If you found a bug, or something doesn’t work right and you know it should, file a bug report for image.module. Full documentation on the Image module can be found in Contributed Modules > Image handbook.

Tips and Tricks
A collection of tips and tricks from the Drupal Newsletters, "How to make Drupal do things you didn’t think it could."

August 2005: Upgrade, Play B-I-N-G-O!, & E-commerce
UPGRADE
Upgrading is especially important this time because of the major security fix. Failing to upgrade can result in someone cracking into your website and abusing it. Even if it is not a security issue, it is a good idea to upgrade every time a stable version of Drupal is released. This way, you have the latest bug fixes and new features. However, before you upgrade, be sure to backup your database and files so that you can roll back in case of any unforeseen issues.

357

Drupal Handbook

3 Aug 2007

PLAY B-I-N-G-O!
Want to help Drupal? Like random games of chance? Why not combine both of these interests in one fell swoop and participate in: Patch Bingo: http://drupal.org/patch-bingo and Bug Bingo: http://drupal.org/bug-bingo. These links will take you to a random issue in the Drupal queue. Test out bugs to see if they’re still an issue, try out patches to see if they work and comment on whether or not they’d be useful. You’ll both add some wacky adventures to your life, and help Drupal at the same time!

E-COMMERCE
Check out this nice ecommerce module for Drupal: http://drupal.org/project/ecommerce. While I wouldn’t recommend it to start an entire store, it has everything you need to make your own little gift shop and sell t-shirts, coffee mugs and more. Plus, it integrates nicely, so your store looks just like the rest of your website. You can get more tips from Bryght’s "Best Practices" section at http://support.bryght.com/taxonomy/term/8.

Commentator array
Lately on my website, which runs Drupal 4.7.4, I have been getting serious performance problems. In one hand I have a lot of modules installed. In the other hand I have a lot of personal code I have wrote to make my site more attractive. One of these things was to show user’s profile data on every comment, just below user’s image. Data like location, country and a nice country flag. Well, the only way I could imagine to do this was either loading user’s profile or querying DB on comment.tpl.php. That means I had to repeat this operations on every comment. Of course this was totally redundant if the same user was commenting more than once in the same thread, having nodes were I was loading some user’s profiles even more than 20 times. This of course is a bad practice and makes your site pretty slow. So today I was thinking it would be cool to load all commentators information before displaying the comments. And here is how I made it. 1. On node.tpl.php file, after node has been closed, add this php code: if ($node->comment) { global $commentators; $commentators = mystuff_getcommentators($node->nid); } 2. On template.php file, create this function:

358

3 Aug 2007

Drupal Handbook

function mystuff_getcommentators($nid) { $result = db_query("select distinct uid from {comments} where uid > 0 and nid = $nid"); while ($u = db_fetch_object($result)) { profile_load_profile($u); $commentators[$u->uid] = $u; } return $commentators; } Of course, on this function you can add other stuff to the user object besides user’s profile. 3. On comment.tpl.php file, display user’s info whenever you want it: global $commentators; if ($picture) { print theme(’user_picture’, $comment, ’comment’); } if ($comment->uid) { print $commentators[$comment->uid]->profile_location_city . "<br/>"; print $commentators[$comment->uid]->profile_location_state . "<br/>"; print $commentators[$comment->uid]->profile_location_country . "<br/>"; } (Profile fields must be set on profile settings page) And that’s it! I love to do stuff without touching a line of Drupal’s or modules code. PS: I have been looking for some kind of solution for this on the forum, but haven’t found anything so I did it myself. PS2: Should this be on PHP snippets section?

June 2005: Custom Content Types, WYSIWIG Editors, Organize Your Content & Quick Support
CUSTOM CONTENT TYPES Need more flexibility in creating content? Are the simple page and story content types not enough for your site’s needs? Do you wish you could create content types on the fly by just filling in a few fields? Try the Flexinode http://drupal.org/project/flexinode module. Once installed, you can go to administer->content->content types and create custom content types. For each content type, you can specify a set of fields that can be filled out by the content contributors. Once you set up all the fields, you can easily add content by selecting the new content type from the create content menu.

359

Drupal Handbook

3 Aug 2007

WYSIWIG EDITORS Writing rich content in Drupal is sometimes a hassle. You either write the page in a separate WYSIWIG editor and copy it into Drupal or code HTML in the tiny textarea. However, it is possible to easily integrate one of the many inline WYSIWIG editors into Drupal. You can choose from TinyMCE http://drupal.org/project/tinymce, FCKEditor http://drupal.org/node/16118 and HTMLArea http://drupal.org/project/htmlarea. Install one of these modules and within minutes, you can create diverse content right from your browser. ORGANIZE YOUR CONTENT Is your content rampaging all over the place? Organize it and make it easy to locate. Drupal ships with a power organization module called Taxonomy http://drupal.org/handbook/modules/taxonomy. Taxonomy allows you to define sets of categories called "vocabularies". This makes it extremely easy to organize and group content and make your website more navigable. QUICK SUPPORT Feeling a little lost? Need some quick support with Drupal? Get an IRC client and pop into #drupal-support on irc.freenode.net. Someone could be there to help you out.

September 2005: Newest modules, Change any string, Remote authentication, and tracking project issues
Get the newest modules -- fast!
This tip comes from kbahey: To view a list of newly released modules, use the URL: http://drupal.org/taxonomy/term/14. This will show you the newest modules at the top of the list!

Change any string
All strings in Drupal can be changed. Just switch on locale module, then under admin/locale/language/add create a language, with a custom code and name. Now you can manage strings under locale/string/search. "Untranslated" (in this case: unchanged) strings fall back to English. Read the handbook page at http://drupal.org/node/24593 for more information.

Remote authentication
If you want to use remote authentication against your site, then create a role with no permissions and put a user under this role. So it’s nopermissionuser@my.drupal.site.

360

3 Aug 2007

Drupal Handbook

Keep tabs on project issues
This tip comes courtesy of sepeck: Want to keep up with changes to your favorite module? Interested in chipping in your two cents about Drupal core development? Want to be pinged back when someone responds to your specific issue? Check out the project subscribe options at: http://drupal.org/project/issues/subscribe . Here you can choose selected projects (or all of them, if you have lots of hard disk space to burn!) and receive e-mail about all issues, or only your own issues.

Winter 2005/2006: Tracking projects with RSS and Module Linking
Track activity and changes on your favorite projects with RSS Contributed by Bèr Kessels The CVS log is often underrated as a means of tracking what happens to your favorite project. Let us take as an example the project named "shazamgallery": Visit the link http://drupal.org/cvs?file=/modules/shazamgallery/ to see the latest commits to that project. The /modules/shazamgallery/ in the url can be replaced by anything of your interest. You can even track changes to one file. For example, http://drupal.org/cvs?file=/modules/shazamgallery/shazamgallery.mysql lets you track changes to the database file only. The most interesting part, however, is the RSS feed that comes with that at http://drupal.org/cvs?rss=true&file=/modules/shazamgallery/ Use this to track your own contribs (to see if some other contributor slips in features, or bugs, by accident). Or to track changes of the projects you use on your drupal site. Module Linking Contributed by Heine Deelstra When linking to a module-specific image or CSS file, do not use a hardcoded modules/name.module/ path, because this will break in multisite installations, where modules can be at site/sitename/modules/. Use drupal_get_path(’module’, ’name’) instead.

Planning a web site
http://drupal.org/node/88594/

361

Drupal Handbook

3 Aug 2007

--> Overview While implementing a website planning is very important. I have learned this the hard way. I wrote this document while planning my family website. This will be my second complete site redesign for this site that has been up for about five years. Although this is a fairly simple site the same planning process would apply to any site. The most important thing I have learned was that the lack of planning in the first two attempts significantly limited the end site. Many of the limitations, or headaches, could have easily been solved during the planning phase. I am not a programmer although I manage eight production web sites from e-commerce to purely informational to just for fun. Some of this may seem obvious to those with programming experience but for the do it yourselfers I hope this will help get you started. Requirements Gathering requirements is key and really needs to be the first step in the Website implementation process. If you are like me it is also the hardest to force myself to do. On my last attempts once I had some idea about what I wanted I tried out a couple of CMSes and then loaded one and started adding content. This time is different. One thing about the requirements below to keep in mind is this is not a totally serial process. During each step I am continually adding to each proceeding step. As I go through the process more and more things come to mind. The first thing I considered is: What will the website publish or do? For a store this might be selling products, handling RMAs, selling advertising space, or hosting forums about your products. You also need to think about things like: What languages will you site need to support? Will it need to be able to handle transaction processing? Will it need to talk to other sites? If it talks to other sites, what standards are out there that you will need to comply with? Do you need to secure access? Basically anything else you can think of that is important to how you want your site to function. For my family site I came up with the following requirements: I need various people to be able to publish content. We need to be able to publish pictures, videos, audio clips, wish lists, blogs, and stories. We need a way to secure some of our content yet other content will be open to the Internet. We need a shared calendar that allows for event scheduling. We would like a place to document our genealogy. The site needs to be easy enough for my grandmother to use. None of the users are programmers so it needs to be easily deployed with a minimum of coding. We would like to easily change the look and the feel of the site during different seasons or whenever we feel like it. There is no income so I need to keep the costs down. The content needs to be easy to search. I need to be able to get the majority of the content out if I decide to restart again some day. We would like the ability to be able to comment on content. We would like the ability to have polls. We publish a bunch of pictures to it should be easy to publish pictures especially and keep them very organized.

362

3 Aug 2007

Drupal Handbook

The second thing I consider is: Who will be using the website? It is best to break your users into groups, even if a group will only have one person in it for now. This is especially important if there is any possibility for growth. The user groupings should be broken into functional groups that will change based on the site. For a store site you might have customers, site administrators, vendors, and your accountant. For my family site I am able to break the users into the following groups: Administrators â This group will have full control over the site. They will be able to change site layout. They will have control over user access controls. Family members â This group will contribute content. They will need to be able to update and upload content. Many of the users are not technical. Friends â This group will view all of the content but will not contribute content. Anonymous users â This group will be able to view some of the content but not all. They will not need to be able to update the content or provide comments. The next thing I consider is: How will the content be accessed? What are some possible work flows? For a store I might want to make sure that I can link to vendors. I would want to make sure that vendors could update content but that I would have approval of any changes. I would want to make sure that putting an item on sale is access controlled. I would want my highest profit, best selling items right up front. I want to make sure a search works well enough to return just a handful of items. For my family site I want easy and simple entry of content and simple viewing of content. The users inserting content are trusted so I would like for them to have options about where their content is published. I would like the users to handle the content so that I don’t have to get involved every time someone adds or changes something. Users should have a way to pull up specific content easily. They should be able to sort by date, subject, category, and content type. Our current site ended up with a huge amount of unorganized content. It was a great site for current news or pictures but finding an old audio clip was next to impossible. It would be best if all the content could be organized using the same organizational structure. Our current site we ended up with a totally different sorting system and access method for each type of content since we used somewhat unrelated modules. The new one I want people to be able to pull all content types of a certain subject when they want to. Based on what you are trying to do you could take this further but this was enough for me to use as a base set of requirements. Evaluating CMSes and Modules

363

Drupal Handbook

3 Aug 2007

Now that I have an idea of what I want the system to do it was time to start looking at the options. Based on my budget and eagerness for a system that could be tailored to my needs GPL was obvious. I looked into all the popular CMSes and some not so popular ones. When it came down to it, for what I wanted Drupal was hands down the best choice. I could go through the others ones but I will skip to what I liked about Drupal. I really like the everything is a node idea. I also like the way taxonomy was implemented. From a work flow stand point those two parts made Drupal stand out above the rest. Not knowing the system I assumed it might take me a little more work to get it setup but in the end it would be a seamless website with the ability to eventually, if not immediately, meet all of my requirements. Once I picked Drupal I spent a bunch of time looking at modules. There seems to be at least one module for everything I wanted that was not included in the base. I wrote down all of the possibilities and worked out in my head how it would all come together. I won’t go through all of the modules here but basically this step was just a bunch of reading. Testing Drupal and modules Next I went right to setting up the site. I installed the Drupal base and just started playing. While I really like Drupal on virtual paper for me it was not final until I saw how it worked. I was pleasantly surprised. It took me a little while to really get the whole picture but once I did it all clicked. It was very slick and really was the seamless base I wanted. I tried a ton of modules. Based on my requirements it was very important to me that everything worked with the base in a productive way. I did not want to end up having to pull up a picture in a different way than I had to pull up a video. I can’t say I have everything i want but you can’t always get everything you want and I did get much closer than expected. I ended up with image, image_pub, quotes, wishlist, video, and audio. I am still looking for a few odds and ends but for the most part I was able to get all of these installed and working. Once I had this worked out I started working on taxonomy. For me this was the most difficult to decide and also the most important. Producing a ton of unusable content would have made the rest of this useless. Drupal has a bunch of articles on taxonomy which helped a bunch. I tried on paper a whole bunch of things and then would talk to he users. They would provide feedback and I would take another stab. Some of the items listed below may not be considered taxonomy because it is not set up as a category in Drupal but is already part of the system. Although this might still change some currently we have the following vocabulary: Subject â This would be the subject of the content. It could be one of the children, a house, my truck, or a project. Every node should have at least one subject and the ability to have multiple subjects. Subject Date â This will default to the submit date but it can be changed since many times content is added that is older media. Type â This is the node type (image, video, story, blog, ....

364

3 Aug 2007

Drupal Handbook

Submitter â This is who submitted the content. Category â This is some more descriptive category (funny, news, woodworking, taekwondo, ...). Basically I expect this to grow as our hobbies change and develop but every node should have at least one category and the ability to have multiples. Submit Date â When the content was submitted. After this, I put up a test site, got everything working, and had the real users have a go at it. Although I knew a little they are really the only ones that can make it break and have to use it. I administer the family site I rarely add any content. I will tell you that on first pass the site is much better than I expected. We have along way to go for the perfect site but the combination of Drupal and a good plan is a fantastic starting point.

Server tuning considerations
The performance of your Drupal site is dependent on three main factors: the goals of your site, the resource demands of your site traffic, and the system performance and configuration of underlying technologies.

Identifying Drupal performance goals
If the goals of your site are to have a speedy user experience, such as Google, then you should focus on simplicity and ensure you have the resources to deliver pages in 1.5 seconds. If you goal is to have an aesthesticly pleasing site then a rich theme with lots of interactive javascript and longer load times might be acceptable. Either way you should begin with clear goals in mind before tuning your site for performance because there are many permutations of performance.

Analysing your site’s traffic and resource consumption
You wouldn’t use another system administrators underwear. Neither should you use their performance configuration. Each site is unique and must be tailored to address your sites traffic impact on four resources: bandwidth, CPU, memory, and disk input/output. Profile your site’s performance loading: bandwidth, anonymous page views (general reads), concurrent number of users (unique reads), concurrent number of user posts (writes) are all important in building your sites profile.

Understanding and configuring your stack for performance
Configuring your server for performance falls outside the scope of the Drupal handbook and you should reference authoritative sources for each component of your server hardware and software stack. In many cases you will not have control of your hardware or the software components you rely on. We provide a list of configurable options that other Drupal administrators have found useful in tuning their sites for performance. It is possible to destroy

365

Drupal Handbook

3 Aug 2007

your site by configuring incorrectly. Be careful and back up configurations before making changes. 1. Understanding LAMP performance. This LAMP performance study revealed that Apache is bandwidth limited, PHP is CPU limited, and MySQL is memory limited and disk I/O bound. Be sure to compile your stack natively for maximum performance. You can also read Optimize high traffic servers. 2. Analyze your site’s performance bottlenecks: CPU, memory, bandwidth, input/output. Once you have identified what is causing your system performance problems you can make configuration changes or resource upgrades. Use top and ps for analysing processes that are using up too much RAM or CPU. Netstat, mrtg/awstats, who’s online block will help for identifying network problems. top ps -aux netstat -anp | sort -u If there are other applications running on your server such as (mail, ssh, anti-virus, spam checking, web services, custom applications, etc) that are consuming contrained resources you might need to move them to a new server. 3. Bad guests consuming too many resources: Crawlers, Aggregators, Spammers. Search engines may crawl your site and cause a performance degradation, although if they crawl as an anonymous user then they should recieved cached pages which consume less resources. Slow down the robots crawling your site by adding a robots.txt line like this: User-Agent: * Crawl-Delay: 10 Disallow: /archive Here 10 is the delay in seconds between page requests. Disallow robots from sections of your site that do not need indexing. See Controlling what gets indexed -- the robots.txt file. Some RSS clients are set to check for aggregator feed updates too frequently. Check your logs for aggressive reads of feeds from a specific IP address. Spammers have many ways of consuming your sites resources, be sure your site has a spam blocking strategy. Drupal 4.7 includes a check to ensure that that forms originated on the site. This is to prevent spammers from creating large amounts of comment and trackback spam remotely. Apache performance Apache is usually bandwidth limited so you should be aware how much bandwidth your server has access to. You can ask your hosting provider how much bandwidth you have or you can use a tool like lperf. The mod_rewrite module for Apache can consume resources if the directives are included in local directories through .htaccess files. If you have control of the Apache configuration then these directives should be moved to httpd.conf. You can also configure Apache to handle more connections with MaxSpareServers, ServerLimit, MaxClients. CGI is slow. mod_php is popular and fast, FastCGI is fast and secure. Read this tutorial on configuring Apache for Configuring Apache for maximum performance.

366

3 Aug 2007

Drupal Handbook

PHP tuning: CPU consumption and optimizers:Use a PHP optimizer such the upcoming Alternate PHP Cache, Zend Optimizer, eAccelarator a development of mmcache PHP. You can also read Optimizing PHP. MySQL performance tuning Bandwidth: Images or media are likely to be the greatest source of bandwidth consumption which with limit Apache’s performance. In order to ensure images are delivered quickly the theme should explictly call the images directly to reduce the PHP overhead of looking for image files. Details will be provided in the future. Drupal resource consumption: Measuring modules memory usage, measure DB query times, and duplicate queries for modules or pages with devel.module. The number of modules enabled on your site may effect performance but should be measured using the techniques outlined above. If the module has slow query times look at tuning the tables with schema changes and using the the MySQL optimization tools, such as ANALYSE and EXPLAIN. Other areas for analysis are theme resource consumption if you theme has a lot of PHP calls. There are several known performance issues in Drupal 4.6.5 including the URL alias table is loaded into memory frequently and the use of Path and PathAuto modules will lead to an increase in the number of aliases in the table (fixed in 4.7 and higher). Recent improvements to session handling for anonymous users and a proposed file cache that bypasses Drupal’s page loading mechansims offer significant performance improvements for anonymous users. Configuring Drupal for performance: Cron jobs such as aggregating lots of feeds can be resource intensive. If the cron jobs are set too frequently there can be a consistent drain on server performance. Drupal has a cache that is very effective for pages served to anonymous users. It can be found at administer >> settings Server architectures for scalability and performance: separate web server and database server, MySQL replication topologies, clustering servers. This page was authored by Kieran Lal, from CivicSpace Labs. If you would like to contribute or edit this page please contact me. If you would like to fund performance improvements for Drupal please contact Kieran as well.

Enable default 404 handling for some file types
On high-traffic, multi-editor Drupal sites, there can be missing files related to page design. An image gets renamed. A bot spams the site looking for a specific .cgi exploit. And so on. By design, Drupal is defined as the 404 handler for all instances in the .htaccess file. That code is: # Customized error messages. ErrorDocument 404 /index.php

367

Drupal Handbook

3 Aug 2007

Drupal (and other php-based CMS systems) do this so that index.php handles all URI requests and can generate the right page. The problem is that using Drupal as the 404 handler invokes a full bootstrap load for any missing file. Adding the following code to .htaccess eliminates some of this, by telling Apache to handle certain types of 404 errors: # This overrides the Drupal 404 handler for files that should never be handled by Drupal <FilesMatch "\.(gif|jpe?g|png|s?html|css|js|cgi)$"> ErrorDocument 404 default </FilesMatch> We also need to put a new line: RewriteCond %{REQUEST_FILENAME} !\.(gif|jpe?g|s?html|css|js|cgi)$ Just before the line: RewriteRule ^(.*)$ index.php?q=$1 [L,QSA] This elminates the following file types from invoking Drupal if a 404 is encountered: - gif - jpeg - shtml and html - css - js - cgi Doing so avoiding invoking Drupal’s bootstrap in order to look for missing files. This procedure minimizes database load and helps boost site performance. -- WARNING -There is a known issue that occurs if you block .png files with this method. It affects the system_test() function in system.module, which relies on a phantom .png call to the directory ’/system/test/’. If you block Drupal’s 404 handling for .png files and do not allow this exception, you lose the ability to configure the site for clean_urls.

Simple Decision Tree for Drupal Enterprise Scalability
Contributed by Benson Wong on the developer’s email list. February 2006

368

3 Aug 2007

Drupal Handbook

Here’s my scaling tree. As you progress up the tree, you will find that time, money, maintenance, headaches will all increase. 1. Use a PHP cache: I found that using APC speeds up Drupal by a lot, 3 to 5 times the pages view per second. This was _literally_ a 5 minute install (on FreeBSD) for a 300% to 500% performance improvement. I think at that point it was my dev servers SATA HDDs were the bottle neck. It sits beside me and when I hit it with ab, I can hear the HDDs wrrrrr like crazy. 2. Use mod_gzip (or ob_compress or whatever it is in php, I prefer mod_gzip, or mod_deflate in Apache2) The benefits of this are amazing, considering the minimal effort it takes to implement. If doesn’t matter if it takes Drupal 0.002 seconds to generate a 40K of html, if it takes like 1 to 2 seconds for a client to download it (more if using a modem). mod_gzip usually gives a 10% to 80% compression depending on the size of pages. Amazing results for 10 minutes of work. 3. Get a faster DB server. I’m thinking of 3x15K SCSI (raid 5), dual way xeon mysql server from freebsdsystems.com for my next installation. These things rip . Expensive (~$5K to $7K) but fast. An average Drupal dev charges like $100USD these days right? A super fast db server is still more bang for your buck than 50 to 70hrs of code performance tuning. 4. Get faster (or more) Web Servers. Maybe not the same specs as above, but fast anyways. 5. Get a load balancer, or a reverse HTTP proxy (squid) to distribute the load 6. Do MySQL replication 7. Profile / tune Drupal’s code (shudder).

Slow contributed modules determined using the developer module
If you have tested a module with the devel.module and run the memory tests highlight above then please post the results. If you add performance results in the comments they will grow.

Squid Caching
Squid is a fully-featured, open-source web-content caching system. In accelerator mode, squid can be used in between your users and your web-server to cache objects and reduce requests against your web server(s) and database server(s). Usually, Drupal has very dynamic content (nodes gets comments and so on, the pages look different from one user to the other) and it has its own cache so Squid caching Drupal content is neither really desired nor really feasible. Drupal does supply the necessary headers which tells

369

Drupal Handbook

3 Aug 2007

Squid not to cache its pages. However, images and other static content can be cached by Squid and usually it really helps.

For more information on setting up squid, please see http://www.squid-cache.org/.

Tools, tips, and links on optimizing mysql
Here are some basic, but high impact ways to optimize MySQL for Drupal (there are much more sophisticated and expensive ways to speed up your database of course): Am not sure if these tips do any good for someone on a shared hosting plan or not (do shared plans have access to a my.cnf file?). Also, I can only confirm these setting for MySQL 4.0.2 thru the latest 4.0.x version, but I think it would work for 5.x (maybe someone can confirm this and leave a comment...). Actually, it will work for below 4.0.2 I think as long as you add set-variable = before each line (see this page for more on set-variable) 1. Get this script, upload it, unzip it, and install it in your /etc folder (at the root of your server, not your Drupal install, right). Then run it from the command line by entering sh /path-to-file/tuning-primer.sh The script will run and what you’ll be left with is an output with some info and suggestions about your MySQL settings. Was shocked to learned that on my VPS the cache was not even enabled - very helpful to know! 2. Next open your my.conf file in pico or some kind of proper code/text editor: Depending on the memory resources you have available you’ll want to paste in something like these examples (adjust up or down depending on how your system differs, of course): For a setup with 500mb or ram paste this in your my.cnf file: [mysqld] max_connections = 800 max_user_connections = 800 key_buffer = 36M myisam_sort_buffer_size = 64M join_buffer_size = 2M read_buffer_size = 2M sort_buffer_size = 3M table_cache = 1024 thread_cache_size = 286 interactive_timeout = 25 wait_timeout = 1800 connect_timeout = 10 max_allowed_packet = 1M max_connect_errors = 999999 query_cache_limit = 1M query_cache_size = 16M

370

3 Aug 2007

Drupal Handbook

query_cache_type = 1 tmp_table_size = 16M For a system with 256mb of ram: [mysqld] max_connections=500 max_user_connections = 500 key_buffer = 16M myisam_sort_buffer_size = 32M join_buffer_size = 1M read_buffer_size = 1M sort_buffer_size = 2M table_cache = 1024 thread_cache_size = 286 interactive_timeout = 25 wait_timeout = 1000 connect_timeout = 10 max_allowed_packet = 1M max_connect_errors = 999999 query_cache_limit = 1M query_cache_size = 16M query_cache_type = 1 tmp_table_size = 16M 3. Save your my.cnf file and restart mysql. This can be done via WHM or the command line (not sure what that command is - sorry) Your new settings are now active and you can see run the script from above again and see the difference in your results. After some experiementing I’ve found that it is useful to look at the script results right after making a change just to see if your modifications were recognized by the system and get the early returns from whether things were improved or not - but - to get a truly accurate reading from the script you should check back in 24-48 hours after rebooting mysql (this is actually noted at the top of the script itself, but it doesn’t really explain why). Also, I’ve found that the way I’ve got Drupal set up it is particularly demanding in the tmp_table_size and table_cache areas (e.g., you may want to bump up the number for both of these areas in the settings above) If you’d like to read up on more about mysql tuning I suggest taking a look at these resources: Tuning MySQL for Drupal Tuning a MySQL server in 5 minutes MySQL variables

371

Drupal Handbook

3 Aug 2007

Tuning MySQL for Drupal
For a general overview read MySQL performance tuning. Start with an appropriate MySQL option file. For servers with at least 2GB RAM dedicated to MySQL we recommend my-huge.cnf. For servers, with a lot of writes we recommend my-innodb.cnf instead of the default MyISAM engine type. To reduce the overhead of creating connnections we recommend using persistent DB connections. If a query is called at least twice with no modifications to the queried tables a significant performance improvement can be gained by avoiding the processing of the query and the execution of the query by reading the query from the MySQL query cache. To learn how to set up the query cache read a practical set-up. Be sure to have enough cached threads or you will launch too many new threads as described in this story about a Yahoo site. The biggest performance boosts can come from identifying and tuning the slowest queries using the MySQL slow query logs. You can use the DB Maintenance module or use the mysqlcheck commands below in a cronjob. echo "OPTIMIZE TABLE accesslog,cache,comments,node,users,watchdog;FLUSH TABLES;" |mysql -u user -ppasswd If you have complete control of the datbase server you can use: mysqlcheck -o -A -p MySQL supports many different engine types including MyISAM, InnoDB, and Archive(MySQL 5). Performance sites should use InnoDB for most tables particularly tables such as node that get a lot of writes and reads. MyISAM exclusive table locks for updates before selects versus InnoDB’s row level locking can mean MyISAM blocks reads if there are many writes. Convert from MyISAM to InnoDB. In MySQL 5 a new table type called the archive table type was introduced to deal with common requirements for web applications like access logs where only INSERTS and SELECTS were done. If tables such as the Access Log table are determined to not have DELETE, UPDATE, and REPLACE then this MySQL engine type can often offer significant performance improvements as they have done for sites like Slashdot, Yahoo, and Live Journal. Read and use the PHP Page Snippet for MySQL Tuning

Tuning PHP
1. If you have CPU cycles to spare, or if bandwidth is a more constrained resource than CPU cycles, you can add the following to php.ini: output_handler = ob_gzhandler A comment in php.ini explains:

372

3 Aug 2007

Drupal Handbook

"You can redirect all of the output of your scripts to a function. For example, if you set output_handler to ’ob_gzhandler’, output will be transparently compressed for browsers that support gzip or deflate encoding. Setting an output handler automatically turns on output buffering." This functionality is further described here. very interesting presentation from a PHP developer Additional resources: PHP Project Page

Persistent database connections
Drupal uses pconnect() when connecting to the database for a slight performance improvement if PHP is configured to allow pconnect. But there are times when PHP should be configured to disallow persistent connections to the database. Each apache process can potentially obtain a persistent connection to each database the server is hosting. If there are lots of apache processes and lots of databases it is common to see the database throwing "too many connections" errors. If this occurs there are a couple of options: Increase the number of available connections the database will allow. If most connections are idle most of the time, this is a viable solution. Disable pconnect via the XXsql.allow_persistent = Off attribute in your php.ini. The performance hit from this setting is very slight.

PHP caches
PHP is a scripting language. Each time a PHP script is run to generate a webpage with Drupal, your web server must compile the PHP script into an executable format. This results in an obvious amount of overhead each time a page is generated. A PHP cache can be installed to save and re-use compiled PHP scripts, thus greatly reducing the amount of overhead required for Drupal to display a web page. There are a number of PHP caches (aka accelerators) available, including: PHP Accelerator After Burner Zend Accelerator

373

Drupal Handbook

3 Aug 2007

APC : Alternative PHP Cache
APC is a free and open PHP op-code cache that can significantly speed up PHP applications in certain cases. Here are instructions on how to install PHP APC on Ubuntu Dapper (and Debian?)

eAccelerator
From what I can tell eAccelerator is the best free php accelerator. Here are my notes on how to set the control variables (in php.ini): ;linux 2.6 has 32meg limit. If you have the memory and lots of modules try to set even higher e.g to 64 eaccelerator.shm_size="32" ; people have suggested that putting this directory on a fast separate disk will help ; you shouldn’t be generating that much activity on this disk anyway because of the shared memory configured above eaccelerator.cache_dir="/Applications/MAMP/tmp/eaccelerator" eaccelerator.enable="1" eaccelerator.optimizer="1" ; You can set this to 0 for production sites. 1 means checks modification times so you don’t need to restart web server ; if you are editing your php. You aren’t editing php scripts on live sites are you? eaccelerator.check_mtime="1" eaccelerator.debug="0" eaccelerator.filter="" eaccelerator.shm_max="0" eaccelerator.shm_ttl="3600" eaccelerator.shm_prune_period="0" ; set this to 1 if you want to just use the memory cache: good if you have configured a large one eaccelerator.shm_only="0" eaccelerator.compress="1" eaccelerator.compress_level="9"

Turck MMCache
The Turck MMCache has been confirmed to work well with Drupal. Installation is quite simple, resulting in a quick and noticeable performance increase.

374

3 Aug 2007

Drupal Handbook

Overview: According to the project’s home page: "Turck MMCache is a free open source PHP accelerator, optimizer, encoder and dynamic content cache for PHP. It increases performance of PHP scripts by caching them in compiled state, so that the overhead of compiling is almost completely eliminated. Also it uses some optimizations to speed up execution of PHP scripts. Turck MMCache typically reduces server load and increases the speed of your PHP code by 1-10 times." Compatibility: The Turck MMCache runs on Linux and Windows, working with Apache 1.3 and Apache 2.0, compatible with PHP 4.1 and later. The following versions of MMCache have been tested successfully with Drupal 4.1+: 2.3.15, 2.3.23, 2.4.6. Installation: Step-by-step installation instructions can be found here. Once properly installed, you should immediately notice an improvement. CPU Utilization: The sar utility from the sysstat collection gathers system activity numbers over time. The following sar snapshot taken from a dedicated Drupal server shows how the installation of MMCache can help reduce system load on even a heavily-optimized web server (MMCache was installed around 12:00PM): 11:00:00 %idle 11:10:00 94.44 11:20:00 95.64 11:30:00 95.18 11:40:00 95.58 11:50:00 95.88 12:00:00 96.11 12:10:00 99.38 12:20:00 99.01 12:30:00 99.31 12:40:00 AM AM AM AM AM AM PM PM PM PM PM CPU all all all all all all all all all all %user 3.71 3.86 4.49 4.05 3.76 3.38 0.52 0.79 0.57 0.59 %nice 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 %system 1.85 0.50 0.33 0.36 0.36 0.52 0.10 0.20 0.12 0.12

375

Drupal Handbook

3 Aug 2007

99.29 12:50:00 99.45

PM

all

0.44

0.00

0.11

Troubleshooting: An easy way to tell if MMCache is working properly after following the installation
told them to be written with the ’mmcache.cache_dir’ directive. If no files are appearing, something is wrong.

instructions is to see if temporary files are being created in ’/tmp/mmcache’, or wherever you

First, be sure that PHP has properly loaded mmcache. Create a short script on your web browser called ’phpinfo.php’ as follows: <?php phpinfo(); ?> Load that file in your browser to find a wealth of useful information. Search for any

occurances of the word ’MMCache’. If it’s not there, then MMCache is not loaded. Double check your ’Configuration File (php.ini) Path’ on that same page, and be sure that you modified the correct ’php.ini’ file. Verify that you installed ’mmcache.so’ into the directory specified by the

’extension_dir’ directive. Also, try restarting your web browser to be sure the latest

configuration changes have been made. Finally, be sure to look in your web server’s error log to

see if there are any hints there. (Note that the phpinfo() function call reveals a _lot_ of
information about your system. For security reasons it is very unwise to make this information available to the general public. If you created ’phpinfo.php’ in a public place, be sure to remove

it when you’re finished troubleshooting.) Additional resources: Turck MMCache Home Page

Useful article on optimizing PHP
A HOWTO on Optimizing PHP was initially pointed out in this forum topic. The article describes how to optimize PHP in a variety of settings. It also includes a nice discussion on caching. For people who are setting up servers, or who are interested in learning more about how Drupal can run more efficiently, this article is a good read.

Tuning Drupal on OS X Tiger
Using the devel module (http://drupal.org/node/31553) I discovered that the default mysql configuration parameters were slowing drupal down. To see where your mysql is installed type at the command line: which mysql The selection of configuration files are in share /mysql; or if you followed the above instructions for installing MySQL, it should be in /usr/local/mysql/support-files.

376

3 Aug 2007

Drupal Handbook

The configuration file is in etc/mysql4; or if you followed the above instructions for installing MySQL, it should go in /usr/local/mysql but is not there by default. You can put it there by copying it in: sudo cp /usr/local/mysql/support-files/my.large.cnf /usr/local/mysql/my.cnf. Restart MySQL for the new settings to take effect. To view the current variable settings for MySQL, from the terminal command line client type: mysqladmin -uroot -p variablesI opted for the "my.large.cnf" settings and halved the sql query times. You can monitor MySQL through a pleasant user interface using MySQL Administrator, though it seems to expect my.cnf at /etc/my.cnf (it will still work, you just can’t view the conf file). I also discovered that I could roughly halve page load times by using Apache 2 instead of the stock Apache on Tiger.httpd -v to see what version you are running. I downloaded the php and Apache 2 from ServerLogistics: http://serverlogistics.com/downloads.php. I am not sure I can recommend this for production sites as I do see some error diagnostics I haven’t resolved yet. I didn’t expect such a big difference with Apache2. Measurements with a system call profiler show that it does about half the read(2) system calls as Apache 1.3. The overall impression I have from my benchmarking is that drupal pages require a lot of disk I/O to synthesize. Anything you can do to speed up or miminize (e.g. caching) is going to help. MySQL already has plenty of caching if a my.cnf files is being used. For the Apache/PHP part busy sites will need a php accelerator.

377

Drupal Handbook

3 Aug 2007

Upgrading from previous versions
This chapter contains articles that discuss the upgrading process of your drupal installation. Please note that comments are not meant to address problems you found during installation. For problems with installation, please address your questions at proper places. Note that Drupal versions prior to 4.6.3 are now known to have security vulnerabilities and therefore you should upgrade to the latest version of Drupal. After upgrading Drupal core you might need to convert custom modules and convert custom themes. NOTE: One of the most IMPORTANT things to do BEFORE you upgrade, is to backup your sites files and database. See this node for an example of an automated backup script.

Introduction to upgrading
Every few months, a new version of Drupal is released. In order to fix security issues and take advantage of many new features, upgrading your Drupal site to the latest version is recommended. Upgrading your Drupal site involves three basic steps: 1. Back up your existing site and database. 2. Download and unzip the new Drupal files to your server. 3. Run the update.php script, which will update your database. However, to make your update run as smoothly as possible, there are various preparations that experienced Drupal users do to guarantee the least frustrating upgrade and minimal interruption to their users. These best practices are represented in this full tutorial along with the basic steps. NOTE: You should check to see if the contributed modules you rely on have been upgraded as well. Old versions of modules will not run on an upgraded version of Drupal (e.g 4.7 modules do not work on a Drupal 5.x site).

Getting started: Choosing your method and preparing the site
Before you begin the actual upgrade, determine which interface methods are available for you to use to update your site. The server you use to host your site may limit you to one of the following options: Command line. Via SSH terminal access, you can connect to the server, enter commands directly, and complete all the steps in the upgrade. GUI. You can use phpMyAdmin, a browser-based MySql interface, to do anything you need on your database. And you can use any FTP client, such as SmartFTP, to transfer the files for your Drupal site from your desktop to the server.

378

3 Aug 2007

Drupal Handbook

Once you have determined whether you will use the GUI or command-line version (or a bit of both), you’re ready to prepare to upgrade by following the instructions given in the links below.

Preparing the site
Complete the following steps to prepare your site for upgrading: Login as USER 1, the root user, the very first account created when Drupal was installed. If you cannot login as the root user, you will need to modify the update.php script once you load the new files for your site. Turn off all modules that are not core modules: administer >> modules Also, switch your theme back to the default theme (’BlueMarine’ in 4.7 and lower, ’Garland’ in 5.x): administer >> themes

Do I need to upgrade my database?
After uploading the new files, visit http://example.com/update.php, read and act upon the instructions, then click through to "run the database upgrade script". You may expand the "Select version" fieldset to review the updates Drupal automatically selected or simply click update. Drupal 5 and later will also alert you to run update.php if it is detected that your database is no longer up to date. The alert will appear on the Administration page (admin) and the status report (admin/logs/status).

Important! : Backing up the database and existing files
Please back up the existing files and database for your site before you begin the rest of the upgrade process. Even if you have determined that you may not need to upgrade the database, it doesn’t hurt to make a backup. If the upgrade process fails, you may not be able to resurrect your site without the use of backups. Choose either the GUI or command-line method for backing up your site.

Backing up your site (GUI)
Backup your Drupal files Using your FTP client, download all your existing Drupal files to your hard drive and put the files in a folder called ’backup’. Backup your database with phpMyAdmin Select your database from the dropdown box on the left If you are upgrading a test site, choose your test site database.

379

Drupal Handbook

3 Aug 2007

Click the "Export" tab Click "select all" Make sure to check the "structure" and "data" checkboxes Check "Save as File" desktop Click the "Go" button and save the .sql file to your desktop. Let’s put it in the same ’backup’ folder where you backed up your Drupal files.

Back up your site (command line)
Back up your Drupal files Copy the contents of your Drupal directory to a new directory called "backup" cp -r . backup/. Where the directory ’drupal_site’ is a the path to your live site. If you are upgrading a test site, this would be your test site directory. Go ahead and back up your test site files to a new directory. Make sure the .htaccess file gets copied to the ’backup’ directory as well. Back up your Drupal database with MySQL Before you begin, it’s best to turn off all automated jobs (cron jobs). a) Navigate to your live site directory, and download a special script to your Drupal site folder which will backup your database to a file called ’backup.sql’. Put the backup in your ’backup’ directory. cd drupal_site/ wget
http://cvs.drupal.org/viewcvs/*checkout*/drupal/contributions/sandbox/dr...

chmod +x drupalsqldump.sh If you are upgrading a test site, the path ’drupal_site’ would be the path to your test site. b) The following command will look at your Drupal settings file, automatically connect to the database, and make a backup of it. If you are running a version of Drupal that is 4.6 or newer, then enter the following: ./drupalsqldump.sh sites/default/settings.php > backup/backup.sql If you are running a version of Drupal 4.5 or older, run the following: ./drupalsqldump.sh includes/conf.php > backup/backup.sql

380

3 Aug 2007

Drupal Handbook

If you are upgrading a test site, the path ’drupal_site’ would be the path to your test site. Remember where you saved this backup.sql in case there is an error during the upgrade.

Create a test site first or upgrade your existing site?
It is recommended that you copy your existing site to a test site and upgrade that one first. Even though you have made backups and can restore your site, you don’t want your live site (the one people are actively visiting) to crash and burn if something bad happens during the upgrade. Copying your Drupal installation to a test site takes a few steps: Make a backup of your existing Drupal files and database Copy the files to a test-site subfolder on your server Copy your old database to a test-site database Change some configuration settings If you choose not to create a test site, skip forward to Downloading Drupal and installing the files. Otherwise, choose either the GUI or command line method for Copying your live site to a test site.

Copy your live site to a test site (GUI)
Before you begin, decide where the new installation will be located. Usually you can just install Drupal to a subdirectory: example.com/test_site/. Make sure you have already completed the steps for backing up your site. I. Setup a test-site database with phpMyAdmin Create a new database "test_site_db" Select the database from the dropdown box on the left Click the "SQL" tab Upload the backed-up SQL script file you just saved by clicking the "Browse" button and selecting it. It should have the extension .sql. Hit the "GO" button to upload the .sql script and execute it II. Change settings.php (or includes/conf.php) in your backed-up Drupal files. Open and edit the file located under sites/default/settings.php (or includes/conf.php) with a plain text editor such as jEdit. Follow the directions in the file and modify these three settings: $db_url = mysql://user:pass@localhost/test_site_db’; (test-site database login & password, URL location of the test-site database. "localhost" usually works by default.)

381

Drupal Handbook

3 Aug 2007

$base_url = ’http://www.example.com/test_site’; (This is where you want to move Drupal. You can install Drupal to a subdirectory such as http://www.example.com/test-site. This is what we want.) $db_prefix = ’’; (Sometimes your database tables will have a prefix. Ask your webhosting company for help if you think this is causing a problem. Otherwise leave it blank. II. Upload the backed-up Drupal files to a test-site folder on your server First, create the subfolder "test_site" first. Right-click in SmartFTP and click "New"...."Folder". Other FTP clients may have slightly different methods. Using an FTP client such as SmartFTP, upload all the backed-up Drupal files to the directory: http://www.example.com/test_site In FTP world this is usually seen as public_html/test_site" or "www/test_site". IV. Check if your test site works. Navigate to http://www.example.com/test_site and you should see a working copy of your live site. V. Get ready for the basic steps.The basic steps will repeat some of the work you just did such as backing up your live site and database. You can skip those steps in the basic steps instructions.

Copying your live site to a test site (command line)
Before you begin, decide where the new installation will be located. Usually you can just install Drupal to a subdirectory: http://www.example.com/test_site/. Make sure you have already completed the steps for backing up your database. I. Copy your live site files to a test site directory. Copy the contents of your live site directory to a new directory called "test_site" cp -R /path/to/drupal/path/to/drupal_backup Make sure the .htaccess file gets copied to the test_site directory as well. II. Setup a blank test-site database with MySQL a) Create a new, blank MySQL database (login to MySQL) and give permissions for a user to access it:

382

3 Aug 2007

Drupal Handbook

mysqladmin -u dba_user -p create test_site_database (Where ’dba_user’ is an example MySQL user which has the CREATE and GRANT privileges. Use the appropriate user name for your system.) b) MySQL will prompt for the ’dba_user’ database password and then create a blank test_site database. Next you must login and set the access database permissions: mysql -u dba_user -p c) Again, you will be asked for the ’dba_user’ database password. At the MySQL prompt, enter following command: GRANT ALL PRIVILEGES ON IDENTIFIED BY ’password’; test_site_database.* TO nobody@localhost

where ’test_site_database’ is the name of your database ’nobody@localhost’ is the username of your webserver MySQL account ’password’ is the password required to log in as the MySQL user. d) To activate the new permissions you must enter the command: flush privileges; and then enter ’\q’ to exit MySQL. III. Change settings.php (or includes/conf.php) in your test_site directory a) Open and edit the file located under sites/default/settings.php (or includes/conf.php) with an editor. Follow the directions in the file and modify these three settings: $db_url = ’mysql://user:pass@localhost/testsite_db’; (test-site database login & password, URL location of the test-site database. "localhost" usually works by default.) $db_prefix = ’’; (Sometimes your database tables will have a prefix. Ask your webhosting company for help if you think this is causing a problem. Otherwise leave it blank.) $base_url = ’http://www.example.com/test_site’; (This is where you want to move Drupal. You can install Drupal to a subdirectory such as http://www.example.com/test_site. This is what we want.) IV. Insert the backup.sql file into the test_site database Now that you have a new blank test_site database, you must take the backup.sql file created by the live site database and run it. This will create a copy of the live site database on the new test site database.

383

Drupal Handbook

3 Aug 2007

a) Change to the test_site directory. cd test_site b) Get the database insertion script, and set permissions on the script. You database may a limit on the size of file it can import. Use the --max_allowed_packet option for mysql to increase the size of db import. wget ’http://civicspacelabs.org/home/files/drupalsql’ chmod +x drupalsql.sh -O drupalsql.sh

c) Now execute the script which will create all the Drupal tables needed on the test_site database: If you are running a version of Drupal 4.6 or newer, then enter the following: ./drupalsql.sh test_site/sites/default/settings.php < /path/to/backup.sql If you are running a version of Drupal 4.5 and older, run the following: ./drupalsql.sh test_site/includes/conf.php < /path/to/backup.sql V. Check if your test site works Navigate to http://www.example.com/test_site and you should see a working copy of your live site.

Downloading Drupal and installing the files
Choose either the GUI or command line method for downloading and installing the files. If you setup a test site, you are going to be updating it instead of your existing, live site.

Downloading Drupal and installing the files (GUI)
I. Download and unzip (using unzipping software such as WinZip) the latest Drupal release to your desktop II. Move your old Drupal files You made a backup, right? Using your FTP client, move all your old Drupal files on your server to backup directory. If you are upgrading a test site, move your test site files. It is considered best practice to remove the old files completely rather than overwriting to ensure you have a clean installation of the new files. III. Upload the new version of Drupal Using your FTP client, upload the new version of Drupal to the same place where your old files were located. If you are upgrading a test site, upload the files to your test site directory.

384

3 Aug 2007

Drupal Handbook

Make sure your files directory is writable. IV. Upload contributed modules Again with your FTP client, upload the new version of all your contributed modules. Make sure you have the version of the module which matches your new Drupal version. V. Copy over necessary files from the ’backup’ copy directory Using your FTP client, copy the following files from your ’backup’ directory to the Drupal directory on your server: .htaccess sites/default/settings.php (*** see note below!) the ’files’ directory any other files you need from the ’backup’ directory *** If you are upgrading from a version of Drupal that is older than Drupal 4.5, you will have to look in your ’backup’ directory for a file called: <strong>includes/conf.php</strong> Then using a plain text editor such as jEdit, copy the following three lines as they appear in your conf.php file: <strong>$db_url = mysql://user:pass@localhost/drupal_db’; $base_url = ’http://www.example.com’; $db_prefix = ’’;</strong> And paste them over the appropriate lines in your new Drupal file on your server, located here: <strong>sites/default/settings.php</strong> It’s simply a matter of overwriting the above three lines in settings.php with the lines in conf.php. These settings are responsible for connecting your Drupal to the database and to the files it needs. The file name and location was changed from Drupal 4.5 to 4.6, hence the magical dance involved.

Downloading Drupal and installing the files (command line)
I. Replace your Drupal files 1. Navigate to your Drupal directory and move all the old files using the standard Unix ’mv’ command. If you are upgrading a test site, this means move all the test site files. Move these to a backup directory. 2. Download and untar the new Drupal files to your Drupal directory: cd drupal_site/ wget

385

Drupal Handbook

3 Aug 2007

http://ftp.osuosl.org/pub/drupal/files/projects/drupal-4.7.3.tar.gz tar -xzvpf drupal-4.7.3.tar.gz If you are upgrading a test site, the path ’drupal_site’ would be the path to your test site. II. Copy over necessary files from the ’backup’ directory Copy over the following files from the ’backup’ directory to your Drupal site directory: .htaccess sites/default/settings.php (*** see note below!) the ’files’ directory any other files you need from the ’backup’ directory *** If you are upgrading from a version of Drupal that is older than Drupal 4.5 , then you will have to look in your ’backup’ directory for a file called: includes/conf.php Then using your favorite text editor, copy the following three lines as they appear in your conf.php file: $db_url = mysql://user:pass@localhost/drupal_db’; $base_url = ’http://www.example.com’; $db_prefix = ’’; And paste them over the lines in your new Drupal file located here: sites/default/settings.php It’s simply a matter of overwriting the above three lines in settings.php with the lines in conf.php. These settings are responsible for connecting your Drapal to the database and to the files it needs. The file name and location was changed from Drupal 4.5 to 4.6, hence the need to move these lines to the new file.

Running update.php
If you have previously determined that you do not need to update your database, you may skip the following step. However, it does not hurt to run the update.php script just to verify whether or not a database update is necessary. Just make sure that you have made a backup of your database first. If you setup a test site, you are going to be running update.php on it instead of your existing, live site. I. Did you login as USER 1? Previously, you were asked to login as USER 1, the root user, the first user created on your Drupal site. If you were not able to do so, you will need to edit the update.php script in a text

386

3 Aug 2007

Drupal Handbook

editor. Otherwise, you will not be permitted to update the database. Change TRUE to FALSE for the $access_check statement like so: $access_check = FALSE; After you complete the upgrade, be sure to CHANGE the update.php file BACK TO IT’s ORIGINAL STATE if you have made this change. Otherwise, anyone would be able to run the update.php file on your site. II. Run update.php In your web browser navigate to the directory where Drupal is installed: http://www.example.com/update.php or http://www.example.com/test_site/update.php test site)

(if

you

are

upgrading

a

The update script should only be run once, it will complete all the updates at once. If prompted for which version, choose the closest starting version that makes sense for you. This will update the default Drupal and contributed module database tables automatically (versions prior to 4.7 will require manual upgrade of the contributed modules). Once the script has stopped loading, be sure to scroll to the bottom to look for errors.

Optional configuration steps
I. Review unique steps for your site Your site is unique like you. You might have special files or a special configuration. During your site upgrade it’s important to keep notes about any special changes you made. More often then not when people have problems, it’s because they forgot some special steps that are unique to their site. Keep track of these steps on a change board, which you can use in future upgrades. II. Get additional features(modules) Drupal comes with many features but your site may have special needs. You can get additional modules from the Drupal modules page. You must know which Drupal modules are compatible with your site (e.g. use the 4.7 version of a module with Drupal 4.7.x.) In Drupal 4.7 and greater your contributed modules will upgrade automatically with the core Drupal upgrade as long as you have the new version uploaded to the site before running update.php. III. Convert your custom modules to the new version You may have custom modules on your site. If you need to learn how to upgrade your modules you can learn about in the upgrading section of the Drupal developer’s handbook. IV. Manually configure special steps for your database The update script is designed to automatically upgrade your database. However, from time to time there are steps which could not be automated. These steps appear as commands at the bottom of your update.php report. There may also be special steps which are recommended or where found too late to be fixed by the update script.

387

Drupal Handbook

3 Aug 2007

If you are moving from Drupal 4.4 to Drupal 4.5 then you need to change the path table to replace node/view/number and book/view/number to node/number. Users path changed from /user/view/number to /user/number. You should also enable legacy module to do handle URL requests of the old type. We recommend you upgrade to the latest release which takes care of all known database issues at this time.

Post-upgrade steps
Congratulations! You have completely upgraded your Drupal installation. You should now go to your adminster >> modules page and enable new modules from your upgrade. Be sure to then go to adminster >> access to get enable permissions to use that module for different roles. Make sure anonymous users don’t have too many permissions. The last step in an upgrade is to delete or move the following files from your site: install.php update.php CHANGELOG.txt INSTALL.txt LICENSE.txt MAINTAINERS.txt UPGRADE.txt If you have upgraded a test site and are satisfied with the results, you will now need to copy the test site to a live site. If you have more questions, please consult the Troubleshooting FAQ guide and please don’t hesitate to Ask for Help in the Forums.

Testing Your Newly Upgraded Site
Once your upgrade is complete, it is important to test your site for functionality and for potential problems visitors to your site may see. I. Test your new version of Drupal You should test your site to make sure it works. We recommend that you try the most common tasks your users do on the site. A good way to to see what your users like to do on your site is to review your site administration logs at administer >> logs. For a more thorough review we recommend you review the administration help in your site at administer >> help. Each page of help documentation has links to the most important pages for each module.

388

3 Aug 2007

Drupal Handbook

II. Prevent file not found errors After you upgrade your site you should check your site for bad links, to prevent the file not found errors. The http error number for these pages is 404. You can use a simple tool to check the links on your site. You will see errors in you Drupal Administrator logs as well as your web server error logs. Perform the following commands through the administrator menu on your site: Enable contributed image module administer >> modules Set permissions so images can be written for userid running link check. administer >> access control Enable the menu module administer >> modules Disable the logout menu administer >> menus From a command line on a computer connected to the Internet run wget with the following options: The cookie this command is referring to is the cookie downloaded from your browser when you last logged into your Drupal site as an admin. wget -r --delete-after --cookies=off --header=’Cookie: PHPSESSID=xxx’ http://yoursite.com -r to recursively crawl the site. --delete-after, --cookies=off tells the crawler not to use a cookie. --header=’Cookie: PHPSESSID=XXXX’ tells the Drupal site that session information will be passed in the http header. This should be repeated 2 more times; once for a regular userid, and once for an anonymous userid. After the link check is done check your Drupal admin logs and your webserver error logs. Look in your browser preferences to see what cookies you have for your url. III. Invite users to test Your users are your best source of feedback. They will tell you quickly which parts of your site are not working like they expect them to. Send an email informing users that your test site is available for them and instruct them how to give feedback. You may wish to install the feedback module to assist with user feedback.

Copy your test site to a live site
For those that created a test site, there is one additional step in the process. Now that you have successfully completed upgrading your test site, it is time to copy your test site to your live site. Moving your Drupal Installation takes a few steps:

389

Drupal Handbook

3 Aug 2007

Make a backup of your test site files Copy the test site files to your root directory on your server Change some configuration settings Choose either the GUI or command line method below.

Copying your test site to your live site (command line)
TIP: Make sure your test site is a recent copy of your live site, otherwise you will lose changes. It might be a good idea to create a new test site if it has been a while. I. Backup Your Drupal Files Copy the contents of your live site directory to a ’backup’ directory, in case something goes wrong. cp live_site/.htaccess backup/. Make sure the .htaccess file gets copied to the ’backup’ directory as well. II. Copy your test site files to your live site directory 1. Delete all your live site files with the Unix ’rm’ command. You made a backup, right? 2. Copy the contents of your test site directory to your live site directory cp test_site/.htaccess live_site/. Make sure the .htaccess file gets copied to the test_site directory as well. III. Change settings.php in your live site Drupal files Open and edit the file located under live_site/sites/default/settings.php with a plain text editor such as jEdit. Follow the directions in the file and modify this setting: $base_url = ’http://www.example.com/’; (This is the address of your live site directory. This tells Drupal where to look for the Drupal files to connect with.) There is no need to change the database settings. Just take note that your test site database is now being used as the live site database. IV. Check if your live site works Navigate to http://www.example.com/ and you should see your newly upgraded live site.

Copy your test site to a live site (GUI)
TIP: Make sure your test site is a recent copy of your live site, otherwise you will lose changes. It might be a good idea to create a new test site if it has been a while.

390

3 Aug 2007

Drupal Handbook

I. Backup Your Test Site Files Using an FTP client such as SmartFTP, download all your existing test site files to your hard drive. The especially important files to keep track of are settings.php, and .htaccess. II. Change settings.php in your test site Drupal files Open and edit the file located under sites/default/settings.php (or includes/conf.php) with a plain text editor such as jEdit. Follow the directions in the file and modify this setting: $base_url = ’http://www.example.com/’; (This is the address where you will upload your live site directory. This tells Drupal where to look for the Drupal files to connect with.) There is no need to change the database settings. Just take note that your test site database is now being used as the live site database. III. Upload the test site Drupal files to your live site directory Using an FTP client such as SmartFTP, 1. Download all your live site files to a backup folder on your desktop. 2. Delete all your live site files on your server. You made a backup, right? 3. Upload all the test site files to the directory: http://www.example.com/ In FTP world this is usually seen as "public_html/" or "www/". IV. Check if your test site works Navigate to http://www.example.com/ and you should see your newly upgraded Drupal site.

Differences from 4.7 to 5.x
This section will be the central location for noting differences between 4.7 and 5.x and items to consider when upgrading or switching versions. Please click the "add child page" link below to add anything you consider significantly different between these versions.

Important note on upgrading from 4.7 to 5.1
As noted in this comment: "DO NOT attempt to go from 4.7.6 to 5.1 direct. You MUST upgrade to 5.0 first, else update.php will fail. there are database changes at 5.0 and 5.1 and they need to be done in sequence. this useful fact is not documented anywhere but it is hinted at here http://drupal.org/drupal-5.1

391

Drupal Handbook

3 Aug 2007

Important note on upgrading from 4.7 to 5.1
As noted in this comment: "DO NOT attempt to go from 4.7.6 to 5.1 direct. You MUST upgrade to 5.0 first, else update.php will fail. there are database changes at 5.0 and 5.1 and they need to be done in sequence. this useful fact is not documented anywhere but it is hinted at here http://drupal.org/drupal-5.1

Version specific upgrades
People have contributed version specifc upgrade instructions over time and you can find them here. The general instructions and pattern of upgrade has remained fairly similier across many Drupal versions. See the Introduction to upgrading for more generic information.

Upgrading from Drupal 4.4 to 4.5
If you upgrade from Drupal 4.4.x, you will need to create the users_roles and locales_meta tables manually before upgrading. To create these tables, issue the following SQL commands: MySQL specific example: CREATE TABLE users_roles ( uid int(10) unsigned NOT NULL default ’0’, rid int(10) unsigned NOT NULL default ’0’, PRIMARY KEY (uid, rid) ); CREATE TABLE locales_meta ( locale varchar(12) NOT NULL default ’’, name varchar(64) NOT NULL default ’’, enabled int(2) NOT NULL default ’0’, isdefault int(2) NOT NULL default ’0’, plurals int(1) NOT NULL default ’0’, formula varchar(128) NOT NULL default ’’, PRIMARY KEY (locale) ); PostgreSQL specific example: CREATE TABLE users_roles ( uid integer NOT NULL default ’0’, rid integer NOT NULL default ’0’, PRIMARY KEY (uid, rid)

392

3 Aug 2007

Drupal Handbook

); CREATE TABLE locales_meta ( locale varchar(12) NOT NULL default ’’, name varchar(64) NOT NULL default ’’, enabled int4 NOT NULL default ’0’, isdefault int4 NOT NULL default ’0’, plurals int4 NOT NULL default ’0’, formula varchar(128) NOT NULL default ’’, PRIMARY KEY (locale) ); Note from comments: For upgrading from 4.4 to 4.5 you need to run extra SQL stuff. If your phpwebdmin broken, you can use this small php script to do the update. <?php // Connecting, selecting database $link = mysql_connect(’host’, ’dbuname’, ’dbpw’) or die(’Could not connect: ’ . mysql_error()); echo ’Connected successfully’; mysql_select_db(’dbname’) or die(’Could not select database’); // Performing SQL query $query = "CREATE TABLE users_roles (uid int(10) unsigned NOT NULL default ’0’, rid int(10) unsigned NOT NULL default ’0’,PRIMARY KEY (uid, rid))"; $result = mysql_query($query) or die(’Query failed: ’ . mysql_error()); $query = "CREATE TABLE locales_meta (locale varchar(12) NOT NULL default ’’,name varchar(64) NOT NULL default ’’,enabled int(2) NOT NULL default ’0’,isdefault int(2) NOT NULL default ’0’,plurals int(1) NOT NULL default ’0’,formula varchar(128) NOT NULL default ’’,PRIMARY KEY (locale))"; $result = mysql_query($query) or die(’Query failed: ’ . mysql_error()); // Closing connection mysql_close($link); ?>

Upgrading from Drupal 4.5 to 4.6.3
The following is a simple step-by-step approach to upgrade a site from Drupal 4.5 to Drupal 4.6.3. It takes about an hour and a half to complete and it is important to follow each step carefully to avoid glitches or gremlins appearing at a later stage.

393

Drupal Handbook

3 Aug 2007

Before you Start
If you are using any of these modules in your Drupal 4.5 site that you plan to upgrade, please read the notes at the bottom of this book page: Image.module, Forum.module, Event.module. Make a backup of your Drupal MYSQL database and the Drupal 4.5 files & folders on your server, so you can recover your complete site in case anything should go wrong during the upgrade.

Step-by-step Upgrade from Drupal 4.5 to 4.6.3
1. Log into your Drupal 4.5 site as the administrator, go to ADMINISTER --> MODULES and disable all extra add-on or contributed modules you may have installed, i.e. modules that don’t come with the core Drupal download . I have listed below the core standard Drupal Modules: standard Drupal modules -------------------------aggregator.module archive.module block.module blog.module blogapi.module book.module comment.module drupal.module filter.module forum.module help.module legacy.module locale.module menu.module node.module page.module path.module ping.module poll.module profile.module queue.module search.module statistics.module story.module system.module taxonomy.module throttle.module tracker.module upload.module

394

3 Aug 2007

Drupal Handbook

user.module watchdog.module ================= 2. Go to ADMINISTER --> THEMES and make BLUEMARINE the default theme. 3. Go to the root of the Drupal directory and open the file called CHANGELOG.txt. Make a note of the version number and date (important!) in the first line at the top of the file. 4. Go to your includes directory and make a copy of the conf.php file on your local computer. 5. Delete all the Drupal files and directories from your server using an FTP program or a control panel filemanager provided by your web host. IMPORTANT: before doing this, make sure you have a backup of your Drupal MYSQL database and the Drupal 4.5 files & folders on your server. You will need your old "/files/" folder and its contents to copy to the new site later, and backing up the other files will allow you to recover your complete site in case anything should go wrong during the upgrade. 6. Download Drupal 4.6.0 and upload all the files to your server. 7. Go to the sites/default directory and edit the settings.php file (you can use your old conf.php file as reference). 8. Once settings.php file has been edited, go to your site and login as the administrator. 9. Go to http://www.yoursite.com/update.php. 10. You should be presented with the instruction screen for upgrading. Click on the link to start the upgrade script; you will be asked from which version you are upgrading from. This is very important: revert back to the note you made earlier from the 4.5 CHANGELOG.txt file. 11. Click the "Update" button. You should see a successful green "OK" after each update operation and finally a link to go to your main and administration pages. If you get red error messages, it means some or all of your update has failed. 12. On a sucessful update, go to the root Drupal directory and make a note of the version number & date from the very top of the CHANGELOG.txtfile (important). 13. Go to the sites/default directory and make a copy of the settings.php file to your local computer. 14. Delete all the Drupal files from your install. 15. Download Drupal 4.6.2 and upload the files to your server and restore the information in settings.php. 16. Go to your site and login as the administrator. 17. Go to http://www.yoursite.com/update.php (click on your browser’s Refresh button a few times to make sure it’s not loading from cache and the previous update.php file). 18. Click on the link to run the update script. Select the correct version number and date from the CHANGELOG.txt file you made a few steps back. 19. Click the "Update" button. You should see a successful green "OK" after each update operation and finally a link to go to your main and administration pages. If you get red error messages, it means some or all of your update has failed. 20. Repeat this process again to upgrade from Drupal 4.6.2 to version 4.6.3. 21. Once you have reached a live version of 4.6.3, you can now start downloading the 4.6 versions of the add-on contributed modules & Themes you used with your 4.5 site. All appear to work okay apart from event.module that needs extra special attention. When you’re

395

Drupal Handbook

3 Aug 2007

downloading a 4.6 version of the modules. Some of the more complex modules will usually have a unique module-update.php file included, to ease the process. Check the readme.txt or install.txt in the module folder as you download them to check for upgrading instructions.

Finalising your upgrade
There are a few significant differences between Drupal 4.5 and 4.6.x that means to finalise your upgrade you may need to apply the following:

Rebuilding your Drupal Search Index.
Because of the new improved search module, your site’s search index will need to be rebuilt. 1. Go to ADMINISTER -->> SETTINGS -->> SEARCH. It will indicate how much of your upgraded site is being indexed. 2. If your site search index is not 100%. Type www.example.com/cron.php in your browser. 3. Wait for a minute (longer if you have a very large site) and press the back button to bring you back to the SETTINGS/SEARCH page. 4. If your site is still not 100% indexed and/or you received an error message when running CRON.PHP adjust the settings accordingly and type www.example.com/cron.php again. 5. Repeat the process until your site is 100% indexed

Blocks
There are a lot of improvements in how BLOCKS are built in Drupal 4.6.x. If you had block paths configured on the block administration page in your Drupal 4.5 site, you’ll have to reconfigure these after the upgrade. 1. Go to ADMINISTER --> BLOCKS 2. Click on the CONFIGURE link for each BLOCK you applied special PATH conditions to on your Drupal 4.5 site and modify accordingly

Permissions
Please note that permissions screen has moved to ADMINISTER -->> ACCESS CONTROL in Drupal 4.6.x. To ensure your permission settings match those set on your Drupal 4.5 site, follow these steps: 1. Go to ADMINISTER --> ACCESS CONTROL 2. Double check that the permissions are correct and click on SAVE CONFIGURATION.

396

3 Aug 2007

Drupal Handbook

Forums
After upgrading, you need to re-associate the category terms you used in Drupal 4.5.x to FORUM TOPIC node types. The reason is that there is a change in how FORUMs are managed between version 4.5.x and 4.6.x including the new FORUM configuration screen that makes it easier to manage your FORUMS. 1. Go to ADMINISTER --> CATEGORIES 2. Click on EDIT VOCABULARY TERM for the FORUM category 3. Scroll down and ensure that FORUM TOPIC node types are associated with your Vocabulary Term. There also appears to be a bug in the update.php script dealing with forums that registers every LAST POST in each category to Anonymous. Worth checking the Upgrade Poblems Forum in case someone else has worked out what’s wrong.

Images
Upgrading a site with the image.module installed also appears very problematic. I didn’t have the image.module in the site I upgraded so I can’t help with any tips. Best to follow the forum discussions in the Upgrade Problems Forum

Events
Upgrading a site with the event.module installed also appears very problematic. The events.module comes with a special update-event.php script, which appears to work when you run it, but, I have tried it on a few occasions and it doesn’t seem to upgrade properly. I ended up spending so long trying to work out what’s wrong it was quicker for me to copy and paste each event from the old site into the new site by hand. There maybe a better solution in the Upgrade Problems Forum

Upgrading from Drupal 4.6.3 to 4.6.5
The following is a simple step-by-step approach to upgrade a site from Drupal 4.6.3 to Drupal 4.6.5. It is a relatively straightforward thing to do and takes about 15 minutes to complete. It is important to follow each step carefully to avoid glitches or gremlins appearing at a later stage.

397

Drupal Handbook

3 Aug 2007

Before you Start
There are no database changes between Drupal 4.6.3 and Drupal 4.6.5 but it’s worth making a backup of your Drupal MYSQL database as well as the files & folders on your server before starting your upgrade. Tip for beginners who want to back up the database: If you are unfamilir with PHP MYADMIN or other MYSQL database management tools it’s worth downloading and installing the Database Administration Module (dba.module) for Drupal. It allows you to backup your site database from within Drupal very simply and easily.

Step-by-step Upgrade from Drupal 4.6.3 to 4.6.5
For a trouble free upgrade, it’s recommended to follow each step carefully. It should take about 15 minutes to complete these steps. 1. Once you have made a backup, check to make sure you are upgrading from the correct version of Drupal. (Using a text editor like notepad.exe or other, open the CHANGELOG.TXT file from the root (main) folder of your Drupal installation and check the very first few lines. That indicates the version of Drupal you are using.) 2. Download a copy of your /SITES/ folder to your local computer 3. Download, unpack and upload the Drupal 4.6.5 files to your server. (You are simply overwriting the existing core modules and files with the updated Drupal 4.6.5 versions so it will just take a few minutes depending on your connection speed.) 4. After all the files have been uploaded sucessfully with no errors, upload the copy of the /SITES/ folder you created on your local computer at step 2 to your upgraded Drupal installation. 5. Congratulations ! Your site is now upgraded to Drupal 4.6.5.

Upgrading from Drupal 4.6.4 to 4.6.5
The following is a simple step-by-step approach to upgrade a site from Drupal 4.6.4 to Drupal 4.6.5 It is a relatively straightforward thing to do and takes about 15 minutes to complete. It is important to follow each step carefully to avoid glitches or gremlins appearing at a later stage.

Before you Start
There are no database changes between Drupal 4.6.4 and Drupal 4.6.5 but it’s worth making a backup of your Drupal MYSQL database as well as the files & folders on your server before starting your upgrade.

398

3 Aug 2007

Drupal Handbook

Tip for beginners who want to back up the database: If you are unfamilir with PHP MYADMIN or other MYSQL database management tools it’s worth downloading and installing the Database Administration Module (dba.module) for Drupal. It allows you to backup your site database from within Drupal very simply and easily.

Step-by-step Upgrade from Drupal 4.6.4 to 4.6.5
For a trouble free upgrade, it’s recommended to follow each step carefully. It should take about 15 minutes to complete these steps. 1. Once you have made a backup, check to make sure you are upgrading from the correct version of Drupal. (Using a text editor like notepad.exe or other, open the CHANGELOG.TXT file from the root (main) folder of your Drupal installation and check the very first few lines. That indicates the version of Drupal you are using.) 2. Download a copy of your /SITES/ folder to your local computer 3. Download, unpack and upload the Drupal 4.6.5 files to your server. (You are simply overwriting the existing core modules and files with the updated Drupal 4.6.5 versions so it will just take a few minutes depending on your connection speed.) 4. After all the files have been uploaded sucessfully with no errors, upload the copy of the /SITES/ folder you created on your local computer at step 2 to your upgraded Drupal installation. 5. Congratulations ! Your site is now upgraded to Drupal 4.6.5.

Differences from 4.6 to 4.7
This section will be the central location for differences between 4.6 and 4.7 and items to consider when upgrading or switching versions. Please click the add a child page button to add anything you find or consider significantly different between the versions.

Block visibility settings
Page specific visibility settings have changed between Drupal versions 4.6 and 4.7. In 4.7 the is a new option to use PHP code to determine when to show the block. If the code returns TRUE, the block is displayed. But because that option was not in Drupal before 4.7, you first have to switch it on from (administer -> access control).

Configure options centralized
Continuing the UI work started back back between 4.4 and 4.5, many one time configuration options have been moved from odd locations to admin >> settings menu.

399

Drupal Handbook

3 Aug 2007

If you have previously had trouble finding such one time configuration options such as work flow for content types or post length, check for them in admin >> settings menu.

core module help text linked to the handbook now
Core modules help text now have a link to the Drupal.org handbook. In your local Drupal (4.7) site, if you have the help module turned on you have admin >> help That takes you to this page ?q=admin/help Let’s pick a common one, taxonomy ?q=admin/help/taxonomy At the bottom of this text is a paragraph with a link For more information please read the configuration and customization handbook Taxonomy page. If you click on the link, you are brought back to Drupal.org. If anyone has provided additional information to that module since release, they will now get the updated text and and additional material people have seen fit to contribute as child pages.

Creating context sensitive menus with primary and secondary menus
About context sensitive menus One popular way to navigate a web site is to have to have a simple hiearchy of navigation, with primary pages acting as "parents" to secondary pages, or "children." When a primary page is visited, links to its secondary pages become visible. And when a secondary page is visited, its "sibling" secondary links are made visible. In this way, the the secondary links are "context sensitive". That is, the links to a particular group of secondary pages are displayed only when that group’s parent or sibling pages are visited. Drupal 4.7 allows you to easily create context sensitive menus using primary and secondary menus. To enable this behavior, in admin >> settings >> menu you must set both Menu containing primary links: and Menu containing secondary links: to the same menu.

Don’t turn off contributed modules that provide an .install file
The Basic Upgrade Steps handbook page recommends to turn off all modules that are not core modules before starting the update. Since Drupal 4.7 provides an install and update system for contributed modules this is not always correct. Contributed modules that come with an .install file should be kept enabled. The .install file is not only used to do setup tasks, it also includes instructions to perform updates. If the module is enabled when running update.php, these instructions can be automatically executed

400

3 Aug 2007

Drupal Handbook

during the Drupal update process. This of course requires that the module’s old files are replaced by the new ones before the update. If such modules are disabled before the update process, database error messages are likely to appear when they are enabled again. Also performing the module’s update afterwards is a rather cumbersome task.

Module .install files
As of version 4.7, modules authors can use .install files to do module setup work. A .install file is run the first time a module is enabled, and is used to do setup required by the module. The most common task is creating database tables and fields (which prior to version 4.7 was done manually). .install files are also used to perform updates when a new version of a module needs it. More information for module developers can be found in the developers handbook here. The short answer for site admins is that if a contributed module uses this new method, you will no longer need to manually load SQL tables into the database.

Primary/secondary links now part of the menu system
In 4.7 Primary and Secondary links have been incorporated into the menu system. Your theme will still need to have the code to display them but behavior is handled through admin >> settings >> menu settings. Then links are added in admin >> menu. The migration script attempts to successfully migrate your existing links but you will need to verify if it is successful.

queue module removed from core
The queue module has been removed from Drupal core. There are a variety of reasons for this and if you wish you can search the development archives for the relavant discussions around 10 months ago. No one has stepped forward to maintain queue module. For those needing moderation they should look to the newly updated nmoderation module by Jeff Eaton. The Nmoderation project has been updated to 4.7 compatability. It now uses the VotingAPI for its storage and calculation, so in the coming months it will also benefit from the increasing integration with actions.module and views.module that is being added to the API.

401

Drupal Handbook

3 Aug 2007

Removal of base href statement from header
Using the $base_url from settings.php, Drupal previously generated a base href statement in the header for all HTML output. The base href statement has been removed in 4.7 in an effort to make Drupal more W3C compliant. This will change the way in which relative links are encoded by hand in a Drupal site. Previously, to link to a Drupal node such as http://example.com/drupal/node/1000 one would create a relative link in an a href statement like this <href="node/1000"> Now, with the absence of the base href statement, the relative link is written relative to the domain name like this <a href="/drupal/node/1000"> When updating from 4.6 to 4.7, update.php will fix relative links in previously existing content in nodes comments custom blocks node submission guidelines user registration guidelines Site administrators will want to check HTML code with relative links that they have added in other places (such as content managed by contributed modules). Developers creating new Drupal sites for move to a different location when production ready should be aware. If you build a site in http://example.com/drupal/ all of the relative URL’s that the content might include have to be expressed in terms "/drupal/..." (see above). If you then move the site to another folder location or a root domain, the URL’s cease to function. It is recommended that if you plan to move the site to a root domain, then construct it in a subdomain so that the relative URL is preserved. Or developers may choose to borrow from update.php to create a script to update their tables (perhaps someone will share such a script).

402

3 Aug 2007

Drupal Handbook

Some HTML Tags stripped from mission statement
In phptemplate engine the $mission and $footer_message variables were changed to run through the filter_xss_admin() function. This limits the allowed HTML code slightly. Scripts and CSS styles are no longer allowed. To get around this new limitation, in your page.tpl.php file you can replace print $mission with include ’mission.tpl.php’. Create a file mission.tpl.php with your mission statement and it will be called by your page.tpl.php.

XTemplate engine removed from core
The XTemplate theme engine has been removed from the Drupal core and replaced by the PHPTemplate engine. A 4.7 version of the XTemplate engine is available here and will be maintained as a contributed module.

403

Drupal Handbook

3 Aug 2007

Troubleshooting FAQ
If you are installing Drupal for the first time, or you are trying to configure some part of your existing installation, chances are your problem has been asked and answered countless times already. Use this list of Frequently Asked Questions as your initial problem-solving helper. If you don’t find your answer here, search the entire Drupal site. Failing that, you can ask for help in the Support forum. DO NOT simply post a Support Forum request without at least making an effort to find the answer yourself. Yes, we know its tempting, but the answer you seek has been found by someone else before you.

How to troubleshoot (read this first)
Before panicking or posting questions to the forum, here are a few ways and places you can look for clues to your problem. Set a man a fire and he’s warm for a night. Set a man afire and he’s warm for the rest of his life. 1.

Stop and think
As ever, identify what changes you’ve made recently, what new modules may have been installed. Most of the time something seems to go wrong, it’s your fault. Remember that :-) and avoid those "Doh" moments after posting your problem. Are you SURE the modules you installed are the right versions? 2.

Read the errors
If pages are just not displaying, see your server logs. Find them, read the last few entries to see what’s going wrong. Errors like .htaccess config problems - "Internal server error" - Error 500 directive not allowed here Memory problems Fatal error: Allowed memory size of 8388608 bytes exhausted Misbehaving javascript - modules/troublesome/utility.js 404 file not found can be found there. 3.

404

3 Aug 2007

Drupal Handbook

Validate your page
If it’s a layout problem - alignment, font size, overflowing blocks etc - For the love of Mike run it through the validator. Validation is a target to aim at, but admittedly not always easy to achieve. However, you should know what errors exist, and how important they are. Specifically, close all tags correctly and fix structural problems. The rest of the complaints about entities and invalid attributes are less of an issue. If it’s a non-public dev site get the web developer toolbar and use the "Validate local HTML" option. Get the web developer toolbar anyway, and use the CSS inspector to find out what styles apply to which elements. Bring up the DOM inspector [CTRL-SHIFT-I] Use the ’Select element by click’ pointer and click on the problem element Navigate the DOM tree to ensure it’s the right element Select ’CSS Style Rules’ from the right pane where it says ’Object - DOM Node’ Click through the ’Rules’ and find out all the places where the element gets its formatting from. The rule at the bottom takes precedence. Learn about the first ’C’ in CSS - the Cascade Check out the same for the container and child elements - one items margin may be another items padding. (List items especially) If you find unwanted css coming from a core Drupal css - over-ride it in your own style.css with the same rule pattern, don’t hack core.

4.

Read the README
No, Really. Although many modules can ’just work’ on installation, some bits (like enabling HTMLTidy under WYSIWYG) need an extra step or two. It’s not broken, it’s documented in the README. Some modules have dependancies on server PHP extensions or assume other modules are available (eg ’forum.module’ assumes ’comment.module’ is available, and dies if you turn them off). The README should mention this. Some modules have potential conflicts, or may even require patches to other modules (see img_assist+tinyMCE). Again, the answer may be hidden in plain sight. Avoid the head-slap moments and read everything you can that came with the module. 5.

Search the right way
If the error you see (in the log or the screen) doesn’t make sense to you, try a search on it. Use Google, and quote the error as best you can. Google: "Argument #1 is not an array" drupal. - A google on a phrase, plus the keyword ’drupal’ is probably better than a drupal.org

405

Drupal Handbook

3 Aug 2007

search. Take care to leave out pathnames (but filenames are probably useful). Try different permutations of quotes around what seem to be discreet parts of the message. Try searching both with and without arguments. Strings input by the user won’t help much when searching for the problem elsewhere. 6.

Identify the source of the problem
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ’(n.nid), n.title FROM category c INNER JOIN category_node r ON c.cid = r.cid INN’ at line 1 query: SELECT c.*, r.DISTINCT(n.nid), n.title FROM category c INNER JOIN category_node r ON c.cid = r.cid INNER JOIN category cn ON c.cnid = cn.cid INNER JOIN node n ON c.cid = n.nid INNER JOIN node cnn ON cn.cid = cnn.nid WHERE n.status = 1 AND n.moderate = 0 ORDER BY cn.weight, cnn.title, c.weight, n.title in /var/www/html/doadance/drupal/includes/database.mysql.inc on line 120. Error like the above are not caused by drupal database.inc. They are simply found by it because a module has sent some bad instructions to the internals. We need to find where the call came from, unfortunately you won’t get a call stack by default. Try to identify the table being addressed in this query to see what module may be doing it. In this case it looks like category, but it may in fact be any other module that’s trying to directly access data about categories.

7.

Dump some diagnostics
Debugging. If you are really trying to find the causes, it may help to display some of the code. Try the devel.module For one-off quick hacks, when you just want to know why you are seeing (EG): warning: in_array() [function.in-array]: Wrong datatype for second argument in /home/httpd/global/drupal/modules/node.module on line 1303. Try some lightweight code. Go look at that file. Modify it a bit. It’s safe to do so if you remember to undo aferwards. On line 1303, node.module we find in_array(’status’, $node_options) on the line before try inserting the code: print("Node options are : ’".print_r($node_options,1)."’");

406

3 Aug 2007

Drupal Handbook

and see if that gives any clue. A useful data dump when debugging, even within node pages themselves is sometimes. print("Node is : ".print_r($node,1)"); 8.

Ask the right questions
When posting questions on the Drupal forum, it’s usually better to post more info than less. The more work you can demonstrate has gone into solving it already, the more likely folk are to help you get the rest of the way. Do ask questions "The smart way". Do follow up in the same thread if you resolve it - even if no-one else posted. Do consider submitting your solution as a comment under Troubleshooting FAQ or the elsewhere in the handbook. In Drupal, it’s usually important to know if you are on a shared hosting provider - mention this! 9.

Identify the module that’s giving you problems
All Drupal ’pages’ are dynamically created to one extent or another. Which dynamically created pages are published under which URL is usually defined in each modules hook_menu() implimentation. When installing or investigating new modules, it’s usually interesting to open up the code and look at the ***_menu() function to see what it does. Conversely, if you want to find which module is serving which page, you’ll have the search there also. To answer a question like "how is my sites rss.xml created?", a troubleshooting process may be: Do a find-in-files for "rss.xml" This returns, sure enough, a result in node.module : node_menu() This tells us that the function in question - that serves that page - is node_feed(). This is where you want to look for further details. All dynamic pages can be debugged by starting like this. Look at the URL, identify the module that serves that URL, trace the callback through the code.

My admin > modules page is blank
This is most likely a memory issue. On this page all modules are loaded, whether they are enabled or not. This can cause PHP to run out of available memory. There are two fixes:

407

Drupal Handbook

3 Aug 2007

1. Remove (unused) modules--the quickest/easiest solution. 2. Increase PHP’s memory limit, either by adding: memory_limit = 12M to your php.ini file (recommended, if you have access) ini_set(’memory_limit’, ’12M’); in your sites/default/settings.php file php_value memory_limit 12M in your .htaccess file in the Drupal root The popular distribution from CivicSpace requires 24MB of memory so you may have to experiment with what memory value works for your needs. All fatal errors can result in a blank modules page. If you want to be sure if the memory limit is causing this problem, you should check your web server error logs. Hunt for a line that looks like: Fatal error: Allowed memory size of 8388608 bytes exhausted (tried to allocate 418591 bytes) in /path/to/drupal/includes/database.mysql.inc on line 29 That indicates that Drupal needed more memory than PHP was allowed to give it. Always keep in mind that generally, "Less is More." The less memory your installation consumes, the faster it is, and the more people can visit your site at one time. You may have to restart Apache for the configuration changes to take effect.

How do I get the User Login block back
The block administration page can be reached on Drupal 4: http://www.example.com/?q=admin/block Drupal 5: http://www.example.com/?q=admin/build/block If you need to login, visit: http://www.example.com/?q=user Note: Use the literal word user, not your username or user id.

Client does not support authentication protocol requested by server...
You are installing a new install of Drupal and during setup receive the error Client does not support authentication protocol requested by server; consider upgrading MySQL client. You are probably using MySQL 4.1 or higher and need to reset the password to pre 4.1 style.

408

3 Aug 2007

Drupal Handbook

Webhosting issues for new Drupal users
A lot of new Drupal users run into issues getting Drupal to work properly on their webhost. These problems are not Drupal problems as such, they are usually the way the webserver is configured. Complex and functional web applications like Drupal will naturally require a lot more from a web server than just hosting a static HTML site would. Unfortunately there is usually a knowledge gap between the Drupal installation documents and the exact environment a new user is confronted with when attempting to install and configure Drupal. For more experienced users that have a little Unix and Apache (a typical webhost setup) knowledge under their belts, bridging the gap between their webhosting environment and the general purpose Drupal installation guide is no problem. Things are more confusing for less experienced users though. The following info is intended to help newbies come to grips with the documentation and their webhosts environment. There are a wide range of web site configuration tools (eg CPanel, Plesk, webmin etc) and near infinite number of ways a webhost could configure a webserver. What this means is that a lot of the general Drupal docs you read will have to use the lowest common denominator (ie Unix shell commands) to describe configuration steps. Less experienced users will not fully understand what these commands do or why they should do them, and definitely won’t know when to deviate from them. To make matters worse most webhosts don’t even offer shell access, so the instructions need to be ’translated’ to whatever control panel they offer. The following topics will hopefully provide just enough insight into Apache and Unix that new users will be able to better understand the installation documentation and ’tune’ their sites for running Drupal without too much pain. As a new user you might also gain an understanding of why most of the docs are written the way they are. Note: There are webhosts that offer Drupal specific hosting for those without the time or inclination to do it themselves. See http://drupal.org/services and http://drupal.org/forum/34 for more info.

Brief intro to Unix file permissions
Unix is a multiuser operating system. That means that it was designed for multiple users to be logged in at once and each running their own programs without getting in the way of each other. Every program that runs on a Unix machine runs as a specific user account. This includes the webserver itself, any command line shell you are running, and whatever software you use to access the servers filesystem and admin interfaces (eg FTP software, CPanel interface etc). When you log in with a username and password through an FTP client or a control panel you are now operating on the server using that user account.

409

Drupal Handbook

3 Aug 2007

Note: this doesn’t include any Drupal user accounts you have set up. They only exist in your Drupal database, not as any operating system user accounts. All files on a Unix server have an owner and a group assigned to them. Whenever a file is created on the server it is automatically owned by the user account running the program that created it. Each user account also has a primary group associated with it, and this group also gets assigned to the files group. Each file and directory also has a set of permission ’bits’ assigned to it as well. These permission bits determine what access various users get to a file. The owner of a file is allowed to change these permissions, but all other users can’t change them (with the exception of the root user). The file permission bits are arranged into three sets: ’user owner’, ’group owner’, and ’other’. These three sets can also be referred to as ’user’, ’group’ and ’world’ respectively. ’world’ or ’other’ refers to the permissions that apply for any user that isn’t the owner and isn’t in the files group. Each of these can have its own combination of three basic permissions. The three basic permissions are ’read’, ’write’, and ’execute’ and are abbreviated as ’rwx’. When you see dashes replacing a letter that means that the permission is absent eg ’r--’ means that only read access is present. When all three sets of permission bits are combined you get a setting like ’rwxr-xr-x’ which represents ’rwx’ for the owner, ’r-x’ for the group, and ’r-x’ for everyone else. You will also see permissions represented as a numerical shorthand eg 755 or 644 etc. In this case the value of ’r’ = 4, ’w’ = 2, and ’x’ = 1, and the digits are determined by adding up these numbers for each set. examples: 755 is shorthand for ’rwxr-xr-x’. Translation: full access for the owner, everyone else has read and execute access 664 is shorthand for ’rw-rw-r--’. Translation: the owner and the group get read and write access, all other users get read access. For files these permissions settings are quite straight forward. ’read’ allows accessing the contents of a file, ’write’ allows the file to be changed or deleted, and ’execute’ allows the file to be run as a program from the command line shell. Note that the execute bit isn’t really required for PHP files as they don’t generally get run from the shell. Permissions on directories are a little different from those on files. ’read’ allows the contents of a directory to be listed, ’write’ means that you can add or delete files in the directory, and ’execute’ allows direct access to files in the directory (if you already know their names). On most directories read and execute bits tend to go together ie typically directories will either have both bits set or neither set.

410

3 Aug 2007

Drupal Handbook

There is a friendly tutorial here if you need more information: http://www.perlfect.com/articles/chmod.shtml

Host-specific error messages
Some web hosts generate inexplicable errors when you install, upgrade, or even use certain contrib modules in Drupal. The host may not know they’re the one causing the problem, mostly because you assume you’re the one who doesn’t understand the inner workings of Drupal. Here are a few host-specific error messages we’ve encountered, and how you can ask your host to solve them. Hosting Company Error Message While editing a View, you receive the following error message: Forbidden. You don’t have permission to access /admin/build/views/edit/1 on this server. While editing a Content Template (Contemplate), you receive the following error message: Forbidden. You don’t have permission to access /admin/content/templates/yourtemplatename on this server. Solution Ask the host to make a mod_security entry for your www.example.com account. Ask the host to make a mod_security entry for your www.example.com account.

Webmasters.com

Webmasters.com

If you have something to add to this list, please post a comment, and one of the document maintainers will add it for you, then erase your comment.

SELinux may cause mysterious permission problems
Security Enhanced Linux (SELinux) is a relatively new, powerful mechanism for fine-grained access control on Linux systems. Properly configured and maintained, it offers much better protection from misbehaving programs and exploitable security weaknesses of server application stacks than conventional Unix systems can provide. Many distributions now come with SELinux support enabled by default, or at least make it available for installation. SELinux is installed/available on Red Hat, Fedora, Debian, Gentoo, SuSE, Slackware, and Ubuntu, among others. If you (or your ISP) are running Drupal under an operating system which has SELinux installed and enabled, you may find that certain operations fail mysteriously. Symptoms include, for example, files not being written or read though the webserver has permissions; communications operations such as sending mail or attempting XMLRPC operations failing, although firewall permissions are OK, etc.

411

Drupal Handbook

3 Aug 2007

You can confirm that SELinux is causing the problem by turning SELinux off temporarily (run the command setenforce 0 as root) and try the operation. If it succeeds, likely SELinux is the culprit. (I’m assuming that this is a development setup, not a production machine - SELinux is designed to protect your system, so turning it off on a production machine is not to be done lightly). You can get more information about exactly why SELinux is shutting you down by looking in the log files that it generates, for example, in /var/log/audit/audit.log on FC4. Look for ’avc’ (access vector cache) messages. Once you have tracked down exactly what aspect of SELinux policy is causing your operation to fail, you can modify the SELinux configuration to fix the problem. This may be as easy as turning on a boolean configuration setting in a configuration file, or as complicated as writing a new snippet of SELinux policy. Using the avc messages, the supplied SELinux administration tools and a little bit of help from Google, the SELinux FAQs/tutorials on the web, and folks on the various the SELinux mailing lists, you should be able to find your way around configuring additional policy to get Drupal to do what you need. I highly encourage you to bite the bullet and run with SELinux enabled, though it does involve a rather steep learning curve.

Typical webhosting setups
The typical webhost sets up their servers so that each website gets a user account to manage it (eg your FTP login). Each user account has a home directory where they can create files. These website files will generally be owned by the user account that uploaded them. The default permissions on these files usually won’t allow other users to write to them for obvious reasons. On most servers by default, the webserver runs under a different user account. eg on a Debian Linux server, Apache usually runs as the www-data user. Some webhosts though might have installed Apache modules that switch the webserver to run as the owner of the files it is serving up. Note: To find out what user the webserver is running as, you can use the phpinfo() function. There are various ways of doing this - you can upload your own php file to do so, or that functionality might already be built into tools you already have available like phpmyadmin. Most documents or people answering forums tend to assume that the webserver is running as a different user account. The explanations get a bit too fiddly and convoluted otherwise. But if your server does run the webserver as your own account, keep that in mind when reading other docs or answers - they might be aimed at the case where it runs as a different user. How the web server is set up determines which permissions get used to control access to your files. If the webserver runs under your user account, then Unix uses the file owners permissions to provide access to your files. If the webserver runs as a different user, then Unix uses either the ’group’ or ’other’ permissions to determine access depending on whether or not the webserver

412

3 Aug 2007

Drupal Handbook

account is in the files group or not.

Using PHP to change files on the webserver
One side effect of having files created by Drupal (eg the image module), is that your user account might not have ownership of them any more. And you might not be able to delete the or move them around. There is a workaround though. You can create a small PHP script containing the commands you want to carry out and upload it to the server. Once uploaded, you can run it from your web browser by entering the URL for it. The script will run as the user account the webserver runs as. Be sure to remove the script after you have used it though. Documentation for PHP filesystem functions: http://php.net/manual/ref.filesystem.php And documentation for the PHP system() function: http://php.net/manual/function.system.php With these techniques you should be able to get the webserver to do anything the Unix shell can do. Take care doing this though. These are the kind of tasks where it pays to practice them on your test instance first - you do have a test instance right?

What do all those Unix commands mean?
You will notice references to Unix commands in some documentation or forum posts and might be a little unsure what they do. The reason a lot of the docs or forum posts just list the underlying commands is because they are a much more universal interface and the process can be expressed quickly without writing long winded paragraphs describing things. You may wonder why you would want to know what these Unix commands do, but once you have a better idea of what they do you can then translate them to the functionality provided by your control panel or FTP client etc.

Some Unix command you’ll see mentioned:
chmod changes the permissions on files and directories. The ’-R’ (for recursive) option switch changes the permissions on subdirectories and files as well. mv moves or renames files and directories. In general to rename a file or a directory you ’move’ it to its new name. rm removes (ie deletes) files and/or directories. To remove a directory you need to use the r (for recursive) switch ie ’rm -r’.

413

Drupal Handbook

3 Aug 2007

cp copies files and directories. The ’-p’ (for preserve) option switch also copies permissions and ownerships etc. The ’-r’ (for recursive) option switch also copies subdirectories and files as well. The ’-a’ (for archive) option switch includes both -r and -p options. mkdir creates a directory. ln creates a filesystem link. The main kind you will see mentioned is a ’symbolic link’ (using the ’-s’ option switch) which behaves a bit like a shortcut in windows. You can create a link to a file or directory located somewhere else and it will behave just like a copy of that file or directory. But because they are linked rather than just copied, changes to one are reflected in the other. wget a command to download web pages or files off the net and save them to disk. tar a zipping and unzipping utility. eg the Drupal download is what’s called a tarball. tar is used to ’unzip’ the tarball into a subdirectory. mysql and mysqladmin command line utilities for connecting to and managing a MySQL database. Just about anything they can do can also be done by phpmyadmin.

Special characters:
/ the Unix directory separator (just like with URLs) and also represents the root directory. When a path starts with / it is an absolute path ie it starts with the root directory. A path ending in / is an optional way of explicitly referring to a directory rather than a file. .. refers to the parent directory (just like in Windows). A path starting with this is relative to the current directory. Can be chained together eg ../.. refers to the parent of the parent directory. . like ’..’ but refers to the current directory. * wildcard that matches any number of characters (like in Windows) ? wildcard that matches just one character (like in Windows)

What permissions does Drupal need?
Now that you know which user the webserver runs as, you’ll need to make sure your file and directory permissions are set properly. If you set them too tight Drupal won’t run properly or even at all. Too loose and you run a higher risk of security breaches.

414

3 Aug 2007

Drupal Handbook

Most of the time, any files you upload should end up with the correct permissions to run a basic Drupal site. Your webhost will have set the default permissions so they will be able to be read by the webserver. Where things get trickier is with the infamous ’files’ directory. If you install or enable modules that upload files or images, they get stored under this directory. To do this, the webserver will need write access to this directory. What this also means is that any files you upload will be owned by the webserver user account and may not be able to be moved or deleted any more by your FTP client or control panel as you might not have enough permissions. In most cases don’t worry about this too much, but if you really have to delete some of these files manually there are ways around the problem by uploading your own PHP scripts for the webserver to run and change the permissions. Basic summary of file permissions for a Drupal installation: All the Drupal files (eg .php, .module, .css, .theme and images etc) will need to be able to be read by the webserver account. The ’files’ is generally the only directory will need to be writable by the webserver account. If you get error messages complaining about missing files, or not being able to open/read a file etc and you know that the file really is there - chances are that the webserver doesn’t have read permissions for it. Recheck the permissions on subdirectories etc. Ideally your settings.php file won’t be world readable as it contains your database connection string (with password). But sometimes you can’t avoid it if making it world readable is the only way your webserver can read it. Along similar lines, ideally for security reasons you won’t have to make anything world writable. But on a lot of webhosts it is hard to avoid having to make the ’files’ directory world writable. What ever you do don’t go making anything other than the ’files’ directory world writable. That makes it easy for other users to overwrite your Drupal files. If it is possible through your admin interface it can be useful to assign the group ownership of the ’files’ directory to the group the webserver runs as, and allow group write access. This improves security a bit by not requiring the directory to be world writable. Quite often you will hear people talk about setting permissions to 777 which is no restrictions at all. While that is a good way to isolate any permissions issues when troubleshooting, you should try to tighten the permissions back again afterwards if possible. Preferably you wouldn’t need to use 777 permissions anywhere. Another thing to keep in mind is that a permission setting only tells part of the story about access - when troubleshooting it is also important to know who the owner and group are, and well as which user the webserver runs as.

415

Drupal Handbook

3 Aug 2007

Why is this uploading stuff so difficult?
The reason it is more complicated when you need to upload files and/or images is because you are now operating the web server in a different way. With standard HTML only Drupal configuration, Drupal is not creating any files on the web servers filesystem. When in that mode it runs like a standard web site - all the web server needs to do is read the files, it doesn’t need to write anything. All the content you submit to the site is going into the database not the filesystem. But to be able to upload files or images through the Drupal interface, now Drupal needs to be able to write files to the filesystem on the server. This gets tricky because most of the time you don’t want the webserver to be able to write files into your site directory. Just think what would happen if someone exploited a vulnerability in someone else’s website on that server - they could now overwrite any of your website files very easily. Just think what you could get up to just by uploading PHP files if other peoples sites had wide open write access - no don’t try this. So generally web servers aren’t allowed to write files in peoples websites. If you do want to Drupal to be able to write files into a subdirectory - you will have to manually weaken the filesystem security to make it work. This isn’t a Drupal issue - any code (eg PHP, Perl, Python etc etc) run by the web server will need those permissions weakened if they are to be able to write files to part of your web directory. You may also run into upload filesize problems that require changing settings like: memory_limit, post_max_size, upload_max_filesize etc. These settings are there to limit what any one website can do to overload the server. If these are too high, it allows one site to completely tie up the server causing trouble for all the other sites. Its all just the nature of sharing a server with lots of other people. There will be security and resource limits put in place to stop a badly behaved user causing trouble for the others. Your webhost is trying to strike a balance between ease of use and security. Different webhosts will draw the line in different places - that is why it is impossible to write detailed docs that cover all situations.

"Headers already sent" error
If you get a "headers already sent" error, there are two likely causes. If this error is not the first error message on the page, then it is most likely a ’avalanche effect’ of previous errors and you may ignore it. Instead, focus on fixing the errors before it. When you fix the first error message(s), the "headers already sent" error(s) will most likely disappear.

416

3 Aug 2007

Drupal Handbook

However, if you get an error "headers already sent" as the first error, especially when trying to log in and it tells you the error is near the end of a file (check which file "output started at" points to), that probably means that there are extra spaces or lines after the closing ?> php tag. Just delete them, and everything should work fine. The extra whitespace being added probably is caused by a bad unpacking program and / or a windows editor adding it.

"LOCK TABLES sequences WRITE" error
This is in reference to the following kind of error: user error: Access denied for user: ’user@host’ to database ’database’ query: LOCK TABLES sequences WRITE in [path]/database.mysql.inc on line xx When you installed Drupal, you created a database and a database user. This error is caused by that database user not having a certain privilege over your database. When you come across this problem, first, double check that you have granted all privileges to your user. You can try to grant the LOCK tables privilege by executing the following query: GRANT LOCK TABLES ON databasename.* TO username@localhost IDENTIFIED BY ’password’; If the GRANT command does not seem to have any effect on MySQL, you may need to follow it by "FLUSH PRIVILEGES." If you still get this problem, and you are using shared hosting, it is very likely that your host does not usually let users have the kind of permission required. For reference, you may want to read these forum posts. You need to contact your host (e-mail seems better than live support for this) and ask (if you are using mySQL 4) for global LOCK TABLES privilege for your user in that database. Although there are fixes in the forums, these are not recommended. If your host denies your request, they may not be an appropriate place for your Drupal site.

"Method POST is not allowed for the URL /index.htm" error (Error 405)
Your Drupal directory contains both an index.html and index.php file. Remove the index.html file or configure your web server to look for index.php first before index.html. The same goes for basically any html file in your Drupal directory. If you have for example "node.html" in your root, you get the error message for every form that is submitted to node/*.

417

Drupal Handbook

3 Aug 2007

"Page Not Found" error when trying to access a subdirectory
When you create a subdirectory inside the main Drupal directory that requires authentication (with a .htaccess file), you may receive a "Page Not Found" Drupal page instead of the page you expect to receive from the subdirectory. This is caused by the way Drupal handles unauthorised access to items. There is an easy fix to this problem. The following line should be added to the end of the .htaccess file in the subdirectory you are trying to access (NOT THE DRUPAL .HTACCESS FILE). ErrorDocument 401 "Unauthorized" Doing this rewrites the default 401 error so that it is not intercepted by Drupal.

Block referrer spam
In some Content Management Systems, you can configure a block that shows what links people clicked to come to your site. This is called a referrer sting. Drupal doesn’t display this referrer, which is a good thing. Many porno and online poker sites have robots that are sending "fake" referrer strings, claiming they entered your site via their own site. When you would have a block displaying these referrers, they would get more hits from people clicking these displayed referrer URL’s. So it is a good thing that Drupal doesn’t display these referrers, apart from the referrer logs admin page. Often, the robots sending these referrers do this via a so-called zombienetwork, thousands and thousands of misconfigured or hacked PC’s which are "open proxys". You can’t really block this referrer spam, the robots are sending real user-agents, are using many URL’s and there are so many zombie IP addresses that are changing fast, that you can’t block these. There is some work underway to block bad behaving robots and users from within Drupal. This will probably be part of Drupal 4.7. Until that time, the only way to block the referrer spam it by looking at your referrer log and look for often used word in the fake referrer URL’s, like "online-poker". Now you can block these words in your .htaccess file. Say you want to block the referrers "internet-poker" and "viagra" as well as all user-agents that contain "looksmart" First localize your .htaccess. This file is most likely in your Drupal document root. You can use vi, pico, notepad or another editor. Now go to the end of the file and just before the last line add: # Block referrer spam RewriteCond %{HTTP_REFERER} (viagra) [NC,OR RewriteCond %{HTTP_REFERER} (internet-casino) [NC,OR] RewriteCond %{HTTP_USER_AGENT} (Looksmart) [NC]

418

3 Aug 2007

Drupal Handbook

RewriteRule .* - [F] You don’t have to restart your webserver, these settings take place immediately. When you look at your logs, you will still see the spamming robots with the fake referrer URL’s. But you will see that these clients now get a 404 error, this means that they are not allowed to access that (or any other) page. If the robot that is sending this referrer spam is a "smart" robot, it will know sending the fake URL didn’t work. Now it wont stop all the bad guys, they will probably try to send another URL. Or the will go to another site to spam there. But there is a chance you will make it a better world. Try it.

.htaccess sample list plus domain blocking
As described you can block via the use of .htaccess. Here is a sample list to stop trackback spam (or splogs) from occuring in the first place. Here is a list already made available to use, which blocks several spams. # Single word blocks RewriteEngine On RewriteCond %{HTTP_REFERER} poker [OR] RewriteCond %{HTTP_REFERER} medicine [NC,OR] RewriteCond %{HTTP_REFERER} pills [NC,OR] RewriteCond %{HTTP_REFERER} diet [NC,OR] RewriteCond %{HTTP_REFERER} viagra [NC,OR] RewriteCond %{HTTP_REFERER} mortgage [NC,OR] RewriteCond %{HTTP_REFERER} casino [NC,OR] RewriteCond %{HTTP_REFERER} insurance [NC,OR] RewriteCond %{HTTP_REFERER} loan [NC,OR] RewriteCond %{HTTP_REFERER} buy [NC,OR] RewriteCond %{HTTP_REFERER} xanax [NC,OR] RewriteCond %{HTTP_REFERER} meridia [NC,OR] RewriteCond %{HTTP_REFERER} incest [NC,OR] RewriteCond %{HTTP_REFERER} lesbian [NC,OR] RewriteCond %{HTTP_REFERER} viagra [NC,OR] RewriteCond %{HTTP_REFERER} adult [NC,OR] RewriteCond %{HTTP_REFERER} hentai [NC,OR] RewriteCond %{HTTP_REFERER} tramadol [NC,OR] RewriteCond %{HTTP_REFERER} phentermine [NC,OR] RewriteCond %{HTTP_REFERER} gambling [NC,OR] RewriteCond %{HTTP_REFERER} texas- [NC,OR] RewriteCond %{HTTP_REFERER} holdem [NC,OR] RewriteCond %{HTTP_REFERER} pharmacy [NC,OR] RewriteCond %{HTTP_REFERER} ultram [NC,OR] RewriteCond %{HTTP_REFERER} tramadol [NC] RewriteRule .* - [F,L]

419

Drupal Handbook

3 Aug 2007

Remember to use [ and ] to close the arguments above. read more on: http://www.i-marco.nl/weblog/archive/2005/08/29/saving_some_valuable_ban... Or another way is to block domains also in the .htaccess file: SetEnvIfNoCase Referer ".*.baddomain.com" BadReferrer SetEnvIfNoCase Referer ".*anotherbaddomain.com" BadReferrer order deny,allow deny from env=BadReferrer read more on: http://www.hojohnlee.com/hacks/2006/01/12/blocking-spam-domain-referrals...

Color picker doesn’t appear on theme configuration page
Color module is not enabled Make sure to enable color.module on Administer » Site building » Modules (admin/build/modules). File download settings The color picker is incompatible with the Private download method and will only show when the download method is set to Public - files are available using HTTP directly. Visit Administer » Site configuration » File system (admin/settings/file-system) to check the download method your site uses. PHP’s image library GD is not enabled. Check your status report at Administer » Logs » Status Report (admin/logs/status) to see if the GD library is working on your server. This is needed to actually create the images. If it is not, you need to install it or get your host to do so for you. Javascript is disabled. You still see the Color scheme fieldset with a select box and a number of textboxes, but no longer the color wheel or the preview. Make sure you have Javascript enabled in your browser.

Drupal 4.7 Install inserts CGI-BIN in URL
In some hosting environments it is necessary to use the optional BASE_URL setting in settings.php. Uncomment the line by removing the # at the beginning, type in the site URL and save.

420

3 Aug 2007

Drupal Handbook

Duplicate entry error
This page is for errors similar to the one below: user error: Duplicate entry ’24’ for key 1 query: INSERT INTO node (status, moderate, promote, sticky, title, body, format, uid, created, type, teaser, changed, nid) VALUES(’1’, ’0’, ’1’, ’0’, ’test’, ’this is a test’, ’1’, ’1’, ’1149692821’, ’story’, ’this is a test’, ’1149692832’, ’24’) in .../includes/database.mysql.inc on line 66. warning: Cannot modify header information - headers already sent by (output started at .../includes/common.inc:384) in .../includes/common.inc on line 192. The likely problem (short form): At some point, the sequence table in your Drupal database was not updated. The solution 1. Access your database. Check the affected table. In this case, the error tells us that it is the node table (query: INSERT INTO node). This also happens with other tables, modify these instructions accordingly. 2. This is the node table, so the problem is the node id (nid). Each node has a unique id. Look at your table, and find the highest node id (nid). If you have many nodes, it may help to sort your table by nid to find the highest one. 3. Go to your sequences table. Change the node id in the sequences table to a number higher than the id you found in step 2. The problem (long form): The ’key’ in a table is a column where every entry has to be unique. For example, in the users table, every UID (user id number) must be unique. You don’t want two users with the same id! Drupal keeps track of what is the highest ID value separately, in the sequences table. When a new user is created, Drupal checks the sequences table to find out what the next UID should be. Presumably this is more efficient than checking the user table itself. Drupal then creates the new user, updates the user table with the new user information, and updates the sequences table with the new UID. The same thing happens for the node table, comment table, really, a whole bunch of tables. Sometimes, for some reason, Drupal does not update the sequence table. The number there becomes out of date. So let’s say that in the node table the highest NID is 300, but somewhere, something went wrong, and in the sequences table, the NID is only 297. The next time Drupal makes a node, it will check the sequences table, and try to make a node with a NID of 298...whoops! That already exists.

421

Drupal Handbook

3 Aug 2007

The solution (long form): The error itself can tell us a lot. Let’s divide it into 3 parts: The error: user error: Duplicate entry ’24’ for key 1 Duplicate... meaning the ’24’ is the same as something else in the table, something where no two things can be the same. Which table? Which column? The query: query: INSERT INTO node (status, moderate, promote, body, format, uid, created, type, teaser, changed, nid) sticky, title,

INSERT INTO [tablename] tells us which table produced the error. What follows is a list of column names. The values: VALUES(’1’, ’0’, ’1’, ’0’, ’test’, ’this is a test’, ’1’, ’1’, ’1149692821’, ’story’, ’this is a test’, ’1149692832’, ’24’) in .../includes/database.mysql.inc on line 66. The values we tried to insert into columns of the NODE table... We already know ’24’ was the problem, we see here it is the LAST value, corresponding to the LAST column, the nid, or node id. So the problem is, we tried to insert 24 into the nid column of the node table, when that value already existed (duplicate entry!). Why? Because the sequence table was not updated, and told Drupal the wrong nid. The solution is to enter a value for nid into the sequence table that is higher than ANY nid in the node table. To find the highest nid in the node table, access your database, however you do it. Find the node table, and sort it by nid. Write down the highest value. Let’s say for this example that the highest number is 68. Go to the sequences table, and find the row that has nid in it. Replace the number there with ANY number higher than the highest value in the node table. For this example, the highest value was 68. 69 would work, so would 70, 90, and 201. ANY NUMBER higher than 68 would work in this example. Additional point: 99% of the time, the solution is in the sequence table, but this error will come up ANY time you try to insert duplicate data into a column where every value has to be unique.

422

3 Aug 2007

Drupal Handbook

E-Mail from Drupal is bouncing or not being sent
If you are not receiving any E-mails from Drupal, or if E-mail sent by Drupal is bouncing, then ensure that the SMTP configuration is set properly in your php.ini. If you continue to have problems, the use the "user_mail_wrapper" option included with Drupal. You can now hook up your own custom SMTP library to Drupal instead of using the default PHP mail() function. For more people mail() will work just fine, but for others this is a major problem and it does not work properly. If you just want to get started you will have to download a custom wrapper function from the Drupal contrib repository. If you already have a favorite SMTP function you want to use you will have to create your own wrapper function. Make an include file that defines a user_mail_wrapper function: user_mail_wrapper($mail, $subject, $message, $header); This function should take the parameters and pass them to the SMTP lib. You will probably have to configure the SMTP lib in some way. Modify your configuration file (conf.php) to include: $conf["smtp_library"] "path/to/wrapper.inc"; =

Check out http://cvs.drupal.org/viewcvs/drupal/contributions/tricks/smtp/ for an example. Originally written by Kjartan on January 9, 2002, with modifications. Customize smtp.inc from the repository above to ensure that the proper settings for your SMTP server are being used.

Relay SMTP mail to external mail server using smtp.class
Note that there is now also a SMTP module that will do this for you: http://drupal.org/project/smtp The following are steps that I used to get Drupal 4.6.x running on Apache with PHP 4.3.10-15 to successfully relay mail to an external mail gateway without using the php_mail() function. I have tested this on Postfix and Exchange server mail gateways successfully. 1. Download class.smtp.inc from http://www.phpguru.org/downloads/smtp/smtp.class-1.0.5.tar.gz. 2. Untar using tar âxzvf and copy class.smtp.inc to the /includes directory. 3. Edit the file and change the following lines to coincide with your external mail gateway: $this->host = ’localhost’; Change localhost to the IP address of your mail gateway. You may also use the FQDN instead of the IP address if you have DNS set up correctly to something like yourmailgateway.yourdomain.com. $this->helo = ’localhost’; Change localhost to reflect the hostname (FQDN) of your external

423

Drupal Handbook

3 Aug 2007

mail gateway. For example: yourmailgateway.yourdomain.com. If your gateway requires SMTP authentication to relay mail, then you will need to modify the following lines to appropriately reflect the authentication credentials. (If you manage your own mail gateway or it resides within local subnets behind your firewall, then you should be able to leave authentication set to FALSE and allow relaying based upon IP address/network ID. This will probably only affect you if you use a hosting company for email management. $this->auth = FALSE; (change to TRUE) $this->user = ’’; (put username here(you may need to preceed with domain; e.g. domain\username)) $this->pass = ’’; (put password here) 4. Download smtp.inc from http://cvs.drupal.org/viewcvs/drupal/contributions/tricks/smtp/ and place it in your /includes directory. No modification to this file is needed. 5. Add the following line to the sites/default/settings.php file before the closing ?> tag: $conf["smtp_library"] = "includes/smtp.inc"; 6. Finally be sure to add the IP address of the mail gateway to the [mail function] section in your php.ini file and restart your web server. Good Luck! I hope this saves you the hours of researching it took me to get it running.

Error 1364 upon importing database.mysql with MySQL 5.0+
Symptom When you use the file database/database.mysql to create a drupal database, MySQL reports the following error: error 1364 (hy000) line 803: field ’page’ doesn’t have a default value. This error is caused by the following lines in database.mysql: REPLACE blocks SET module = ’user’, delta = ’0’, status = ’1’; REPLACE blocks SET module = ’user’, delta = ’1’, status = ’1’; You may have additional problems when working with Drupal. Sidebars will be absent and posting content results in an error: user error: Field ’revisions’ doesn’t have a default value [snip] Cause

424

3 Aug 2007

Drupal Handbook

MySQL 5.0 and higher have a strict mode that is currenty incompatible with a number of queries in Drupal. The Windows Installer from MySQL.com enables this strict mode by default. Workaround There are several workarounds 1. Replace in my.ini the current sql-mode line with sql-mode="MYSQL40" 2. Start MySQL with the option --sql-mode="MYSQL40" 3. Execute the query SET GLOBAL sql_mode=’MYSQL40’ MySQL needs to be restarted before changes in my.ini have an effect. My.ini can be found in the MySQL installation directory or the Windows directory, depending on your configuration. Note: After switching MySQL mode you have to recreate your Drupal database or your site will not function properly.

Error on installation step 3: Warning: Table ’[database].access’ doesn’t exist [...]
To run the install script point your browser to the base url of your website (i.e. http://www.example.com). You will be presented with the "Database Configuration" page. On Step 3 of INSTALL.txt - RUN THE INSTALL SCRIPT you do not arrive at the Database Configuration page, but are greeted with the following warning(s) instead: Warning: Table ’[database].access’ doesn’t exist query: SELECT CASE WHEN status=1 THEN 0 ELSE 1 END FROM access WHERE type = ’host’ AND LOWER(’[ip-address]’) LIKE LOWER(mask) ORDER BY status DESC LIMIT 0, 1 in [path]/includes/database.mysql.inc on line 172 Followed by one or more warnings concerning headers that have already been sent: Warning: session_start() [function.session-start]: Cannot send session cookie - headers already sent by (output started at [path]/includes/database.mysql.inc:172) in [path]/includes/bootstrap.inc on line 811 This happens if you have already edited the $db_url variable in settings.php. The installer will no longer be automatically invoked, because Drupal assumes installation has already been completed. To remedy, run the installer manually by visiting http://example.com/install.php.

425

Drupal Handbook

3 Aug 2007

Fatal error: Allowed memory size of X bytes exhausted (tried to allocate Y bytes)...
That indicates that Drupal needed more memory than PHP was allowed to give it. Increase PHP’s memory limit, either by adding: memory_limit = 12M to your php.ini file (recommended, if you have access) ini_set(’memory_limit’, ’12M’); in your sites/default/settings.php file php_value memory_limit 12M in your .htaccess file in the Drupal root The popular distribution from CivicSpace requires 24MB of memory so you may have to experiment with what memory value works for your needs.

Fatal error: Call to undefined function
This is almost always a symptom of version problems with a contrib module (or theme) This is most often seen in form functions -undefined function: form_*() but could result from any missed upgrade step listed in the module developers upgrade notes which lists the deprecated functions, but most likely means you have installed the wrong version of the module (or that a compatable version doesn’t exist yet). You may find that turning on legacy.module will support a few of the older (deprecated) functions that the troublesome module is trying to call.

Fatal error: Call to undefined function: form_*() on Drupal 4.7
After installing a module on Drupal 4.7 you get the error: Fatal error: Call to undefined function: form_*() in [module_path] This error usually occurs on the modules settings page, but also on other module pages containing forms. Most likely cause: the module is specific for Drupal version 4.6. The way forms are created changed completely in version 4.7. This new forms API means that all former form_* functions such as form_checkbox, form_select and form_submit, are no longer available. Solution: You need to download a 4.7 specific version of the module in question. If the module isn’t available for 4.7 you might want to try the version marked as "CVS". If that one does give the same error you should try to update it yourself. For easy forms you can use

426

3 Aug 2007

Drupal Handbook

formupdater.module. An online version of this is available here: http://lullabot.com/formupdater If you succeed in converting the module you should send it to the author so that he can upload it for others to download. You may also get this error if you use php snippets in pages or blocks that display forms. Disable such snippets before upgrading.

Fatal error: Cannot redeclare blah_function() in ../modules/blah.module
Usually seen on the admin/modules page, the admin/themes page, or after modifying module or theme files. As the error say, you have duplicate function declaration. Most common cause seems to be : On the modules page and themes page, (themes/*/*.theme) is evaluated once each. EVERY file in themes/*/*.module

If you (or someone) tried making their own module by copying an existing directory (which is the correct step 1) but failed to rename every function inside the files to their new theme name (which is the neccessary step 2) you’ll get this error. Go in and physically remove/move the module/theme files you don’t use out of the modules/themes directory. Try to "find in files" for that funcname listed in the errors and see where the dupe is. Even just having a backup called "Copy of troublesome.module" Is illegal, as the dir scan returns it as another available theme. It gets evaluated, then conflicts with the original. Rename it to troublesome.module.bak instead This error can also arise if two different module installs choose to use and bundle the same third party library. This is pretty rare. Do the find-in-files to identify the problem, and enquire with the respective module projects. PS - NEVER have a module the same name as a theme!

Forgotten your Drupal account password
When you forgot your Drupal account password for user 1 (the administrator) and the email notification doesn’t work, you can still set the password via a database query.

427

Drupal Handbook

3 Aug 2007

Execute the following query on your drupal database: UPDATE ‘users‘ SET pass = MD5(’newpwd’) WHERE uid=1; Of course, change ’newpwd’ to the password you want.

Forum overview stopped working
Following a problem of the forum overview stopped working (missing vocab after disabling, deleting, re-enabling the module as described here When the forum module is first enabled, it creates a vocabulary of its own (called Forum) where it stores half its structure. If for any reason this vocabulary is deleted (like you decide you don’t want forums yet, or you’re working on an unstable development site) re-enabling the module will not correctly re-create the needed vocab again Thus, you end up with only half a working forum. It seems you can post topics, but the indexing and overview pages are a bit scrambled, and don’t list anything useful. (Just remaking a new ’Forum’ vocabulary manually will not work.)

The Fix
... is to tell the forum module to forget its old invalid vocabulary id and make a new one. Short answer is this code needs to run: <?php variable_del(’forum_nav_vocabulary’); ?> I use the devel.module, which provides a console where I popped this line, and a variable viewer which showed me what happened, but another quick way is: Create new node (don’t save) Set content to php code. Disable wysiwyg if needed Paste the above in the body Preview the php code will execute, although you won’t see anything yet. discard the node, don’t need to save it. visit admin/forums this triggers the forum code to check if its parameters are correct. they are not so it will create the Forum vocab as needed

428

3 Aug 2007

Drupal Handbook

continue, create a new forum or container. The pages should work again as they are supposed to.

FTP uploads and file permissions using Transmit
Transmit has the capability to change the permissions of a file as it uploads it to your server. Make sure the check-box "Auto-set my permissions" is unchecked. Typically, Drupal (all versions) like to have most of their files at octal 755 or 775. If you accidentally have Transmit set to change things to 644 or something similar, your newly-uploaded Drupal site will not work.

Help! I enabled a buggy module and now I can’t disable it!
A situation can arise where you’ve enabled a module through administer >> modules, but then because of a fatal error of some kind cannot get back to administer >> modules to disable it (sometimes you cannot access any pages of your site at all) -- only the error is displayed and nothing else. This can be resolved by executing the following query in the database: UPDATE ‘system‘ SET ‘status‘ = ’0’ WHERE ‘name‘ = ’module_name’ LIMIT 1; This will disable the module so that you can access your administration panel again.

How can I adminstrate my navigation on my Drupal site? (version 4.5 or older)
A lot of questions come up about how navigation on drupal can be modified, tweaked, altered or any other synonym. The theme: example, Internet explorer, Netscape, Opera, Lynx has two Navigation block that look like this (assuming you have managed to add link ’Mypage’ there by defining a ’page’): will show: * Navigation * home * news feeds * archives * blogs * books * forums * My Page * polls

429

Drupal Handbook

3 Aug 2007

* search but also: Navigation * create content * recent posts * news aggregator Where the second one (create content etc.) changes its name to name of the user after the user logs in. Themes: marvin and unconed have no generic navigation block but has the same links in the menu on the top of the page. Other themes do not have any version of generic navigation block. In the poast drupal used to have a , what I call "functional navigation". Each module -each function- could add a link to a general list of links. That list could then be displayed anywhere in drupal. The list has only one level. so sub-elements were not possible. For most of the CMS powered sites a functional navigation is the best method of navigation: forums, blogs etc all have their own specific content-display and content navigation, based on their function. But as of drupal 4.3 people started inventing all sorts of navigation modules. These modules would use tabs, blocks, or even hardcoded (D)html to make the navigation easy. So in drupal 4.4 there was a general, standard "navigation" block introduced. But this one was not configurable. Only modules could add items in that block. So as of 4.5RC JonBob together with lots of others came up with a nice menu system, fully configurable, with permissions and of course multi-levelled (as was the previous too). Q: I like the first, generic Navigation block but most of the themes do not display it, even after I enable Navigation block in the configuration of blocks. A: The links list is still present in drupal, even in 4.5. You can print a list of linkes using for example: <?php $output .= theme("links", link_page(), " " :: " ); ?> the list will then be something like blogs :: forum :: mypage :: weblinks Not all themes use this function. In fact, nowadays only very few do. So you will need to add this manually somwhere. For example in a custommade sideblock you can say:

430

3 Aug 2007

Drupal Handbook

<?php return $output .= theme("links", link_page() "<br />" ); ?> Please refer to the documentation on drupal.org about printing vs returning in blocks. This is different in some releases of drupal! Q: What does the Navigation block in block config refer to? (which block displayed above is THE navigation block?) A: That is the default drupal navigation blok. It offers multi-levelled navigation. It is also a place where some modules place their navigation too (event.module for example). You can disable this block, but you will then not be able to get into your adminstration, other than typing in the urls by hand. So be carefull! Q: Where is the first (generic) Navigation block defined? What to look for if I want to add it to my theme? I like xtemplate so far so that’s where I would like to have the generic navigation block. A: That is an implementaion of <?php print $output .= theme("links", link_page() "<br />" ); //Or something very similar ?>

How do I get rid of the "Welcome to your new Drupal website" on the front page?
If you are seeing this message it is because your front page is set to ’node’ and you have no content promoted to the front page. To fix this, you either need to (1) promote something or (2) change your front page. (1) Edit a node (or create a new node) and click the arrow next to "Publishing Options" to expand that section. There is a checkbox labled "Promoted to front page". If you check that and (re)submit the node it will show up on the front page and the welcome message will disappear. (2) By default, the front page of your site is ’node’, which is a list of all nodes that have been promoted to the front page as explained in (1). If you don’t like this, you can change your front page to any page you like. To do this, go to www.yourdomain.com/admin/settings and click the arrow next to ’General settings’ to expand that section. Towards the bottom, you will see ’Default front page’. If it’s still at the default, it will be ’node’. Change this to the page you would like to be your front page. That is, the page that loads when you go to www.yourdomain.com. For example, if you want people to go straight to the blogs, you would put ’blog’ in that setting.

431

Drupal Handbook

3 Aug 2007

This message is hard coded into the program files so, at this time, it is not possible to have your front page set to ’node’, have no nodes promoted, and not have this message without changing the source code. A work-around can be found here: http://drupal.org/node/30816#comment-53200 .

How do I get the Navigation block back
A common question in the forums, is you disable a block without realizing the implications of what it does. For instance the main menu/navigation block. Visit http://www.example.com/?q=admin/build/block to change block settings. Visit http://www.example.com/?q=admin/build/menu to change menu items.

How do I unset the clean URLs?
After enabling the clean urls in configuration all content is inaccessible, because the system you run drupal on, does not support (all) clean urls. Clean urls are those fancy looking addresses: instead of www.example.com/?q=/foo/bar you see www.example.com/foo/bar with clean urls. Problem is that you cannot set it back, because you cannot browse to the specific page anymore. There are two solutions: The first one is very handy if you have mysql access. Run the mysql command: UPDATE variable SET value = ’s:1:"0";’ WHERE name = ’clean_url’; DELETE FROM cache; Alternatively, you can modify the appropriate settings.php file: you should add the line $conf[’clean_url’] = 0; somewhere in this file. NOTE: Drupal 4.6 has added the ability to detect whether your site is capable of running with clean url’s. If the option to turn them on is greyed out, then you will be unable to activate it until you resolve the underlying issue. NOTE: In some situations you can navigate to http://example.com/?q=admin/settings and disable it there.

How to login once you have turned your site off-line for maintenance

432

3 Aug 2007

Drupal Handbook

Once you have turned your site off-line using maintenance(admin/settings), you can log back in by visiting: http://example.com/?q=user Note: Use the literal word user, not your username or user id.

admin

»

settings

»

site

You need to enter the username and password of an account with permission to administer site configuration. User 1 has this ability as a safety net, should you not have this turned on in other administrator account(s). If you attempted to login with a username that does not have the "administer site configuration" permission you will be stuck in that user account until you clear the browser’s cookies. Simply instruct your browser to delete cookies for the site and visit the referenced URL above again. You can also use another browser to access the URL. To return the site to online mode visit the following page: Drupal 4: administer » settings (admin/settings) Drupal 5: Administer » Site configuration » Site maintenance (admin/settings/site-maintenance). On the page, set Site status to Online. If you are truly desperate you can try the following database queries to restore access: UPDATE variable SET value = ’s:1:"0";’ WHERE name= ’site_offline’; DELETE FROM cache WHERE cid = ’variables’;

HOWTO: Download a fresh copy of a missing or corrupted module/image/file
Thanks to revision control, you can download any file from any version of Drupal from 3.0 onwards by using the ViewCVS server. 1. Go to http://cvs.drupal.org/ . You should see something looking similar to a folder listing. 2. Click on the drupal folder. 3. Click the Select Branch dropdown next to Show files using tag: and select the appropriate DRUPAL-X-Y-Z tag in the Non-branch tags section. The file index will change to a view of the files from that release. 4. Browse to the appropriate folder. (Ignore any empty folders. Due to the way CVS stores information, you may come across empty folders that didn’t actually exist for your release.) 5. Click the dotted number in the Rev. column for the file you need. This will show a preview of the file. 6. Right click the download link and choose Save Target As.... 7. Make sure the file type is set to All Files. Browse to the desired location on your disk and press Save.

433

Drupal Handbook

3 Aug 2007

You should now have a fresh copy of the missing or corrupted file.

Installation/configuration
406 Error when XMLRPC is used
Some hosting providers (at least one!) may disable xmlrpc.php scripts to plug security holes in older versions of the XMLRPC libraries. If you’ve installed Drupal and enabled the BlogAPI module or the Drupal login module on such a provider, you’ll get "406 errors" when you try to use the features. One possible solution (aside from convincing your provider to turn the relatively ineffective security measure off) is to rename the xmlrpc.php file in drupal’s main directory. While this is bad and will make upgrading a bit of a hassle, it can get you up and running. You’ll have to alter blogapi.module to point to the newly renamed file, as well as any other modules that point to xmlrpc.php. In the case of blogapi.module, the reference can be found on line 560: 560: $xmlrpc = $base_url .’/’. ’xmlrpc.php’;

Junk {head} {styles} codes as output
Symptom: When visiting your Drupal site for the first time you see what looks like code output, instead of the expected theme: {head} {styles} {_BLOCK_.header.logo} {_BLOCK_.header.site_name} {secondary_links} {primary_links} {_BLOCK_.header.blocks} This chunk of code is followed by the standard welcome message. Cause: Changes made after 4.6.x was released in PHP 5.0.5+/5.1.1+ and the template engine XTemplate are incompatible. The quickest solution is to go to http://www.example.com/?q=admin/themes and change the default theme to Chameleon or Marvin. Before you can change the theme you’ll need to be logged in. Either create the first account or login at http://www.example.com/?q=user.

434

3 Aug 2007

Drupal Handbook

Another solution is to switch to a PHPTemplate based theme. PHPTemplate is another theme engine, which will become the default in Drupal 4.7 anyway. You will need to download and install PHPTemplate before you can use themes that depend on it. Make sure to disable all XTemplate themes to prevent visitors from using them. Drupal 4.6 comes with two XTemplate themes included: Bluemarine and Pushbutton. A PHPTemplate version of Bluemarine is available. Primary/Secondary links configured in the theme general settings will not carry over to PHPTemplate. You will need to re-configure any Primary/Secondary links in the PHPTemplate configuration of the theme.

Login after disabling the User login block
If you disabled the User login block and need to login, you can visit the login page on: http://example.com/?q=user The alternative http://example.com/user will only work when clean URLs are enabled. Note: Use the literal word user, not your username or user id.

Login doesn’t work or must be done twice
There are at least two possible reasons why you can experience a symptom of "Visit the site, login, and while the username and password are correct the user does not appear to be logged in."

Cookies
Make sure cookies are enabled in your browser.

Cache Problems
It seems that sometimes the cache doesn’t get updated when logging into a site so even after logging in the user is still shown the cached version of the site: not logged in. The source of this problem (browser, webserver, Drupal settings) is not completely understood. One solution seems to be to disable the Drupal cache of the site, though that has the undesired side effect of increasing the load on your site. Another workaround is for the users to hit the browser refersh button which seems to work fairly well, but has the drawback of not being easily discoverable and is a hassle for every user of the site. On a site where only one or two users login, this is not a problem. On a community site it is a bigger problem.

435

Drupal Handbook

3 Aug 2007

For the next version of Drupal - the problem is fixed as a result of this issue.

Logging in at www on a site with no www in the baseurl
This problem is more easily understood and fixed. If a site is set with http://example.com as the base URL and the user types www.example.com into his URL then he will still be presented the main page. When the user uses the login block to login then Drupal will send them a cookie with www.example.com as the domain and will forward the user to http://example.com where the cookie will not be valid and the user will not be logged in. One solution to this problem is to configure your server so that the URL and the Drupal settings match perfectly. If you are using apache and .htaccess is enabled you can achieve this with an .htaccess rewrite directive inside of the "Various rewrite rules" section: RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC] RewriteRule ^(.*)$ http://example.com/$1 [R=301,L] While the example has always been to remove the www, the problem and this solution can be reversed for adding www. This second issue has been fixed for the "next" version of Drupal in this issue

Login problems on PHP 5.2
This problem manifests itself when visiting a new page after login; the system seemingly forgets that the user has already logged in. This problem occurs due to the way PHP handles objects in session handlers. It effects all Drupal versions upto Drupal 4.7.4 and Drupal 5-beta 1. The best method of fixing this for Drupal 4.7.4 (and below) users is to upgrade to Drupal 4.7.5 which fixes this problem. For those wishing not to do a full upgrade yet but need in "instant fix", a patch for Drupal 4.7.4 is available on http://drupal.org/node/93945#comment-155161. See Patches » HOWTO: Apply patches for help on applying the patch. For Drupal-5 beta testers; this has been resolved since the Beta-1 release.

My layout collapses - content appears below left column (IE) or overflows over the right (FF)
This commonly happens in themes that use CSS for flexible column layouts. First, please Validate your page and fix all the problems you can. Use the web developer toolbar to validate local pages.
More on validation below.

436

3 Aug 2007

Drupal Handbook

The most common problem is:

The content is too wide for the space it’s been given
What’s a poor robot to do? If you tell a robot to push 1130 pixels into a bag that only holds 1000 - something’s gonna break. Overlap or overflow are the only things the page renderer can do. (There is currently no supported ’shrink to fit’ option, and ’expand to fit’ isn’t available in current versions of CSS.) This is often seen in pages that embed tables, objects (like Flash) or large images that are of fixed-width and end up making the content column (plus sidebars) wider than the available screen space. With percentage-width themes, the available space will depend on browser window size, which you cannot control. CSS work-arounds abound, but the first solution is to shrink your content if at all possible. This is especially easy if you’ve pasted in a fixed-with table. Just remove the width attribute. Another approach is it apply #content{overflow:auto;} on your css. This results in a scrollbar in the middle of your page when the content forces it, and is not always very nice-looking, but it’s better than the alternatives. #content{overflow:hidden;} also works, is safer on your design, and looks better (maybe) but may hurt accessibility slightly. You can try #content{min-width:450px;} and similar fixes, but you’ll need to browser-test. Any suggestions on getting this right are welcome. Last resort - if you would rather the page always expand to fit your content - and trigger browser scroll bars at lower resolution - is switch to an old-fashioned table-based layout. If CSS is too hard for you, you may have to give up on tableless design. OTOH, if you are keen, alternative fixes are always being proposed over at alistapart.com and CSS3 apparently will make this dilemma solvable.

Validation Woes
While validation is The Right Thing to do, some warnings/errors are important, some less so. In general: document type does not allow element "div" here; (inside a P) - may have side effects, but is probably non-fatal. It’s because of the way some themes, or the line-break converter place extra (block-level) markup inside paragraphs - which is not technically right. Can ignore. end tag for element "..." which is not open. Possibly related to the above. Fix it if possible

437

Drupal Handbook

3 Aug 2007

there is no attribute ... or required attribute ... not specified. OK to ignore. or end tag for "..." omitted, but OMITTAG NO was specified Likely to be a sign of layout problems. If the end of a DIV or a TABLE (or other block-type tags) is missing this will probably be very bad and needs fixing. Traditionally seen in badly cropped teasers that try to display the top half of a table. an attribute value specification must be an attribute value literal unless SHORTTAG YES is specified. Fix it if possible, but probably safe to ignore. cannot generate system identifier for general entity ... or reference to entity "..." for which no system identifier could be generated. OK to ignore. For more CSS troubleshooting, try the instructions for using the CSS inspector to find the active styles and go from there.

Mysterious 403, 404, 406 or 500 errors depending on submitted content
When submitting certain words in content, you receive a 403, 404, 406 or 500 error message. This behaviour is most likely caused by the Apache module mod_security. Depending on its filter settings, phrases that trip the module include lynx, perl, mother, select from, table, cc:, and many more. Ask your host to tone down the mod_security settings. Alternatively you can try to add the following to .htaccess: # Turn off mod_security filtering. <IfModule mod_security.c> SecFilterEngine Off </IfModule> This will turn off filtering by mod_security. Not all hosts will allow this, so you may need to contact your hosting provider.

Permission denied in includes/file.inc
This describeds an error which may occur with to Drupal 4.5.2. The details for other versions may differ.

438

3 Aug 2007

Drupal Handbook

http://www.example.com/?q=admin/settings might yield error messages like this: warning: mkdir(files): Permission denied in /data/www/public/includes/file.inc on line 77. warning: mkdir(files/tmp): No such file or directory in /usr/data/www/public/includes/file.inc on line 77. This means that Drupal needs write access to create (and later access) the files and files/tmp directories. One way to solve this is to give the webserver write access in the directory. Another common solution seems to be granting everybody write access to the "files" directory. Both solutions has the drawback that somebody else is able to write files into that directory. [if you know a better solution, please mention it here] Solution 1 (recommended) In the drupal root directory: mkdir -p files/tmp chown -R www files Note: you may need to substitute www with the user id of your webserver process. Solution 2 In the drupal root directory: mkdir -p files/tmp chmod -R 777 files

Persistent ’Welcome to Drupal’ for anonymous users
When anonymous users see the ’Welcome to Drupal’ message on the frontpage (?q=node) even though you have promoted nodes to the frontpage, you may experience an access problem. This is usually the result of uninstalling an access module* without disabling it properly. First, you have to exclude other possible causes. Make sure: anonymous users have ’access content’ permission a node has been promoted to the front page OR you have set the front page path on the settings page If the above conditions have been met, you may use the following SQL queries to reset the node_access table. You can run these from the command line or in phpmyadmin by clicking on the SQL tab of your right hand pane and pasting the querries into the text area, then clicking go. Warning: the following SQL queries will reset the entire node access table: TRUNCATE node_access; This query deletes all access rules. The next query grants the ’view’ permission to all nodes. INSERT INTO node_access (nid, gid, realm, grant_view, grant_update, grant_delete) VALUES (0, 0, ’all’, 1, 0, 0);

439

Drupal Handbook

3 Aug 2007

* For example: taxonomy access, organic groups, nodeprivacy by role, simple access

phpinfo
On occassion it is useful to see what your php settings are. You can create a php page using phpinfo() function from within your own Drupal install if you can create php type content. This is probably not a page you want to leave permanently but can be useful for finding specific information. http://us3.php.net/phpinfo Create a page of php content type and copy and paste the following line in it. <?php phpinfo(); ?> It will probably mess up your sites formatting.

Plain unstyled HTML output
If your site appears as plain HTML with missing styles and/or images there are two main reasons: 1) You are trying to use a theme that is not active. This can happen when you have set the default theme in settings.php but that theme has not yet been added or configured. It can also occur when did not switch back to the default theme before upgrade. To fix that issue, go to admin > build > themes and select the default theme (Garland in 5.x and Bluemarine in 4.7 and 4.6). 2) Your $base_url setting (in your settings.php file) is misconfigured. The $base_url setting is what gets prepended to all paths for extra resources like stylesheets, images, javascript includes and form handlers. If the browser can’t find those resources on that path, then they will be missing from the rendered HTML you see in your browser. example: When developing and testing on a local Drupal version you might use localhost in your $base_url. This works fine when using the browser on the development computer, but when you access Drupal from another computer all these extra resources are missing. What is happening is that browser on the other computer is trying to access these extra resources from localhost and failing to find them there. The solution is to change $base_url to use a hostname that points to Drupal from both computers (ie not localhost).

440

3 Aug 2007

Drupal Handbook

Setting up Clean URLs
You put AllowOverride into the apache config for your server (ususally httpd.conf). Here is an example: ServerAdmin webmaster@example.com # DocumentRoot /home/example/http DocumentRoot /home/example/drupal Options +FollowSymLinks +Includes ServerName old.example.com ServerAlias www.old.example.com ErrorLog /var/log/apache/old.lexample.com-error.log CustomLog /var/log/apache/old.example.com-access.log common AllowOverride All Next fix up the .htaccess in /home/example as follows: RewriteEngine on # Modify the RewriteBase if you are using Drupal in a subdirectory and # the rewrite rules are not working properly. #RewriteBase / RewriteBase /home/example/drupal # Rewrite old-style URLs of the form ’node.php?id=x’. #RewriteCond %{REQUEST_FILENAME} !-f #RewriteCond %{REQUEST_FILENAME} !-d #RewriteCond %{QUERY_STRING} ^id=([^&]+)$ #RewriteRule node.php index.php?q=node/view/%1 [L] # Rewrite old-style URLs of the form ’module.php?mod=x’. #RewriteCond %{REQUEST_FILENAME} !-f #RewriteCond %{REQUEST_FILENAME} !-d #RewriteCond %{QUERY_STRING} ^mod=([^&]+)$ #RewriteRule module.php index.php?q=%1 [L] # Rewrite current-style URLs of the form ’index.php?q=x’. RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d # RewriteCond %{REQUEST_FILENAME} !^index.php RewriteRule ^(.*)$ /index.php?q=$1 [L,QSA] NOTE: the change to the last rule above. Without it you may get odd results similar to what is reported in http://drupal.org/node/54417. Do read the handbooks too.

441

Drupal Handbook

3 Aug 2007

Lastly reload your http server.

unblocking account through SQL
Say you accidently ’block’ your admin account and cannot log in. From with in a MySQL client you can run this command to unblock it update user set status = 1 where uid = 1;

Weird behaviour - module-theme name collision
When someone is building a custom site it can happen that same name module and theme are being developed. This results in very weird behaviour from Drupal’s side: overriding hooks can make your blocks disappear, print $content returns only ’array’, hence disappearing admin interfaces which force us to alter the database to get back on track. Now we have to find out how to remove the new theme and switch back to an old one. We are lazy people, moreover our site is big, with lots of content, so reinstalling is not an option. I tested this with mysql, so these hints are for mysql only. Dump your database first, and save it somewhere safe so we have a backup. We are going to edit the dumped records, and reinsert the database. I used this method because using my favourite editor is way easier and safer than using mysql shell (anyway we shouldn’t edit a live site database). The theme name is registered in the following tables in your database: system, variables and block. After many tries I realised I have to clear the cache manually, meaning to remove all the INSERT INTO ‘cache_‘ lines in order to see results. Change the ’default_theme’ value in ‘system‘, where note that ’s’ stands for string length, so be sure you put the string length after the ’s:’. Also make sure you change the value to an existing theme (available themes listed in ‘system‘). And remove, or rename your troublemaker theme. The change in ‘block‘ is imperative, otherwise the blocks will not appear. Drop your old database from the sql server and insert the edited one. Voila, we have recovered from a theme crash.

Where is the taxonomy choice when adding content?
http://drupal.org/node/31156 --> Q: Where is the taxonomy choice when adding content?

442

3 Aug 2007

Drupal Handbook

A: Most likely, you need to assign a taxonomy vocabulary to the content type. You’ve just created a taxonomy and filled it with a perfect array of terms. But there’s no category menu on the post submission page! What gives? You’ve forgotten a critical step: Assigning your taxonomy to a content type. Go to (administer > categories > edit vocabulary) and look under the "Types" heading. There you can assign your taxonomy to any content types you want. Save your configuration here, and try to submit a post. Your taxonomy should now be available to you.

Miscellaneous
How can I change Drupal’s character encoding? (UTF-8 and Unicode)
Several people have asked how to specify the character encoding that Drupal uses. The short answer is: you can’t, but you don’t have to. Drupal uses UTF-8 for encoding all its data. This is a Unicode encoding, so it can contain data in any language. You no longer need to worry about language specific encodings for your website (such as Big5, GB2312, Windows-1251 or 1256, ...). Also, when Drupal imports external XML data (such as RSS or XML-RPC), it is automatically converted into UTF-8 (iconv support for PHP will be required for most encodings). If you really want to change Drupal’s encoding, you will experience a lot of troubles, because of the various ways Drupal can receive and send out data (web, e-mail, RSS, XML-RPC, etc).

443