January 18, 2013

Using Patch and Diff

This link has useful instructions.

$ sudo diff -ruBN registration_original.php registration_withPhone.php > ~/Desktop/registration.diff

$ sudo patch -p0 < registration.diff
- this command will make original match _withPhone

$ sudo patch -p0 -R < path/file.patch
- reverse a patch; see drupal.org for more.

Git directions:

Install Git
$sudo apt-get install git-core

$ cd to directory containing files to patch (unless header of patch lists directories below that)

$ sudo git apply [path/to/git_patch]

Posted by kkwaiser at 11:55 AM | Comments (0)

December 19, 2012

Add timeline view of datasets

The goal of this to do is to establish a graphical view of the span of various datasets.

1. Add Datetime field to Dataset:
Collection Dates|field_dataset_sample_dates|Datetime|Select List

- This field type is required by timeline. You could also modify the module itself which is probably better.

- Set Permissions for the new field (view Anonymous, edit colleague)

- Must be 1 value only (not unlimited)

2. Install Timeline

$ cd ~/sites/all/modules
$ wget http://ftp.drupal.org/files/projects/timeline-6.x-2.1.tar.gz
$ tar -xzf timeline-6.x-2.1.tar.gz
$ rm timeline-6.x-2.1.tar.gz

- Enable timeline and VBO, run update.php

3. Build VBO view (Unnecessary, Timeline is compatible with field type Date.

Content: Collected - From date Default
Content: Collected - To date Default
Content: Collection - From date Default
Content: Collection - To date Default
Node: Title Title

Content: Collected (field_beg_end_date) - From date not empty

Bulk Operations (php execute)
Default sort by node title
Uncheck preserve across pages


4. Copy dates to new field (Unnecessary, Timeline is compatible with field type Date.

$object -> field_dataset_sample_dates[0]['value'] = str_replace("T", " ", $object->field_beg_end_date[0]['value']);
$object -> field_dataset_sample_dates[0]['value2'] = str_replace("T", " ", $object->field_beg_end_date[0]['value2']);

5. Delete VBO view and module

6. Add Timeline view


Items to display

Node: Title
Content: Collection - From date Default
Content: Collection - To date Default

Node: Type = Data Set
Node: Published Yes

Page Display

7. After realizing that Timeline only works with date fields of 1 value (From/To) I am aborting this mission because that is incompatible with our data model.

Posted by kkwaiser at 09:45 AM | Comments (0)

December 18, 2012

Recurring Updates to Drupal Modules

*Highjacking my own blog post*

Patch Drupal Core
Drupal 6 doesn't like empty, required radio buttons and this causes problems when using the Conditional Fields module. The patch here, allows the form validation to ignore required, hidden and empty radio-button fields. Patch at line 700. Referencing post is here.

If, after updating WYSIWYG, the biography field when adding a new Person (/node/add/person) is autopopulated with a break tag apply this patch (at least until the editor is finally patched) to avoid the addition of
tags into blank paragraphs.
- Create a text file containing the patch (para_fix.diff)
- SFTP it into the wysiwyg root directory
- Apply it $ patch -p0 < para_fix.diff

I've heavily customized this theme so any updates should be done very carefully. Unfortunately, I haven't thought about this much and don't know what the best approach to updating it will be. Right now, I just hope no updates come out.

When new versions of this module come out the print/lib/dompdf/ folder needs to be replaced. This library allows for pages to be printed as PDF.

Another module with a library that needs to be replaced. I recommend copying the original library into the new module folder. smtp/phpmailer/

There are two changes that need to be made to biblio files everytime the module is updated:

1. Change the appears of the export links:

"Tagged to Endnote"
line 922 954
function _build_biblio_tagged_link($base, $nid) {

"RTF to RichText"
line 912 943
function _build_biblio_rtf_link($base, $nid) {

Posted by kkwaiser at 04:42 PM | Comments (0)

Copy date field values with Drupal VBO

Ugly PHP snippet follows:


$date1 = str_replace("T", " ", $object->field_beg_end_date[0]['value']);

$object -> field_dataset_sample_dates[0]['value'] = strtotime(str_replace("T", " ", $object->field_beg_end_date[0]['value']));
$object -> field_dataset_sample_dates[0]['value2'] = strtotime(str_replace("T", " ", $object->field_beg_end_date[0]['value2']));


This video gave led me to the strtotime function which shouldn't actually be used for copying to datetime fields.

VBO documentation node

Posted by kkwaiser at 04:20 PM | Comments (0)

December 06, 2012

Block user accounts via database operation

I've had problems where I want to block a 100 or more user accounts at once. This leads to a Drupal memory error. To avoid the error you need to block accounts 5 or so at-a-time (working off the admin/user/user page).

This SQL can be used to block a lot of accounts at once based on role.

UPDATE drupal_users
LEFT JOIN drupal_users_roles ON drupal_users.uid = drupal_users_roles.uid
SET drupal_users.status = 0
WHERE drupal_users_roles.rid = 8

Posted by kkwaiser at 10:06 AM | Comments (0)

Unexpected 404 Page Not Found errors Drupal 6


I was in the process of locking some old user accounts and had just logged into the database via phpMyAdmin when the site started showing 404 Errors everywhere. The menus were not populating but there were signs that the site was still able to connect to the database. I remember I hit the users table but didn't (shouldn't have) made any changes when things went awry. I'm pretty certain nothing changed on the backend but that should be considered.


FYI, I figured this out. Well, kind of. Via this page I had to run update.php. The problem was potentially related to the menu system or, prior to the freeze, I was trying to lock accounts. Operating on too many accounts at once leads to a WSOD. Possible memory error?

Posted by kkwaiser at 09:07 AM | Comments (0)

August 07, 2012

Dynamic construction of EML xml file name

There are patches available for the Views Bonus Export module to accomplish some of this. Although, it appears a bit hackish and hasn't seen any recent development.

Don't put "view-" in default export filename

- see threads linked therein

Posted by kkwaiser at 04:02 PM | Comments (0)

July 24, 2012

Fixing display of Private and Public files

Apparently FileField Stats doesn't play well with Views of type Node. Because of this, I needed to create new views for listing data files on the data set node. Here is some documentation on these Views. Once the View Panes were built, I added them to the Data Set Panel Node Template.

I have two content types with a node reference between them: [Data Set]->[Data File]. I'm also using the Node Referrer module to reverse the node reference direction. This is D6. Here are the fields of interest:

[Data Set]
Associated Data File : [field_dataset_datafile_ref] - Node Reference Type

[Data File]
Public Data File: [field_datafile_public] - FileField Type
Associated Data Set: [field_dataset_referrer] - Node Referrer Type

I want to display referenced [Data Files] on the [Data Set] node via a View that takes the NID of the [Data Set] as an argument and uses relationships to pull in a list of files from the [Data Files] nodes. I will embed this View into a Panels Node Template. Originally, I used a Node type view, but the download link fails because of previously mentioned problems.

Here's my setup:

View Type: File
Relationship 1: "Content: Public Data File Field" > Label: Public Data File
Relationship 2: "Node: Referrer" > Relationship: Public Data File > Label: Referencing Public Data Nodes > Using field: [field_dataset_datafile_ref]

Argument: "Node: Nid" > Relationship: Referencing Public Data Nodes

Content: Public Data File (field_datafile_public) > Relationship: Public Data File

Here's an example of a Data Set node displaying the file from a Data File node: http://umbs.lsa.umich.edu/research/node/8021

Posted by kkwaiser at 10:58 AM | Comments (0)

April 23, 2012

Bookmark-able searches for Drupal's Biblio module

I've noticed that searches into our bibliography don't produce a linkable URL. While there may be other ways around this, one can always add /search/[terms] to the end of the URL:


Posted by kkwaiser at 02:12 PM | Comments (0)

April 10, 2012

Incorrect path for CCK FileField

Strange bug that give an uploaded file the incorrect path for a time. To recreate:

1. Upload a file to a node. Will get a path like this:


2. Save. Path remains:


3. Now go into Edit mode. The path is now correct:


Related issues on Drupal.org

It is the fault of FileField Paths.

File name replacement pattern does not work anymore (CCK + FileField) but after second saving

Node links to original file path after creation until the node is saved again

FileField Paths 2.x (currently in internal development) is reverting back to the original method of using the CCK widgets fields to store the data instead of using the FileField Paths database table, which will fix this issue and a few others at the same time.

Agileware proposes a solution: change the module weights (how? IDK).

Hefox proposes a patch (with rave reviews).


Fixed in the dev version of FileField Paths. The stable version is now 2+ years old!!!!!!!!!

Posted by kkwaiser at 04:33 PM | Comments (0)

February 28, 2012

Loggin and communication data requests - Part 1

Relevant but related to data downloads:
Part 3, part 2 and part 1.

The goal here is to offer a contact form that will structure requests for access to private data files. Right now, I'm using the same form used by the Data Download functionality but that may need to change because the data download reuses the same information time and again and the submission content for a data request will be different than that of a data request. Capiche?

Any ways, here is where I am:

1) Added a field to data set indicating whether it is Public/Private

2) If Private, a specific Panels template is called which includes a link to the Data Download form. This link is formatted to place the dataset NID in the url because I need this in order to get the data set contact's email. The URL looks like http:/umbs.lsa.umich.edu/research/weform?id=342
3) I added a private (hidden) field to the webform with a default value of %get[id] to make it part of the submission data.
4) Enabled Webform Rules and created a rule that triggers when Data Download form is submitted *if* the data set is private.
5) Added custom php rule to create the email. Ran into asinine token related issues which frustrate me to know end!!!
6) fin

Posted by kkwaiser at 04:06 PM | Comments (0)

Logging and communicating file downloads. Part Treux

[EDIT: I had to reconfigure how files were displayed. Switching to a File type of View. See this post for more.]

If you want part 2 and part 1.

Implementation Round 2:

1) Install and enable additional modules

Squeeze - gives ability to interrupt a file download by redirecting to a Webform
Filefield Stats - gives cryptic name to file download link, allows squeeze to not fire until the file is actually clicked on (i.e., user can still view node page)
Download Stats - introduces Rules action to trigger upon file download. I will use this to send an email to the file contributor with information from the Webform

$ sudo drush dl squeeze-6.x-1.x-dev filefield_stats download_count
$ drush en squeeze filefield_stats download_count

* May need to apply this patch for Squeeze

2. Create a webform to collect use information

3. Visit update.php and Configure

- Permissions (admin/user/permissions)
Squeeze - check all for administrator, nothing else
Download Count - Check all for admin, view own download counts for Authenticated
Filefield Stats - check all for admin, nothing else

- Modules
Squeeze (admin/settings/squeeze):
Check Default for 'Show page?';
Squeeze enabled content types: Data File Data Set;
Default Squeeze form: Data Download Form;
Check Redirect back to protected page

Download Count (admin/settings/download_count):
No changes
You can disable all the new menu items though admin/build/menu-customize/navigation

Filefield Stats: no options

4. Per the Squeeze module: File fields should have 'Generic files + Stats URL [+ Download Count]' as display type

I use a View (admin/build/views/edit/datafile_list) to list files so this setting is in the Field section of the pertinent view. Change the Public file, leave Private files as is.

5. Create a Rule that will trigger upon download and send an email to the Data Set Contact
This rule should include the following conditions (custom PHP):
Is downloaded file from a Data File CT?
Does the Contact want to be downloaded when files are downloaded?

The action should do the following:
Retrieve Data Set contact information
Retrieve last webform submission for the IP of the downloading user
Package the Webform submission information into an email and send to Contact.

6. [Optional] Get this module patch taken care of for usability purposes.

7. Profit

Posted by kkwaiser at 12:26 PM | Comments (0) | TrackBack

February 21, 2012

How to force browsers to download a csv file

1) Open the .htaccess file found in the core drupal installation
2) Add this line

AddType application/octet-stream .csv

I believe I have solved this. It appears you can either set "DefaultType application/octet-stream" or enable the mime_magic module. Recommendations or opinions on these approaches are welcome. Notes follow.

Modify .htaccess


DefaultType application/octet-stream

Modify apache2.conf


DefaultType text/plain

DefaultType application/octet-stream

Restart apache

Modify httpd.conf


DefaultType application/octet-stream

Restart apache

Enable mime_magic


Enable mime_magic
$ sudo a2enmod
-> mime_magic

$ sudo /etc/init.d/apache2 restart

Disable a module:

$ sudo a2dismod
-> mime_magic
$ sudo /etc/init.d/apache2 restart

Posted by kkwaiser at 01:03 PM | Comments (0)

January 23, 2012

Tweaking the housing form

Log of changes:

Added the CSS Injector module as a way to easily style the current form:

- All fields are uniform width
- Field are larger with padding for internal text
- Required * is larger and red
- Date picker is larger

Added CCK Tweak Field to:
- change Save to Submit
- modify a few other "add another" buttons.
- Removed Preview button.

Other changes:
- Role is a drop down field
- Added javascript warning that will appear if the browser has it disabled
- Refashioned "Instructions" to include just contact and information
- Created "Travel Information" grouping, Guests is and will remain separate for technical reasons
- Under vehicle information, changed Model to Make/Model
- Moved all research questions into Research Site Use Application
- Removed Project Lead Question and hid one of the research project node reference fields.
- Implemented this patch to stop captcha errors upon pressing "add another"
- Removed "Related Links" field from Research project
- Changed UMID to University of Michigan ID

Posted by kkwaiser at 01:27 PM | Comments (0) | TrackBack

January 17, 2012

Autocomplete Widget Error

An HTTP error 0 occurred. https://umbs.lsa.umich.edu/research/autocomplete_widgets/variable/field_attribute_unit

This error started cropping up after implementing Secure Pages. The fix is here.

Posted by kkwaiser at 04:46 PM | Comments (0) | TrackBack

December 19, 2011

Lock a node from further edits by its author

Status: Impossible

Take a look at the stupid configuration mistake I was making.


Wide ranging support-post that offering nothing concrete.

Narrowly focused support-post offering something concrete but in-the-end insufficient

Is it possible to take away access from specific nodes? - sure but not in the way you want to do it.

Other stuff:

Help me!!

Workflow has the solution!!

Speaking of Workflows, inconclusive posts I love.

Cricket, cricket

As long as I'm linking to everything tangentially related to this topic.

cool api knowledge:

content_access_action_acl_revoke_access($node, $author, $settings);

Posted by kkwaiser at 04:20 PM | Comments (0) | TrackBack

Tweak REU application form

The second year for this form is coming around and of course there are items I hadn't anticipated.

1. Remove edit capabilities for authors after the form is "submitted"

- Visit admin/content/node-type/reu-application/access and remove "Edit Own" permissions. Enable node specific settings.

- Enable Workflow Access (admin/build/modules)
- Visit the workflow settings for REU Application (/admin/build/workflow/edit/1)
- Adjust Messages put across by rules

Show Message: REU Application is In Progress
Application not submitted! When you are ready to submit, click Edit and change the status from In progress to Submitted and Save your changes. Warning: You will lose edit rights up submission!

Show Message: REU Application is Submitted
Application submitted! No further changes are allowed to this application. You will be contacted when a decision regarding your application is reached. Thank you for applying!!

2. Add Year to REU application
- Default to 2011
- Use VBO to populate old applications
- Incorporate year filter into views

Posted by kkwaiser at 03:46 PM | Comments (0) | TrackBack

December 07, 2011

Optimizing Node Reference Autocomplete

Looks like the way to do this is to use a View (under advanced settings for the CCK field) that is optimized with filters and caching. Haven't tried this out though.


Something that may be more efficient in your case: Use a view to restrict the list of possible nodes instead of restricting by type. This will allow you to optimize your query by removing the ORDER BY and avoiding any sorts on the returned list.

And a suggestion from daggerhart via IRC:

additionally, you could write you own query, and use it in the view instead of the generated one (you'll have to hook into the view before it executes)

Posted by kkwaiser at 03:55 PM | Comments (0) | TrackBack

November 29, 2011

Query for Webform Submissions - Snippets

$ip = '::1';

// execute sql using db_query
$sid_sql = db_query("SELECT n.sid FROM drupal_webform_submissions n WHERE n.remote_addr = '%s' ", $ip);

// fetch database results in an array
$results = array();
while ($row = db_fetch_array($sid_sql)) $results[] = $row;

//get last sid as an array $last_sid["sid"]
$last_sid = end($results);

// query to retrieve submitted webform data
$webform_sql = db_query("SELECT data FROM drupal_webform_submitted_data n WHERE n.sid = '%s' ", $last_sid["sid"]);

// fetch database results in an array
$webform_submission = array();
while ($row = db_fetch_array($webform_sql)) $webform_submission[] = $row;

/*put $webform_submission information into message body*/


Another option
is to use a webform hook but this returns all of the submissions:

module_load_include('inc', 'webform', 'webform_submissions');
$values = webform_get_submissions($nid, null, $user->uid, 1);

Posted by kkwaiser at 03:15 PM | Comments (0) | TrackBack

November 22, 2011

Logging and communicating file downloads. Part Deux

This post is an attempted implementation of a need I've posted on previously, specifically the third point.

This approach brings in two more modules:


This module also support "squeezing" only files on webpage. I.e. user can open page, but to download any file from this page - he is asked to fill a form. To accomplish this you need to use Filefield CCK field to store files and Filefield Stats module - http://drupal.org/project/filefield_stats

Fieldfield Stats - "is a small module which provides a new formatter that outputs a special link for tracking downloads. Each download tracks the File ID, User ID, Node ID, Host IP & Referrer URI and a timestamp."

h/t: This support request
Alternative to keep an eye on.

Warning! Both of these modules are in development and appear to be D7 dead-ends. That said, the show must go onnnn.

1) Download, install, enable the two modules. Run update.php

2) Create a Webform Node to collect desired information

3) Switch the display style to: Generic files + Stats URL [+ Download Count]
- Data File content type (/admin/content/node-type/data-file/display)
- Modify the view used for Data Files within the Data Set Node Template Panel

4) Navigate to /admin/settings/squeeze
- Set Default Squeeze Form - to webform node from 2)
- Check "Default for 'Show Page'?"
- Enable for Data File and Data Setcontent type

5) Evaluate

While this works as expected, I noticed that Squeeze fires only once per user, regardless of how many nodes they download from. This is good from a usability perspective but doesn't work so well if I want to notify Data Originators when their files are downloaded. I may be able to work around this with some combination of Rules, Download Count, Webform Rules and Webform.

6) Extend further
Initial tests show that Download Count can be used to trigger rules when Public files are downloaded. Next is to use that rule to send an email to the data originator with information from the completed webform.

Posted by kkwaiser at 08:30 AM | Comments (0) | TrackBack

November 16, 2011

Enhancing Drupal Security

Fun stuff. Here are some notes.

I already plan on using an SSL certificate in conjunction with Secure Pages and Secure Pages Prevent Hijack to encrypt forms I use on the Research Gateway.

A fairly exhaustive page with pointers to security modules.

A nice blog post on 10 security modules yields the following:

Secure Password Hashes - will implement the D7 user password encryption on D6. I need to look into how it cooperates with existing passwords before installing it. It appears version 6.x-2.x of this module will rehash existing passwords. This module creates a new table for storing passwords.

Of course, the Password Module implements this same functionality. It has far fewer users, a better known maintainer and claims a more direct upgrade path the D7. Fuuu. Version 1.x is not a security enhancement. This module doesn't create any new tables which should make the upgrade simpler??

Use Login Security to guard against password guessing and put in place automatic account logging and notification.

Posted by kkwaiser at 03:39 PM | Comments (0) | TrackBack

October 05, 2011

Devel snippets

Overview of the print statements is presented here.

# load a node given a specific NID

$mn = node_load(8503);

# pretty print the node array

# ugly print the node array

# load a CCK field array into a variable (a node reference in this case)
$dfNid = $mn->field_dataset_datafile_ref;

# load a portion of a CCK field array:
$dfNid = $mn->field_dataset_datafile_ref[0][nid];

# now load the reference node
$dfNode = node_load($dfNid);

Posted by kkwaiser at 02:40 PM | Comments (0) | TrackBack

September 23, 2011

Logging and communicating file downloads

I had considered a feature freeze for the Research Gateway to keep the upgrade path to D7 as clear as possible but this may not abide.

Here is one I am thinking to add:

When a datafile is downloaded email the data originator to let them know about it, possibly including email and purpose information from the downloader.

The collection of downloader information (e.g., email, institution, purpose) can be done in a number of ways.

1) Have them create a full account
2) The first time they go to view a data set or list of data sets, collect the needed information and store it in a cookie. Anytime they download a file, email the data originator. Q. What happens if cookies are disabled.
3) Upon clicking a file link, interrupt with a popup screen asking for downloader information. Potentially store this in a cookie or ask for it everytime a file is downloaded. Either way, auto-email the information to the originator.

Relevant modules:

Scant findings thus far.

Email Download - not compatible with CCK fields, otherwise it does everything needed.

And that's it - although it may work to come up with a custom solution using CCK and Rules.

Posted by kkwaiser at 04:22 PM | Comments (0) | TrackBack

