rockmigrations
Overview
Generate ProcessWire field definitions, templates, and migrations.
Access: $rm = rockmigrations();
Core Migration Patterns
Basic Migration
$rm->migrate([
'fields' => [], // Define fields here (Top-Level preferred)
'templates' => [], // Assign fields to templates
]);
Critical: fields vs fields-
fields: ADDS all fields. Use for incremental updates.fields-: ADDS listed fields; REMOVES unlisted fields.Any field not listed is removed from the template. Use for initial template setup.- Rule: Always list ALL fields you want to keep in the template when using
fields-.
- Rule: Always list ALL fields you want to keep in the template when using
Project Defaults (rm-defaults)
Sets German defaults, AdminThemeUikit tweaks, and installs language modules.
$rm->setPagenameReplacements('de');
$rm->setModuleConfig('AdminThemeUikit', ['toggleBehavior' => 1]); // Consistent clicks
$rm->setModuleConfig('ProcessPageList', ['useTrash' => true]);
$rm->setLanguageTranslations('DE');
$rm->installModule('LanguageSupportFields'); // ... plus PageNames, Tabs
$rm->setFieldData('title', ['type' => 'textLanguage']);
Common Mistakes
// DON'T - watch() is for file/module watching only
$rm->watch($rm->createRole('editor', ['page-edit']));
// DO - direct API call
$rm->createRole('editor', ['page-edit']);
Field Definitions
Standard Properties
All fields support these keys. Omitted from examples for brevity.
'label' => 'My Label',
'description' => 'Help text',
'notes' => 'Notes below input',
'icon' => 'cube',
'columnWidth' => 50, // 0-100%
'required' => 1,
'showIf' => 'field=1', // Conditional visibility
'tags' => 'groupname', // Field grouping
Basic Types
// Text / TextLanguage
'my_text' => ['type' => 'text', 'label' => 'Title'],
// Textarea / TextareaLanguage
'my_textarea' => ['type' => 'textarea', 'rows' => 5],
// Integer
'my_int' => ['type' => 'integer'],
// URL
'my_url' => ['type' => 'URL', 'textformatters' => ['TextformatterEntities']],
// Checkbox (1/0)
'my_check' => ['type' => 'checkbox', 'label' => 'Active?'],
// Toggle (Yes/No)
'my_toggle' => [
'type' => 'toggle',
'formatType' => 0, // 0=Int
'labelType' => 0, // 0=Yes/No
'defaultOption' => 'yes'
],
// RockMoney
'my_price' => ['type' => 'RockMoney'],
// RockIcons
'my_icon' => ['type' => 'text', 'inputfieldClass' => 'InputfieldRockIcons'],
Date & Time
'my_date' => [
'type' => 'datetime',
'dateOutputFormat' => 'd.m.Y H:i',
'dateInputFormat' => 'j.n.y',
'timeInputFormat' => 'H:i',
'datepicker' => 1, // Focus
'defaultToday' => 1,
],
Rich Text (WYSWYG)
// CKEditor
'my_body' => [
'type' => 'textarea',
'inputfieldClass' => 'InputfieldCKEditor',
'contentType' => 2, // 2=HTML content type
'formatTags' => 'p;h2;h3;h4',
'toggles' => [3], // 3=CleanNBSP toggle
'toolbar' => 'Format, Bold, Italic, BulletedList, PWLink, Source', // Simplified
],
// TinyMCE
'my_tiny' => [
'type' => 'textarea',
'inputfieldClass' => 'InputfieldTinyMCE',
'contentType' => 2, // 2=HTML content type
'settingsFile' => '/site/modules/RockMigrations/TinyMCE/simple.json',
],
Selection & Relations
// Options
'my_options' => [
'type' => 'options',
'options' => [
1 => 'Option A',
2 => 'Option B|With Description',
],
],
// Page Reference
'my_page_ref' => [
'type' => 'page',
'derefAsPage' => 1, // 0=PageArray, 1=Page, 2=PageOrFalse
'inputfield' => 'InputfieldPageListSelect', // or Select, Radios, AsmSelect
'findPagesSelector' => 'template=basic-page',
'labelFieldName' => 'title',
],
Files & Media
// Image
'my_image' => [
'type' => 'image',
'maxFiles' => 1,
'extensions' => 'jpg jpeg png svg',
'maxSize' => 3, // MP
'okExtensions' => ['svg'],
'gridMode' => 'grid',
],
// Generic File
'my_file' => [
'type' => 'file',
'extensions' => 'pdf xlsx',
'maxFiles' => 10,
],
// RockImagePicker
'my_picker' => [
'type' => 'RockImagePicker',
'sourcepage' => 1, // Source Page ID
'sourcefield' => 'images', // Source Field Name
],
Containers & Complex Types
// Repeater (Auto-creates 'repeater_my_rep' template)
'my_rep' => [
'type' => 'FieldtypeRepeater',
'fields' => ['title', 'sub_field'],
'repeaterTitle' => '#n: {title}',
'familyFriendly' => 1,
],
// FieldsetPage (Virtual page in field)
'my_fieldset' => [
'type' => 'FieldtypeFieldsetPage',
'fields' => [
'title' => ['required' => 0],
'nested_field',
],
],
// Fieldset (Open/Close pair)
'grp_open' => ['type' => 'FieldsetOpen'],
'grp_close' => ['type' => 'FieldsetClose'],
// RockGrid
'my_grid' => [
'type' => 'RockGrid',
'grid' => 'col-12', // Class definition
],
// RockPageBuilder
'my_builder' => ['type' => 'RockPageBuilder'],
Access Control & Logic
Roles & Permissions
Apply to fields or templates.
'editRoles' => ['editor', 'admin'],
'viewRoles' => ['guest', 'editor'],
'createRoles' => ['admin'], // Templates only
'addRoles' => ['admin'], // Templates only (add children)
Creating roles:
$rm->createRole('editor', ['page-edit', 'page-view']);
$rm->createRole('admin', ['page-edit', 'page-view', 'page-create']);
Template Family & Sort
'product' => [
'fields' => ['title', 'price'],
'family' => 'ecommerce', // Group templates
'sortfield' => '-created', // Descending date
'noChildren' => 1,
'parentTemplates' => ['home'],
],
Conditional Visibility (showIf)
- Syntax:
field=value,field!=value,field>5 - Logic: Comma
,= AND; Pipe|= OR.
// Show if 'has_url' is checked AND 'type' is NOT 'internal'
'showIf' => 'has_url=1, type!=internal',
Best Practices
- Top-Level Definitions: Define ALL fields in the
fieldsarray first. - Reference Names: Only use field names strings in
templatesarray. - Naming:
snake_casefor fields,kebab-casefor templates. - Repeaters: Always include
titleinfields. - Clean Migrations: Avoid inline field definitions in template arrays.
D
Database Changes
ALWAYS Use RockMigrations
When you need to create or modify:
- Fields - Use
$rm->createField() - Templates - Use
$rm->createTemplate() - Pages - Use
$rm->createPage() - Fieldgroups - Let RockMigrations handle automatically
// CORRECT - Always use RockMigrations
$rm->createField('my_field', 'text', ['label' => 'My Field']);
$rm->createTemplate('my-template', ['label' => 'My Template']);
$rm->createPage(template: 'my-template', parent: '/', title: 'My Page');
// WRONG - Never change database directly
// $this->fields->save($field); // Don't do this
// $this->templates->save($template); // Don't do this
// Direct SQL queries: DON'T do this!
NEVER Modify Database Directly
- Never write raw SQL queries to create fields, templates, or pages
- Never use
$db->query()or similar for schema changes - Always go through ProcessWire API or RockMigrations
- If you must run SQL for data migration, create a migration file
Creating Pages with Data
Use named parameters with colon syntax for createPage():
// CORRECT - Named parameters with colon syntax
$rm->createPage(
template: 'client',
parent: '/clients/',
name: 'demo-client',
title: 'Demo Client',
data: [
'client_email' => '[email protected]',
'client_status' => 'active',
],
);
// WRONG - Array syntax will fail with "Array to string conversion"
$rm->createPage('/clients/demo-client/', [
'template' => 'client',
'title' => 'Demo Client',
]);