Building reusable Drupal recipes for procedural content
Procedural guides are often trapped in PDFs, spreadsheets or duplicated website pages. When an editor changes one instruction, finding every outdated copy becomes a maintenance task. A structured Drupal approach makes the sequence, timing and supporting media first-class content, so the same guide can power a web page, an app and later other channels without rewriting prose.
Building a Drupal Recipe module for step-by-step content means packaging that structure as reusable configuration. The Recipe module lets site builders define content types, fields, vocabularies, media handling and related dependencies, then share the definition as YAML. It is not a conventional PHP module that hard-codes each guide; the reusable asset is the editorial blueprint, while editors continue to create ordinary content.
Consider a Melbourne laneway café that publishes a timed sourdough guide and a Sydney produce market that changes its advice by season. Their editors need consistent ingredients, numbered instructions, photographs and warnings, but each organisation retains ownership of its voice. Australian publication schedules also shift around public holidays and school terms, making scheduling and revision history practical requirements.
This article uses Drupal 10 or 11, Composer, Drush, configuration management and Views. You will model guide and step content, package the setup with Recipe, add editorial controls, validate the fields, render an accessible interface and prepare the result for distribution. Custom PHP is justified only when the site needs behaviour that configuration cannot express.
Model the content before configuring fields
Start with the editor’s tasks rather than a list of database columns. A guide normally has a title, summary, preparation and cooking times, yield, equipment, ingredients, warnings, source and hero media. Each instruction needs its own position, heading, body, optional duration, photograph and tip. Storing every step in one long body field makes ordering, reuse and validation unnecessarily difficult.
Use two related content types when steps must be referenced independently: a guide and a guide step. Connect them with an entity reference field, and give each step an integer position field. Alternatively, use Drupal’s Book module for a chapter-based structure. Recipe can package either choice, which lets you compare editorial models before committing to an implementation.
Keep metadata reusable. Ingredients can use a taxonomy term; equipment and allergens can use controlled vocabularies; cooking times can use integer minutes rather than free text. These choices support filters, accessible labels and consistent cards across templates. They also reduce the amount of custom code required later.
Install Recipe and create a portable definition
If your distribution does not already supply Recipe, install a release compatible with your Drupal core version, commonly with composer require drupal/recipe, followed by drush pm:enable recipe. Check the module’s release matrix and dependencies first, because major core versions may require different builds. Clear caches after enabling and confirm that the Recipe administration route appears under the development configuration area.
Build and test the content model on a development site, then use Recipe’s export facility to capture the required configuration. The resulting YAML file should include the content types, fields, vocabularies and other explicitly selected dependencies. Keep recipe files in version control, review their diffs and import them through the Recipe interface or the command supplied by the installed release rather than hand-writing an unfamiliar schema.
A recipe is declarative configuration, not an executable installer with hidden procedures. This makes its dependency boundaries important: missing media types, roles or views can leave an imported site incomplete. The same configuration-first principle appears in configuration management patterns across middleware platforms, although Drupal recipes rely on Drupal’s own APIs and configuration objects.
Shape the editorial workflow
A structured model still produces poor content if anyone can publish unfinished instructions. Give authors permission to create and revise steps, editors permission to arrange and approve them, and publishers permission to move a complete guide to a published state. A moderation or workflow module can record who changed each stage and expose clear labels such as “In review” and “Approved” to editors.
Plan publication timing around Australian public holidays, school term dates and regional operating hours. Store event timestamps in a timezone-safe way, let Drupal convert them for the reader, and show the intended date beside timed steps. This avoids confusion when a national site publishes from different states and a daylight-saving boundary falls between the preview and release.
Require a complete preview before publishing. The preview should combine the guide, its ordered steps, linked media, allergen information and the final URL slug. Keep revisions enabled, record meaningful status changes and provide a quick comparison when copy is corrected. For seasonal produce, a scheduled revision can preserve the version that was published on market day without overwriting later updates.
Validate fields and expose structured metadata
Validation belongs as close as possible to the field. Make essential guide fields required, restrict time and yield values to sensible ranges, and set step positions to positive integers. Recipes cannot guarantee by configuration alone that positions are unique within one guide; add a small validation module or use a proven contributed validation extension when the editorial team must not create duplicate positions.
Structured metadata can help search engines and other channels interpret the content, but it must describe what readers actually see. Generate Schema.org Recipe JSON-LD from the same fields used by the page, including ingredients, instructions, yield and preparation time. Do not publish ingredients or nutrition claims that are missing from the visible guide. If a field can contain warnings or optional values, make the generated structure reflect that distinction.
For Australian sites, use Australian English consistently, including “organisation” and “licence” as a noun, and record source links on the appropriate .com.au or other domain. When a guide includes commercial guidance, show prices in AUD and say whether the 10% GST is included. These small conventions prevent ambiguity for local readers and make the content reusable by Australian teams.
Build an accessible front end
Create a View or exposed form that resolves each guide’s related steps and sorts them by position. Render the sequence as an ordered list, keep step headings in the heading hierarchy, and give every control a visible text label. A Twig template can reuse field formatters, but it should not scatter the business rules across templates; the Recipe package remains the source for the underlying configuration.
Add drag-and-drop reordering only as an enhancement. The ordinary edit form must still provide move-up and move-down controls that work with a keyboard, and the JavaScript should submit the resulting order through the same entity form. Announce successful moves to assistive technology, preserve focus sensibly and avoid replacing the complete form after every request.
Design for the narrow screens and intermittent connections common when staff consult recipes at markets or on site. Keep instructions legible without horizontal scrolling, make photographs optional, and provide the complete text without relying on video or an image. Cache rendered guide pages where possible, but ensure that editing a step invalidates the relevant cache tags so readers never see an old instruction with a new title.
Test, version, and distribute the recipe
Test the recipe against a clean Drupal installation that does not already contain the target content types. Import it, create a guide, attach media, publish it and inspect the result as an anonymous visitor. Also test failure cases: missing image, incomplete ingredient, duplicate step position and expired moderation permission. Record the Drupal, PHP, Recipe and contributed module versions in the project documentation.
Review conflicts before importing over an established site. Existing configuration may already use the same content type or field identifiers, and imported roles or taxonomy terms can affect permissions elsewhere. Use namespaced identifiers where appropriate, migrate existing content separately and back up both the database and files. Store recipes and migration scripts in Git so changes can be reviewed, approved and reproduced.
Then compare the implementation paths before deciding that more custom code is necessary. A recipe is strongest when it standardises editorial structure; a custom module remains appropriate for genuinely dynamic rules, integrations or algorithmic behaviour.
| Approach | Best suited to | Main trade-off |
|---|---|---|
| Manually created content types | A single site with no shared blueprint | Configuration is duplicated between environments |
| Drupal Book module | Long, chapter-based guides | Limited support for structured recipe metadata |
| Recipe with related content types | Reusable guides, controlled fields and repeatable workflows | Requires careful dependency and identifier management |
| Custom PHP module | Dynamic validation, external integrations or unusual behaviour | Higher development, testing and upgrade cost |