create-template
File: bin/create-template.php
Inserts a new template into the database and compiles it to a PHP file, using a JSON definition file as input. This is the CLI equivalent of creating a template through the Template Builder UI and clicking Save.
Usage
Run from the WordPress root directory:
wp eval-file wp-content/plugins/sanil-website-builder/bin/create-template.php path/to/definition.json
The only argument is the path to your JSON definition file. The path can be relative (resolved from the current working directory) or absolute.
Definition File Format
The definition file is a JSON object with the following fields:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
name |
string | Yes | — | Display name shown in the Template Builder list |
schema |
array | Yes | — | Array of template nodes (the layout tree) |
category |
string | No | "default" |
Category slug for grouping templates |
builder_type |
string | No | "template" |
"template" for content templates, "titlebar" for title bar templates |
supports |
string | No | "" |
Comma-separated post type slugs this template supports |
Minimal example
{
"name": "Simple Heading Card",
"schema": [
{
"type": "div",
"id": 1,
"direction": "column",
"gap": 8,
"sanilwb_padding_vertical": "12",
"sanilwb_show_desktop": "1",
"sanilwb_show_tablet": "1",
"sanilwb_show_mobile": "1",
"children": [
{
"type": "heading",
"id": 2,
"heading-font-size": "18",
"heading-font-weight": "600",
"link": "1",
"sanilwb_show_desktop": "1",
"sanilwb_show_tablet": "1",
"sanilwb_show_mobile": "1"
}
]
}
]
}
Full example with all fields
{
"name": "News Horizontal Card",
"category": "news",
"builder_type": "template",
"supports": "post",
"schema": [
{
"type": "div",
"id": 1,
"direction": "row",
"align": "flex-start",
"gap": 12,
"sanilwb_border_style": "solid",
"sanilwb_border_color": "#e8e8e8",
"sanilwb_border_width_bottom": "1",
"sanilwb_padding_vertical": "12",
"sanilwb_show_desktop": "1",
"sanilwb_show_tablet": "1",
"sanilwb_show_mobile": "1",
"children": [
{
"type": "image",
"id": 2,
"image-size": "medium",
"link": "1",
"width": "130",
"flex-shrink": "0",
"sanilwb_show_desktop": "1",
"sanilwb_show_tablet": "1",
"sanilwb_show_mobile": "0"
},
{
"type": "div",
"id": 3,
"direction": "column",
"gap": 6,
"flex-grow": "1",
"sanilwb_show_desktop": "1",
"sanilwb_show_tablet": "1",
"sanilwb_show_mobile": "1",
"children": [
{
"type": "heading",
"id": 4,
"link": "1",
"heading-font-size": "16",
"heading-font-weight": "600",
"heading-color": "var(--color-text)",
"heading-hover-color": "var(--color-primary)",
"sanilwb_margin_top": "0",
"sanilwb_margin_bottom": "0",
"sanilwb_show_desktop": "1",
"sanilwb_show_tablet": "1",
"sanilwb_show_mobile": "1"
},
{
"type": "meta",
"id": 5,
"sanilwb_show_desktop": "1",
"sanilwb_show_tablet": "1",
"sanilwb_show_mobile": "1"
}
]
}
]
}
]
}
Schema Node Reference
A schema is an array of root nodes. Each node is a JSON object. The type and id fields are required on every node. Children are nested under a "children" array.
Common fields (all node types)
| Field | Description |
|---|---|
type |
Node type identifier — see the node types table below |
id |
Integer, unique within the schema |
sanilwb_show_desktop |
"1" to show on desktop, "0" to hide |
sanilwb_show_tablet |
"1" to show on tablet, "0" to hide |
sanilwb_show_mobile |
"1" to show on mobile, "0" to hide |
sanilwb_padding_vertical |
Vertical padding in px |
sanilwb_padding_horizontal |
Horizontal padding in px |
sanilwb_margin_top |
Top margin in px |
sanilwb_margin_bottom |
Bottom margin in px |
sanilwb_border_style |
CSS border-style value (solid, dashed, dotted) |
sanilwb_border_color |
CSS color string |
sanilwb_border_width_top/right/bottom/left |
Border width per side in px |
sanilwb_border_radius_top/bottom |
Border radius in px |
sanilwb_background_color |
CSS color string |
Responsive overrides use double underscore suffixes: fieldName__tablet, fieldName__mobile.
Node types
type |
Description | Key fields |
|---|---|---|
div |
Container — flex row or column | direction (row/column), gap, align, justify, flex-grow, flex-shrink, children |
heading |
Post title | heading-font-size, heading-font-weight, heading-color, heading-hover-color, link ("1" wraps in anchor) |
image |
Featured image | image-size (WP image size key), width, link, animate-hover |
excerpt |
Post excerpt | excerpt-font-size, excerpt-color, excerpt-length |
meta |
Date and author line | meta-font-size, meta-color, show-author, show-date |
topic |
First post category label | topic-font-size, topic-color, topic-background-color |
text |
Static text node | text-content, text-font-size, text-color |
For the complete field reference including all CSS-mapped properties, see CLAUDE.md → Data Structures → Template schema, or review the SANILWB_Template_Compiler class.
What the Script Does
- Reads and parses the JSON definition file.
- Validates that
nameandschemaare present and thatbuilder_typeis a known value. - Calls
SANILWB_DB::insert()to write the row to{prefix}sanilwb_templates. - Calls
SANILWB_Template_Compiler::compile()to generate the PHP render file atwp-content/sanilwb-templates/template-{id}.php. - Prints the new template ID on success.
The result is identical to saving a template through the UI — the template is immediately available for use in the Page Builder widget.
Example Output
Template inserted. ID: 7
Template compiled. File: /var/www/html/wp-content/sanilwb-templates/template-7.php
Done. Template 'News Horizontal Card' created with ID 7.
Error Cases
| Error | Cause |
|---|---|
No definition file specified |
First argument was omitted |
File not found |
The path does not exist or is misspelled |
Invalid JSON |
The file contains a JSON syntax error — check with jq . file.json |
must include a 'name' field |
The name key is missing or empty |
must include a 'schema' field |
The schema key is missing or is not an array |
builder_type must be 'template' or 'titlebar' |
Unknown value passed in builder_type |
SANILWB_DB class not found |
Plugin is not active — activate it first |
Failed to insert template |
Database error — check $wpdb->last_error via wp db query |
Compiled file not found |
Insert succeeded but wp-content/sanilwb-templates/ is not writable |
Typical Workflow
Use this script to seed templates for a blueprint definition, test the compiler with specific node configurations, or bootstrap a development environment without clicking through the UI.
# 1. Reset everything first
wp eval-file wp-content/plugins/sanil-website-builder/bin/reset-plugin-data.php
# 2. Create templates from definition files
wp eval-file wp-content/plugins/sanil-website-builder/bin/create-template.php definitions/news-card.json
wp eval-file wp-content/plugins/sanil-website-builder/bin/create-template.php definitions/news-titlebar.json
# 3. Verify the templates were created
wp db query "SELECT id, name, category, builder_type FROM wp_sanilwb_templates;"