Drupal "Hacks"

Categories:

As part of the website redesign, we're adding new sections for user generated content.  We needed to keep this content separate from the rest of the site, so that any user could edit the user sections, but not the rest of the site.  For basic content types, this is simply a matter of defining a new content type based on the standard drupal "node", and then assigning the correct permissions to that new type.  But what if you want to do something similar to a more advanced content-type such as a book?  One could extend the book module to support a similar derived content feature (best solution).  But that can take a fair amount of time, and with no guarantee of changes being accepted upstream, you face the possibility of either running outdated module code, or having to reapply your edits for every update.  A quicker, and much simpler method, especially for those with little programming experience, is to make a few, essentially cosmetic changes to the book module.  These changes consist primarily of changed the names of the tables the module stores its data in, and the internal name that drupal uses to identify the module and its components.  And while your modifying, you can easily alter the human-readable names and descriptions.  And its all as easy as Find & Replace.  

The Easy Way: 

One should make a backup copy of the books module.  I would suggest creating a new directory, name it after the short, drupal id form of the content type, and place the files from the book module in this directory.  Renaming them would be a good idea too.  Then do the following in all of those files.

One could easily do a "Replace all" on "book" and "Book" with the words/identifiers you desire.  Caveats:  the word replacing book cannot have spaces, and should not have other odd characters; not starting with a number would be advisable as well.  A short word or acronym or other identifier would be preferred here.  The reason for this is that in some places "book" is being used as an identifier by Drupal, and so we must make sure that what we use will not cause the PHP or SQL to break.  In our case, we replaced it with "cnrc", since this new book will be used to provide books and book pages for the Community Networking Resource Center area of the new website.  "Book" is used only in description and such, and is not used internally by Drupal.  As such, we can replace it with whatever we want.  Just be careful of including quotation marks, either single or double, as they could be misinterpreted by PHP.  In our case we replaced it with the expanded acronym.  The plural of "book" and "Book" are sometimes used as well.  The process described above will replace the appropriate portions of these words, thus leaving the replacements with an "s" suffix.  If this is undesirable, use either a "match only whole word" feature, or replace the plural forms first.

Whats Really Going On:

 The .info file included with module contains the data that is displayed in the "Modules" section of the admin screens.  Its not important to change it, but doing so will make your life (or however assumes job of maintaining the site's life) a lot easier.   The fields here can contain pretty much any value.

The .install file contains the code responsible for installing and uninstalling the module.  Its what makes the correct tables in the database, for instance.  To truly keep the data from the various "book" modules separate, we need to make our module use a different table.  The requires editing the sql queries encapsulated in the PHP.  I also suggest renaming the function as well.  Not only does it improve clarity, it prevents naming collisions.  Drupal, at least as far as I've seen, runs in one big namespace.  Hence, all modules must provide unique function names.  The convention is to prefix the functions with the modules short (internal drupal) name.

 The .module file contains all the internal workings of the module.  The same thing about function names applies here as in the .install file.  the *_node_info function contains the base parameters (drupal name,verbose name, and description).  The variables whose values are wrapped in t(' ') will accept Unicode characters.  the "module" variable will not.  In here the paths and such are defined as well.  The find & replace method will modify these as well, thus allowing one to customize the url locations.

Motivation and Alternatives:

The redesign of the site presented us with a case wherein we might have books that only staff should be able to edit, and other books that should be open to the general public.  With the current book module, that is not possible.  I suspect one may be able to achieve similar functionality with the CCk for Drupal 5, however, I haven't had time to explore it yet.  Given my programming background, I found modifying the module much simpler than learning the quirks of a Drupal interface. 

 


Comment from Matthew Isaacs on May 9, 2007 - 12:19pm

I found a module this morning that looks like it will provide this missing access control functionality to the book content type. See http://drupal.org/project/bookexpand for more info. It just came out today, however.