Building Drupal with Reusable Fields

CCK and Field API

CCK is the most useful module for Drupal. It adds custom fields and content types to Drupal. Drupal 7 incorporates the community efforts of CCK into the core as the Field API.

Field API UML

The CCK module allows a content type to have multiple fields with various field types and different field widgets and formatters. A field must be assigned a widget to define its input style and at least one formatter to define its display style. The UML diagram above describes the relationship between content types, fields, field widgets, and field formatters in creating a CCK type.

Reuse Fields

Add new field

When a CCK field is added to a content type for the first time, this CCK field’s is created in Drupal as a class and an instance is assigned to the given content type. When the field is assigned to a content type, its configuration parameters are stored in the instance instead of the class. Instead of adding new fields to a content type, adding existing fields is a better option to reduce the system’s complexity and to improve scalability.

Add existing field

Adding an existing field only requires the administrator to choose a field from a list of fields defined in other content types and select a widget to define the input style. The most recently created field instance brings in the default parameters that can be changed later.

Reuse Fields with the API

CCK allows adding customized fields, widgets, and formatters in modules. Many third-party modules (Drupal CCK modules list) are already created to accomplish different tasks, including images, videos, and other internal and external references. CCK for Drupal 6 provides a set of API (CCK Developer Documentation for Drupal 6) for module developers. Drupal 7 provides native Field API for module developers.

Performance Issues

CCK (or Field API in Drupal 7) adds extra complexity to a Drupal system. When creating a new field, the field’s definition is added to the field class table and the field’s configuration is added to the field instance table; meanwhile, a new table is added to the Drupal database to store the field data. Database tables add complexity to the system. In addition, queries of nodes will incur JOIN expressions of tables to field data. Multiple JOINs will impact database performance since MySQL responds poorly to queries with multiple JOINs of tables if not properly configured.

Reuse of fields can reduce the number of tables in the Drupal database. For example, if 10 image fields, field_image_a, field_image_b, …, field_image_j, are added to the system, 10 tables are added to the database. If a single content type only utilizes two image fields, one thumbnail and one image, we can redefine the fields as field_image_thumbnail and field_image. Only two tables are introduced to the database with the latter configuration.

Reuse of fields can also reduce the system’s complexity. Instead of creating and maintaining 10 different fields, Drupal admins maintain only two fields and their documentation. Database administrators only need to improve performance of two extra tables. KISS is always a good principle.

Building Drupal with Naming Conventions

Creating Drupal sites is easy and requires no fancy skills. Drupal installation is simply one-click; setting up modules is simply one-click; creating new content types is also simple mouse clicks. Unfortunately, the power of control over Drupal is usually abused because of Drupal’s initial impression of simplicity. When building a hobby site, Drupal entities, such as blocks, content types, views, and URLs, are created randomly without deliberate consideration. Meanwhile, Drupal gurus would probably go in another approach by carefully planning names ahead.

Naming conventions

Naming conventions are overhead for most casual hobby use of Drupal. When a hobbyist wants to install Drupal for the first time, the guy won’t gain anything from naming conventions. When the hobbyist becomes a Drupal professional and sets up his tenth Drupal installation for a client, the guy may want some naming conventions for blocks, fields, content types, and views he created so he can easily maintain the other nine Drupal websites.

The Drupal community has defined coding standards for naming functions and variables. This standard is roughly based upon PEAR Coding Standard. Unfortunately PHP does not support either dot-separated packages or namespaces. Neither does Drupal support namespaces for its variable names and machine names for fields, content types, views, and other Drupal entities.

Human-readable Names and Machine-readable Names

Drupal demands two different types of names: a human-readable name and a machine-readable name.

Human-readable name and machine-readable name

The human-readable name is a text field containing any character. Drupal stores it as plain text into the database and treats it as plain text to display. Drupal recommends the human-readable name to contain only alphanumerics and spaces. However, this is not a strict restriction. The human-readable name can be used for applying naming conventions.

The machine-readable name is a text field containing only lowercase letters, numbers, and underscores. Drupal usually uses the machine-readable name directly as PHP variable names, database table names, and database field names. The machine-readable name must then follow the strict character restrictions. Machine-readable names only allow the use of lowercase letters, numbers and underscores. Underscore becomes the only option to define namespaces in machine names.

For example, for a user-created Blog type:

> * Name: user.Blog
> * Type: user_blog
> * Description: A user Blog content type.

End users may be unable to understand the meaning of Create a user.Blog. Using underscore-separated machine names and leaving the human-readable names as usual is probably a better idea.

The user created blog type can be rewritten as:

> * Name: Blog
> * Type: user_blog
> * Description: A user Blog content type.

While developers can recognize the user.Blog content type from user_blog, users reads Create a Blog in their menus.

A longer name example may write:

Jounral:
> * Name: Journal
> * Type: webinit_acad_journal

Journal Issue:
> * Name: Journal issue
> * Type: webinit_acad_journal_issue

Journal Article:
> * Name: Journal Article
> * Type: webinit_acad_journal_article

Building Conventions

Naming conventions to Drupal developers are kinda the same thing as coding standards to programmers. Building conventions among Drupal developers is reaching consensus among a team of developers. The technical leader is responsible for building up conventions in his team.

Consumer Consensus Although consumers may not see any machine-readable names explicitly on web pages, human-readable names are visible to consumers in many menu items. Developers must realize that human-readable names are consumed by end users. Display names are not only meaningful to developers, but also meaningful to end-users. In addition, end-users are also concerned about entity descriptions.

Developer Consensus Developers may reach an agreement about naming conventions.

The above example about academic journals and articles is defined by use case. All journal-related items belong to the journal subsystem of the acad scope because journals and articles are designed within the journal subsystem. Along with the content types, developers can create journal related blocks and views following the namespace webinit_acad_journal_. For example,

A Journal View:
> * Name: Journal view
> * Machine: webinit_acad_journal_view_journal

A Journal Issue View:
> * Name: Journal issue view
> * Machine: webinit_acad_journal_view_issue

The functionality domain is more useful for functions like node reference views and other assisting-purpose views. For example, in webinit_acad_journal_issue content type, it has a node reference field of journals from a view dedicated to listing journals. The view follows the pattern,
> * Name: Node reference view of journals
> * Machine: noderef_journal

However, this view can also be put into the namespace specified above,
> * Name: Node reference view of journals
> * Machine: webinit_acad_journal_noderef_journal

By packaging content types and views into the same namespace, users are able to focus on the problem scope and the set of features in Drupal provided by developers. Developers can easily find out bugs within the scope during maintenance.

Next article will discuss Reusable Fields.