September 19, 2011

Multi-step conditional forms in Drupal

Collection of notes and links relating to a potential project of unspecified character.

Web forms in Drupal - Rules/CCK vs Webform module

Multistep registration form in Drupal 6 - lacks the term "conditional"

Multistep Module - "Multistep adds multiple-step functionality to content type editing forms." May not play well with Conditional Fields module.

Pageroute Module - similar to Multistep?

Multistep in D7 -

To summarize, the options appear to be a multiple content types with rules that direct the user between forms OR the webform module - I'm not seeing examples of a multi-step conditional content type (node/add) form.

Posted by kkwaiser at 12:52 PM | Comments (0) | TrackBack

June 28, 2011

Install DEIMS EML2Drupal Modules

One of the tools developed by the DEIMS group is EML2Drupal, a set of Drupal modules dedicated to generating EML compliant metadata for datasets using the DEIMS content types. This is a simple list of steps involved in setting it up - I'm pretty sure documentation exists on the project page but I like to have my own steps in instances such as these.

1) Visit the DEIMS Google Code site.
2) Download eml_config and views_bonus_eml
$ cd sites/all/modules
$ sudo wget http://deims.googlecode.com/files/eml_config.tar.gz
$ sudo wget http://deims.googlecode.com/files/views_bonus_eml.tar.gz

3) Unpack the modules
$ sudo tar -xzf views_bonus_eml.tar.gz

- Note: I applied a patch found here to allow anonymous users to access EML feeds.

4) Enable the modules (admin/build/modules)
- Bonus: Views Export EML
- EML Config

5) Configure EML Config
- EML Config store metadata that will appear in every EML document
- Complete the form found at http://yoursite.com/eml_config

6) Create a view for EML Feeds (eml_view)
- Key attributes: Type Node, Default + Feed displays
- Arguments: Node NID, Fields: Node NID
- Feed Display: EML Style,
- Provide as file: view-%view.xml, Inherits defaults
- Attach to: Default, Path: eml_view

7) Embed Default eml_view in the Panels Node Template for Datasets
- Node: Nid: Node ID
- Display Feed Icons

Next steps:

Unfortunately, Data Creator information is not part of the output EML file.

Posted by kkwaiser at 01:47 PM | Comments (0) | TrackBack

April 21, 2011

Drupal SEO Followup

Over a month ago I installed PathAuto and XML Sitemap on the Research Gateway with the goal of increasing search engine referrals. Here are a few graphs which imply a positive correlation. A few bullet points:

- The trend before installation of SEO modules was toward more search engine referrals so it is possibly my efforts only expedited this trend.
- I spent about a day installing and configuring these modules.
- The number of URLs indexed does not indicate *which* URLs are indexed. I believe Google discards indexed-URLs if they have low information content and many of our pages probably fit that description. I don't expect our entire site (~11000 URLs) to be indexed, ever. It appears to have hit a plateau but I expect the number to continue fluctuating.
- I never got the .htaccess rewrite rule (www.umbs.lsa.umich.edu -> umbs.lsa.umich.edu) to work properly. I hate .htaccess rule syntax.

(right-click > view image to embiggen)

(right-click > view image to embiggen)

(right-click > view image to embiggen)

Posted by kkwaiser at 11:23 AM | Comments (0) | TrackBack

April 04, 2011

Something to look forward to...

When your Monday begins by finding an inexplicable bug that previously didn't exist, you worry. When updating to the most recent version of your modules solves the problem, you rejoice.

Posted by kkwaiser at 10:29 AM | Comments (0) | TrackBack

March 24, 2011

Trying EDIT's DarwinCore Model

I've tried EDIT's Darwin Core Module before and always run into bugs. This time though, I am going to make notes.

To reproduce
1) Download and enable the Darwin Core Module
2) Create a DwC Location
3) Create a DwC Specimen
- within the Specimen Node Add form, try to create a new Location


PHP Fatal error: Only variables can be passed by reference in /var/drupal/sites/all/modules/location/location.module on line 1050, referer: http://umbs-desktop.eeb.lsa.umich.edu/drupal/node/add/darwincore

Posted by kkwaiser at 04:45 PM | Comments (0) | TrackBack

March 18, 2011

Dropdown menus hidden behind Panels Panes in Internet Explorer

Time to fix this issues. Navigation is severely inhibited because the menus navigation isn't accessible. This is either a CSS/theming (Marinelli) issue or a rendering (Panels) issues. Or, it could be something else altogether.

Related issues:

Nice Menu drop down disappearing behind nearby panel content in IE7+

Marinelli Drop-down issue with Panels on IE7

Menu hidden behind nice menu and panels in IE7

I ended up adding the following z-index line to layouts.css

#utilities {
padding: 5px; /* originally 0; */
margin: 0px auto;
width:970px; /* match page width */
z-index: 1000 !important;

Posted by kkwaiser at 10:58 AM | Comments (0)

March 16, 2011

Showing total number of items in a view

Wow. What. A. P.I.T.A.

All I want to do is add a header to a View that says the following:

You are viewing [numItems] of [totalItems] records.

and it is nigh impossible.


[crowd snickers]

All you do is modify this simple snippet:


< ?php
$view = views_get_current_view();
$items_displayed = $view->pager['items_per_page'];
$num_rows = $view->total_rows;

You are viewing < ?php print $items_displayed; ?> of < ?php print $num_rows; ?> records.

and you get what you are asking for.

[Not so fast Mister and Miss Opensource...]

If you are limiting the number of items to display, then you need to have a Pager on your view. Problem solved.

[There you go again...]

If your view takes an argument a collision between Drupal Core and Views causes the pager not to render and your total row count is always 1. You might think adjusting the offset would work, but noooo.

If you have Houdini's stomach, you can hack Core. Or, maybe, you want to create a module to accomplish it - because you know your site doesn't have enough modules yet.

[But wait, simple, simpletons...]

The cause of your problem isn't actually the pager, it is the use of distinct in Core which returns a count of 1 which is the problem you were experiencing in the first place.

[Oh yeah. It gets better...]

While having an NID argument can cause the problem, so can having Content Access and/or ACL enabled.

Posted by kkwaiser at 12:04 PM | Comments (0)

March 04, 2011

Stock import View for data tables

I am using the Table Wizard module to expose data tables to Drupal. I use a stock-view to create the View that allows includes attached feeds. Below is the code for that View, the only change that should be needed is to change 'tablename' to the name of the database table containing the data.

