Introduction
Drupal is a powerful open-source content management framework, whose core functionality is hugely extensible through the use of contributed modules, of which there are literally thousands! This allows you to do all sorts of weird and wonderful things.
Drupal can also be used to provide Processing Sketches with a sophisticated backend capable of processing and serving up data in many different ways. I frequently use it as part of my local development to perform batch processing tasks and the like, which can then be integrated in a sketch, for example.
The simple method outlined in this tutorial uses JSON – a lightweight data interchange format to demonstrate how Drupal can be used to provide a Processing Sketch with a list of images and titles by using just a few contributed modules. Emphasis is placed upon the Views module, as this provides an incredibly powerful means of pulling data out of a database. It also introduces the CCK (Content Construction Kit) module, which allows users to define custom content types and assign fields to them; think geo-location data, profiles, pictures, text, and dates etc.
Some of the topics covered in this tutorial will show you how to:
- define custom content types and their associated fields using Drupal and the CCK module
- generate cached image variants based on user-defined custom presets
- construct database queries or views using the Views module – a smart query builder
- output views in both HTML and JSON
- access and display a view’s results in Processing
Drupal
Installation
Here you’ll find instructions on how to download, install, and configure the latest version of Drupal for your particular development environment. MAMP and variants such as LAMP (the M and the L refer to Mac and Linux respectively) offer a contained and relatively foolproof Apache Server, MySql, and PHP stack for whatever platform you happen to be using; this is all that is required to host and run Drupal. Personally, I use MAMP on a Mac. I usually install Drupal in a sub-folder to help keep things organized; decompressing Drupal into your public_html folder and renaming it to processing or whatever is the easiest way to achieve this.
Drupal has a very active and supportive community. Google or search the forums if you’re having difficulties getting up and running with Drupal. If you’ve ever installed WordPress (who hasn’t!?) you shouldn’t have too much difficulty.
Please note that this tutorial assumes that you are using Drupal 6.17. Version 7 is nearing release, but is not production ready at the time of posting.
Once you’ve run the install script and told Drupal all about your database and filled out all the configuration settings you’ll be redirected to the welcome page:
Modules
The next thing to do is download the following Drupal contrib modules to your modules directory:
- admin_menu (6.x-3.x-dev)
- cck (6.x-3.x)
- devel (6.x-1.20)
- filefield (6.x-3.7)
- imageapi (6.x-1.8)
- imagecache (6.x-2.0-beta10)
- imagefield (6.x-3.7)
- views (6.x-2.11)
- views_datasource (6.x-1.x-dev)
Note: You will need to create a directory called modules in your /drupal/sites/all folder as this does not exist by default.
Avoid placing contributed modules in the /drupal_folder/modules folder, as this is where Drupal’s default core modules live. This image shows my /drupal_folder/sites/all/modules folder with all the above modules decompressed inside it.
Now navigate to drupal_folder/admin/build/modules to see the list of all available modules (the downloaded modules will also appear in this list), and ensure the following are enabled:
A new black toolbar should have appeared at the top of the screen. This makes finding things in Drupal a whole lot quicker and easier, and avoids countless page refreshes when drilling down through menus. The rest of this tutorial assumes that you have this toolbar working.
CCK
Step 1 – Create new content type
First we need a new content type to store our images.
Select ‘Content management > Content types > Add content type’ from the toolbar. This should present a form with various fields in groups, which need to be filled out. Many of them can be left with default settings. The following lists only those groups of fields that need to be altered in some way:
- Identification:
- Name: Image
- Type: image
- Submission form settings:
- Body field label: delete the word ‘Body’ already in this field, so that it is blank (we don’t need body text in this example)
- Comment settings:
- Default comment setting: disabled (we don’t need the commenting system)
Submitting the form should result in a redirect to a list of available content types including the one we just created with the following green success message at the top: The content type Image has been added.
Step 2 – Add image field to Image content type
At this stage our newly created content type only stores a title, and a few other items of information relating to authorship etc. To upload and store images we will need to add an image field to this content type.
First click on the ‘manage fields’ link to the right of your newly created content type, and then fill out the form as shown below:
The next screen presents another form with lots of fieldgroups affecting the behaviour of this field. The only change we need to make is to make our new field required* under Global settings near the bottom of the form.
Although for this tutorial you can submit the form with the default settings, take a look at some of the other options for future reference.
ImageCache
- Navigate to ‘Imagecache’ under ‘Site building‘ menu
- Add new preset called ‘thumbnail’
- Add a resize action of 75×75 pixels by entering 75 and 75 into width and height fields respectively
- Save preset
A Drupal icon appears at the bottom of the screen providing a demo of how your new preset will affect images.
Devel
Among other things the devel module provides a convenient way to generate dummy or test content for a site, including images.
- Click on ‘Generate items > Generate content‘ link in the toolbar
- In ‘Which node types do you want to create?’ check that Image is the only type selected
- Change ‘Max word length of titles’ to 1 (default of 8 is excessive)
- Do it!
You should get a progress bar indicating that the action is being performed before returning to the Generate content page with a list of new nodes created and a total of how many were created (default 50).
If you click on the ‘home’ link in the breadcrumb trail you should see a paginated list of your newly created images, which can be clicked and viewed, or edited individually. Note: If you click on a nodes ‘edit‘ tab you’ll see the form used to create nodes of this type when doing it manually, i.e. by clicking ‘Create content‘ in the left-hand navigation block and choosing ‘Image‘; do this when you want to name and upload your own custom images, rather than have them automatically generated by the Devel module.
Views
Although our home page displays all of our newly created content it is insufficient for our purposes, as by default it displays the teaser for any new content added to the system in reverse chronological order regardless of its type, i.e. anything with the promote to front page flag set as part of its workflow.
Views is the module that will allow us to be much more selective in the construction of a new page.
- ‘Site building > Views‘ brings up a page of available views - all of which are disabled by default
- Now there are two options on how to proceed:
- Click the ‘Add‘ tab and name the view images and click ‘Next‘ leaving all other settings as defaults, and proceed with the configuration of the view by hand beginning at the Filters section directly below, or
- Copy my exported view code and click on the ‘import‘ tab to avoid the configuring the view by hand. If you choose the latter option just paste in the code and progress directly to the Processing section of this tutorial, but check the imported view gives you a new menu item called ‘Images‘ at the top right-hand side of the screen and that the view includes the default and json tabs
$view = new view;
$view->name = 'images';
$view->description = '';
$view->tag = '';
$view->view_php = '';
$view->base_table = 'node';
$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', 'Defaults', 'default');
$handler->override_option('fields', array(
'title' => array(
'label' => 'Title',
'alter' => array(
'alter_text' => 0,
'text' => '',
'make_link' => 0,
'path' => '',
'link_class' => '',
'alt' => '',
'prefix' => '',
'suffix' => '',
'target' => '',
'help' => '',
'trim' => 0,
'max_length' => '',
'word_boundary' => 1,
'ellipsis' => 1,
'html' => 0,
'strip_tags' => 0,
),
'empty' => '',
'hide_empty' => 0,
'empty_zero' => 0,
'link_to_node' => 0,
'exclude' => 0,
'id' => 'title',
'table' => 'node',
'field' => 'title',
'relationship' => 'none',
),
'field_image_fid' => array(
'label' => '',
'alter' => array(
'alter_text' => 0,
'text' => '',
'make_link' => 0,
'path' => '',
'link_class' => '',
'alt' => '',
'prefix' => '',
'suffix' => '',
'target' => '',
'help' => '',
'trim' => 0,
'max_length' => '',
'word_boundary' => 1,
'ellipsis' => 1,
'html' => 0,
'strip_tags' => 0,
),
'empty' => '',
'hide_empty' => 0,
'empty_zero' => 0,
'link_to_node' => 0,
'label_type' => 'none',
'format' => 'thumbnail_default',
'multiple' => array(
'group' => TRUE,
'multiple_number' => '',
'multiple_from' => '',
'multiple_reversed' => FALSE,
),
'exclude' => 0,
'id' => 'field_image_fid',
'table' => 'node_data_field_image',
'field' => 'field_image_fid',
'relationship' => 'none',
'override' => array(
'button' => 'Override',
),
),
));
$handler->override_option('filters', array(
'status' => array(
'operator' => '=',
'value' => '1',
'group' => '0',
'exposed' => FALSE,
'expose' => array(
'operator' => FALSE,
'label' => '',
),
'id' => 'status',
'table' => 'node',
'field' => 'status',
'relationship' => 'none',
),
'type' => array(
'operator' => 'in',
'value' => array(
'image' => 'image',
),
'group' => '0',
'exposed' => FALSE,
'expose' => array(
'operator' => FALSE,
'label' => '',
),
'id' => 'type',
'table' => 'node',
'field' => 'type',
'relationship' => 'none',
),
));
$handler->override_option('access', array(
'type' => 'none',
));
$handler->override_option('cache', array(
'type' => 'none',
));
$handler = $view->new_display('page', 'Page', 'page_1');
$handler->override_option('path', 'images/default');
$handler->override_option('menu', array(
'type' => 'default tab',
'title' => 'default',
'description' => '',
'weight' => '0',
'name' => 'navigation',
));
$handler->override_option('tab_options', array(
'type' => 'normal',
'title' => 'Images',
'description' => '',
'weight' => '0',
'name' => 'primary-links',
));
$handler = $view->new_display('page', 'JSON', 'page_2');
$handler->override_option('fields', array(
'title' => array(
'label' => 'title',
'alter' => array(
'alter_text' => 0,
'text' => '',
'make_link' => 0,
'path' => '',
'link_class' => '',
'alt' => '',
'prefix' => '',
'suffix' => '',
'target' => '',
'help' => '',
'trim' => 0,
'max_length' => '',
'word_boundary' => 1,
'ellipsis' => 1,
'html' => 0,
'strip_tags' => 0,
),
'empty' => '',
'hide_empty' => 0,
'empty_zero' => 0,
'link_to_node' => 0,
'exclude' => 0,
'id' => 'title',
'table' => 'node',
'field' => 'title',
'relationship' => 'none',
'override' => array(
'button' => 'Use default',
),
),
'field_image_fid' => array(
'label' => 'thumbnail',
'alter' => array(
'alter_text' => 0,
'text' => '',
'make_link' => 0,
'path' => '',
'link_class' => '',
'alt' => '',
'prefix' => '',
'suffix' => '',
'target' => '',
'help' => '',
'trim' => 0,
'max_length' => '',
'word_boundary' => 1,
'ellipsis' => 1,
'html' => 0,
'strip_tags' => 0,
),
'empty' => '',
'hide_empty' => 0,
'empty_zero' => 0,
'link_to_node' => 0,
'label_type' => 'custom',
'format' => 'thumbnail_url',
'multiple' => array(
'group' => TRUE,
'multiple_number' => '',
'multiple_from' => '',
'multiple_reversed' => FALSE,
),
'exclude' => 0,
'id' => 'field_image_fid',
'table' => 'node_data_field_image',
'field' => 'field_image_fid',
'relationship' => 'none',
'override' => array(
'button' => 'Use default',
),
),
));
$handler->override_option('style_plugin', 'views_json');
$handler->override_option('style_options', array(
'root_object' => 'nodes',
'top_child_object' => 'node',
'field_output' => 'normal',
'plaintext_output' => 1,
'format' => 'simple',
'content_type' => 'default',
'using_views_api_mode' => 0,
));
$handler->override_option('path', 'images/json');
$handler->override_option('menu', array(
'type' => 'tab',
'title' => 'json',
'description' => '',
'weight' => '0',
'name' => 'navigation',
));
$handler->override_option('tab_options', array(
'type' => 'none',
'title' => '',
'description' => '',
'weight' => 0,
'name' => 'navigation',
));
Filters
Click the + symbol next to ‘filters’ and locate the following two filter types and set them accordingly:
- Node: Published: yes (as a precaution we don’t want to display content that isn’t ready)
- Node: Type: is one of Image type
Fields
Click the + symbol next to ‘fields’ and select the following two fields from the list and configure them as follows:
- Node: Title: default settings
- Content: Image: leave default settings, but change format* to ‘thumbnail image‘ and label to ‘none‘
When you start adding fields to your view you’ll notice that the views module provides a live preview at the bottom of the page, to give you an overall impression of what the final view will look like. Notice what happens when you change the image format* to generic files, or some other setting.
Displays
You should now have a view that looks similar to this:
At this stage we’ve only setup a few defaults for our view and it is not accessible as a page via a URL until we add a display.
Pages
- Click ‘Add display‘ from the left hand panel while ensuring that ‘Page‘ is the selected item in the drop down list
A new section called Page settings will have appeared below Basic settings. This will allow us to assign a URL and menu item to this view.
- Click ‘Path’ and enter images/default as our preferred URL
- Click ‘Menu’ and choose ‘Default menu tab’ and enter default as the Title
- In ‘Default tab options‘ choose ‘Normal menu item‘ and set its title to: Images and select ‘Primary links‘ from the Menu options list.
If you now save the view you should see a new menu item ‘Images‘ appear on the top right-hand side of the screen. Clicking on this link will take you to /drupal_folder/images where you should see the results of our view displayed. Return to the view editing page either by choosing the ‘Site building > Views‘ link, or by hovering near the top of our view until an ‘edit‘ link appears.
JSON
Now it’s time to get the contents of our view as a JSON document.
- Click ‘Add display‘ with ‘Page‘ selected as before
- Under Basic settings:
- Name: to ‘JSON’
- Style: click ‘override‘ to avoid affecting the default settings (!Important), and then choose ‘JSON data document‘ as the style. On the following screen you can submit the defaults.
- Page settings:
- Click ‘Path‘ and enter images/json as our preferred URL
- Click ‘Menu‘ and choose ‘Menu tab‘ and enter json as the title
If you update and save the view you should be taken to the completed view, which should now have two tabs entitled: default, and json. If you click ‘json‘ your browser should present you with a JSON representation of the view.
The final thing to do is ensure that our fields are labelled sensibly, as this affects the JSON output by the views_datasource module.
- Ensure that JSON is our selected display in the view editor, and then click ‘Fields‘
- Fields:
- Node: Title: Click override if not already using overridden values and enter: title (lowercase)
- Content: Image: Again, double check that status is ‘using overridden values’, and then choose custom label option and enter: thumbnail, and finally choose ‘thumbnail url’ from the format* select list
Update and save the view and check the first line of json output has the correct labels, something like:
{"nodes":[{"node":{"title":"Caecus","thumbnail":"http:\/\/localhost\/processing\/sites\/default\/files\/imagecache\/thumbnail\/filefield_1b265U_2_5.jpg"}}
Processing
Now that Drupal is setup and running it's time to fire up Processing!
Json
Jer Thorp aka blprnt has kindly posted a processing library along with a really useful introduction to using JSON within Processing, which you should read. Also, grab a copy of his library and stick it in the usual place.
All you need to do now is copy this code into an empty sketch and fill in the URL of your JSON data document in the 'request' string. If you get an parsing errors, try uncommenting some of the println statements and examine the JSON String being returned, and ensure that the keys used as arguments to getJSON* match the labels returned by your JSON view.
Sketch
import org.json.*;
ImageNode[] nodes;
PFont font;
void setup() {
size(455, 245);
font = createFont("SansSerif", 11);
textFont(font);
textAlign(CENTER);
String request = "http://localhost/processing/images/json";
String result = join( loadStrings( request ), "");
try {
JSONObject json_view = new JSONObject(join(loadStrings(request), ""));
//println(json_view.toString(2));
JSONArray json_nodes = json_view.getJSONArray("nodes");
nodes = new ImageNode[json_nodes.length()];
//println("json nodes: " + json_nodes.toString(2) );
for (int i = 0; i < json_nodes.length(); i++) {
//println(json_nodes.get(i));
JSONObject json_node = (JSONObject)json_nodes.get(i);
json_node = json_node.getJSONObject("node");
String title = json_node.getString("title");
String imageUrl = json_node.getString("thumbnail");
//println(title + ": " + imageUrl);
PImage thumbnail = loadImage(imageUrl);
nodes[i] = new ImageNode(title, thumbnail);
}
}
catch (JSONException e) {
println ("There was an error parsing the JSONObject.");
};
}
void draw() {
background(72);
int x=20;
int y=20;
fill(255);
for(int i = 0; i < nodes.length; i++) {
ImageNode node = nodes[i];
image(node.thumbnail(), x, y);
text(node.title(), x+75/2, y+90);
x+=85;
if(x > width-85) {
x=20;
y+=105;
}
}
}
// Simple container class
class ImageNode {
String title;
PImage thumbnail;
ImageNode(String title, PImage thumbnail) {
this.title = title;
this.thumbnail = thumbnail;
}
String title() {
return this.title;
}
PImage thumbnail() {
return this.thumbnail;
}
}
Result
When you run the above sketch you should see something like this:
And if you don’t?
Double check that your view is properly setup, and that your Processing sketch is configured with the right URL and that the keys match the labels being used in the view. Finally, leave a comment below and I’ll try and help you troubleshoot it.
If I’ve made any errors in this post (yikes!), or it doesn’t make any sense let me know and I’ll try and make the necessary amendments.






Processing JS Test