Drupal Notes

Here are the steps for getting Drupal up and running.

  • Reserve a domain name
  • Assign it in the Control Panel in BlueHost.  Use a folder name matching the domain.
  • Download the latest Drupal (6.14 at this writing) and upload it into the folder.
  • Copy the file [DOMAIN FOLDER]/sites/default/default.settings.php file to [DOMAIN_FOLDER]/sites/default/settings.php.
  • Create a new database in the BlueHost database manager.  Name it the same as the domain name.  Keep in mind that when you create a database, it is automatically prefixed with the account name, in this case tamaraco_
  • Also create a user.  The username should be the same as the domain.  Use the short net password.
  • Next assign the new user to the new database.  Give the user all privileges.  Notice that the username is also prefixed with the parent domain.
  • Hit the URL and Drupal should show up.
  • When you get to the database part, just enter in the info and remember to prefix everything with the parent domain.

Here is what I did to configure it.

  • TURN OFF THE ABILITY FOR USERS TO REGISTER!!!!
  • Enable the path module.
  • Turn off the 'Powered by Drupal' block under Admin / Blocks
  • Add the ImageAPI module
  • Add the ImageCache module (comes with ImageCacheUI)
  • Add the WYSIWYG Module
  • Add the IMCE WYSIWYG Bridge Module
  • Add the IMCE Module
  • Go to Home >> Administer >> Site configuration >> Wysiwyg and download and install TinyMCE.  Reload the page and then choose TinyMCE for Full HTML.  Then go to Home >> Administer >> Site configuration >> Input formats and set the Full HTML to be the default format type.
  • This video blog entry explains the profiles, and settings for IMCE.
  • Add the Devel module and also the Theme Developer module.  These are clutch!
  • If you want to be able to add PHP in your pages, Goto: Administer > Site building > Modules 'Core-optional' subsection.
  • The transliteration module is a MUST have for converting filenames that have spaces and other freaky characters in them

Apache stuff

  • Add this to the root .htaccess file to show any errors rather than the "White Screen of Death" php_value display_errors
  • Also increase the max file upload file size if you need for users to be able to upload files, especially bigger ones.
  • Configure php.ini in the html root and bump up the memory.  I actually had to do this at the domain root level, in other words, I couldn't do it globally for all of my sites, I had to put a php.ini file in the web root of each project.

CRON

  • go to bluehost cpanel and find your home directory on the left, copy that.
  • go to the advanced section and click on cron.
  • add a cron job like this php -q /home/YOUR-SITE/public_html/cron.php
  • note that the home directory is different on different accounts.

Links

Moving Drupal

  • http://drupal.org/node/1654
  • Just did a Drupal move but it was to an IP Address with a subdirectory.  This caused Apache to not properly intercept URLs because Drupal wasn't at the root.  The trick to get this site up and running temporarily was to go into .htaccess and set   RewriteBase /~galaxypa where ~galaxypa was the name of the directory.
  • I also ran update.php which seemed to help.  I set the $update_free_access = TRUE; in settings.php so that I could run that without being logged in.

Performance

  • Make sure that you go into the performance tab and enable caching, at least at the normal level.
  • Consider using boost for bigger sites that require performance.  Click here to check out a nice video that covers the basics of installing and configuring boost.
  • Here is a good article comparing some different Drupal setups with APC, PHP 4 vs PHP 5, etc.
  • Here is a good blog on performance, especially MySQL.  I think this guy is the dev for Drupal.
  • Turn on CSS aggregation.  As an added bonus, IE 6 will not allow more than 31 style sheets and Drupal is often CSS heavy so this will solve that problem.

Bugs

Ideas

  • This article has 16 clones you can build with Drupal, e.g. Digg
  • Here is a video that shows how you could build Base Camp using Drupal

CCK

  • This article discusses how you can create your own compound fields for CCK
  • When to use CCK vs Taxonomy
  • Huge problems with Date import on CCK.  Had to do a few things.  One, switch to select boxes for editor type.  Two, make sure you have rc4 on node_import.  Three, download the patch from comment 89 and install it into sites/all/modules/node_import/supported/date/date.inc.  Lastly, make sure your validation settings on the date will support all the data fields you're uploading.
  • Here are some tips on theming CCK fields from within a template tpl file

Panels

Debugging

  • dprint_r is a PHP method for displaying a nested variable
  • dpm($obj) is a Drupal method for showing a message given an object
  • here is a script for bootstrapping Drupal

SEO

  • This is a good article containing top ranking points for Google

Security