$view = new view;
$view->name = 'dt_tablename';
$view->description = 'dt_tablename';
$view->tag = 'tw';
$view->view_php = '';
$view->base_table = 'dt_tablename';
$view->is_cacheable = FALSE;
$view->api_version = 2;
$view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */
$handler = $view->new_display('default', 'dt_tablename', 'default');
$handler->override_option('fields', array(
'did' => array(
'id' => 'did',
'table' => 'dt_tablename',
'field' => 'did',
'label' => 'did',
'exclude' => 0,
'relationship' => 'none',
$handler->override_option('access', array(
'type' => 'none',
$handler->override_option('cache', array(
'type' => 'none',
$handler->override_option('title', 'Contents of dt_tablename');
$handler->override_option('header', 'This is a view of a raw database table. It may be sorted in various ways by clicking the column headers.

If you identify a particular field that does not need to be used in views of this table, go to the analysis page and check the Ignore box for that field. It will then no longer appear here.');
$handler->override_option('header_format', '1');
$handler->override_option('header_empty', 0);
$handler->override_option('empty_format', '1');
$handler->override_option('items_per_page', 3);
$handler->override_option('use_pager', '0');
$handler->override_option('style_plugin', 'table');
$handler->override_option('style_options', array(
'grouping' => '',
'override' => 1,
'sticky' => 0,
'order' => 'asc',
'columns' => array(
'did' => 'did',
'info' => array(
'did' => array(
'sortable' => 0,
'separator' => '',
'default' => 'did',
$handler = $view->new_display('page', 'tablename Page', 'page_1');
$handler->override_option('header', '');
$handler->override_option('path', 'admin/content/tw/view/dt_tablename');
$handler->override_option('menu', array(
'type' => 'none',
'title' => '',
'description' => '',
'weight' => 0,
'name' => 'navigation',
$handler->override_option('tab_options', array(
'type' => 'none',
'title' => '',
'description' => '',
'weight' => 0,
'name' => 'navigation',
$handler = $view->new_display('panel_pane', 'tablename Pane', 'panel_pane_1');
$handler->override_option('title', 'tablename Pane');
$handler->override_option('header', '');
$handler->override_option('pane_title', '');
$handler->override_option('pane_description', '');
$handler->override_option('pane_category', array(
'name' => 'View panes',
'weight' => 0,
$handler->override_option('allow', array(
'use_pager' => FALSE,
'items_per_page' => FALSE,
'offset' => FALSE,
'link_to_view' => FALSE,
'more_link' => FALSE,
'path_override' => FALSE,
'title_override' => FALSE,
'exposed_form' => FALSE,
'fields_override' => FALSE,
$handler->override_option('argument_input', array());
$handler->override_option('link_to_view', 0);
$handler->override_option('inherit_panels_path', 0);
$handler = $view->new_display('feed', 'CSV Feed', 'feed_1');
$handler->override_option('items_per_page', 0);
$handler->override_option('style_plugin', 'views_csv');
$handler->override_option('style_options', array(
'mission_description' => FALSE,
'description' => '',
'attach_text' => 'CSV',
'provide_file' => 1,
'filename' => '%view.csv',
'parent_sort' => 0,
'seperator' => ',',
'quote' => 1,
'trim' => 0,
'header' => 1,
$handler->override_option('row_plugin', '');
$handler->override_option('path', 'tablename.csv');
$handler->override_option('menu', array(
'type' => 'none',
'title' => '',
'description' => '',
'weight' => 0,
'name' => 'navigation',
$handler->override_option('tab_options', array(
'type' => 'none',
'title' => '',
'description' => '',
'weight' => 0,
'name' => 'navigation',
$handler->override_option('displays', array(
'page_1' => 'page_1',
'panel_pane_1' => 'panel_pane_1',
'default' => 0,
$handler->override_option('sitename_title', FALSE);
$handler = $view->new_display('feed', 'XLS Feed', 'feed_2');
$handler->override_option('items_per_page', 0);
$handler->override_option('style_plugin', 'views_xls');
$handler->override_option('style_options', array(
'mission_description' => FALSE,
'description' => '',
'attach_text' => 'XLS',
'provide_file' => 1,
'filename' => '%view.xls',
'parent_sort' => 0,
$handler->override_option('row_plugin', '');
$handler->override_option('path', 'tablename.xls');
$handler->override_option('menu', array(
'type' => 'none',
'title' => '',
'description' => '',
'weight' => 0,
'name' => 'navigation',
$handler->override_option('tab_options', array(
'type' => 'none',
'title' => '',
'description' => '',
'weight' => 0,
'name' => 'navigation',
$handler->override_option('displays', array(
'page_1' => 'page_1',
'panel_pane_1' => 'panel_pane_1',
'default' => 0,
$handler->override_option('sitename_title', FALSE);

Posted by kkwaiser at 11:21 AM | Comments (0)

March 03, 2011

Drupal 6 SEO with PathAuto

I'm on an SEO kick and have decided to install the PathAuto Module. Here are my steps. I found this tutorial - despite the comments - to be useful.

1) Download and install PathAuto 6-1.x
- it looks like directions for 6-2.x would differ. Specifically, steps 5 and 6 appear unnecessary.

2) Enable Pathauto (admin/build/pathauto)

3) Configure Pathauto (admin/build/path/pathauto)

Strings to Remove: a
- I want the URLs to be friendly to human readers

Update Action: Do nothing. Leave the old alias intact.
- Building on an existing site, don't want to muck things up.

Node Paths
Default path pattern: [type]/[title-raw].htm
Pattern for all Biblio paths: bibliography/[title-raw].htm
Pattern for all Data Set paths: data/[title-raw].htm
Pattern for all Housing Application paths: housing/[title-raw].htm
Pattern for all Person paths: people/[title-raw].htm
Pattern for all REU Application paths: reu/[title-raw].htm
Pattern for all Research Project paths: projects/[title-raw].htm

Taxonomy term paths
Default path pattern: [vocab-raw]/[catpath-raw].htm

5) Automate the PathAuto bulk update process
- Follow this tutorial and specifically this comment.

- Created a file called pathauto.php and place it in the root drupal directory. The only change I suggest is reduce the number listed in this line "variable_set('pathauto_max_bulk_update', 100);"

6) Navigate to http://yoursite.com/pathauto.php
- This script will run as long as your webbrowser is at this URL.

7) Install and enable Global Redirect
- No further configuration needed
- This will forward all /node/1234 URLs to the URL Alias which will force search engines to index 2 URL instead of two.

8) Rebuild sitemap.xml

- It is probably be to set up your aliases before setting up your sitemap but if you tend to do things in the wrong order (me, me!) you can go to your site map settings and rebuild them.

Posted by kkwaiser at 09:53 AM | Comments (0)

March 01, 2011

Setup XML Sitemap for Drupal 6

I've noticed the Research Gateway does not appear as prominently as I think it should on some search results. Here are the steps to creating a sitemap for submission to google and bing, which I think should remedy this.

1. Download XML Sitemap
- enable XML sitemap, XML sitemap engines, XML sitemap modal UI, XML sitemap node, XML sitemap taxonomy

2. Visit the /admin page

- I hit a WSOD on ITS servers. Remedy is here.
- Note: Server errors logs for the Research Gateway are available here.

3. Visit the Edit section of content types and vocabularies to Include that content in the XML SiteMap.

Content types Enabled: Biblio, DataSet, Institution, Research Project, Variable, Person, Variable, Page

Vocabularies Enabled: UMBS Keywords, USGS Maps, Dataset Theme, Michigan Counties and Townships, Institution Categories, GNIS Classes

Note: a brief test showed that unpublished nodes are omitted from the sitemap
Note: a second brief test indicates that only nodes that are viewable to Anonymous users are included in the sitemap.
Further explanation: I use the Content Access module and set a content type to be Include in the sitemap but not viewable to Anonymous. I then created two nodes of this content type and - at the node level - made one of them viewable to Anonymous. After running cron.php this node showed up on the sitemap.

4. Configure XML SiteMap (admin/configuration/xmlsitemap)
- Added Bing and Google as search engines to submit sitemap to.

5. Verify ownership for Bing and Google.
- Create Webmaster Tools account at each site
- Place an xml file (Bing) and an html file (Google) in the site's root directory.

6. The sitemap is expanded everytime cron.php is run.

Posted by kkwaiser at 03:51 PM | Comments (0)

February 24, 2011

Further Private Download instructions

Posted by kkwaiser at 12:06 PM | Comments (0)

February 22, 2011

IRC with Bdragon

This is a conversation I had on the IRC on whether patches to add polygon support and multiple points per map would be accepted into the GMap module.

< start>

< kbk1> Bdragon: got a sec for a quick question on this?

< Druplicon> http://drupal.org/node/338745 => Multiple locations on a single map => Location, Code, normal, needs review, 57 comments, 1 IRC mention

< Bdragon> kbk1: Things are pretty hectic over here atm

< kbk1> Bdragon: My employer is willing to sponsor completion of those patches. It'll be for D6 (instead of D7). Are you OK with committing this to the D6 branch?

< kbk1> Bdragon: I just want confirmation before we pony up.

< Bdragon> kbk1: Sponsorship is problematic for me atm because I'm fulltime with Tag1 Consulting.

< kbk1> Bdragon: we would go through Agileware; I've already talked with them and gotten an estimate

< Bdragon> kbk1: As is, I don't like the idea of storing polys as multiple locations. I had to maintain a site that did this in production and it's slow and buggy. Much better to use spatial tables... Have you looked at the geo module yet?

< kbk1> Bdragon: That's understandable. Would you commit the "Multiple locations on a single map" patch? I've looked into Geo a bit but wouldn't switch to it in the D6 incarnation of my site.

< Bdragon> kbk1: Not as it currently is. For it to be reliable locations an offset column will need to be managed in {location_instance} -- location doesn't guarantee that it returns stuff in the same order currently.

< Bdragon> kbk1: I am quite opposed to the patch, I spent weeks getting *rid* of it on a site.

< Bdragon> kbk1: It needs to be done in a much cleaner way than that patch

< kbk1> Bdragon: That explains why it has been pending for 3 years. This is beginning to sound like a 'no'.

< Bdragon> kbk1: It's outside the scope of location. [This post] is still relevant.

< Druplicon> http://groups.drupal.org/node/6089 => Bdragon's vision for doing locations "right" in Drupal => 31 comments, 11 IRC mentions

< kbk1> Bdragon: Seems things are more complicated than they appear. Either way, Gmap and Location work great for us and perhaps we can contribute in some other way in the future. Thanks.

< Bdragon> kbk1: I followed up with a suggestion.

< kbk1> Bdragon: Thanks. I collaborate with a few other data manager types and geographic data in Drupal is a big question of ours. It's not out of the question that we would submit for federal grant money to fund improvements. If our conversation ever goes there we will keep all of this in mind.

< Bdragon> kbk1: re: a grant -- good idea. I really want geospatial in drupal to go somewhere, but bolting adhoc junk onto gmap and location isn't the way to get there. Bolting conformant stuff on the other hand (WKT support for gmap would be awesome for one, but I don't have the time to write it)

< end>

Posted by kkwaiser at 12:05 PM | Comments (0)

February 17, 2011

Node Ref Create & Node Import

With a large number of housing applications about to come in, I figured it would be worth my time to expedite the import process. This necessitated a small patch on the Node Import module to compensate for the fact that I use Node Reference Create. This issue documents my work.

Posted by kkwaiser at 09:43 AM | Comments (0)

February 16, 2011

Print $node array at submission

Drupal IRC snippet

kbk1: I need to get a print out of the array that is created when someone hits submit on the node/add form. I've got devel and drupalforfirebug installed and can see the form before submission. Help?

xjm> kbk1: If I recall you'll want to do a dpm($form_state), maybe in a hook_nodeapi
kbk1: nodeapi when $op == 'validate'

Posted by kkwaiser at 02:44 PM | Comments (0)

Notes on Views Custom Field (Drupal 6)

A few notes on Views Custom Field:

1) Enabling the module adds a new Field Type, "CustomField", to the Views configuration page.

2) Simple snippet used in the PHP field type:

print_r($data->node_data_field_app_fname_field_app_role_value); //print a value
print var_export($data, TRUE); // prints the data array
print_r($data); // prints the data array
dsm($data); // Requires devel, neater output

3) Weird behavior alert! The field names change when new fields are added. There are workarounds but so far a true solution is only found in the Drupal 7 version Views PHP.

Great module.

Bonus snippet:

echo $data->node_node_data_field_housing_inst_affil_title . " [nid:" . $data->node_node_data_field_housing_inst_affil_nid . "]" ;

Posted by kkwaiser at 08:45 AM | Comments (0)

February 10, 2011

Documentation for the DEIMS EML2Drupal module



- Should "Site name acronym" be limited to 3 letters? That's an LTER thing.
- URL should be admin/eml_config with a link "EML Configuration" on the admin page.
- Capitalize the first letter of each field "e.g., Country"
- An optional button to make Provider info the same as Publisher info
- The form uses a "Create" button for EML Config File -> confirmation message should read "Your EML settings have been saved created."
- A way to view/modify EML Config files would be good; after submitting my first thought was, where'd my Config info go??


- Need to include a base_url when constructing the datatable url:

- You need to be logged in to view the EML file?

- What is the point of www.yoursite.com/eml_view

Attaching an EML feed to a dataset panel template:

- Modified the EML Style Feed to "Provide as file" and changed to .xml
- Attached to the Default EML View
- Inserted the Default View into the Panels template

Posted by kkwaiser at 09:12 AM | Comments (0)

February 07, 2011

Configuring Sendmail in Drupal 6

Apparently you're not supposed to use your uniqname to authenticate the UM SMTP server. This is a place holder for an ongoing task.

Here is a post on configuring Sendmail. Not so helpful post on same topic.

Good overview of three ways to handle email in Drupal.

Posted by kkwaiser at 02:09 PM | Comments (0)

January 26, 2011

Rebuilding Drupal caches

This is mostly a bookmark right now but at some point I want to figure out how to programmatically rebuild caches in Drupal. Caches expire and don't seem to rebuild until someone goes to view a page, for a page such as our research site map this means a 15 second load time.

The thread discusses how to accomplish cache rebuilds via a custom module.

Here's a informative section on Cron and Caching.

Posted by kkwaiser at 09:07 AM | Comments (0)

January 20, 2011

Known "bugs" and bugs in the housing application

Here goes:

1) Clicking "Add another item" two times creates undefined solution
- This basically means the applicant will have to answer the captcha question twice instead of once.
- Severity: minor nuisance
- Solution: The module developers are aware of the problem, hopefully a fix with be forthcoming.

2) Applicants must have their browser's JavaScript enabled for the form to work.
- The latest Google Analytics report indicates 91-93% of visitors to our website have JavaScript enabled.
- Severity: potential headache
- Solution: Hire a very expensive programmer, go to PDF application, use last year's application (which only barely functions without javaScript)

3) Spam filters might eat some of the auto-emails?
- Problem occurred with REU applicants but may not happen here.
- Severity: Won't affect our processing or reception of housing applications. If researchers begin creating accounts and not receiving autoemails then this will become a bigger problem.
- Solution: I've adjusted the text of autoemails in an attempt to not trigger spam filters. Further action may be possible but will require more research.

4) If you submit, backup, submit, backup enough times the hidden fields (e.g. guest fields) will appear even if they should be hidden.
- Cannot reproduce this on a regular basis
- Severity: Minor
- Solution: Don't backup and submit several housing applications!

Posted by kkwaiser at 01:23 PM | Comments (0)

January 19, 2011

Code Snippet for pulling Node Reference and Multigroup information in Drupal 6

Saving are the snippets.

Here's the Node reference snippet. It loads a referenced node and prints out some of the fields.

//Print Guest Information

echo "------------------- Guest Information ------------------- \n";
$guest_ref = $node->field_housing_guest_ref;

foreach( (array)$guest_ref as $item){
$guest = node_load($item[nid]);
$guest_arrival = explode('T', $guest->field_housing_guest_dates[0][value]);
$guest_departure = explode('T', $guest->field_housing_guest_dates[0][value2]);

echo "Guest name: " . $guest->field_housing_guest_fname[0][value] . " " . $guest->field_housing_guest_lname[0][value] . "\n";
echo "Arrival: " . $guest_arrival[0] . "\n";
echo "Departure: " . $guest_departure[0] . "\n\n";

Here is the multigroup example:

//Print Guest Information
echo "------------------- Guest Information ------------------- \n";

$guests_fname = $node->field_housing_guest_fname;
$guests_lname = $node->field_housing_guest_lname;
$guests_age = $node->field_housing_guest_age;
$guests_dates = $node->field_housing_guest_dates;

$i = 0;
foreach($guests_fname as $item){
$guest_arrival = explode('T', $guests_dates[$i][value]);
$guest_departure = explode('T', $guests_dates[$i][value2]);

echo "Guest: " . $item[value] . " " . $guests_lname[$i][value] . "\n";
echo "Arrival: " . $guest_arrival[0] . "\n";
echo "Departure: " . $guest_departure[0] . "\n\n";


echo "----------------------------------------------------------------- \n\n";

Posted by kkwaiser at 10:43 AM | Comments (0)

January 18, 2011

Downgrading from PHP 5.3 to 5.2 all for Drupal

Contributed modules in Drupal 6 don't like PHP 5.3. For example, I'm pretty sure CCK's export and multigroup views integration hate it.

Notes on backing down the step - or jumping off the cliff, we'll see how it turns out. This is on Ubuntu 10.04 btw.

Newbie friendly tutorial

Drupal friendly tutorial

Instructions for Ubuntu 10.10

Details I didn't quite understand

$ wget http://randyfay.com/sites/default/files/karmic_0.list
$ wget http://randyfay.com/sites/default/files/php_1.
$ sudo mv karmic_0.list /etc/apt/sources.list.d/karmic.list
$ sudo mv php_1. /etc/apt/preferences.d/php

$ dpkg --get-selections | grep php
$ sudo apt-get remove libapache2-mod-php5 php5 php5-cli php5-common php5-gd php5-mcrypt php5-mysql

$ sudo apt-get autoremove
$ sudo apt-get update
$ sudo apt-get install php5 libapache2-mod-php5 php-db php5-cli php5-common php5-xsl php5-gd php-pear php5-mysql php5-curl php5-memcache

Add three lines to /etc/apt/preferences.d/php

Package: php5-mcrypt
Pin: release a=karmic
Pin-Priority: 991

$ sudo apt-get mcrypt

$ php -v

Modify /etc/php5/apache2/php.ini

max_execution_time = 200
memory_limit = 128M
log_errors = On
error_log = /var/log/apache2/php_errors.log

And...BINGO, WAMBO, KAPOW, I can now export content types in Drupal again.

Posted by kkwaiser at 12:51 PM | Comments (0)

January 17, 2011

Further modification of the housing form

Notes, notes, notes

1) Patched core so that it would quit messing with my hidden, required radio buttons. It was screwing with the post-submission validation step. More here.

2) Made Guests its own content type (rather than use CCK3 multigroup which is Views-impaired). Using Node Relationship and Modal Frame with a node reference field to allow guests to be added.

3) Made the Guest node reference field unrequired due to validation errors. Report here.

4) Auto-emails are set up to fire to registrant and UMBS staff, need to tweak the php in these emails.

5) Upon submission, need to redirect to generic confirmation page.

Posted by kkwaiser at 09:57 AM | Comments (0)

Avoiding spam filters

Blogpost hijack...begin!

Installed the SMTP module and am optimistic my problems are now ALL solved. To wit:

Original Header:

Received-SPF: pass (google.com: best guess record for domain of www@[server1].umich.edu designates [ip1] as permitted sender) client-ip=[ip1];

New Header

Received-SPF: pass (google.com: best guess record for domain of [site_email]@umich.edu designates [ip1] as permitted sender) client-ip=[ip1];

Original Header:

Received: (from www@localhost)
by [server1].umich.edu ( id p0OIMVP3003713;
Mon, 24 Jan 2011 13:22:31 -0500

New Header

Received: FROM umbs.lsa.umich.edu ([server1].umich.edu [ip1])
By [server2].umich.edu ID 4D3EE9D9.6ED0B.21456 ;
Authuser kkwaiser;
25 Jan 2011 10:18:49 EST

Blogpost hijack...end!

Email I sent to www-sig:

A not insignificant portion of auto-emails coming from my website (Drupal install hosted on an ITS Virtual Server) are being flagged as spam. The emails are generally user-confirmation or password reset emails. Is there anything I can do to increase the likelihood that these emails go through to the recipient without being caught in spam filters?

See below the fold for the responses I received. I will focus on changes I've made next.

Change subject line of auto-emails

Account confirmation:

- Original: Account details for [username] at University of Michigan Biological Station
- New: Registration confirmation at the University of Michigan Biological Station

Password recovery:

- Original: Replacement login information for [username] at University of Michigan Biological Station
- New: Replacement login information at the University of Michigan Biological Station

Basically, I'm hoping that removing the username from the mix will do the trick. I've also removed username references from the body of these emails.

Check to see if the email servers I'm using are flagged as spam sources

1) Look at email header to determine IP address of email servers. This page is a good source of information.

2) Plug IP Addresses into a web application that checks against listings of spam sources.

3) ITS provides a similar service for spam blockers on the UM campus.

None of the servers I am using were flagged so I'm going to focus on altering the structure of the auto-emails at this point.


I'm not optimistic that the above changes are going to have much affect and it is too important that our emails get to where they need to be.

I've run DNS reports (after reading this thread) at this site and this site for umbs.lsa.umich.edu and sent them on to ITS Webmasters for feedback. Hopefully, this will help.

This thread discusses DNS report results that may indicated spam filtering problems.

Change "From" email address:
Original: umbs-research-gateway@umich.edu
New: umbs-research-gateway@umbs.lsa.umich.edu

Response 1:

There are several things you can do. First is to avoid the use of words, or combinations of words, which can trigger the Bayesian filters. Lists of common spam words are available via Google. Another thing is to be sure that your outgoing emails are properly formatted. Formatting errors with RTF/HTML/etc. can flag messages. Header formatting is also an issue. Another is of course attachments.

One thing you can do is check the headers of the messages that get flagged. Many filters attach a header (e.g. X-SPAM) with the "hit count" (instances of triggering the filters) for each test. That might tip you off as to what in particular is causing the messages to be flagged.

Hope that helps. Please let me know if there is anything else I can do.

Response 2:

Do what Jaime already said first (and note that if the message recipient uses the ITS IMAP service, spam factors are off by default, but the recipient can have them turned on for all future messages by contacting imap-postmasters@umich.edu).

In addition to what [the previous emailer] already said, you can check the IP address from which your message is being sent (N.B.: NOT the IP address of your website, nor your domain name, but the IP from which the email is actually originating) to see if it has a bad reputation as an IP address from which spam originates. Check both the realtime blackhole lists that U-M uses ( http://spambusters.mail.umich.edu/troubleshoot/blockstatus/ ) as well as others worldwide (google for both "rbl" and "ip reputation" to find quite a few to check). If you discover you're on a blacklist or the IP in question has a bad reputation, contact postmaster@umich.edu and work with them to resolve the issue.

I advise against pursuing things such as SPF or DKIM for your own domains outside of umich.edu unless you have hard evidence that using one of these will in fact result in significantly better message tagging and acceptance by major ISPs. U-M uses neither, by the way, due to cost/benefit reasons, and I have not heard of any problems resulting from the lack up to this point.

I hope this is useful.

*Emphasis added by me.

Posted by kkwaiser at 09:00 AM | Comments (0)

January 14, 2011

Major impediments re: Housing Application


At least three of them?

CCK3 (multigroup)
- great for getting data in but good luck using it with views. Increasingly think this is a dead-end for D7


CCK 6.x

If a user "Adds Another" and then "Removes this item" on a required field, Drupal's form validation throws any errror - even if the user has another field completed for that field. The error has been on the CCK issue topic for 4 years and is not yet resolved.

Conditional Fields 6.x-2.x

- Validation of form fails if a hidden, required field is not complete. Appears the problem is only with the 6.x-2.x branch

Conditional Fields 6.x-1.x

The above problem does not seem to appear in this branch but it is impossible to have multiple fields control the same field per this issue.

Posted by kkwaiser at 12:29 PM | Comments (0)

January 11, 2011

Setup Google Analytics for Drupal6

Here are the steps (as I remember them). You don't need to add the code to every page:

1) Install and enable Google Analytics
2) Check permissions
3) Configure GA (i.e., specify roles to track)
4) Register site with GA
- Create New Website Profile (enter URL)
- Copy Web Property ID to GA config in Drupal
- Verify Site Ownership? - This part is a bit fuzzy but you may need to place an html file in the root web directory to prove you are the site admin.

5) Configure reports and wait. It will take up to 1-2 days for data to kick-in.

Posted by kkwaiser at 10:10 AM | Comments (0)

January 10, 2011

Devel conflict with "Add Another" button on Drupal forms

A note that the Devel Module conflict with the Add Another button that shows up on content types with an unlimited number of entries. See more here.

Posted by kkwaiser at 01:59 PM | Comments (0)

Drupal update notes

Nothing to see here except a few reminders for a round of updates I need to run:

WebForm 3.x needs to be updated. Currently disabled due to highly critical vulnerability

WYSIWYG - after update will need to either 1) patch module to remove unwanted breaks in blank text boxes OR 2) update CKeditor which may have fixed the bug

I've run a full drush update on the test site

Posted by kkwaiser at 09:31 AM | Comments (0)

January 06, 2011

How to for Drupals Devel Module

Post 201!!

I've been wanting to write this one for a while. This will be my second install and use of the Devel Module. Here are my steps:

1. Download and enable Devel
- No sub-modules needed at this point
- run update.php

2. Check/adjust permissions (admin/user/permissions)
- Give admin everything

3. Check Devel settings (admin/settings/devel)
- defaults for now

4. Enable Devel-created Blocks (admin/build/block)
- Development and Execute PHP are the blocks I've enables. Be sure to make them visible to the Administrator role and NOBODY ELSE.

- For some unjustifiable reason these blocks only appear on the block admin page (Marinelli theme) but not on any other pages (Garland theme).


Nevermind, apparently when you have multiple themes on a site you need to enable the block on each theme. This post tipped me off.

5. Further notes
- After enabling Devel, each node will have a new Devel tab where you can see the components of the node (e.g, arrays and shit), tokens and other stuffs.

Posted by kkwaiser at 03:33 PM | Comments (0)

December 22, 2010

Enhancing core's Taxonomy module in Drupal

A note that I'm going to start using the following modules and why.

Unitag Module - allows a free-tagging vocabulary to become Read-only.


Terms that are entered and are not part of the vocabulary are sent to limbo for management approval. This is perfect because I want researchers to tag with their own terms but I don't want them mucking up my system!

1) Install and Enable
2) Go to Unitag Settings (admin/content/taxonomy/unitag/settings)
3) Enable Read only and Sanitize on the Keyword and Classification vocabularies

Taxonomy Role very similar to Taxonomy Permissions. Basically controls whether a particular vocabulary will appear on the node edit form based upon their Role.

1) Install and Enable
2) Visit Permissions to set which roles will be able to see which Vocabularies on the node/edit form.

Posted by kkwaiser at 11:39 AM | Comments (0)

December 16, 2010

Notes on Updating to Drupal 6.20

Of course, less than a week after I go live with v1.0 of the Research Gateway a stream of holiday releases crop up. This is for notes on the upgrades.

Form is as follows:
What I've got
What is available and/or recommended
The download link of the version I'm going to install
Drupal core 6.19
Recommended version: 6.20 (2010-Dec-15)
Content Construction Kit (CCK) 6.x-3.x-dev (2010-Nov-10)
Recommended version: 6.x-3.x-dev (2010-Dec-06)
Date 6.x-2.x-dev (2010-Nov-13)
Recommended version: 6.x-2.6 (2010-Aug-14)
Development version: 6.x-2.x-dev (2010-Dec-13)
FileField 6.x-3.7
Recommended version: 6.x-3.9 (2010-Dec-12)
Image Resize Filter 6.x-1.9
Recommended version: 6.x-1.10 (2010-Dec-05)
ImageField 6.x-3.7
Recommended version: 6.x-3.9 (2010-Dec-12)
Markup 6.x-1.x-dev (2010-Jul-11)
Recommended version: 6.x-1.0-alpha1 (2010-Dec-14)
Node export 6.x-2.22
Recommended version: 6.x-2.24 (2010-Dec-09)
Views 6.x-2.11
Security update: 6.x-2.12 (2010-Dec-15)

Posted by kkwaiser at 08:59 AM | Comments (0)

December 15, 2010

NodeAccess vs Content Access + ACL

My notes while evaluating these similar modules. Spoiler alert, I went with Content Access + ACL.

+ Fewer rebuilds of the permissions (rebuilding is really annoying when experimenting/developing)
+ Configuration of default access for content types are all on one page
+ Out-of-the-box ability to set access for Roles per content type
+ Out-of-the-box ability to set access for Roles and Users per Node
+ 6000+ users
- D7? No D7 port in the works
- No development activity for the last 1.5 years

Content Access
- Rebuilds are time consuming!
- Need an additional module (ACL) to get user-specific access to node, however ACL seems well maintained and is an API only module
- Default configuration is on each Content Type config page
- User interface not as slick as NodeAccess
+ D7 port is underway
+ 20,000+ users

So, to summarize, NodeAccess is +5/-2 and Content Access +2/-4 but Content Access wins? Is this the BCS or something?

Posted by kkwaiser at 01:15 PM | Comments (0)

Improving and refining access to content in Drupal 6

Just when I thought I had things figured out I've been forced to revisit the issue of content access in Drupal. Hopefully, this will be a good thing in the end as I have also considered DataSet, DataFile and other access issues.

This post is log of changes:

1) Install and enable Content Access and ACL.

See evaluation post of CA here.

2) Modify default access and publication states for content types:

- Unpublished by default
- Default Content Access Settings: Anonymous = View
- Using View Unpublished to allow view access to non-Authors, non-Admins by role (REU Reviewer and Staff)

REU Application
- Published by default
- Content Access: View/Edit limited to REU Reviewer

Housing Application
- Published by default
- Content Access: View/Edit limited to Staff

Research Project
- Published by default
- Content Access: View to Anonymous, Edit to Author
- Catch: If the Author wants to let another User edit their Project, the node will have to be published and Content Access settings should be changed accordingly (i.e., Not Viewable to Anonymous, add user with permissions.)

DataSets, DataFiles, Variables will look the same as Research Project

Research Sites,
- Published by Default
- Content Access: Viewable by anonymous
- Problem

Posted by kkwaiser at 01:13 PM | Comments (0)

December 13, 2010

User Related Modules for Drupal 6

I've come to the conclusion that all Project Leads (PI's, Graduate Students, Co-PI's) will be required to maintain an account through our Research Gateway. There are several reasons for and implications of this decision. Explanation follows:

Reasons for:
1) Project Leads will eventually need a user account anyways as they will be submitting data later on.
2) Project Leads need to register their Research Project with UMBS as part of their application. Without an authentication requirement, anonymous users would need the ability to create Research Projects and this just doesn't seem like a good idea

1) Another account for people to manage
2) Exposure to the Research Gateway
3) Personal information and Research Projects will be saved and should cut down on future effort once complete

Where Confusion Arises:
I currently have Research Projects from 2010 that returning researchers may want to cite when they apply to visit UMBS in 2011. For this to be possible I will need to 1) create User accounts for those researchers a priori and 2) give them the ability to edit the Research Project, because 3) the researcher will need to complete further fields.

Either way:

User Import Module can be used to create many Users via a csv import.

User Import Framework Module looks like User Import's little brother.

Protect Critical Users Module will not allow specified Users to be deleted. Seems sensible.

Node Access User Reference Module allows a CCK field that specify Users who can be configured to have View or Edit abilities on a node. For fun, see if you can find the killer caveat on the project page!!

UserPlus Module seems like a bulk operations module for Users.

Posted by kkwaiser at 04:05 PM | Comments (0)

December 09, 2010

A new module to expose external tables to Views?

I really need a module that exposes data in external tables to Views. Unfortunately, of the two existing options one is one its way out and the other has poor issue-response statistics - I repeat, poor, poor, poor issue-response statistics - no documentation - I repeat, no, no documentation - and is a bit convoluted. Do you sense frustration?!

This has led me to imagine a module that adds a new View type, call it External Table, with configuration options on the Views interface whereby users can specify an external table by name. This module would then pass the table fields (column headers) to Views which could be added to a view of the table. Honestly, I would stop there at first and later build in filters that could be applied to values within a column, passing of arguments, and other bells and whistles.

This philosophy differs from that of other modules in a few ways. Specifically, it is 1) 100% dependent on the Views module, 2) highly focused in its mission, 3) completely integrated into the Views module configuration interface (i.e., no extra admin configuration options).

How to do this? Here are a few posts that may be relevant:

The Views Developers Group has taken up this subject.

Apparently, the "Displaying the Forecast section" of this tutorial is helpful.

Webchick recommends the code uploaded in this comment.

Someone wishing for similar functionality within Drupal 7.

This patch may contain parts of a solution but note a TW dependency: Enable views to handle external tables properly, allowing for joins across tables in different mysql databases

Just some references to previous posts of mine related to this subject:

Delving further into the Data Module

How to for the Data Module

Overall Approach to Data in Tables with Drupal

Storing data in tables (not csv's)

Posted by kkwaiser at 08:56 AM | Comments (0)

December 06, 2010

Theming Marinelli

First off, this is a hack and I'm not a themer so don't think any of the following is the correct way to do things. I'm in the uncomfortable position of having to mimic the css of a different site. The following is a temporary fix (i.e., crappy approximation.)

1) Install Marinelli and enable Giordani.

2) Setup dropdown menu's

Keep: Site Name, Shortcut Icon, Search Box

Path to shortcut Icon:

Dropdown for menu items

3) Edit primary links menu (admin/build/menu-customize/primary-links)
- Enable and Expand all links you want to show up.
- Mimic the structure found here :http://www.lsa.umich.edu/umbs/

4) Tweak CSS:

Increase spacing between lines of text:
body{ line-height: 1.5em;}

Menu changes ->

Reduce header height
line 29
height: 100px;

padding: 5px; /* originally 0; */

line 127
left: -19px

line 135
#utilities #plinks ul li {
margin-right: -14px;

line 101
#utilities form { /*search box*/

Modify graphics.css

line 8
background: url("http://www.lsa.umich.edu/vgn-ext-templating/sites/umbs/images/tone.gif") repeat scroll 0 0 #EDEDED;

line 13
border: 12px solid #FFFFFF;

line 20
remove call to rotate.php, set background to white
#header {background: #FFFFFF; /*rotates images in the banners folder */}

Change look of search box
line 42
#utilities input.form-text {
background: none repeat scroll 0 0 #FFFFFF;
border: 1px solid #000000;
color: white;



Modify the test of the home page link:
line 86
#header h1 a, #header p a{
color: #FFFFFF;
text-shadow: 3px -1px 1px #1D496F;

5) Put the Menu and Search Bar below the header image following this post.

* Note the Captcha Option that shows up below the search bar causes it to get misplaced. Going to live with it for now.

6) To modify Logo/Header areas see this post

Posted by kkwaiser at 01:26 PM | Comments (0)

Establishing Workflow for Researcher Products

The concept is relatively straightforward, establish a workflow system around researcher-created products to ensure content isn't published prematurely.

- Abundantly obvious as to which state is appropriate at a given time
- Publication of content is the final step

- Three Statuses:

