Recipe-Based Projects Guide¶
CMS Planner provides special support for recipe-based architectures, particularly Drupal recipes. This guide covers patterns, best practices, and examples for planning recipe-based projects.
What are Recipe-Based Projects?¶
Recipe-based architecture uses self-contained configuration packages (recipes) that can be combined to create feature-rich applications. Each recipe bundles all the configuration entities needed for a specific feature.
Common in:¶
- Drupal CMS - Drupal recipes and site templates
- Laravel - Package-based features
- Rails - Engine-based modules
- Other CMS platforms - Modular feature packages
Drupal Recipes¶
Drupal recipes are the primary use case for CMS Planner's recipe-based support.
Recipe Structure¶
A typical Drupal recipe includes:
recipe_name/
├── recipe.yml # Recipe metadata and dependencies
├── config/ # Configuration entities
│ ├── node.type.example.yml # Content type
│ ├── field.storage.node.field_example.yml # Field storage
│ ├── field.field.node.example.field_example.yml # Field instance
│ ├── taxonomy.vocabulary.example.yml # Taxonomy
│ ├── views.view.example.yml # View
│ ├── pathauto.pattern.example.yml # URL pattern
│ ├── metatag.metatag_defaults.node__example.yml # Meta tags
│ └── image.style.example.yml # Image style
└── README.md # Documentation
What Goes in a Recipe¶
Include (Configuration Entities):
- Content types (node.type.*.yml)
- Field storage (field.storage.*.yml)
- Field instances (field.field.*.yml)
- Taxonomies (taxonomy.vocabulary.*.yml)
- Views (views.view.*.yml)
- Pathauto patterns (pathauto.pattern.*.yml)
- Metatag defaults (metatag.metatag_defaults.*.yml)
- Image styles (image.style.*.yml)
- Block types, paragraph types, etc.
Do NOT Include (Simple Config):
- Module enablement (core.extension.yml)
- Site configuration (system.site.yml)
- System settings
Recipe Naming Convention¶
Use flat naming with project prefix:
✅ Good:
- saplings_person
- saplings_service
- vital (site template)
- myproject_blog
❌ Bad:
- saplings/person (nested path)
- vital/site_template (nested path)
- person (no prefix)
Shared Field Storage¶
A critical pattern in recipe-based projects is shared field storage, where one field definition is reused across multiple content types.
Why Shared Fields?¶
Benefits: - Data consistency across content types - Easier site-wide changes - Better entity references - Simplified Views and relationships
Example:
# Created by saplings_person recipe
field.storage.node.field_phone:
type: telephone
# Used by:
- Person content type
- Location content type
- Department content type
Planning Shared Fields¶
When generating an FRD for a recipe-based project, CMS Planner documents:
- Which recipe creates the shared field
- Which content types use the field
- Installation order dependencies
- Field reuse diagram
Example FRD Section¶
## FR-001: saplings_person Recipe [MUST HAVE]
**Creates Shared Field Storage:**
- `field_phone` - Used by: Person, Location, Department
- `field_services` - Used by: Person, Location, Department, News
- `field_department` - Used by: Person, Service, Event, Internal Resource
**Installation Requirement:** Must be installed BEFORE recipes that use these shared fields.
**Recipe Structure:**
saplings_person/
├── recipe.yml
├── config/
│ ├── node.type.person.yml
│ ├── field.storage.node.field_phone.yml (SHARED)
│ ├── field.field.node.person.field_phone.yml
│ ├── field.storage.node.field_services.yml (SHARED)
│ ├── field.storage.node.field_department.yml (SHARED)
│ ├── taxonomy.vocabulary.specialties.yml
│ ├── views.view.provider_directory.yml
│ └── pathauto.pattern.person.yml
└── README.md
Installation Order Dependencies¶
Recipe installation order matters when recipes share field storage.
Dependency Chain Example¶
1. saplings_person
├─ Creates: field_phone, field_services, field_department
2. saplings_service
├─ Uses: field_department (from saplings_person)
├─ Creates: field_locations
3. saplings_location
├─ Uses: field_phone, field_services (from saplings_person)
├─ Uses: field_locations (from saplings_service)
4. saplings_department
├─ Uses: field_phone, field_services, field_locations
├─ (uses fields from multiple recipes)
5. vital (site template)
├─ Installs: all saplings recipes
├─ Adds: demo content
FRD Dependency Diagram¶
CMS Planner includes a dependency diagram in the FRD appendix:
Appendix A: Recipe Dependency Graph
saplings_person (foundation)
↓
saplings_service
↓
├─→ saplings_location
├─→ saplings_event
├─→ saplings_news
├─→ saplings_alert
├─→ saplings_department
└─→ saplings_internal_resource
↓
vital (site template)
Site Template Recipe¶
The master site template recipe installs all dependencies and demo content.
Example: vital Recipe¶
# vital/recipe.yml
name: 'Vital Healthcare Site Template'
description: 'Complete healthcare site with provider directory, services, locations, etc.'
type: 'Site template'
recipes:
# Base platform
- drupal_cms/admin_ui
- drupal_cms/authentication
- drupal_cms/seo
# Saplings recipes (in order!)
- saplings_person
- saplings_service
- saplings_location
- saplings_event
- saplings_news
- saplings_alert
- saplings_department
- saplings_internal_resource
# Demo content integrated
install:
- default_content
Demo Content Integration¶
Demo content is NOT a separate recipe—it's integrated into the site template:
vital/
├── recipe.yml
├── config/
└── content/ # Default Content module format
├── node/
│ ├── person-1.json
│ ├── service-1.json
│ └── location-1.json
├── taxonomy_term/
└── file/
Themes vs Recipes¶
Important: Themes are NOT recipes.
Theme Structure¶
vital_theme/ # Drupal theme (NOT a recipe)
├── vital_theme.info.yml
├── vital_theme.theme
├── templates/
├── css/
└── js/
The theme is installed by the site template recipe but is not itself a recipe.
FRD Generation for Recipe Projects¶
When using /functional-requirements for a recipe-based project:
1. Provide Recipe Context¶
/functional-requirements
Building Drupal site template with recipe-based architecture:
**Base:** Byte site template (fork)
**Platform:** Drupal CMS 2.0+, Drupal Core 11.3+
**Recipes:** Saplings collection (8 recipes)
**Features:**
- Provider directory (saplings_person)
- Services catalog (saplings_service)
- Locations (saplings_location)
- Events calendar (saplings_event)
- News/blog (saplings_news)
- Alerts (saplings_alert)
- Departments (saplings_department)
- Internal resources (saplings_internal_resource)
**Theme:** vital_theme (subtheme of Mercury)
**Demo Content:** Integrated into vital recipe
2. Generated FRD Includes¶
- One FR per recipe (FR-001 through FR-008)
- Recipe structure examples with config entities
- Shared field storage matrix in appendix
- Dependency diagram showing installation order
- Installation instructions with proper ordering
- Demo content specifications
- Theme requirements (separate from recipes)
3. Story Point Estimation¶
Each recipe gets estimated separately:
- Recipe creation - Export config, organize, test
- Field storage planning - Identify shared fields
- Configuration entities - Content types, views, etc.
- Testing - Clean installation, dependency testing
- Documentation - README, examples
- Demo content - Create sample data
4. CSV Backlog¶
Organized by recipe:
Tasklist,Task,Tags
"Phase 2: Core Recipes","[EPIC] saplings_person Recipe [34 points]","SP-34,Phase-2"
"Phase 2: Core Recipes","- [STORY] Person Content Type [13 points]","SP-13,Phase-2"
"Phase 2: Core Recipes","-- [TASK] Define fields [5 points]","SP-5,Phase-2"
"Phase 2: Core Recipes","-- [TASK] Create shared storage [3 points]","SP-3,Phase-2"
Example Projects¶
Healthcare Site (Vital)¶
Recipes: 8 Saplings recipes + vital site template Shared Fields: field_phone, field_services, field_department, field_locations Installation Order: Critical due to shared field dependencies Demo Content: Integrated into vital recipe Story Points: 720 total across 8 phases
University Site¶
Recipes: faculty, courses, programs, departments, events, news Shared Fields: field_department, field_faculty, field_term Installation Order: faculty → courses → programs Story Points: ~600 points
E-commerce Site¶
Recipes: products, categories, reviews, shipping, payments Shared Fields: field_category, field_price, field_availability Installation Order: categories → products → reviews Story Points: ~800 points
Best Practices¶
Planning¶
- Identify shared fields early - Plan which recipe creates each shared field
- Document dependencies - Clear installation order requirements
- Group related functionality - Each recipe should be cohesive
- Plan demo content - Representative samples for all features
Estimation¶
- Recipe creation - 8-13 points per recipe (config export + testing)
- Shared field storage - Add 3-5 points for planning and testing
- Dependencies - Add buffer for dependency testing
- Demo content - 5-8 points per recipe for quality samples
Testing¶
- Clean installation - Test each recipe in isolation
- Dependency order - Verify installation order works
- Shared fields - Confirm field reuse works correctly
- Demo content - Validate content imports properly
Documentation¶
- README per recipe - Installation, dependencies, features
- Shared field matrix - Document all field reuse
- Installation guide - Step-by-step with proper order
- Architecture diagram - Visual dependency graph
Common Pitfalls¶
❌ Wrong: Nested Recipe Paths¶
✅ Right: Flat Recipe Names¶
recipes/
├── vital/
├── vital_theme/ (this is a theme, not recipe!)
├── saplings_person/
└── saplings_service/
❌ Wrong: Simple Config in Recipes¶
✅ Right: Only Config Entities¶
❌ Wrong: Optional Demo Content Recipe¶
✅ Right: Integrated Demo Content¶
Getting Help¶
- Documentation: https://kanopi.github.io/cms-planner/
- Drupal Recipes: https://www.drupal.org/docs/extending-drupal/drupal-recipes
- GitHub Issues: https://github.com/kanopi/cms-planner/issues
- Email: code@kanopi.com