Synchronization between prod and dev

  • This article gives background on the primary key solution and some Toad queries.

Templating

  • Nice article discussing using templaets based on path, taxonomy etc.  This is multiple pages.
  • Discussion that covers creating a node template for a single node

Menus

  • Good article on Menus.  Menu Block. etc. 
  • Decent article on taxonomy menus (at the bottom).
  • Good article on implementing tertiary menus with one line of code
  • When using Menu Trails, go to Blocks | Add Menu Block.  Set the menu to Primary Links, Item to <root of primary links>, and then set the starting level to 3.  Also make sure you check the visibility on the blocks because last time I did it defaulted to 'show only on the following pages'.
  • Pathauto gives you URL paths from tokens.  I like the setting that follows the content path.  [menupath-raw]
  • Short article about using PathAuto to create paths on taxonomy

Images

  • Good behind the scenes article on how ImageCache workds

Zen Theme

  • Grab Zen and follow manuals for creating a subtheme.
  • Swap out the logo.png and the favicon.ico
  • go into layout-fixed.css and setup sidebar sizes

Theming

function yourmodule_nodeapi($node, $op, $teaser = NULL, $page = NULL) {
  switch ($op) {
    case 'view':
      drupal_add_css(drupal_get_path('module', 'yourmodule') . '/css/yourmodule_style.css');
      drupal_add_js(drupal_get_path('module', 'yourmodule') . '/js/yourmodule.js');
      break;
  }
}

Views

  • In order to reference another field it has to be listed ahead of the field you are working with
  • The View Type option you get when you create a View specifies the table that a select query will run against
  • Use the distinct flag on the base props to limit the results to distinct rows
  • Interesting article about how to create Term Views that map to some specific URL
  • This is a great tutorial that shows you how to create a Node Reference CCK field that points to a custom block.  Views are then used to show the related blocks.
  • Here is a cool technique for getting multiple views on the same page without coding.  Here's how you find the display id.
  • If you have a text field with a list of 'allowed values' you provided when building the content type then there will be two fields listed when you choose that field for views.  One will be the field name and the other will be 'allowed values'.  If you want the allowed values you put into the content type in the exposed filter then you have to select the 'allowed values' version of the field when adding it to the filters.  This is what gives you the select / combo box in the exposed filter.

Running Drupal Locally

  • PHP 5.3 and Drupal 6 don't get along.  Download WAMP, then download the php 5.2.6 addon.  You can switch WAMP to run 5.2.6 from the console.
  • if there are any other versions of PHP running on your system, chances are good that WAMP won't work.  You will probably need to kill them.
  • Create a new DB using PHPMyAdmin from the WAMP console
  • To add a new user to the database...
  • CREATE USER 's1'@'localhost' IDENTIFIED BY 'password';
    GRANT ALL ON *.* TO 's2'@'localhost';
  • Enable clean URLs from WAMP console Apache -> Apache Modules -> rewrite_module

Drush

  • Drush was a pain to get up and running.  Follow the docs to install the GnuWin32 stuff.  Use the installers so that the DLLs get registered.
  • This is my drush.bat file -> @c:\native\wamp\bin\php\php5.2.6\php.exe drush.php -l http://localhost/s1 -r c:\native\wamp\www\s1 %1 %2 %3 %4 %5 %6 %7 %8 %9
  • Still not sure what I did to get through the errors I had.  I did install PEAR but not sure if that's what fixed it. May try this articleThis one had good info too.
  • To download core type drush dl drupal-6.16 and the core will be downloaded and unzipped into the current folder
  • Zenophile has support for Drush.  Check here

Files

  • Drupal method for getting the path to the files directory file_directory_path()
  • Absolute path to the Drupal server root, $_SERVER['DOCUMENT_ROOT']
  • Drupal method for getting the path to the Drupal installation base_path()

Nice Way to Views page have multiple tabs

  • Create a view page and set the menu item to be a tab
  • Create a second view page and set the menu item to be a tab
  • Add this code in the header

<?php drupal_set_message('Please note, this page is under development and will currently display all business units', 'warning');?>
<a href="/my-account">My Tasks</a> | <a href="/my-account/my-business-units" style="color: grey">My Business Units</a><br/>
<?php global $user; ?>
<h3>All Activity in My Business Units:</h3>

Rules

  • Nice page on editorial workflows using Rules

Get a List Modules Running