1) In progress - researcher is actively editing the content, accessible to the Content Owner and site Administrator. NOT PUBLISHED
2) Ready for review - content is ready to be published (i.e. version 1 is complete). Administrator should check for keywords and web-necessary index terms. NOT PUBLISHED
3) Published - Researcher and Administrator agree all Content is ready for public release.

Rules to implement:

At this point, only the Statuses exist but rules can be added to send out email notifications upon Content creation or Content publication.

Posted by kkwaiser at 09:20 AM | Comments (0)

December 04, 2010

Using Node Clone in Drupal 6

A smattering of steps:

1) Download, install and enbable the Node Clone Module.

2) Set permissions at admin/user/permissions so that the appropriate roles can either Clone All Nodes or Clone Own Nodes.

3) Configure the Clone module at admin/settings/clone. I omitted all Content Types except DataFile and Variable just to be conservative.

4) Test

Posted by kkwaiser at 01:06 PM | Comments (0)

Building a Friendly Metadata Interface for Researchers in Drupal

This is what my job is all about but I haven't had much of a chance to focus on it in the last month or so. The following steps are taken with the goal of building a user-friendly interface for researchers to manage research projects, personnel, metadata and datasets within a web-database framework. DEIMS, the framework alias, stands for the Drupal Ecological Information Management System.

Here are the steps in bullet point fashion. Assumptions as to knowledge of the basic content type structure (Research Project, Person, Research Site, DataSet-> DataFile-> Variable) is assumed. For a primer, see this article by several LTER data types.

1) Create content from within another content type

The nested nature of metadata storage it is somewhat counter intuitive to the manner in which we would normally create it. For example,

DataSet -> DataFile -> Variable

The intuitive way to create metadata is to start at DataSet and create the DataFiles and Variables as they come up. This isn't immediately possible in Drupal but as I outline in this admittedly sparse post, javascript can be used to generate pop-up screens that allow for this.

2) Allow researchers to clone or duplicate DataFiles and Variables

The metadata held with DataFile is necessarily redundant due to the fact that only one file upload is allowed per DataFile. If the researcher has a lot of files with identical metadata (but different data values) they can clone a DataFile node and alter only those bits of information that are unique. For example, they can just upload a new file. See a How to for the Node Clone module.

3) Allow uploaded files to be (available to the) Public or Private.

No researcher is going to trust you with their data if, in the second after it is uploaded onto your website, it becomes available to anyone with an internet connect. The DataFile content type I use has 2 upload fields, one public and one private. The latter restricts access of the file but not the metadata to the researcher and the administrator. Here's my post on creating a Public/Private file system in Drupal.

4) Build a friendly, navigable layout that allows easy travel from point A to point B.

This will be ongoing but a few improvements to date:
- Use Panels to so that users are presented with content they have authored.
- Create custom menu for different User Roles.

5) Establish a Workflow system around Research Projects, DataSets and DataFiles that allows progress to be saved but not published.

See this post for more notes.

Posted by kkwaiser at 12:44 PM | Comments (0)

December 02, 2010

Allowing User Roles to View Unpublished Content in Drupal

Intro: I have unpublished content that comes via CCK-built registration form and I want specific User Roles to be able to access (view) it but not edit it.

Problem: Only User Roles with "Administer Node" rights can access (view) unpublished content, but this also give them Edit rights. In this case, I don't want the people who are evaluating incoming applications to be able to edit the applications. This is more for their protection than anything else.

1) Work something out with panels that evaluates the Author's Role and if that User Role = Applicant, then only allow the Authenticated (Acting) User to view the Node...........Actually, I don't think this will work...

which is why I went with this

2) The View Unpublished Module places an additional permissions section into admin/user/permissions that allows you to specify which roles can View unpublished content (on a per content type basis.)

Posted by kkwaiser at 10:29 AM | Comments (0)

November 30, 2010

Porting the REU Application form to Drupal

We host a Research Experience for Undergraduates program here at UMBS and I've been asked to build the registration form (process, actually) into our Drupal site. Here are the notes:

REU Components:

1) Content profile attached to User Registration page. This is our Person content type and collects basic, personal information. Also use, AutoAssignRole to associate the registration page (reu-registration) with the REU Role.

2) REU application (a Content Type with bunch of CCK fields):
- modules used: Private Download, CCK3, Markup, Multi-column checkboxes & radios, probably other "basic" modules

3) Use panels & views to customize /user page

4) Build custom Menu system for logged in User
5) Associate workflow states with the REU application
6) Build views for staff use of REU apps
7) Add a new role "REU Reviewers" for faculty who review incoming apps
- in setting up Role Permissions, had to go this route to view unpublished content.
8) Setup auto-email to fire whenever an REU application is moved to "Ready for Review"
9) Adjust confirmation of Account Creation email and redirect to new "CHECK YOUR EMAIL" page after hitting submit.

Upon confirmation of email account and first login, forward to
Staff Components:
not done yet

Posted by kkwaiser at 11:42 AM | Comments (0)

November 29, 2010

Overhaul the beta site


1) Install a local copy of the live site
2) Change database prefix and settings.php
3) Update current modules using drush
4) Run update.php, cron and check Status Report
- modded a few directory permissions
- cron giving me some crap about /tmp but I'm going to ignore is
5) Install new modules:

$ sudo drush dl content_profile modalframe email_registration rules token jquery_update noderelationships autoassignrole cck_required_by_role node_clone permission_select conditional_fields auto_nodetitle workflow

Following my post on d.o, I need the dev version of a few modules

Check for available versions of a module:
$ drush pm-releases tabs

$ sudo drush dl tabs-6.x-1.x-dev
$ sudo drush dl cck_fieldgroup_tabs-6.x-1.x-dev
$ sudo drush dl jquery_update-6.x-2.0-alpha1

jQueryUI notes:
$ cd sites/all/modules/jquery_ui/
$ more README.txt
$ sudo wget http://jquery-ui.googlecode.com/files/jquery-ui-1.7.3.zip
$ sudo unzip jquery-ui-1.7.3.zip
$ sudo mv jquery-ui-1.7.3 jquery.ui

jQueryUpdate notes:
$ cd ../jquery_update/
$ more README.txt
Oh, apparently you just enable the module...didn't expect that.

6) Enable said modules as well as Triggers and CCK Field Permissions. Run update.php and cron.php

7) Download, enable CCK3 (Multigroup) and Schema

8) Working on updating metadata structures...
Done: NodeRelationships (create node from within node); Re-establish datafile, check fields against DEIMS fields
- This still needs work

9) Setup permissions for Admin
- Give admin rights on Permission Select and then Master Permissions.

10) Create two new User Roles & Set permissionss:
- Colleague - for research, instructional and misc summer visitors
- REU Applicant- for incoming REU applications

11) Import housing Application
- adjust field permissions
- need to look at permissions for creating research project

12) Setup Content Profile and AutoAssignRole
- Person as profile component
- Upgrade to AAR-dev following errors reported here and here.
- Allow anonymous users to create account (w/email confirmation)
*Need to adjust welcome message
- Tweak field-level permissions
- adjust fields on Person content type to resemble housing application

13) Had to switch to dev version of CCK Required by Role and apply a patch. See my post here.

14) Make Person Content Profile available for REU registration and create Auto-Assign Role URL for registration.

15) Install CAPTCHA Module and enable on Housing Application. See related post here.
- I didn't add it to user registration because I plan to use email confirmation. Should I add it???

16) Use Panels to setup an advanced User Profile Page
- Bring in a View of content the user has authored
- Display User's Content Profile on Same page
- Need to build menu for users

17) Build REU application & setup workflows
- See this post for steps

18) Change permissions for Views (admin/build/permissions) so only admin can access all views

19) Change default of Person content type NOT to publish

20) Set defaults for Housing Application if the User is logged in. See this post for more.
- Defaults for Date not working See this post for more.

21) Alter Researcher back-end

See this post for more.

Change panel view of Person for people who are logged in
Remove images from Colleague Role
Remove Content Type Person from Your Content View (done)
Add First Time user rule
Modify permissions on new zipcode (done?)
- add private upload fields to data file

Adjust Research Project Fields and Permissions
--stopping for the day. more to come...

Posted by kkwaiser at 04:08 PM | Comments (0)

CCK Default Value Snippets in Drupal

Here are php snippets I used to set default values for logged-in users who are going to apply for housing.

Need to deal with
Date of Birth (See this post for ideas on how to deal with this)

PATTERN USED FOR CONTENT PROFILE FIELDS (role, first name, middle name, last name, gender, umid, address, city, state, country, perm_address, perm_city, perm_state, perm_country, perm_zip, phone, work_phone, emerg_fname, emerg_lname, emerg_phone1, zipcode)

global $user;
$default = content_profile_load('person', $user->uid);
if($user->uid!=1 && user_is_logged_in()){
if (!empty($default->field_person_emerg_email) ) {
$emerg_email = $default->field_person_emerg_email[0]['value'];
return array(
0 => array('value' => $emerg_email)
else return array();


global $user;
$default = content_profile_load('person', $user->uid);
if($user->uid!=1 && user_is_logged_in()){
if (!empty($default->field_person_institution_ref) ) {
$institution_ref = $default->field_person_institution_ref[0]['nid'];
return array(
0 => array('nid' => $institution_ref)
else return array();


global $user;
$default = $user->mail;
if($user->uid!=1 && user_is_logged_in()){
if (!empty($default) ) {
return array(
0 => array('email' => $default)
else return array();

Posted by kkwaiser at 03:58 PM | Comments (0)

November 18, 2010

How to redirect user upon first login in Drupal

Solution is in this comment. Will write a formal How To if I get the chance.

Posted by kkwaiser at 04:43 PM | Comments (0)

November 17, 2010

Advanced help patch for Views

This "how to" focuses on the bulk export and version control functionality of the Views module. The following steps document how to export multiple views at once and create a module from the exported code that will allow you to revert any subsequent changes to your views.

- You have views you want to bulk export; we'll call them myView1 and myView2
- You know how to install and enable a module

- Views (specifically 6.x-2.x)

  1. Modules you will need

    Install Views 2 and enable the following modules: Views, Views exporter, Views UI

  2. Evaluate the Current State of Things

    Navigate to the Views Administration page. You should have Edit | Export | Clone | Delete options next to myView1 and myView2. Once we're done, "Delete" will become "Revert"!

  3. Bulk Export Your Views

    1. Click Tools > Bulk Export to navigate to the Bulk Export page to export myView1 and myView2.
    2. Check the boxes to the left of myView1 and myView2
    3. Choose a module name: my_views
    4. Click Export
  4. Create a Module from the Exported Views

    The results of the export should now be in front of you. Specifically, the results page should be composed of three code-containing regions. This code and the following steps are all you need to create a module that will allow you to revert your views to the state they were in when you exported them.

    1. Create a directory called my_views within your sites/all/modules directory.
    2. Create the following files, paste in the appropriate code, and place them into the my_views directory:
      • my_views.info
      • my_views.module (add a <?php tag at the beginning of this file!)
      • my_views.views_default.inc (add a <?php tag at the beginning of this file!)
  5. Clear the cache

    Just to be safe. Navigate to the Performance Administration page and Clear cached data.

  6. Enable the Module Containing Exported Views

    Navigate to the Modules Administration page and enable my_views Export Module. Save.

  7. Verify Presence of Reversion Option for Exported Views

    Navigate to the Views Administration page. The right of myView1 and myView2 should now read Edit | Export | Clone | Revert. Congratulations, you now have version control in place for your exported views!

Posted by kkwaiser at 09:19 AM | Comments (0)

November 15, 2010

Bulk Modify Access Permissions of Views in Drupal

I'm an idiot and I'm not going to explain why.

Drupal's Views module allows you to limit access to views based upon user Role or by some permission setting. The catch is that the global permissions settings will override those of individual views. Unfortunately, I didn't know this when I started using Views and I have a lot of views I want accessible to Anonymous users and a few views I want accessible only to particular roles.

What are the implications of this:
1) I need to switch my Global permissions so that only the Admin can "access all views"
2) I then need to adjust the Access rights of every single view I've constructed.

There are two options to accomplish 2):
a) Click through every single view and modify the Access settings
b) Export all the views, run a script that modifies the code and then re-import the views

This post is a How To for number 2b):

1) Export all of the views you want to modify. In this case, I want identical permissions on the views I'm going to modify. Specifically, they will all go from no Access settings to access to Anonymous and Authenticated.

2) Use a script to cycle through the my_views.views_default.inc file and change this:

$handler->override_option('access', array(
'type' => 'role',

To this:

$handler->override_option('access', array(
'type' => 'role',
'role' => array(
'3' => 3,
'4' => 4,

I've used python to accomplish this:

#! /usr/bin/python/


marker = " $handler->override_option('access', array(\n"

f1 = open('/blah/sites/all/modules/my_views/my_views.views_default.inc').readlines()
# f1 = open("/blah/myview_test.txt").readlines()
fo = open("/blah/new_view.txt", 'w')
for index, line in enumerate(f1):
if line == marker:

del f1[ index+1]
f1.insert( index+1, " 'type' => 'role',\n")
f1.insert( index+2, " 'role' => array(\n")
f1.insert( index+3, " '3' => 3,\n")
f1.insert( index+4, " '4' => 4,\n")
f1.insert( index+5, " ),\n")
print index, line

for item in f1:

except IOError:

print 'Can\'t open file for reading.'

3) Creating a module of your exported views if you haven't already. Otherwise, place the new views_default.inc file in that module directory. Enable the module and revert all views.

4) These views are hard-coded, will need to fix manually:


Posted by kkwaiser at 09:54 AM | Comments (0)

November 12, 2010

How to use the Version Control and Bulk Export features of Views

This "how to" focuses on the bulk export and version control functionality of the Views module. The following steps document how to export multiple views at once and create a module from the exported code that will allow you to revert any subsequent changes to your views.

- You know how to install and enable a module
- You have views you want to bulk export; we'll call them myView1 and myView2

- Views (specifically 6.x-2.x)

1) Install Views 2 and enable (/admin/build/modules) the following modules: Views, Views exporter, Views UI

2) Navigate to the Views Administration page (admin/build/views)
- You should have "Edit | Export | Clone | Delete" options next to myView1 and myView2. Once we're done, "Delete" will become "Revert"!

3) Navigate to the Bulk Export page to export myView1 and myView2. Click Tools > Bulk Export or browse to admin/build/views/tools/export.

4) Export myView1 and myView2
- Check the boxes to the left of myView1 and myView2
- Choose a module name: my_views
- Click Export

5) Create a module from the exports
$ cd sites/all/modules
$ sudo mkdir my_views
$ cd my_views

- Create the following files, paste in the appropriate code, and place them into the my_views directory:
my_views.module (add a my_views.views_default.inc (add a

6) Clear the cache (just to be safe!)
- Navigate to admin/settings/performance > Clear cached data

6) Enable the my_views module (admin/build/modules)
- the module name should be "my_views Export Module"

7) Navigate to the Views Admin page (admin/build/views) Verify that you now have version control abilities for myView1 and myView2.
- The right of these should now read "Edit | Export | Clone | Revert"

Posted by kkwaiser at 12:40 PM | Comments (0)

November 10, 2010

Setting up Workflow and WF Required Fields in Drupal 6

Need to establish a workflow for our REU Application.

1) Install Workflow and Workflow Required Fields
$ sudo drush dl workflow wf_required_fields
$ sudo drush en workflow wf_required_fields

2) Patch WF Required Fields to associated required fields with workflow states. In this case, I will set fields to be required before workflow state can go to "Complete". Use this patch.

- Move patch to WFRF directory and apply
$ sudo mv wf_required_fields.patch sites/all/modules/wf_required_fields/
$ cd sites/all/modules/wf_required_fields/
$ sudo patch -p0 < wf_required_fields.patch

3) Administer module permissions (admin/user/permissions) for Workflow
- Full rights to Administrator Role, nothing else

4) Add a workflow (admin/build/workflow/add):
- Title: Status of REU Application
- State: In progress
- State: Ready for review
- Permissions for these states: Author, Administrator, REU Applicant, Staff
- No Comments
- Workflow Tab Permissions: Administrator

5) Associate workflow with content type
- Content type: REU Application
- Workflow: Status of REU Application
- Display Workflow Form for: Post

6) Setup Workflow Required Fields (admin/build/wf-required-fields)
- Select REU Application
- Upon Ready for review - selected a bunch of fields here

7) Test notes:
- Although the Workflow status does not change if required fields are empty the Node is still created and error messages show up at the top of the screen. This is actually good because it will allow people to save and return to their application.
- I had to change the settings of a CCK fields so that they were not required to be able to set up WF Required Fields.

Posted by kkwaiser at 02:59 PM | Comments (0)

November 09, 2010

Setup up Private Downloads module in Drupal

Goal: Your Drupal site has a Public file system but you have files you want to limit access to. This is the Public/Private File system conundrum. The following demonstrates how to solve your problem using the Private Download module.

- A Drupal site with a Public file system pointing to "sites/default/files".
- CCK and CCK FileField modules are installed.

1) Understand your system:

- There shouldn't be a private folder in sites/default/files/
$ ls -al sites/default/files
- Are you operating out of a sub-directory? If your Drupal code is found in www.example.com/drupal then you're in a sub-directory. For the record, I'm in a sub-directory and I've set the base_url in settings.php to represent this.

2) Install and enable the Private Download Module

3) Configure Private Download settings (admin/settings/private_download)

- if you're in a sub-directory check the RewriteBase rule and prepend your directory name to it if it isn't there already:
RewriteBase /[optional-subdirectory]/system/files/private
- Save configuration

4) Check to make sure you now have a "private" directory with an .htaccess file

$ ls -al sites/default/files/private
$ ls -al sites/default/files/private/.htaccess

5) Specify which Roles can access files within the "private" directory. Go to admin/user/permissions to configure permissions

- Under "private_download module" check the "authenticated users" box. This will allow anyone who logs into your system to "access private download directory." Of course, you can create your own roles (admin/user/roles).
- Save permissions

6) Add a CCK FileField to a content type, let's call them myFile and myContentType, respectively.

- When configuring myFile go to Path settings > File path and specify "private" (without quotes.) Any files uploaded through this field will end up in the "private" directory.

7) Upload a file
- Create Content > myContentType
- Upload a file into the myFile field. Let's call it test_download.txt.
- Save

8) Everything should be setup now but you can verify everything works:
- Right click on test_download.txt, it should download (or open in browser)
- Left click on test_download.txt > Copy Link Location
- Logout
- Open a new browser tab and try either of these URL's (both should produce an "Access denied" error:


Note: The second URL should be re-written to the first in the browser.

Posted by kkwaiser at 04:01 PM | Comments (0)

Private/Public File Storage in Drupal

Oh, LOOK! There are modules that do this in Drupal. On with the song & dance:

Private Upload

Private Download

The latter two modules are the best options. Great discussion on the two in this forum. This comment outlines integration of CCK FileFields with Private Download via another module, FileField Paths.

Protected Download (Drupal 5 only)

Overall File management module (not Private/Public from what I can tell):
Upload Path

This looks like a helpful post > click me, click me!!

Another Link:

Posted by kkwaiser at 02:02 PM | Comments (0)

November 08, 2010

Multistep Node Add Forms in Drupal

Will return when I figure this out. For now, it's external links:

MultiStep forms in Drupal

MultiStep forms in Drupal using Chaos and Domination

Posted by kkwaiser at 08:16 PM | Comments (0)

Setting up the CAPTCHA Module in Drupal

There are several CAPTCHA and CAPTCHA-like modules in Drupal. I'm using this one. The module currently needs a co-maintainer but with 80000+ users I'm fairly certain it won't fall a part.

Here are setup notes. Also posted on D.O.

Just a bit of documentation...

- You know how to install third-party modules for Drupal
- You have a content type and you want to add a CAPTCHA challenge

1) Install and enable the CAPTCHA Module

2) Configure permissions (admin/user/permissions)
- Probably want to allow Admin role to skip and administer captcha

3) Administer module (admin/user/captcha)
- Check "Add CAPTCHA administration links to forms"

4) Add CAPTCHA to a node-add form:
- Go to Create Content > [My Content Type] or (node/add/[my_content_type])
- Click on "CAPTCHA: no challenge enabled"
- On new page "CAPTCHA point administration" select a challenge type > Save

5) Return to CAPTCHA admin page (admin/user/captcha), refresh, and notice new entry in the Form Protection section [my_content_type_node_form]

Posted by kkwaiser at 11:17 AM | Comments (0)

Patching the CCK Required by Role module

There's a bug in this module that causes it to fail when working with a date field. Basically, the bug keeps you from exempting a Role from completing required fields.

To fix:

1) Update to the dev version:
$ sudo drush dl cck_required_by_role-6.x-1.x-dev

2) Place patch file into the module directory. Patch available here.

3) Apply patch:
$ cd sites/all/modules/cck_required_by_role/
$ sudo patch -p0 < cck_required_by_role.module.patch

4) Check the results

Posted by kkwaiser at 10:35 AM | Comments (0)

November 03, 2010

Delving further into the Data Module

Created two new issues on drupal.org with the hope that I can resolve lingering questions around the Data Module. As TableWizard is kaput, Data is the only game in town.

Do I need a view reference module if I am using the Data Module?

Clarifying the relationship/reference capabilities of the Data Module

Posted by kkwaiser at 12:27 PM | Comments (0)

October 28, 2010

Code Snippets for Rules

Execute PHP Code
PHP code to execute: Block

$my_node = node_load(8223);
$my_role = $my_node->field_person_role;
if ( !empty($my_role[0][value]) ) {
print "Hurray!";


$my_user = user_load(1);

$diff = $my_user->login - $my_user->created;
if ($diff < 30) {

print "created = ";

// return TRUE;

print "ELSE!";
//return FALSE;


print "account = ";
$acc_uid = [account:uid];

$my_user = user_load([account:uid]);

$diff = $my_user->login - $my_user->created;
if ($diff < 30) {

print "created = ";

// return TRUE;

print "ELSE!";
//return FALSE;



Posted by kkwaiser at 07:26 PM | Comments (0)

Virtual hosts and multisites


symbolic links from one directory to core files in another

Virtual hosts

Sites available
$ ls -al /etc/apache2/sites-available/

$ ls -al /etc/apache2/sites-enabled/

Apache modules enabled or available
must have mod-rewrite enabled

To get site into sites-available
cp default foobar.example.com

Move a website from available to enabled
sudo a2ensite [site URL]

Link to Inigo's blog entry on this

Posted by kkwaiser at 03:24 PM | Comments (0)

Cron notes with Marsh


set URL
Enabled services:
- watchdog
-- watch url/cron.php
-- pager with hit cron.php every 15 minutes, if no hit then site is down and will receive email

man cron

crontab is how to invoke cron from cli

get into edit mode:
sudo crontab -e
select nano

Default crontab file:
# m h dom mon dow command

Configure crontab to hit cron.php every 15 minutes:
0,15,30,45 * * * * wget http://informationmanager.eeb.lsa.umich.edu/beta/cron.php
will hit on the hour, 1/4 after, 1/2 past, etc...

Posted by kkwaiser at 03:07 PM | Comments (0)

October 27, 2010

Panels Tutorial

Panels Node Template:

Enable Modules:
Panel nodes
Views content panes
Page manager (Optional)
Stylizer (Optional)

Go to Panels admin page (admin/build/panels)

Edit Node Template (admin/build/pages/edit/node_view)
Add Variant
- Name: DataSet
- Selection Rules
- Create Variant or Update and Save?? Take the former
- Selection Rule > Node: Type > Add > Node Being Viewed > DataSet > Continue
- Choose Layout > Flexible > Continue
- Panel Settings > Continue
- Panel Content > Update and Save

Layout Design
Pane (piece of content) or region (each column or region)

1) Add Region for Personnel
- Content > Show layout Designer > Row > Add Region to Right > Personnel

2) Add Region for Variable Information
- Content > Show layout Designer > Column > Add Row to Bottom > Add Region > Variable Info

3) Update and Save

Add Content

Content > Gear in Region of Interest > Add Content > Node > Methods (field_dataset_methods)

Add Relationship

1) Contexts > Relationships > Node from Reference
- Node: Node being viewed
- Identifier: Owner Reference
- Keyword: ownerreference
- Node reference field: Owner
- Save

2) Now you can add fields associated with the Owner (Person content type)

Add Variable View:

Create a View of DataSet Variables

Add View
Add Content Pane
Change Name (Under Basic Settings)
Change Style -> Table

Add Argument [NID]
Add relationship: Data File - field_dataset_datafile_ref
Add Field: Node Title

Add relationship: Variable - field_datafile_variable_ref > Data File Relationship
Modify Field: Node Title -> add Variable Reference relationship

Input on pane config:

Tweak Field Labels

Configure Arguments
Argument Input > Edit > From Context > Required Context: Node: Node ID

Posted by kkwaiser at 01:05 PM | Comments (0)

October 22, 2010

Approximate a dynamically constructed link or menu item using Rules

Goal: Dynamically construct a link that forwards a user to their edit content profile page (e.g. www.foo.com/user/1/profile/person).

Problem: Drupal's Core menu system is not token-enabled. The tricky part is that the 1 must be dynamically replaced with the [User:ID] of whomever is logged in.

This concept can be applied to both internal links and menu items.
This is something of a workaround and there are no doubt other ways to accomplish this.

Some familiarity with all modules employed here.
A content type call Person which is part of the user profile.
No knowledge of PHP or the Drupal API.

Content Profile
Token - to get the User ID info
Path Rules - Allows you to "Check Path" of destination URL.

1) Create a Page. Call it pageX

2) Under "URL path settings" set a custom URL for pageX. Call it pageX-url. You can also just remember the Node ID and use that instead of a custom URL.

3) Pick a menu to modify (admin/build/menu) and add a menu item that directs users to pageX (path: pageX-url) when clicked on.

4) Configure a rule (admin/rules/trigger) that redirects users who are about to visit www.foo.com/pageX-url to www.foo.com/user/[user:ID]/profile/person:

- Event: "Content is going to be viewed"
- Condition: "Check Path" where the path to check for is "pageX-url"
- Action: "Page redirect" where To: user/[user:uid]/profile/person

5) Navigate to www.foo.com/pageX-url, you should be forwarded to the edit form of the user profile listed above.

Posted by kkwaiser at 12:09 PM | Comments (0)

October 20, 2010

Rules links I don't want to lose

Cancel Post Action for when using "Content is going to be saved"

Field validation lacks a content argument

Rule Event show/hide field A depending on field B value

Can't activate Form Events on a Second Form ( Events for node_type_form have already been activated.)

Triggered Rules vs. Form Events

match an empty field

Check null value in form field

Creating a node programmatically

Using Rules for Node Validation

Posted by kkwaiser at 04:46 PM | Comments (0)

More thoughts on species-related resources at UMBS

I received feedback from our Resident Biologist, Bob Vande Kopple, on the idea I outlined in a previous post. Here are his thoughts, followed by my response.

Hi Bob,

Thanks for the thoughtful reply. In terms of goals, I see four primary species-related resources at UMBS:

- Species presence lists
- Datasets pertinent to a species, taxon, or taxa
- Pubs pertinent to a species, taxon, or taxa
- Biological Research Collections

My goal is to compose a system that is capable of integrating these resources based upon their common thread (i.e., the species) much as we have done with the researchers, publications, research sites and datasets.

Because this is a gargantuan project, my goal is that the process underlying it resemble building blocks. For example, to include a species list (e.g. mammals or insects; they can be done independently) we need two components:

1) A hierarchical, taxonomic list that ranges from Kingdom->Genus
2) A Species "entity" that refers to the correct Genus and includes additional information such as source and region found in.

Once this list is built, the species can later be referenced to relevant Datasets and Pubs. Once the research collection are digitized, each item in the collection can reference the appropriate species (thereby completing the quadfecta and completing a Tree of Life for Northern Michigan.)

Other thoughts:
Planning for how classes will use and contribute to this is a very good idea and should also be done at the outset.

The size and complexity of the insect (or algae?!?) list is indeed intimidating.

Actually, the whole project is intimidating and the way to get this done, in truth, is for us to find grant money that would bring in others to assist. That is what I REALLY want to do. Want to help me write a grant??



Posted by kkwaiser at 11:29 AM | Comments (0)

October 13, 2010

Sending Emails from a Drupal Site

Oh boy. Here comes another brute-force learning exercise. The goal this time is to auto-email a node (e.g., housing application) upon creation.

First, the modules:

PHPMailer - "Adds SMTP support for sending e-mails using the PHPMailer library. Comes with detailed configuration instructions for how to use Google Mail as mail server."
- Couple thousand users, D7 dev version available

SMTP Authentication Support - "This module allows Drupal to bypass the PHP mail() function and send email directly to an SMTP server. The module supports SMTP authentication and can even connect to servers using SSL if supported by PHP."
- ~10,000 users

Views Send - "Views Send allow sending mass mailing using Views Bulk Operations."
- Issues entitled "Send nodes as messages" with uncommitted patch
- <200 users

Printer, e-mail and PDF versions - "This module allows you to generate the following printer-friendly versions of any node:

* Printer-friendly version (webpage format) (at www.example.com/print/nid)
* PDF version (at www.example.com/printpdf/nid)
* Send by-email (at www.example.com/printmail/nid)
- Issue "Option to send node content as an attachment to the e-mail" with a committed patch.
- ~35,000 users + D7 dev version

MimeMail - "This is a Mime Mail component module (for use by other modules)."
- 24,000+ users, No D7 version in the works
- Posts here and here on sending files as attachments (vs nodes)
- How to use mimemail
- Patch to send HTML emails via Rules.

Send - "Uses the Mime Mail module to send HTML emails containing the a node body or teaser"

Posted by kkwaiser at 09:19 AM | Comments (0)

October 11, 2010

User registration workflow: URL redirects

Current state of things:

1) Registration Portal page - splits registrations into Instructional and Research pathways

2) User and Person Registration - Collects personal information (address, etc.) and creates user login. Linked from 1).
a) I switched from CCK3 (Multigroup) to CCK2 because I was getting errors. This page is relevant to the error. See related materials as another post of mine.
b) I removed email authentication because it conflicted with the URL redirect. Should experiment more with this though? Similar post here.

3) Create Research Project for Researchers. Auto direct from 2).
a) Had issues with Rules Module Redirect + Content Profile not entering profile data into the database. Solution here. Similar post here.

4) Create Housing Application. Auto Direct after completion of 3).
- Need to look at this more. The rule redirects every time a research project is created which is too often. I really just want it to happen the first time someone logs in.

Posted by kkwaiser at 12:17 PM | Comments (0)

October 08, 2010

How to for the Data Module

I'm still wrapping my head around this module. Basically, it allows you to expose individual tables (data tables) to the Views module. Here are my notes. The original post is here.

Note, a colleague also experimented with the Data Module and posted his notes here.

- The Data Module and its required modules are installed/enabled.
- Basic working knowledge of Data and Views
- Ability to do direct database insertions

1) Create new Table by going to admin/build/data/create
- An export of my table, data_table_x, is attached.
Note: I used phpMyAdmin to make my ID column auto-increment

2) Insert data into data_table_x
- I used phpMyAdmin to manually insert 3 rows :
id, variable_x, node_ref_id
1, 234, 8021
2, 253, 8021
3, 323, 8021

- The first two columns are arbitrary, node_ref_id column contains the NID of the node I want to reference.
- The Feeds module can be used to accomplish steps 1 and 2.

3) Relate to nodes. Go to admin/build/data/edit/data_table_x/node and specify the Content Type you want to relate to and the column with the NID of the node you want to relate to (node_ref_id, in this case.)

4) Browse to admin/content/data/view/data_table_x, you should see your data. If not, then back to the drawing board with you.

5) Manually populate data_table_node table.
- Again, through phpMyAdmin, I inserted 1 row:
nid, data_table_name, id
8021, data_table_x, 8021

- Note: Is it by design that you need to manually update this table? I do not know.

6) Modify view so the Node Title of the referenced node is visible.
- Edit data_table_x view: admin/build/views/edit/data_table_x
- Add a relationship: Data node: Data table
- Add another relationship: Data node: Node
- Add Node Title field (with mandatory relationship) > "Exclude from display" & "Link this field to its node"
- Modify Table > Style Options to group by Node Title.
- Save
- See export of this view attached.

- The relationship 'Data node: Node' is not available until relationship 'Data node: Data table' is added
- Node Title field cannot be added until relationships are specified

Posted by kkwaiser at 04:12 PM | Comments (0)

October 07, 2010

Evaluating CCK3 and MultiGroup

As part of building a new registration form for UMBS I am considering switching from CCK2 to CCK3, which allows for "Add New" abilities for grouped fields such as Address or Arrival/Departure dates. Here are some important resources:

Usage stats for CCK 6.x-3.x-dev

Relevant Forum Issues:

Support for multiple entry fields and field groups in CCK token

Status of CCK3 and plans for D7
- The last line of this comment summarizes my trepidations vis-a-vis CCK3.

Figure out whether Fields API and Multigroup module can coexist - Discussion on future of multigroup
- Current status of CCK3 summarized in this comment

State of the multigroup module

Possible alternative modules:

Other Critical Questions:

Compatibility of CCK3 with Content Profile for User Registration
- Latest patch for this functionality here.

Similar to above issue.

Posted by kkwaiser at 02:11 PM | Comments (0)

October 06, 2010

Note about sorting Content Taxonomy Fields in Views

This comment says it all:

The ability to do so is there, it's just not immediately obvious.

Although creating a content taxonomy field and throwing it into a table produces a column of term names, Views only sees the data as a bunch of tids. Because of this, allowing the sorting on that column would produce some unintended results.

Instead, you need to create a relationship. Once you've created your Content Taxonomy field, go to your View and add a relationship. Under the "Content" selections, pick the Content Taxonomy field you want sortable. Save that, and now you need to create a new field. Select "Taxonomy: Term" as your field and continue. In the new options and in the "Relationship" dropdown, select the relationship that you just created, make any other changes you'd like, then click the "Update" button.

At this point, you should be able to click your "Style: Table" gear and be able to sort by term name. Just remember to save the changes to the View itself! =)

Posted by kkwaiser at 09:14 AM | Comments (0)

September 28, 2010

Importing Contents Types in Drupal


1) Go to the training site and login.

2) Go to the Content Type Import page (Administer > Content Management > Content Types > Import)

3) Open the DEIMS* content type repository in a new browser tab

4) Select a content type and copy only the PHP code

5) Return to the drupal training site and paste code into the import box

6) Click Import

7) View the content type settings and fields by clicking on Edit and Manage Fields

8) Wash and repeat as needed

*Drupal Ecological Information Management System

Posted by kkwaiser at 03:55 PM | Comments (0)

September 20, 2010

Potential Registration solution

Going to skip the intro for now.

Interesting resources and modules:

Content Profile Module allows you to associate one or many custom content types with a registered user. For example, the Person content type (which hold the name, address, institution reference) could be linked to a User. There is the ability to make the content type part of the User registration process. Multiple content types can be part of the content profile, meaning a Research Project could be part of the registration process as well. Very. Cool. Module.

- How does the content profile module work? That answer is the in this comment (like it was a secret that someone mistakenly let slip.)
- A sketch of an approach for having different registration processes for different roles.
- Interesting issue with good module suggestions: My user flow: choose role, register with partial profile, complete profile
- This post explains how a single user can create multiple content-profile-related content types without getting the error "User already has associated profile." Basically, you set the Author to Anonymous.

Auto Assign Module "provide[s] an automatic assignment of roles when a new account is created.... [It] allow[s] the end user the option of choosing their own role or roles when they create their account and provide[s] paths that will trigger a specific role when an account is created."

- My use case with this module may allow Users to select their role at UMBS (e.g., Teaching Faculty, Graduate Student, PI, etc.) which would then (purportedly) shuttle through a different registration process. See the "My user flow..." link above for more.

- Looking more at this module, it does seem that AutoAssignRole allows two different roles to have different content types associated with them through its integration with Content Profile. For example, both the Instructor and Researcher roles would associate with the Person content type but only researcher would have the Research Project content type associated with it. Multiple registrations forms seems possible with AAR + CP.

Profile Role Module appears to be redundant with AAR (above) but I haven't look into it much.

Automatic Nodetitles is a helper module that would remove the node title field from the registration form.

Email Registration Module - Users can register with an email, no username necessary meaning the username can be removed from the form.

Rules Module for automating processes; good discussion here.

Login Toboggan Module offers several extensions to the login system.

Workflow Module - don't know anything about it, just a bookmark.

Unvetted but interesting modules

User Import


Posted by kkwaiser at 04:43 PM | Comments (0)

September 17, 2010

GMap with KML overlays in Drupal

I've started messing around with the idea of converting our spatial data to KML files to allow us to display on the website. Here are some notes:

Modules Needed:
GMap Addons

To add the same overlay to every node of a given content type:

1) Create your custom content type (call it cct)
2) Add a Location field to the CCT (call it cct_location)
3) Edit the settings of cct_location (admin/content/node-type/cct/fields/field_cct_location)
- Add your macro in the GMap Macro section. My test case uses this code:

[gmap |overlay=kml:http://www.ancientforestnationalpark.org/AncientForestParkGoogleEarth.kml | zoom=3 |center=40.49709237269567,-121.7724609375 |width=100% |height=800px |control=Large |type=Physical]
4) Make sure your CCT is set to display GMaps when viewing the Full Node (admin/content/node-type/cct/display)
5) Now Create Content > cct and add a location. Be sure to put to put in a Location Name (and lat/long or address.)
6) View your node.

Add an overlay to a particular node of a given content type:

1) Create your custom content type (call it cct)
2) Create a GMap Macro Filter for the Body text box. I swiped the following from here.

Go to your input formats config page at admin/settings/filters
Click 'configure' next to the input format that will be used for the content where the map is to be included (typically filtered HTML)
Check 'GMap filter' and save

Now when you insert a gmap macro into a page it should automatically turn into the map with your marker.

3) Create Content > cct
4) Past your macro into the text body. Under Input Format, select GMap Macro. My test case uses this code:
[gmap |overlay=kml:http://www.ancientforestnationalpark.org/AncientForestParkGoogleEarth.kml | zoom=3 |center=40.49709237269567,-121.7724609375 |width=100% |height=800px |control=Large |type=Physical]
5) View your map.

Note: This should also work if you add a cck text field

Add an overlay to a View:

1. Add Node View
2. Add Page Display
3. Set Path
4. Change Style to GMap
5. Change settings for GMap style. Add a macro (or two):
[gmap |overlay=kml:http://gcrc.uga.edu/public/uploads/GCE_site_boundaries_20090724T114716.kml]
[gmap |overlay=kml:http://www.ancientforestnationalpark.org/AncientForestParkGoogleEarth.kml]
Note: I found these kml files on the web by googling "polygon filetype:kml"

6. At this point, you will need to add fields (a requirement of Views). I followed this tutorial the first time I experimented with Gmap + Views. If this part confuses you, you've got a ways to go.
7. Save and navigate to the Path URL.

- If you get an annoying popup window that says only "gmap-auto1map-gmap0" this issue may help #341589: Browser error on overlay

Posted by kkwaiser at 03:27 PM | Comments (0)

September 14, 2010

Differences between $Drush cron and web cron

Oh man, I just learned that clearing your cache and running cron via the web interface vs drush's command line are two different beasts. In the latter case, cron goes into files that the web cron doesn't touch.

This caused problems for me because I hadn't set the base URL and I operate in a subdirectory (e.g., www.example.com/subdir is my homepage.) The problem arose around my gmap pages; the full story is here.

I suppose the moral is to set your Base URL in settings.php if you're working out of a subdirectory.

Posted by kkwaiser at 02:35 PM | Comments (0)

September 13, 2010

Referencing Views from Nodes

I'm interested in finding a functionality similar to the CCK Node Reference module that can point to Views. Here are some options/resources:

View Reference Module adds a CCK Field that will autocomplete with the list of views. Haven't tried it but I'm optimistic.

View Field module - have tried it out and it does work but something about it had left me wanting more.

This issues compares ViewField to NodeReference (from NR perspective.) Nice list of similar modules too.

Both viewfield and viewreference have a solid usage community but they seem to take fundamentally different approaches. I need to learn a bit more about the pro's/con's of those approaches.

Right name, wrong functionality:

Views Attach "will show all nodes that nodereference TO the node currently displaying (plus whatever other filters you have)."

Node reference views "is fundamentally different from modules such as Viewfield, View Reference. These give you a field where you pick a different view for each node. Contrast with this module, where the same view is shown on all nodes: what differs is the list of nodes within the view, which are those you picked in the CCK node reference field."

Not a chance:

Insert View module: Any module that greets you with a security disclaimer is a non-starter for me.

Posted by kkwaiser at 01:33 PM | Comments (0)

September 10, 2010

Post-Installation Notes on using Drush

First things first:
- Change to the root of drupal install before running Drush commands (there may be a way around this, likely involving Alias(?))

Within Drush FAQs
$ drush help

Run Cron:
$ drush cron -v

View available updates:
Navigate to admin/reports/updates
$ drush up (then press n to abort)

Update a module:
$ sudo drush up webform

Note: some modules appear to have spaces in the name (e.g, jQuery UI), use sm to find the actual module name:

$ drush sm
$ sudo drush up jquery_ui

Update database:
$ sudo drush updatedb

Posted by kkwaiser at 10:13 AM | Comments (0)

How To Install Drush

Here are my notes on getting drush installed on my dev machine:

1) Get installation directions (inside README.txt) by going to the Drush FAQ. Read instructions.

2) Download the latest version of Drush from the project page.
$ sudo wget http://download.pear.php.net/package/Console_Table-1.1.3.tgz

3) Unpack the tar.gz into your desired directory. I put it in /opt (not sure if that is recommended practice though.)

$ cd /opt/
$ sudo mv drush-6.x-3.3.tar.gz /opt/
$ sudo tar -xzf drush-6.x-3.3.tar.gz