$result = db_query("SELECT * FROM {system} WHERE type = 'module' and status = 1" );
while ( $module = db_fetch_object($result) ) {
  $version = 'unknown';
  if ( preg_match('/"(6.x-[^"]+)/', $module->info, $matches) ) {
    $version = $matches[1];
  } else if ( preg_match('/Core - Required/i', $module->info) ) {
    $version = 'Core Required';
  } else if ( preg_match('/Core - Optional/i', $module->info) ) {
    $version = 'Core Required';
  }
  print $module->name . "\t" . $version . "\t" . $module->info . "\n";
}

Go Through All of the Nodes in the System

$result = db_query("SELECT * FROM {node}");
$i = 0;
$dups = array();
while ( $n = db_fetch_object($result) ) {
  //print_r($n);
  $node = node_load($n->nid);
  //print_r($node);
  //print_r($node->field_legacy_url);
  $lurl = $node->field_legacy_url[0]['url'];
  if ( ! empty($lurl) ) {
    $exists = array_key_exists($lurl, $dups);
    print $exists . "\t" . $node->nid . "\t" . $node->title . "\t" . $node->field_legacy_url[0]['url'] . "\n";
    $dups[$lurl] = TRUE;
  }
  $i++;
}

Print All Node Ids on Body preg_match

$result = db_query("SELECT * FROM {node}");
$i = 0;
$recs = array();
$dups = array();
while ( $n = db_fetch_object($result) ) {
  //print_r($n);
  $node = node_load($n->nid);
  if ( preg_match('|http://ing-content.thesupergroup.com/sites/ing-content.thesupergroup.com/files|', $node->body) ) {
    print 'n:' . $node->nid . "\n";
  }

}

print "count=" . count($recs);

File Revision Module

Vertical Tabs Module is a backport from Drupal 7 that helps organize the edit screen better.

JQuery UI

  • Adding JQuery UI was a pain in the ass.  I added it to my theme directory and then added the following to the top of template.php.
  • drupal_add_css(path_to_theme() . '/jquery.ui/themes/default/ui.all.css', $type = 'theme', $media = 'all', $preprocess = TRUE);
  • jquery_ui_add('ui.accordion');
  • I used the $(document).ready() function to setup an accordion.  I also noticed that each version of JQuery UI has slightly different API calls so look at the demos that come with the download for the proper usage.

Form to E-mail

  • This page has a quick and dirty way to get a form to e-mail from a block.

Files

  • You can stream a file from PHP by using this code

Input Filters

  • best article I've found on input filters
  • if you need to apply input filters manually, like on fake side blocks, use check_markup('<a href="files:yoyo.img">Hello</a>', 3);  The number 3 is for the input type 'Full HTML' in this case.

Get a List of Database Tables from Exec PHP

// this will get a list of the tables, fields, and keys in drupal.  this rocks.

print_r(drupal_get_schema());

$result = db_query("show tables;");
while ( $n = db_fetch_object($result) ) {
 print_r($n);
}


Schema Dump

$q = db_query('show tables');
$tables = array();
while ($r = db_fetch_object($q)) {
  foreach ($r as $ignore => $table) {
    $tables[] = $table;
  }
}
foreach ($tables as $index => $table) {
  $q = db_query("show columns from $table");
  print "$table ==============================================\n";
  while ($r = db_fetch_object($q)) {
    print "\t" . $r->Field . "\t" . $r->Type . "  KEY=" . $r->Key . "\n";
  }
}
print_r($tables);

Modify the Latest Node Revision Programmatically

$result = db_query("SELECT n.nid, n.vid, nr.body FROM {node_revisions} nr, {node} n where nr.nid = n.nid and nr.vid = n.vid");
$violations = array();
while ( $n = db_fetch_object($result) ) {
  $matches = array();
  $new_body = $n->body;
  $node_changed = FALSE;
  $matches = array();
  if ( preg_match_all('|\s+target\s*=\s*"[^"]+"|', $n->body, $matches) ) {
//    print_r($matches);
    foreach ($matches[0] as $index => $text ) {
      print "N:" . $n->nid . " Tok=" . $text . "\n";//print_r($matches);
      $violations[$n->nid] = TRUE;
      $new_body = str_replace($text, '', $new_body);
      $node_changed = TRUE;
    }
  }
  if ( ! $node_changed ) continue;
  $node = node_load($n->nid);
  if ( $node ) {
    $node->body = $new_body;
    print $node->body;
      print "Saving node " . $n->nid . "\n";
//    node_save($node);
  } else print "ERROR NODE COULD NOT BE LOADED **********\n";
}
print_r($violations);
 

Code review module helps with code checking

Programmatically Create Nods in Drupal

Article on Generating Free Certificates