4) Make the drush command executable
$ sudo chmod u+x /opt/drush/drush
$ sudo ln -s /opt/drush/drush /bin/drush

5) Check if drush is working
$ drush help

I got this error at first:
exec: 53: php: not found

The fix, for me, was buried in this tutorial:

If you get an "exec: 53: php: not found" error after running the last line ("sudo drush dl drush_make") you might have to install the PHP command line interface, with

sudo apt-get install php5-cli

From: http://groups.drupal.org/node/70268

6) Check if drush is working, again:
$ drush help

New (but helpful!) error:

PHP Deprecated: Comments starting with '#' are deprecated in /etc/php5/cli/conf.d/mcrypt.ini on line 1 in Unknown on line 0
Drush needs a copy of the PEAR Console_Table library in order to [error]
function, and the attempt to download this file automatically failed
because you do not have permission to write files in
/opt/drush/includes. To continue you will need to download the 1.1.3
package from http://pear.php.net/package/Console_Table, extract it,
and copy the Table.php file into Drush's directory as
Drush could not execute.

6) Do what the Error Message tells you to do:
- Download the PEAR Console_Table library

$ sudo wget http://download.pear.php.net/package/Console_Table-1.1.3.tgz
$ sudo tar -xzf Console_Table-1.1.3.tgz
$ sudo mv Console_Table-1.1.3/Table.php /opt/drush/includes/table.inc

7) Check if drush is working, yet again:
$ drush help

8) Success, next step is to learn drush commands.

Posted by kkwaiser at 09:38 AM | Comments (0)

September 09, 2010

Summary of mapping modules in Drupal

First off, here is how I'm currently mapping in Drupal:


GMap Module
Location Module
Plus: CCK, Views, CTools, Panels

The Location module supplies the ability to associate locations with nodes in (at least) two ways: 1) Node Location (similar to a Node Title) and 2) CCK Location Field. I use the CCK Location Field. Location also offers Views integration.

The GMap module (maintained by the same team as Location) adds Google Map interface capabilities to the Location and Views module.

I use GMap and Location to georeference nodes of the Institution and Research Site content types. Examples are here:

A View of the sites comprising our research site gazetteer. Note, I am using Jef Poskanzer's Clusterer to group sites.

Here is an example of a research site. The GMap shown is a View modified from that listed above. Basically, I added an NID argument (taken from the URL) to show only the given research site and a tiny GMap macro that autozooms and resizes the map.

I also associate an Institution with nodes of the Person content type and map them here. This is less functional, but it is cool to see where our visitors (researchers, faculty, students, others) come from.


Additional Modules

GMap Addons Module - allows overlay support for KML and other layers. Also, more baselayers. Same maintainer as GMap and Location (bdragon.)

Mapstraction Module - Integrates with Location and Geo Modules to allow the user to select any of a number of mapping services. Low usage numbers. Documentation here.

Geo Module - similar to Location but with support for lines and polygons. Perhaps more advanced in terms of loyalty to GIS principals?

Notes: there's an uncommitted patch for GMap to support polygons.

Geocode and Postal Modules have same maintainer as Geo Module (Allie Micka) and seem designed to extend that module.

OpenLayers Module - the non-proprietary version of the GMap Module? Seems to standalone (don't need Geo or Location.) In fact, integration with Location may not work. This video indicates that OpenLayers is more powerful but harder to use than Gmap. Can create polygons and lines via point and click map interface.

Posted by kkwaiser at 09:42 AM | Comments (0)

September 01, 2010

Revisiting the Taxonomy XML module

I decided to try out the Taxonomy XML module's web service support again. Made a bit more progress this time but am not convinced this is a better solution than building my own species taxonomic vocabulary in Drupal.

Here are the notes:

1) Installed the latest dev version of Taxonomy XML (6.x-2.x-dev).

2) Enabled the Taxonomy GUID and Taxonomy Import/Export via XML

3) Import a taxonomy
- Browse to admin/content/taxonomy/import
- Target Vocabulary: Create New
- Data Source: Web Service
- Taxonomy Server: Biodiversity ... LSID Web Resolver
- Unique Identifier for this service: urn:lsid:ubio.org:namebank:11815
Note: Example LSID taken from the LSID Web Resolver website.
- Optionally enable the "Recurse down the taxonomy tree"
- Import

4) Checking out new taxonomy

A taxonomy is actually created
It doesn't appear to read the schema correctly as the names are almost all incorrect (the LSID is used in place of the actual name.)
Descriptions don't seem to appear either.
Hierarchy seems to import correctly.
Recursion option seems to work

Final point worth mentioning is that there doesn't seem to be a search function (within the LSID resolver) meaning you need to know the full LSID before you can import.

Posted by kkwaiser at 11:43 AM | Comments (0)

August 25, 2010

Drupal and JQuery UI

The Date module now requires the JQuery module. Here are the steps to installing it.

1. Download and unpack the JQuery module into sites/all/modules
2. Enable the module at admin/build/modules. Save.
3. Notice error messages at top of page after saving:

* The jQuery UI plugin is missing. Download and extract it to your jquery_ui module directory. See README.txt for more info. (Currently using jQuery UI Not found).

- The warning contains a link to this (not-so-helpful) page. I changed the drop-down menu to "All downloads" and picked jquery.ui-1.6.zip which has over 94,000 downloads.

4. $ sudo mkdir /sites/all/modules/jquery_ui/jquery.ui/
5. Unzip jquery.ui-1.6.zip into jquery.ui/
6. Run update.php
7. Enable JQuery UI

8. Date PopUp should work correctly now.

Posted by kkwaiser at 09:11 AM | Comments (0)

August 24, 2010

Move production site to development environment

% tar -czf live_sites_backup_8_24_2010.tar.gz /blah/sites/
$ sudo tar -czf alpha_sites_backup_Aug10_delete.tar.gz /blah/sites/*

$ mysql -u root -p beta < /blah/umbs_live_backup_8_24_2010.sql

where beta is the database to be appended to (already existing tables are kept in tack.)

comment this line out of settings.php
#dl( 'gd.so' );

chmod a few files in sites/default/files

- Pretty sure you will also need to go into the database and manually disable the secure pages and perhaps another module.

Posted by kkwaiser at 04:04 PM | Comments (0)

August 15, 2010

Storing data in tables (not csv's)

Updated section on the Data module with pointers to relevant forum posts.

Spent the morning investigating the ways in which a datafile can be stored in drupal. As with images and other complex questions, there are many (attempts at) solutions:

Warrant further investigation:
Webform module - could work for data entry because one webform is a node and each form submission ends up as a row in a table. Views compatibility seems to exist. Would need a separate solution to cover datafiles that are already digital?

Data module helps you model, manage and query related sets of tables. See posts #1 and #6 in this thread. This post hits on D7 and has a few other tidbits as well.

Discussion about moving Data to D7.

While you're not obligated to install it, you need the Schema module for the GUI in Data to work.

Table Wizard module - somehow similar to Data module. Compatible with Views2

CCK TableField module allows you to attach tabular data to a node in Drupal 6 or any entity in Drupal 7. Data is stored in a single db field so I don't know how handy it is for large datasets. CSV import available but primitive. Views can display the table.

Node Table module provides functionality for creating, uploading, editing, and presenting HTML tables within nodes or as nodes. Similar to table manager.

Dead in the water:
Dataset module is for grouping nodes together in sets. Nice name, not relevant

Table Manager module - the maintainer is trying to merge this module with Node Table.

Views Table Group Module is a Views style plugin to display Views results as cells in a table, grouping by row and column. - 1 dev commit thus far, although no bugs.

Cool but not relevant:
DataTables module appears to be for theming Views table views. Still in dev.

Posted by kkwaiser at 11:24 AM | Comments (0)

August 12, 2010

Receive Drupal Security Announcements

To sign up for security notices you need to have a drupal.org account. Then you go to My Account > Edit > My Newsletters > Security Announcements > Save. It seems I update modules/core about once per month.

Posted by kkwaiser at 09:20 AM | Comments (0)

July 21, 2010

Hide exposed search filter

I've figured out how to place a search filter into a Panels template but now I want to hide it when the view doesn't appear. When you expose the filter it appears as a block so I'm assuming the correct PHP snippet in the block configuration would hide it. Here's what I've found thus far:

Tiny snippet here.

This post uses views validation stuff.

MerlinOfChaos makes a point here that the filter is built before the view content is populated. Does this mean it's not possible to hide the exposed filter if the view is empty?

Posted by kkwaiser at 09:20 AM | Comments (0)

July 19, 2010

Force file download of csv's

One option is the Drupal module:

Another may be outlined here (find htaccess or mwinter parts):

Posted by kkwaiser at 01:30 PM | Comments (0)

July 15, 2010

Panels + Views with Arguments

I've found that passing arguments from Panels to Views via the Default or Page view type to be very simple. Passing the same arguments to a Content Panel is not nearly as easy though. Here's what I've figured out:

Helpful Links:
This comment is a solution although it bypasses Panels arguments altogether so it's a bit of a workaround.

Settings for Views:
Arguments > Node:NID (No Relationships, Hide View if no Argument)
Pane Settings > Argument Input
- Node:NID Source > From Context
- Required Context > Node ID

Settings for Panels:
Add the Content Pane to the Panel (Add Content > Views Panes)
Settings > Node: Node ID > Node Being Viewed

Note that I'm working with the Node Template panel which means a context is predefined. If you're working with a different panel you may need to define a context.

Posted by kkwaiser at 10:57 AM | Comments (0)

June 22, 2010

Drupal permissions


Need the ability to restrict access to specific (data) files based upon the user role but allow access to the metadata. The file and metadata are part of the same content type.

Ideally, when a file is uploaded the user would select which users can access the data.

Node Access will allow to a node based upon user role. Sledgehammer instead of scalpel as it blocks access to entire node and not just the filefield.

Content Permissions - "set field level permissions for CCK field." After enabling the module go to admin/user/permissions to set view and edit features for fields.

A recommended solution with .htaccess. Specific to directory though meaning would need separate directory for data sets not to be release.

A really great discussion on different methods.

Content Access module

Access Control List

Posted by kkwaiser at 10:55 AM | Comments (0)

June 10, 2010

Insert module and absolute vs relative paths

When using the Insert module to insert images into a text field in drupal, the default is to use absolute file paths. In order to use relative image file paths (e.g., /sites/default/files/Firefox_wallpaper_0.png) you need to update settings.php with this line.

Posted by kkwaiser at 12:52 PM | Comments (0)

June 09, 2010

Building a "Sensor" Content Type

I've been toying with the idea of creating a "Sensor" content type for the Drupal site. As of now, the fields would mimic what is generally found on a sensor spec sheet but the Alliance for Coastal Technologies also has an implementation worth copying.

Once a sensor is created, then research projects, research sites and data files (or data sets?) that use a sensor could (node) reference it. There are several reasons to pursue this idea:

- A GMap mash-up could easily show where we have sensors deployed
- A dynamic list of the sensors, with their particulars, could be easily generated.
- At some point, the sensor metadata could be included in the overall metadata sheet that accompanies a data set and data file.

A use case example would be a researcher who wants to know if we are collecting a particular variable. A search of deployed sensors for that variable could indicate the general location, data sets and contact personnel.

Posted by kkwaiser at 04:24 PM | Comments (0)

May 19, 2010

Panels and Images

Not that this blog has any followers, but if it did, they would notice that a reoccurring theme is Drupal + Images. Essentially, how to make Drupal + Images = Good.

Thus far, I believe I've made the correct decision in going with the CCK + ImageField approach outlined in this post. However, I've begun messing around with Panels which has re-opened the Image equation:

Drupal + Panels + Images + X = Good

What composes X? And is it really a direct relationship? Maybe something like this is closer:

Drupal + Panels + Images + Log(sin(X))2/0 = Good

I'm not a math-wiz but sometimes imaginary numbers seem fairly descriptive of Drupal.

I'm currently thinking that X is composed of ImageCache (see my notes here) thereby allowing preset sizes to enforce uniformity) and a CCK "Image" content type composed of an imagefield that users would upload images to. With the latter, you could easily create a gallery with views (and with the help of an image vocabulary one could parse the images into several galleries) AND you could draw the images into panels. This commenter and merlinofchaos appear to agree with parts of what I've stated, which is encouraging.


Posted by kkwaiser at 09:23 AM | Comments (0)

April 27, 2010

Customize Biblio endnote export to include citekey (hack)

The Biblio module auto-increments a citation key but this key is not included in the Endote Tagged export by default. Here is a hack to include the citation key. In this case, I export the citation key into the Accession Number field.

1) Open the file containing the biblio_endnote_tagged_export() function: ~sites/all/modules/biblio/biblio.import.export.inc (Line 864)

2) Go to line 923 and change this:

if (!empty($node->biblio_accession_number))
$tagged .= "%M ". trim($node->biblio_accession_number) ."\r\n";

to this:

if (!empty($node->biblio_citekey))
$tagged .= "%M ". trim($node->biblio_citekey) ."\r\n";

Explanation: As mentioned, Biblio can be setup up to auto-increment the citation key (admin/settings/biblio > citekey). These values are stored in the "biblio" table as the field "biblio_citekey". All you are doing is substituting one database field for another.

3) Save the file and test the export.

Posted by kkwaiser at 10:31 AM | Comments (0)

April 23, 2010

Counting number of records in a View

I've added a counter to the Visitors page that shows how many people we are expecting. I swiped the code from here


and placed it in the View header. Cool.

Posted by kkwaiser at 10:42 AM | Comments (0)

April 09, 2010

Getting Panels going

1) Get the latest version of Panels and Chaos Tools

2) Put these modules into sites/all/modules

3) Go to admin/build/modules and enable:
- Views Bonus: Panels
- Panels
- Chaos Tools
- Ctools Page Manager
- CTools Views Content Panes

4) Create a panel.
- Go to admin/build/panels > Panel Page
- Follow this tutorial for more: http://drupal.org/node/206792

Posted by kkwaiser at 11:33 AM | Comments (0)

Updating modules on Live site

This entry outlines how to update a module on the live site using Views 2.10 as an example.

1) View the status of module for the site: admin/reports/updates

2) Download the appropriate modules to your local machine.

3) Put site into maintenance mode: admin/settings/site-maintenance

4) Backup the database through phpMyAdmin
- Place this file in: /Private/drupal...

5) Backup the code
$ cd blah/drupal/newModules/
$ sudo tar -czf sites_backup_4_9_2010.tar.gz blah/sites/
% cp .htaccess ~/Private/drupal/
- Place this file in: /Private/drupal...

6) SFTP the the latest version of the module to drupal/newModules

7) Unpack the new modules into sites/all/modules.
% cd ~/sites/all/modules/
% tar -xzf ~drupal/newModules/blah.tar.gz

8) *Deprecated - see extended entry for original text*

9) *Deprecated - see extended entry for original text*

10) Run update.php

11) Check status admin/reports/updates and errors admin/reports/dblog

12) Navigate to a few pages to make sure everything looks right
- NOTE: the gmap module requires another move. Copy the old sites/all/modules/gmap/thirdparty/Clusterer2.js file into the new module directory.

13) Take site out of maintenance mode

14) Check to make sure the views are functioning properly (again)

8) Delete the old module folders
% rm -rf sites/all/modules/gmap/
% rm -rf sites/all/modules/views/

9) Copy the new modules over
% cp -rf ~/Private/drupal/newModules/views/ sites/all/modules/

Posted by kkwaiser at 10:42 AM | Comments (0)

April 01, 2010

Caching Views 2 pages in Drupal

This Lullabot article on caching is great.

Here are a few links to discussion on caching in Views

I've turned time-based caching on for the research site map to see if that will decrease rendering time. Here are some numbers:

Loading the map of research sites (all 630+ sites) from home on a MacBook with safari, a (mediocre) wireless connection and the view caching set to none gives a LOADING TIME OF 16.87 seconds.

Loading the map of research sites (all 630+ sites) from home on a MacBook with safari (I emptied browser cache and restarted), a (mediocre) wireless connection and the view caching set to time-status with the time options both at 1 hour, gives a LOADING TIME OF 16.7 seconds. Although I cleared the browser cache and ran the test again and the load time was less than 4 seconds.

Since the page cache really sped things up, I'm going to leave it. Still need to make a decision on caching the query and/or html and the length of time store these caches.

This forum touches on a few points. Might be worth posting a question of about time constraints here.

For now, I've set a 6 day cache because I'm not making changes to research sites right now.

Posted by kkwaiser at 09:36 AM | Comments (0)

March 25, 2010

Related content in Drupal

There are several modules out there that publish related content for the user to encourage exploration. Here are some notes:

A comparison of four approaches, see comments for more.

- Similar Entries

- Similar Content

- Similarity (appear abandoned)

- Featured content - a newish module

- Related Links - 6.x version is beta

- Similar Terms

Posted by kkwaiser at 10:37 AM | Comments (0)

March 18, 2010

Inserting images in Drupal Blogs

How to build the ability to insert photos into text bodies, quickly resize them and give the end-user the ability to see the full size image in a slick manner.

These steps are best used with these videos:

MustardSeed has a great video on the Insert module which covers one way to insert photos into blogs and other text bodies.

Lullabot has a good video (quality is so-so) on the Image Resize Filter.

1) Download (if necessary) and enable the following modules to /sites/all/modules:

- A third-party editor for WYSIWYG: FCKeditor or CKeditor
- CCK FileField
- ImageField
- Insert module
- Image Resize Filter Module
- Lightbox2
- Blog module

2) Setup WYSIWYG.
- Download and install fckeditor. Note, at first I tried ckeditor which is not compatible with image resizing.
$ sudo mkdir /blah/sites/all/libraries
$ sudo mkdir /blah/sites/all/libraries/fckeditor
$ sudo tar -xzf fckeditor_3.2.tar.gz
$ sudo cp -rf fckeditor/* /blah/sites/all/libraries/fckeditor/

- Go to admin/settings/wysiwyg and set CKeditor to be used in Filtered HTML settings. I didn't mess with the "Edit" section at all.

3) Configure Lightbox2 at admin/settings/lightbox2/
- I didn't change anything here

4) Setup HTML Input filter for Lightbox2 and Image Resize Filter (admin/settings/filters/)
- Edit: Check Lightbox2 and Image Resize Filter
- Configure: Add <img> to allowed tags; Check "Link to the Original" and add the word "lightbox" (no quotes) to 'rel attribute' box.

5) Create a directory for blog images.
$ sudo mkdir /blah/sites/default/files/images
$ sudo mkdir /blah/sites/default/files/images/blogs
$ sudo chmod 777 /blah/sites/default/files/images/blogs/

6) Add an Image field to the Blog content type (admin/content/node-type/blog/fields)
- field_blog_image; Type = File; Form element = Image
- File Path: images/blogs
- Enable Title Text; Default = "Complete this field for accessibility purposes"
- Enable Alt Text; Default = "Complete this field for search engine purposes"
- Enable Insert button

- In the Display settings, set the image field to hidden. This means the image will only appear when inserted into text.

7) Create a post, upload an image and resize it. If it is resized from the original, when you click on the image Lightbox should pop up and takeover.

Posted by kkwaiser at 11:06 AM | Comments (0)

More on Images in Drupal

One of my goals with the alpha site is to get Bob up and running on a blog. In order to do this, I need to figure out how to handle the images. Here are notes:

MustardSeed has a great video on the Insert module which covers one way to insert photos into blogs and other text bodies.

Lullabot has a good video (quality is so-so) on the Image Resize Filter.

These are the recommended modules:
- WYSIWYG - I currently have this installed on the original demosite. You also need to download a third-party editor. From what I can tell, FCKeditor is a good way to go. The newest version is now named CKeditor, apparently.

- CCK and CCK FileField (a CCK sub-module)

- ImageField allows you to create an image field type for custom content types.

- They say ImageField pairs very well with ImageCache. A closer look at imageCache indicates a lot of dependencies (i.e., baggage) which is exactly what I'm trying to avoid at this point...

- The Insert module "makes inserting images and links to files into text areas or WYSIWYGs much easier."

- The Image Resize Filter Module allows the user to easily resize images in a text body. When the content is posted the resized image is the only image available (e.g., right-click, view image will show the same size image. People are apparently enthused about this but I'm not fully sure why.)

Posted by kkwaiser at 09:09 AM | Comments (0)

Google Analytics on Drupal

We'll probably want to do this at some point. Here's a good video introduction:


Posted by kkwaiser at 09:06 AM | Comments (0)

March 11, 2010

Load latitude and longitude into Drupal via database

Here are my notes:

1) Paired the research and their NIDs with the Lat/long data from bob.

2) Loaded this information into the location table. (reference file: insert_into_location.sql). Note, before loading the lats/longs I changed those database field settings from Decimal(10,6) to Decimal(14,10) to avoid the truncation of the coordinates I input.

INSERT INTO `database`.`location` (
`name` ,
`country` ,
`latitude` ,
`longitude` ,
`source` ,

'Sucker River' , 'us' , '46.665334' , '-85.890727' , '1' , '0'),
( 'Lake Erie' , 'us' , '41.846071885' , '-83.2438109141' , '1' , '0'),
( 'Lake St. Clair' , 'us' , '42.4906916199' , '-82.7712197327' , '1' , '0'

3) Following this site I created a temporary table and loaded the matched nid's and lid's.

(reference file: insert_into_tempTable.sql)
INSERT INTO database.tempTable(

nid, lid


'7958' , '4945' ) ,
('8003' , '5105' ) ,
('7899' , '5112' ) ;

I then transferred this data over to the proper table:
(reference file: update_researchSite_lids.sql)
UPDATE database.content_type_research_site , database.tempTable
SET content_type_research_site.field_research_location_lid = tempTable.lid
WHERE content_type_research_site.nid = tempTable.nid

4) After step 3, all of the sites mapped properly.

5) I also noticed that the LID's showed up in one additional table. I don't know what this table does, but I felt it prudent to insert the relevant information into that table as well. (reference file: insert_into_location_instance.sql)

INSERT INTO database.location_instance (
nid, vid, uid, genid, lid

'0' , '0' , '0' , 'cck:field_research_location:7958' , '4945' ) ,
('0' , '0' , '0' , 'cck:field_research_location:8003' , '5105' ) ,
('0' , '0' , '0' , 'cck:field_research_location:7899' , '5112' ) ,

Posted by kkwaiser at 08:31 AM | Comments (0)

March 05, 2010

Create biblio to research site node references

1) Query for biblio NIDs and associated research sites.

SELECT nid, biblio_custom3
FROM `alpha_biblio`
WHERE biblio_custom3 IS NOT NULL

2) Query for research site NIDs and names:

SELECT nid, title
FROM `alpha_node`
WHERE `type` LIKE 'research_site'

Currently going back to the bib and fixing names. problem with (), don't know why.

3) I used a python script to match the biblio NIDs and the research site NIDs based upon the name. In the process, I found and corrected a number of errors. It would have been more efficient to build the sql into the pyton script but I didn't want to take the time to figure that out.

#! /usr/bin/python
# execfile("/blah/scripts/combineNIDS.py")
import sys, tempfile, string, re, csv, os
fi1 = csv.reader( open('blah/biblioNID_withResearchSites.csv', 'r') , delimiter=',', quotechar='"') #biblio NIDs
fi2 = csv.reader( open('blah/researchSites_with_NID.csv', 'r'), delimiter=',', quotechar='"') # research site NIDs
fo = csv.writer( open('blah/io/matchedNIDs.csv', 'w')) # output Document
bibNID = list()
pairedNID = [["bibNID", "siteName", "siteNID"]]
siteList = list()
pairedNIDCounter= 0

# this loop pairs each research site with the NID of the respective bibliography entry
for row in fi1: #each row is a bib entry
a = row[1].split('/') #separate research sites for a given bib entry
for site in a:
bibNID.append([ row[0], site.strip() ]) # this list is each site in the bib with the biblio NID
for row in fi2: # create a reserach site list we can work with

for bibSite in bibNID: # grab a site from a publication
pairedNIDCounterBeforeTest = pairedNIDCounter # see below
for aSite in siteList: # grab a research site
#print aSite
if bibSite[1].strip() == aSite[1].strip(): # do the two sites match
pairedNID.append([bibSite[0] , aSite[1] , aSite[0]])
pairedNIDCounter += 1
#print pairedNIDCounter
if pairedNIDCounter == pairedNIDCounterBeforeTest: # if this test is TRUE, then a site from the biblio did not have a matching research which means something is wrong
print bibSite #print the biblio site that doesn't match a research site
fo.writerows(pairedNID) # this is the matched NIDs

except IOError:
print 'Can\'t open file for reading.'

4) I then used the following sql files to load the data into the database:

Posted by kkwaiser at 02:35 PM | Comments (0)

March 02, 2010

Multiple search boxes

I finally figured out how to do this:

Posted by kkwaiser at 09:43 AM | Comments (0)

Google maps notes

Here are notes on creating a block view of a gmap that shows only the research site being viewed. It uses the same view used to create the research site map I outlined a while ago.


1) Edit the view
2) add a block view
3) Add an argument:
Provide default argument > Node ID from URL
Action to take if argument does not validate: Display all values
- The last step is important because it allows all of the sites to show up when you go to view the main map. Otherwise the node NID argument for the Map view fails and nothing appears

4) The last step will be to add a bit of php to the administer > blocks > research site section. This will mimic the biblio block I created earlier and will ensure that the map only shows up when someone is viewing a research site.

Other notes. These sites look cool:

Something about Views inheriting arguments, didn't follow up on this but it may be useful in the future: http://drupal.org/node/349739

Tutorial on customizing gmaps, nice links to live websites that showcase legend and staggered loading of markers, code included: http://www.anelloconsulting.com/custom_gmap_solution_dynamically_updated_markers_part_2

Posted by kkwaiser at 09:32 AM | Comments (0)

March 01, 2010

Theme the alpha site


text-shadow:0 1px 3px #4A633D

Change the color to match the following to get the links to show up properly:

Line 566:

ul.primary-links li a:hover, ul.primary-links li a.active {
color: #4a633D;
background: transparent url(bg-navigation-item-hover.png) no-repeat 50% 0;

Line 558:

ul.primary-links li a, ul.primary-links li a:link, ul.primary-links li a:visited {
display: block;
margin: 0 1em;
padding: .75em 0 0;
color: #4a633D;
background: transparent url(bg-navigation-item.png) no-repeat 50% 0;

Posted by kkwaiser at 03:18 PM | Comments (0)

February 17, 2010

Useful bit on Menus in Drupal

Just wanted to highlight this blog post for later use. Note the segment on Navigation.


Posted by kkwaiser at 01:44 PM | Comments (0)

February 12, 2010

Create Node References via database insertions

The goal here is to create a lot of node references that point from publications held within biblio to a CCK content type, Person. Here are some steps:

1) Upload the bibliography to Drupal. Add a node reference field to the biblio content type. I called this field "bib_person_reference".

2) Go to the database (I'm using phpMyAdmin) and run this query to pull out the author names. These will be used (with Node Import) to create the Person instances:

SELECT biblio_contributor_data.cid, biblio_contributor_data.name, biblio_contributor_data.lastname, biblio_contributor_data.firstname, biblio_contributor_data.initials

FROM biblio_contributor_data

3) Export the previous query to a csv file. Here are the first rows:

Table A.
"2","Abdel-Malek, Emile Tadros","Abdel-Malek","Emile Tadros",
"3","Ackert, James E.","Ackert","James","E"
"4","Wadley, F. M.","Wadley",,"F M"

Note: I saved this file as "biblio_author_dump.csv"

4) Prep the author information for Node Import. The Node Import module has a CSV formatting requirement for inputs. Here's what an example of my formatting looks like in a spreadsheet. I then save this with comma delimiters and quotes all around.

Table B.
uid type Full name Last Name First Name Middle Name Comment settings Published Promoted to front page Sticky at top of lists Authored on
1 Person Anonymous Anonymous 0 1 0 0 2010-02-25 14:00:00
1 Person Abdel-Malek, Emile Tadros Abdel-Malek Emile Tadros 0 1 0 0 2010-02-25 14:00:00
1 Person Ackert, James E. Ackert James E 0 1 0 0 2010-02-25 14:00:00
1 Person Wadley, F. M. Wadley F M 0 1 0 0 2010-02-25 14:00:00

Note: I called this file person_create_import.csv. Also note that I tangled with the names a *bit* because the biblio module uses a different name schema than I do.

5) Import and create the Person nodes. A trick here is that I kept each person's full name (aka Node Title) exactly the same as the biblio contributor (author) full name. See the next step for why this matters.

6) Now, match the Person NID's with the Author NID's. I am able to use LEFT JOIN because the Person Title (i.e., full name) is identical to the contributor name (i.e., author name). I was extremely happy when I figured this out.

SELECT biblio_contributor.nid, biblio_contributor.vid, biblio_contributor_data.cid, biblio_contributor_data.name, node.nid, node.title

FROM biblio_contributor_data

LEFT JOIN node ON node.title = biblio_contributor_data.name
LEFT JOIN biblio_contributor ON biblio_contributor.cid = biblio_contributor_data.cid

7) I put the results from the last query in OpenOffice calc. Notice that I sorted this data by the biblioNID (it was sorted by the author name before.)

Table C.
nid vid cid name nid title
2824 2824 1 Anonymous 5643 Anonymous
2825 2825 2 Abdel-Malek, Emile 5644 Abdel-Malek, Emile
2826 2826 3 Ackert, James E. 5645 Ackert, James E.
2826 2826 4 Wadley, F. M. 5646 Wadley, F. M.

8) Next, format the data in Table C so that they can go into an SQL statment. In OO Calc, I created two additional sheets that match the tables I will insert data into:

 Table D.
Name:  alpha_search_node_links
       (biblioNID)              (personNID)   (Full Name)
            sid        type         nid        caption
            2824       node	   5643	      Anonymous
            2825       node        5644	      Abdel-Malek, Emile Tadros
            2826       node	   5645	      Ackert, James E.
Name: alpha_content_field_bib_person_reference
            (biblioNID)          	(personNID)
	vid	nid	delta	field_bib_person_reference_nid
	2824	2824	  0		5643
	2825	2825	  0 		5644
	2826	2826	  0		5646
	2826	2826	  1		5645
The delta denotes the number of authors a publication has. Delta = 0 denotes the first author, Delta = 1 denotes the second author. In this example, publication 2826 has two authors whose node ID numbers are 5646 and 5645.

9) Format the contents of Table D to create the SQL query and then run it (I used phpMyAdmin for this.) Here are two snippets of what the queries looked like in the end:

Insert data into the table content_field_bib_person_reference. This table was created when I added a node reference field to the biblio content type:

INSERT INTO `database`.`content_field_bib_person_reference` (
`vid` ,
`nid` ,
`delta` ,


'2824' , '2824' , '0' , '5643' ),
( '2825' , '2825' , '0' , '5644' ),
( '2826' , '2826' , '1' , '5645' ),
( '2826' , '2826' , '0' , '5646' )


Insert data into the table search_node_links:

INSERT INTO `database`.`search_node_links` (
`sid` ,
`type` ,
`nid` ,

'2824' , 'node' , '5643' , 'Anonymous' ),
( '2825' , 'node' , '5644' , 'Abdel-Malek, Emile Tadros' ),
( '2826' , 'node' , '5645' , 'Ackert, James E.' ),
( '2826' , 'node' , '5646' , 'Wadley, F. M.' )


Note: Some of the names have apostrophes (e.g. 0'Neill). To keep this from interfering with the SQL syntax I added an escape character (e.g., O\'Neill)

10) Finally, clear the memory cache (admin/settings/performance > Clear Cached Data)

11) View a couple of bibliography entries to make sure everything went smoothly.

Note:  The text below is scrap.  It's being saved just in case it comes in handy later.

I ran this query to pull out the person's name and NID (referred to as personNID below):

SELECT node.nid, node.title
FROM node
WHERE node.type = "person"

7) Run the following query to get the author names, their id's (CID) and the id (NID or biblioNID, below) of the publications they are associated with.

This query extracts data from two biblio tables: biblio_contributor_data and biblio_contributor.

SELECT biblio_contributor.nid, biblio_contributor_data.cid, biblio_contributor_data.name, biblio_contributor_data.lastname, biblio_contributor_data.firstname, biblio_contributor_data.initials

FROM biblio_contributor, biblio_contributor_data

WHERE biblio_contributor.cid = biblio_contributor_data.cid

8) Export the previous query to a csv file. Here are the first rows:

Table A.
"2825","2","Abdel-Malek, Emile Tadros","Abdel-Malek","Emile Tadros",
"2826","3","Ackert, James E.","Ackert","James","E"

7) I also ran this query to get the NID's of the biblio entries (biblioNID) and their associated contributor (author) ID's, or CID's.

SELECT nid, vid, cid
FROM biblio_contributor

This produced the following:

Table B.

nid vid cid
25 25 1
26 26 1
27 27 1
28 28 1
29 29 1
30 30 3
30 30 2
31 31 1
32 32 1
33 33 4
34 34 5

Notice below that I have associated the CID's (i.e., the author identifier used by biblio, with the personNID (i.e., the identifier for each person I created.) I got the personNID when I queried the test_person content type. Because the list of persons and the list of contributors are identical, all I did to associate the two was an alphabetical sort and then a paste!

Table C.

cid name lastname firstname initials personNID
1 Gates, Frank C. Gates Frank C 2982
3 Nichols, G. E. Nichols G E 2984
4 Barnes, B. V. Barnes B. V. 2985

For a quick summary, a unique personNID is associated with each cid (personNID -> cid) and the cid is associated with every publication for a given author (cid -> biblioNID). This tutorial was helpful in associating each personNID with the appropriate biblioNID's.

Using OpenOffice Calc, I put Tables B and C on the same worksheet. I added a column to the right of Table A labeled personNID. I filled that column with this equation:


$F$2:$K$1746 -> This references the dimensions of Table C.

MATCH(C2;$F$2:$F$1746;0) -> This matches the CID from Table B to the CID from Table C and returns the spreadsheet row number

MATCH($D$1;$F$1:$K$1;0) -> This returns the column number from Table C that holds the personNID.

When the row number and column number are put together, INDEX returns the value of the given cell, the personNID. This matches the biblioNID with the correct personNID(s).

2) Run the following query to get the author names, their id's (CID) and the id (NID or biblioNID, below) of the publications they are associated with. I did this through PHPMyAdmin.

This query extracts data from two biblio tables: biblio_contributor_data and biblio_contributor.

SELECT biblio_contributor.nid, biblio_contributor_data.cid, biblio_contributor_data.name, biblio_contributor_data.lastname, biblio_contributor_data.firstname, biblio_contributor_data.initials

FROM biblio_contributor, biblio_contributor_data

WHERE biblio_contributor.cid = biblio_contributor_data.cid

3) Export the previous query to a csv file. Here are the first rows:

Table A.
"2825","2","Abdel-Malek, Emile Tadros","Abdel-Malek","Emile Tadros",
"2826","3","Ackert, James E.","Ackert","James","E"

Posted by kkwaiser at 09:01 AM | Comments (0)

February 11, 2010

Automatically creating nodes

One of the bigger usability issues I've run into when creating a content type - say, Research Project - that references another content type - say, Person - is that the person may not be created yet.

Instead of having to stop everything, go create the person and then return to the research project to reference that person there is a better way. These modules allow you to create nodes of a different content type from within a referencing content type.

Node reference create allows you to create a node reference field within a content type and, when entering data into that field, if the referenced content type doesn't exist, it will be created. Of course, the newly created node only has a title (no phone number or address, for example) and you will want to add more information to the newly created person, but this module reduces the total number of clicks needed. Cool.

Autocreate node reference is similar but instead of simply creating a node with a title, it allows the user to specify a template, thereby creating a more complete node. I think...I haven't tried this one.

Posted by kkwaiser at 08:27 AM | Comments (0)

Auto-incrementing in Drupal

Quick post here.

These links were helpful in establishing an auto-incrementing id field in CCK content types.

This site explains an involved method.

The serial module does it easypeasy.

Posted by kkwaiser at 08:22 AM | Comments (0)

February 09, 2010

Feed Biblio fields into Node Reference Create

At the risk of becoming yet another duplicate in the great Biblio, CCK, D7 debate...

I have a bibliography containing ~3000 entries which contain author names (obviously) and references to research sites. Both of these are properly delimited and in separate fields (Endnote tagged %A and %1, respectively.) I also have the following CCK content types: Person and Research Site.

My goal is the following:

Use the Biblio module and Node Reference Create, to automatically feed the Author and Research Site data from the bibliography into Node Reference Create, thereby creating the respective content types and establishing the node references.

This website is still underdevelopment meaning that this could happen either during the Biblio import or after.

Assuming a proficiency in Drupal and PHP, any comments on the feasibility of this? Approximate hours needed? Potential pathways? I realize I may have to contract for this but comments from the community would be helpful prior to that step.

Posted by kkwaiser at 12:58 PM | Comments (0)

Setting up an alpha site

I am now starting a new website which will (hopefully) be deployed by April. This largely entails taking all of the good stuff I've developed on the old site and leaving all the half-finished, half-baked, outdated stuff behind. Here are notes on the process, just in case I need to do this again:

1) Create the drupal website following INSTALL.txt. This is in the subdirectory, http://localhost/alpha. I'm using a separate code base for this, I could not figure out the multi-site, subdirectory configuration for the life of me.

2) Export the desired content types and views from the original, pre-alpha, website.

biblioBlock_relatedResearchSites.php (requires block configuration/code)

Content Types:

3) Copy the appropriate modules over from pre-alpha to alpha:

serial (creates auto-incrementing ids)
taxonomy_xml (for importing the list of Counties and townships)

4) Turn on the modules and import the content types and views. My first attempts to import the researchSiteList view produced the WSOD (white screen of death.) This screen disapeared upon restarting my computer.

5) These modules require configuration:
biblio, gmap, location, probably more

6) Create vocabularies:
- UMBS Keywords - The keywords from the bibliography will populate this vocabulary
- GNIS Classes - related to Research Sites, terms for clumping sites (e.g., lakes, streams, forest). Use taxonomy_xml to import this list (GNIS_Classes.csv)
- Michigan Counties and Townships - for the Research Sites, allows clumping by geographic location. Import with node_import (Michigan_townships.txt)
- USGS Maps - for Research Sites, allows clumping of sites according to maps they are presented on. Import with node_import module (USGS_Maps_in_Michigan.txt)

to be continued...

Posted by kkwaiser at 08:40 AM | Comments (0)

February 03, 2010

Multiple Bibliographies (Biblio Collections)

Sooner or later, we are going to want the capability to host several distinct bibliographies. For example:
1) Main research papers
2) Papers related to Northern Michigan
3) Student research papers

Here are links on drupal.org that are related to this topic. The concept is called biblio collections and it has been talked about for year but not yet implemented.
Here are posts related to this subject:

The most recent Coding discussion on Biblio Collections.

This post: multiple biblios. Comments by Masood, here and Masood, here, are potential work arounds.

separate bibliographies for Biblio 5.x

More discussion on Biblio collections

Another post on multiple bibliographies for Biblio 5.x.

Posted by kkwaiser at 09:25 AM | Comments (0)

January 21, 2010

Taxonomic Solutions

The idea of organizing the Biological Station taxonomic information from scratch is over-whelming and crazy. This post will follow web services specifically related to the classification of species.

- Tree of Life web services returns an xml form.
- Encylopedia of Life (no relation) services.
- Gloval Biodiversity Information Facility, with EOL, offers web services: http://data.gbif.org/ws/

A bit of further digging has turned up two modules that are not fully developed but appear to hold promise:

The CDM Data Portal module is capable of getting information from servers that share the Common Data Model. This module appears to have basic content type information for taxonomic purposes. However, it appears to be available for Drupal 5 only.

There is also the Darwin Core Specimen and Location module which gives you a location content type and a specimen content type when installed. I tried this module out and promptly found a bug but it will be interesting to see where this goes. Rather useless tutorials can be found here and the latest version of the source code appear to be here.

These two GBIF websites also appear helpful. A list of extensions and downloadable vocabularies.

Here's a portal website to a few demonstration sites for the CDM module.

Posted by kkwaiser at 10:04 AM | Comments (0)

January 18, 2010

Exploring Drupal

This post has turned into a recurring theme as I sort through the maze of possibilities within Drupal. Here are some Drupal tidbits that deserve a follow-up at some point:


This post is by a taxonomist who is also a Drupal user. He goes over creating a biological taxonomy using the Drupal taxonomy. At first blush, it seems that the taxonomy capabilities combined with the taxonomy image module might offer a solution for our herbarium samples. Unfortunately, it seems a given taxonomic character could only be associated with 1 image.

Reconciling Data File and Variable

This page outlines how to create multiple nodes of different content types from one submission. I highlight it because we may be able to use it when creating a data file. Basically, you would enter the information for the variable at the same time and, although different content types would be created, it would be fairly seamless. Better usability there.

Here is a nice video about Drupal taxonomy. The last minute or so breezes through a few, potentially useful modules that leverage taxonomy. A comment on the same gives good resources for the Context module (see below.)

It is worth looking into features, spaces, context and panels 2 in Drupal. Within these modules is a great way to increase connectivity within the website. Context and Panels2 seem a bit redundant and I am not sure which is better to use. The whole idea of spaces is strange (surprising given the self-evident name.)


Another good video from GotDrupal. The Rules module will be useful to enforce our data access policy. We will be able to set up a rule that says, when a user tries to download a data file, re-direct the user to the policy page where they can either agree to the terms (and then download) or not. This buttons module may also be helpful.

Web services
If I can figure out how to leverage web services my life will be made much simpler and our website much better. Specifically, how to handle the copious amount of species-related information at the Biological Station.

These materials are in someway related to web services and Drupal:

- A good groups post on the subject.
- Services module to offer services from your site.
- Web services module, apparently an insecure fork of Services that will also be available for Drupal 7.
- Soap Client module for allowing modules to access web services. Current usage is less than 500 sites. Can't imagine how many hours it would take me to figure this out!
- Taxonomy XML is the most intriguing "solution" I've seen thus far. My understanding of it is incomplete but it appears that we could use it to establish taxonomic hierachies (Family -> Genera -> Species), synonyms and common names without doing recreating the tree of life.
- A video about web semantics and using taxonomy terms to bring in related material from other web servers.
Graphing and Charting Data
Initially, I expect all data files to be stored as flat files (e.g., csv, txt) but eventually, it would be great to dynamically generate graphs that summarize data sets. Here are some related links:

- Views Calc module, allows for simple calculations to be made within a view. Fairly limited but interesting.
- A blog post and tutorial on charts and graphs in Drupal.
- A dead module called Xstatistics.
- Views Charts module for integration with the Views module. Looks useful but notice dependencies.
- Charts and Graphs module, a new module that appears redundant with Charts. Probably need to install some flash stuff.

Manage Data Files as Tables

As mentioned above, I currently plan to manage data (e.g., climatic readings) as flat files. However, advances in functionality will require the data be stored as tables within the MySQL database. It looks like the Data module and the Table Wizard Module are the way to do this.

Here is a comparison of the two and here are a few videos on importing data in Drupal.

Posted by kkwaiser at 12:59 PM | Comments (0)

January 13, 2010

Redirect to a data use agreement before download

One of the capabilities our new website will require is the ability to force users to agree to our Data Use Agreement before downloading a data file. I have gotten part of the way to that goal with the steps I outline below.

Here are resources that may be helpful:

Drupal's workflow module
Drupal's actions module
A previous blog post of mine.

Creating a redirect rule

- Install the rules module

- Go to Administer > Rules > Triggered Rules > Add a new rule

- Label: Redirect to Data Use Agreement
- Event: Content is going to be viewed

- Add a condition > Content has type > Next
- Under Content Types: Select Data File

- Add an action > System > Page redirect > Next
- Under To: node/95 (points to data policy) > Save

Now, when you try to view a Data File page you will be redirected to the data policy. Ideally, the next step would be to place a button on the policy page that users would click if they agreed to abide by the policy terms. Upon clicking, they would be sent to the desired data file.

The trick is to retain the desired page (i.e., the data file) and to set another rule that directs the user to the data file. Of course, when this second rule (policy to data file) is implemented, it needs to override rule 1 (data file to policy) otherwise some sick infinite loop would be started.

To be continued...

Posted by kkwaiser at 11:15 AM | Comments (0)

January 12, 2010

Add a block view that leverages node references using views arguments

Here is a 'how to' that I am all to happy to undertake, if only because it means I have achieved something.

I've got two content types, bibliography entries (biblio module), and research sites (CCK module). I have a node reference field in research sites which references the appropriate bibliographic entries.

My goal is to create a block which will appear in the right-hand column when a user is viewing a publication. The block will dynamically populate with "Related Research Sites". The block will not appear if there are no Research Site to Bibliography references OR if the use is viewing non-bibliography content type.

Drupal 6.15
Biblio 6.x-1.9
CCK 6.x-2.6
Node Reference 6.x-2.6
Views 6.x-2.8


The ability to create custom content and node references within CCK. The biblio module is installed and populated with (at least) a few publications.

In this case, I have a custom content type called Research Sites which contains the following Node reference to the Bibliography content type:

Label: Biblio Reference
Name: field_research_site_bib_ref
Type: Node reference


1. Create a View (Administer > Site Building > Views > Add; /admin/build/views/add)
View Name: biblio_related_research_sites
View Type: Node

2. Configure the new view.
Add a Filter:
- Node: Published = Yes

Add a Field:
- Node: Nodereferrer: by field
- Using Field: field_research_site_bib_ref (Biblio Reference)

Note: I selected the node reference from Research Site to Bibliography. If do not select any fields here, all nodes that reference a particular publication will populate the block.

Add an Argument:
- Node: Nid
- Under "Action to take if argument is not present" select "Provide default argument" and choose "Node ID from URL"
- Everything else should be default.

Note: I got this crucial bit from the Geeks and God folks.

Edit Basic Information:
- Change Distinct from No to Yes.

Add a Block Display.

Save your edits.

Here is what my view looks like:

leaf graphic

(Right-click > view image for the fullsize image)

3. Administer the new block.

Go to Administer > Site Building > Blocks (admin/build/block) and drag the new block, "biblio_related_research_sites: Block", to the Right Sidebar area.

Configure the block:
- Block Title: Related Research Sites
- Under "Show block on specific pages" select "Show if the following PHP code returns TRUE (PHP-mode, experts only)."
- Enter the following code:

$match = FALSE;
$types = array('biblio' => 1);
if (arg(0) == 'node' && is_numeric(arg(1))) {
  $nid = arg(1);
  $node = node_load(array('nid' => $nid));
  $type = $node->type;
  if (isset($types[$type])) {
    $match = TRUE;
return $match;

Save Block.

4. Assuming you have a node reference within a research site to a publication, when you go to view the publication, a block should appear on the right listing the appropriate research site.

5. Here's the product with a Related Research Sites block in the right-hand column.

leaf graphic

(Right-click > view image for the fullsize image)

Alternative methods:

I am aware of at least 2 analogous solutions and I am sure others exist as well.

Using Panels 3 (specifically, Mini Panels) would no doubt get you here. I stayed away from this because I am new to Drupal and therefore believe the KISS method is best. The Panels 3 method fails this test because of the need to install the CTools and Panels modules. Besides, I'm pretty sure you need to know how to configure the View anyways...

A simpler option is to use the node referrer module. This module leverages the fact that you've already created a node reference from research site to bibliography and append the related research sites beneath the original publication. I dislike this for two reasons, 1) it is not as pretty because the styling is not inherited from the biblio module and 2) the user will have to scroll to the end of the publication in order to find the related research sites.

Posted by kkwaiser at 09:56 AM | Comments (0)

All about panels3

I spent a good deal of time looking into panels. Here is a list of resources that may be helpful in the future:



Passing arguments:

Passing arguments to a block view:
Very useful

Posted by kkwaiser at 09:01 AM | Comments (0)

January 05, 2010

Configure arguments in the Views module I

One of the over-arching goals of building a new website is to leverage connections that exist among Biological Station resources. This will manifest as suggested 'related content' boxes that populate dynamically when visitors browse our website. For example, if a user browsed to a page that described one of our researchers then the right column of that page might populate with links to data sets that researcher has developed.

Researcher -> Dataset, in other words.

I believe the most efficient way to accomplish this is to build database views that use the Node Reference or the Node Referrer modules.

Here are a few useful resources that I've located:

- Writing php code for arguments
- Using Views arguments to populate blocks
- A GotDrupal.com video on the use of arguments to limit material to particular users.
- Several examples of using php code with node references.

To be expanded, no doubt.

Posted by kkwaiser at 09:30 AM | Comments (0)

January 04, 2010

Update Drupal 6.14 to 6.15

A catalog of steps. Mostly drawing from

$ gedit drupal-6.15/UPGRADE.txt

1. Backup up the database using phpMyAdmin and this tutorial.

2. Backup the sites folder

$ sudo cp -rf /var/drupal/sites/ webBackup/

I also did a backup of the whole drupal directory due to paranoia:
$ tar czf drupal_backup.tar.gz /var/drupal/

The following symlink may need to be replaced as well:
gallery2 -> /usr/share/gallery2/

3. Take the site off-line at Administer > Site Configuration > Site Maintenance

4. Disable all contributed modules. See below the fold for a list of enabled modules. This list is generated by the Enabled Modules module.

5. Put new drupal files into place
$ sudo rm -rf /var/drupal/
$ sudo mkdir /var/drupal
$ sudo cp -rf drupal-6.15/* /var/drupal/

6. Put the old sites folder into place
$ sudo rm -rf /var/drupal/sites/
$ sudo cp -rf webBackup/sites/ /var/drupal/

7. Turn off clean urls

8. To enable clean urls again, copy the old .htaccess file over
$ sudo cp var/drupal/.htaccess /var/drupal/

9. Enabled modules (see list below the fold.)

10. Got this error:
The selected file /tmp/fileKxVVzn could not be uploaded, because the destination sites/default/files/js/gmap_markers.js is not properly configured.

Solved it with this:
$ sudo chmod 777 /var/drupal/sites/default/files/js/


Posted by kkwaiser at 11:34 AM | Comments (0)

December 23, 2009

Install Gallery2

One of the options for working with images in Drupal involves using the Gallery module which acts as a bridge to the Gallery2 opensource software package. Because the LTER content types used Gallery2, I'm installing it to evaluate whether or not to keep it in. Here's what I've done:

- Installed the Gallery module from Drupal
- Installed Gallery2 following this website.

$ sudo apt-get install gallery2
$ whereis gallery2
$ cd /var/drupal/
$ sudo ln -s /usr/share/gallery2/
$ dpkg -L gallery2

- Navigated to http://localhost/drupal/gallery2/install
- Following install wizard
- create login.txt and place in /usr/share/gallery2
- Standard installation...
- storage directory: /var/lib/gallery2/g2data
- set up a DB user through phpMyAdmin
- Set admin id
- installed all modules
- Errors:
* The ImageMagick module was installed, but needs configuration to be activated
* The Multiroot module was installed, but needs configuration to be activated
* The Nokia Image Upload module was installed, but needs configuration to be activated
* The URL Rewrite module was installed, but needs configuration to be activated

- Go to http://localhost/drupal/admin/settings/gallery and specify the URL as http://localhost/drupal/gallery2

- Skipped clean URLs of this step
- Did user synchronization

That's it for now. Merry Christmas.

Posted by kkwaiser at 04:32 PM | Comments (0)

December 22, 2009

Manage Images and Photos in Drupal

Photo and image management is not straightforward in Drupal. As an example, here is a list websites that appear helpful:

- A solid overview of many of the modules listed here.

- A tutorial on how to build an AJAX photo gallery using LightBox

- A list of websites that demo various Drupal photo/image modules.

- A tutorial on Image Picker.

- Possibly more related modules here.

And here is a list of modules that are potentially useful:

- Image
- Image Picker
- Lightbox 2
- Gallery integrates with Gallery2
- Image
- Inline
- Flickr
- Acidfree Albums
- Image Assist
- Embedded Media Field
- CCK Imagefield
- Imagefield Extended
- Imagefield Crop
- Image FUpload a bulk uploading module
- Image Cache
- Photos
Image Publishing

Posted by kkwaiser at 03:33 PM | Comments (0)

December 08, 2009

Get Tabs working with CCK

When creating custom content types, you can group similar fields to make things a bit easier one the eyes. Going one step further you can break up the content type into separate tabs which will reduce scrolling time.

It's fairly easy to set up but there is a bug so I thought I should post this. Basically, the bug leaves the Help text out of the newly created tabs.

The modules I installed to get tabs working:
- Tabs 6.x-1.2 tabs-6.x-1.2.tar.gz (http://drupal.org/project/tabs)
- CCK Fieldgroup Tabs 6.x-1.0 (http://drupal.org/project/cck_fieldgroup_tabs)

To fix use the patch given here: http://drupal.org/node/559850

This is the file that is modified:

Posted by kkwaiser at 02:45 PM | Comments (0)

November 02, 2009

Import a Content Type in Drupal 6

One of the advantages of Drupal is the ease with which you can avoid reinventing the wheel. For example, the LTER folks have created the following Content Types in Drupal:

Data Set - Title, abstracts, geo-temporal references are all part of the basics of a metadata collection
Data File - links to a csv/txt file and includes basic header information
Variable - describes the unites of measurement behind a Data File
Person - Name, contact info, etc.
Research Sites - Places where research is done
Research Project - with project title and abstract

Things to consider:

You can only import fields that do not already exist.

You need the Content Copy module in CCK. Go to Administer > Site Building > Modules > CCK > Click Content Copy > Save. See this entry for more on adding a module.

1) Administer > Content Management > Content Types > Import

2) Content Type: Create Content

3) Copy contents from the exported Content Type you received from your benefactor into the text square and press import.

4) Fail!

leaf graphic
(Right Click > View image for full size.)

The import did not go through because I did not have all of the correct Modules enabled. Note, if the sharing of custom content types is to become widespread we will need sufficient module documentation.

Enable FieldGroup under the CCK Module and reimport:

leaf graphic

5) Go to Administer > Content Management > Content Types to view the Data Set content type. It is there but I'm missing some fields because I don't have all of the modules enabled.

leaf graphic

To fix:
Administer > Site Building > Modules > Date/Time > Date Popup > Save

Posted by kkwaiser at 01:02 PM | Comments (0)

October 28, 2009

Create Research Projects Content Type with Keyword connections

I'm going to create a simple Content Type called Research Project that will hold the Metadata information collected this summer. This will serve as a way for the UMBS community to keep tabs on what is going on.

1) Here are Modules and Sub-Modules I think I need for this:

Administer > Site Building > Modules

CCK > Content, Link, Node Reference, Number, Text, Option Widgest, User References


2) Create Research Project content type:

Administer > Content Management > Content Types > Add content type

Name: Research Project
Type: research_project
Description: Research activities at the University of Michigan Biological Station.
Title field label: Research Project Title
Default Options: Published
Default comment setting: disabled

3) Manage fields

Go to content type (Research Project) > manage fields > New Fields

Added these text fields: Researcher (Check boxes/radio buttons), Abstract

Note that it is probably appropriate to create a Taxonomy of Researchers.

4) Create Keyword taxonomy list

I want to associate keywords with the Research Project so I created a list of keywords. Working off of this list from the LTER.

Because I have a large list, I wanted to do bulk taxonomy uploads (vs 1 at a time):

I went here to get a Drupal 6 module called Taxonomy Batch Operations.

$ cd /home/data/Desktop/
$ mv taxonomy_batch_operations.tar__0.gz taxonomy_batch_operations.tar.gz
$ sudo tar xzf /home/data/Desktop/taxonomy_batch_operations.tar.gz
$ sudo cp -r taxonomy_batch_operations /var/drupal/sites/all/modules/

Then go to enable the Module.

Administer > Content management > Taxonomy > Add vocabulary

Vocabulary name: Keywords
Description: Keywords for describing research projects and datasets.
Content Types: Research Project
Settings: Tags, Multiple select, Required

5) Notice that when you go to Create content > Research Project the keywords show up there and will auto complete as you type them in.

6) I then went in a create two Research Projects and the use of a keyword taxonomy links the two . E.g. if both use keyword: groundwater then by clicking on groundwater you list all research projects assocated with that keyword.

Posted by kkwaiser at 09:27 AM | Comments (0)

October 06, 2009

Enable clean URLs in Drupal 6

Here is how I enabled clean URLs on Drupal6/Ubuntu 9.04:

This site held the key.

Edited settings.php:
$ sudo gedit /etc/drupal/6/sites/default/settings.php &
Added the following:
$base_url = 'http://localhost/drupal6';

Change .htaccess:
$ sudo gedit /usr/share/drupal6/.htaccess &
Added this line:
RewriteBase /drupal6

Change 000-default following this site:
$ sudo gedit /etc/apache2/sites-enabled/000-default &

< Directory /var/www/>
Options Indexes FollowSymLinks MultiViews
#AllowOverride None
AllowOverride All
Order allow,deny
allow from all
< /Directory>

Note: I added a space between "< Directory" because, as html, the Directory lines disappear.

Then do this:

$ sudo a2enmod rewrite
$ sudo /etc/init.d/apache2 force-reload
$ sudo /etc/init.d/apache2 restart

See below the fold for miscellaneous notes I accrued during this process.

Here are some potentially useful sites:

This one addresses Clean URLs on Ubuntu but an error that arises (see following) gets in the way.

For this error:
httpd: Could not reliably determine the server's fully qualified domain name, using for ServerName
(13)Permission denied: make_sock: could not bind to address
no listening sockets available, shutting down
Unable to open logs


To see what ports are being listened on:
$ sudo netstat -anp | grep '^tcp.*LISTEN'

To see apach version information and file locations:
$ apache2 -v
$ apache2 -V

I added "ServerName localhost" to:
$ sudo gedit /etc/apache2/httpd.conf &
$ sudo /etc/init.d/apache2 restart

and the error "Could not reliably determine..." disappears. Note I was using this site.

Changes /etc/apache2/conf.d to include this:

Alias /sev /etc/drupal/6/sites/sev

Options Indexes +FollowSymLinks
AllowOverride All
order allow,deny
allow from all

and the Options permission directive goes away but I still don't have a website.

Posted by kkwaiser at 04:45 PM | Comments (0)

Adding image css to style.css in Drupal 6

Open the style.css sheet for your active theme:

$ sudo gedit /etc/drupal/6/sites/default/files/color/garland-11f64863/style.css

Add the following to the bottom of the style sheet:

.align-right { float:right; margin: 0 0 15px 15px; }
.align-left { float:left; margin: 0 15px 15px 0; }
.frame { padding: 5px; border: 1px solid #aaa; }

Code taken from here.

And this is what the Education page looks like now:

leaf graphic

Posted by kkwaiser at 11:31 AM | Comments (0)

Create link hierarchies in Drupal 6

Start here:

Ok, Framework 2.3, which is set to release in about a week, will fully support Dynamic Persistent Menu. Then will allow secondary links to be shown upon hovering over the primary link.

However, to do this, you must first go to Admin>Site Building>Menus then go to the settings tab at the top. The source for secondary links must be set to 'Primary Links' also. This essentially bypasses the real secondary links menu, and instead uses the hierarchy set within Primary Links. You must set your new 'Secondary Links' under the 'Primary Links' menu by going to 'Edit' on each item and changing the parent element to the primary link you wish for it to be under. In Drupal 6, you can simply drag your desired 'Secondary Links' to the right a bit to nest it under a 'Primary Link'

This basic functionality should also work without the Dynamic Persistent Menu module and on all current versions of framework.

If you want to show the lower-level links on hover then you need something like this, the Nice Menus module.

More work remains on this one...

Posted by kkwaiser at 10:56 AM | Comments (0)

Make content available in Drupal 6

This "How to..." covers adding a link to the homepage and making content available to anonymous (the public) users. I have created a Bibliography content type and will make that available to the public in this example.

Currently, in order to view and search the bibliography a user has to be logged in with Administrator rights. When I logout and try to navigate to my bibliography, I get an Access Denied error.

leaf graphic

To Fix:

1) Log in
2) Create a link at the top of the homepage for the Bibliography

- Administer > Menus > Primary Links > Add item
Path: biblio
Menu link title: Bibliography
Description: Research publications of the UMBS
Save > Save Configuration

- A link should appear in the header now

3) Make content available

- Administer > Permissions
- Under Anonymous User, check the appropriate content
- e.g., access biblio content, search content, use advanced search
- Save

4) Now logout and use the link to navigate to the bibliography:

leaf graphic

Posted by kkwaiser at 09:52 AM | Comments (0)

October 01, 2009

Install new theme in Drupal 6

Going to install a new theme for shticks and giggles. I will be following these instructions.

After browsing themes, I decided to go with the Acquia Slate for its post-millenial, modern accents.

Create a new directory for downloaded themes:

$ sudo mkdir /etc/drupal/6/sites/all/themes
$ cd /etc/drupal/6/sites/all/themes/

Untar the downloaded theme into the specified directory:
$ sudo tar xzf /home/data/Desktop/acquia_slate-6.x-1.4.tar.gz

After going to Administer > Themes, Drupal presents Acquia Slate as an option. Here's the home page now:

leaf graphic

Fairly obvious that it needs formatting but I like the layout. This drives home the point of deciding on styling and layout ahead of time?

Posted by kkwaiser at 05:00 PM | Comments (0)

Change Site Name and Slogan in Drupal 6

Here is how you change the Site Name (at least one way) and a second approach to changing the Slogan. Both result in text of your choice being placed in the header area.

It appears there are multiple ways to change the site name area but I'm following this forum.

This is how things look like with the default settings:

leaf graphic

(right-click > View Image for full size)

To change "localhost" to something else I open settings.php.

$ sudo gedit /usr/share/drupal6/sites/default/settings.php &

and go to the bottom:

#$conf = array(
# 'site_name' => 'Your Site Name',
# 'theme_default' => 'minnelli',
# 'anonymous' => 'Visitor',

And change it to the following:

$conf = array(
'site_name' => 'The University of Michigan Biological Station',
# 'theme_default' => 'minnelli',
# 'anonymous' => 'Visitor',

leaf graphic

So, I just found an easier way to do pretty much the same thing. The impetus for this portion comes from this site. It also involves only the web administer interface (instead of the settings.php file) so may be superior in more than one way.

Go to Administer > Site configuration > Site information and set the Slogan to "The University of Michigan Biological Station". The Slogan appears to the right of the Site Name, meaning you can turn off the Site Name and turn on the Slogan and you should get the same outcome as described above.

Also note that their are Global and Theme-specific settings under Administer > Site Building > Themes. The Theme configuration appears to trump the Global.

Posted by kkwaiser at 04:15 PM | Comments (0)