Tutorial: Using the Page Builder
The Page Builder is a full-screen visual layout editor that lets you compose page content using a hierarchy of sections, rows, columns, and widgets. It runs inside the WordPress post/page edit screen and saves everything to the sanilwb_data post meta field.
This tutorial walks through building a page from scratch — adding layout structure, placing widgets, configuring them, and saving. It also explains how drag-and-drop reordering works and how to use the history panel for undo/redo.
Opening the Page Builder
Navigate to any WordPress post or page in the admin. Below the Gutenberg editor, find the Sanil Page Builder meta box. Click Open Page Builder to launch the full-screen editor.
Understanding the UI
The editor is divided into three areas:
| Area | Location | Purpose |
|---|---|---|
| Topbar | Top bar across the full width | Post title display, device toggle, Save button, Close button |
| Layers Panel | Left sidebar | All create, delete, reorder, and settings actions |
| Canvas | Right side, fills remaining space | Live visual preview of the current layout |
The canvas is read-only for editing. Clicking a widget in the canvas highlights its bar in the Layers Panel and scrolls to it, but all actual editing happens in the Layers Panel. This separation keeps the canvas a clean preview, not an interactive editor.
The Layer Hierarchy
Every page is built from four nested levels. Understanding this hierarchy is essential before you can work effectively in the builder.
Section (full-width band across the page)
└── Row (defines the column split for that band)
└── Column (one Bootstrap grid column)
└── Widget (a content block)
OR
└── Nested Row (a second level of columns inside a column)
Color coding in the Layers Panel
| Level | Bar color |
|---|---|
| Section | Blue |
| Row | Green |
| Column | Violet |
| Nested Row | Light green |
| Nested Column | Light violet |
| Widget | Amber with a colored dot |
This color coding makes it immediately clear what level you are looking at when the panel is long.
Columns hold an ordered list of items
A column's content is a single ordered items[] list. Each item is either a widget or a nested row. You can freely mix them in any order and add as many nested rows as you need. There is no either/or restriction.
Step 1 — Add Your First Section
When the builder opens on an empty page, the Layers Panel shows a placeholder message with guidance text. Click Add Section to add the first section.
A new section is created with: - One row (defaulting to a single full-width column) - One full-width column inside that row
The section bar (blue) immediately appears in the Layers Panel. The canvas updates to show a blank section outline.
To add more sections later: click a Section bar and use the Add Section Below button on its right side. This inserts a new section directly below the current one.
Step 2 — Choose a Column Layout for the Row
Click the Row bar (green) inside the section to expand it. On the right side of the row bar you will see action buttons. Click the Layout button (the grid icon) to open the layout picker popover.
Available column splits:
| Layout ID | Short label | Column widths |
|---|---|---|
single-column-template |
Full | 12 (one column) |
six_six-column-template |
1 : 1 | 6 / 6 |
eight_four-column-template |
2 : 1 | 8 / 4 |
nine_three-column-template |
3 : 1 | 9 / 3 |
three_nine-column-template |
1 : 3 | 3 / 9 |
four_eight-column-template |
1 : 2 | 4 / 8 |
five_seven-column-template |
5 : 7 | 5 / 7 |
seven_five-column-template |
7 : 5 | 7 / 5 |
Click the layout you want. The row updates immediately in both the Layers Panel and the canvas.
What happens to existing widgets when you change a layout? Existing column data is preserved for columns that survive the change. If you switch from a 2-column layout to a 3-column layout, the first two columns keep their widgets and the third column starts empty. If you switch from 3 columns to 2, the third column's content is lost.
Step 3 — Add a Widget to a Column
Click a Column bar (violet) to reveal it. On the right side you will see an Add Widget button (the + icon). Click it to open the Widget Picker dialog.
Available widget types:
| Widget | Label | What it does |
|---|---|---|
posts |
Posts | A post listing grid with query controls, display toggles, and optional carousel |
read_more_btn |
Read More Button | A call-to-action button with URL, style, color, and alignment controls |
title_bar |
Title Bar | A section heading bar rendered using a titlebar template |
Click the widget type to add it. The widget is inserted into the column and its Settings Dialog opens immediately so you can configure it before returning to the canvas.
Step 4 — Configure the Posts Widget
The Posts widget dialog has four tabs. You must configure the Template tab first — the Content tab is disabled until a template is selected.
Template tab
Select a template from the list. Templates control the visual card layout — how the post image, title, excerpt, author, and other fields are arranged. Each template in the list shows a small preview and a label.
After selecting a template, the Content tab becomes available.
Content tab
| Field | What it controls |
|---|---|
| Number of Posts | How many posts to query and display |
| Offset | Skip the first N posts (useful for "show the next 3 after the featured post" patterns) |
| Order | Newest First (DESC) or Oldest First (ASC) |
| Category | Filter to a specific category |
| Exclude Category | Exclude a category from results |
| Specific Post IDs | Show only these post IDs (comma-separated) |
| Show Image | Toggle — only shown if the selected template has an image node |
| Show Topic | Toggle — only shown if the template supports topics |
| Show Excerpt | Toggle — only shown if the template has an excerpt node |
| Show Date | Toggle — only shown if the template has a date node |
| Show Author | Toggle — only shown if the template has an author node |
| Carousel | Enable to turn the post grid into a horizontal sliding carousel |
Display toggle fields (Show Image, Show Topic, etc.) only appear when the selected template actually contains those node types. This prevents setting options that the template can't render.
Style tab
| Field | What it controls |
|---|---|
| Columns | How many columns to display cards in (1–6) |
| Gap (Horizontal) | Space between columns |
| Gap (Vertical) | Space between rows of cards |
| Container (margin, padding, borders) | Spacing around the entire widget block |
Advanced tab
| Field | What it controls |
|---|---|
| Show on Desktop | Toggle visibility at desktop viewport |
| Show on Tablet | Toggle visibility at tablet viewport |
| Show on Mobile | Toggle visibility at mobile viewport |
| Admin Label | Custom name shown on this widget's layer bar (overrides "Posts 1") |
| CSS Class | Custom class added to the widget's wrapper element |
Click Save when done. The canvas updates to show the rendered widget.
Step 5 — Add More Rows and Widgets
To add another row to a section, click the Section bar (blue) and use the Add Row button on the right side of the bar.
To add more widgets to a column, click the Column bar (violet) and use the Add Widget button. New widgets are appended at the bottom of the column's item list. Drag any item's bar to reorder it.
Step 6 — Using Nested Rows
A nested row lets you build a more complex column split inside a single top-level column. For example: inside a wide col-lg-8 column, you want two sub-columns of col-lg-6 each.
To add a nested row:
- Click a Column bar (violet).
- Click the Add Nested Row button (the split-columns icon) on the right side of the bar.
- A nested row appears inside the column with a default single-column layout.
- Click the nested row bar (light green) and use the Layout button to choose a sub-column split.
- Click the nested column bars (light violet) to add widgets inside each sub-column.
You can add multiple nested rows to the same column. Each nested row bar can be dragged independently to reorder it alongside other widgets in the column.
Widgets and nested rows can be freely mixed in any order. For example, a column can contain a widget, then a nested row, then another widget. Use the drag handle on any item bar to reorder them.
Nested rows are limited to one level deep. You cannot add a nested row inside a nested column.
Step 7 — Configure Section Settings
Click a Section bar (blue) and use the Settings button (gear icon) to open the Section Settings dialog.
| Tab | Fields |
|---|---|
| Style | Background color, margin top/bottom, padding vertical/horizontal, border radius, border width/style/color |
| Advanced | Admin label, CSS class |
Section settings are useful for adding background colors to a full-width band or adding breathing room between sections.
Step 8 — Reorder Elements by Dragging
All element types can be reordered by dragging their layer bars. To start a drag:
- Click and hold on any layer bar.
- Move the cursor at least 6 pixels before the drag activates. This small threshold prevents accidental drags when you intend to click.
- A Drag Overlay (a lightweight clone of the bar) follows the cursor. The original bar dims in place.
- Drop onto the target position.
What can be dragged where:
| Item | Can be moved to |
|---|---|
| Section | Any position in the section list |
| Row | Another position in the same section, or any other section |
| Column | Another position within the same row only |
| Widget | Another position in the same column, or any other column (including nested columns) |
| Nested Row | Another position within the same column only |
Step 9 — Undo and Redo
Every action that changes the layout (add, remove, move, save widget/section settings) creates an undo snapshot before applying the change. The undo stack holds up to 50 snapshots.
| Keyboard shortcut | Action |
|---|---|
Ctrl+Z |
Undo the last action |
Ctrl+Y |
Redo (restore the undone action) |
Ctrl+Shift+Z |
Redo (alternative shortcut) |
Shortcuts are ignored when your cursor is inside a text input, textarea, select element, or any contentEditable area — so you can type normally in widget dialogs without accidentally triggering undo.
History Panel
Click the History button in the Layers Panel header to switch from the Layers Panel to the History Panel. The History Panel shows a flat timeline of all actions with the most recent at the top.
- The blue highlight shows the current state.
- Click any entry to jump directly to that point in history (
jumpToHistory()runs undo or redo in a loop to reach the target index). - Entries above the highlight are redoable (future actions you have undone). Entries below are the recorded past.
- The timeline never reorders — undo/redo only moves the highlight cursor through the fixed list.
Step 10 — Device Preview
The Device Toggle in the topbar switches the canvas between three simulated viewport widths.
| Device | Canvas behavior |
|---|---|
| Desktop | Full width (minimum 992 px, keeping Bootstrap col-lg-* columns side-by-side) |
| Tablet | Fixed narrower width |
| Mobile | Fixed narrow width |
Width transitions animate with a 0.25-second ease. On tablet and mobile, the canvas is horizontally centered.
The device state is shared between the topbar toggle and the widget settings dialog's device toggle. Switching one switches both.
Step 11 — Save
Click Save in the topbar. The button has three visible states:
| State | What it means |
|---|---|
| Greyed out / disabled | No unsaved changes — nothing to save |
| Active blue | Unsaved changes exist |
| "Saving…" | AJAX request is in flight — a mutex prevents a second click from firing |
| "Saved ✓" (1.5 seconds) | Request succeeded |
The Save button is disabled when there are no unsaved changes. This is intentional — it prevents unnecessary AJAX requests and gives you a clear signal about whether changes are pending.
Closing without saving: If you click the Close button (or navigate away) while there are unsaved changes, the builder shows a confirmation dialog before leaving. Confirming discards all unsaved changes.
Common Mistakes
The canvas looks empty after adding a Posts widget
Open the widget settings and select a template in the Template tab. Without a template, the Posts widget has no card layout to render and the canvas shows nothing.
I want to add a widget above or below a nested row
Click the column bar and use the Add Widget button — the widget is appended to the end of the column's item list. To reorder it above or below a nested row, drag its layer bar to the desired position.
I changed the row layout and lost content in one column
Changing a row layout from more columns to fewer columns drops the content in the extra columns that no longer exist. This is irreversible in the UI — use undo (Ctrl+Z) immediately to restore the layout before the loss.
I can't drag a row into a different section
You may be dragging the section bar (blue) instead of the row bar (green). Make sure you are grabbing the row bar. Also confirm the target section is open (expanded) so the drop zone is visible.
The canvas doesn't update after I change widget settings
The canvas reflects the last saved state of the widget. Click Save inside the widget settings dialog. The canvas then re-renders with the new values.
Widget layer bars show names like "Posts 1", "Posts 2"
These are auto-generated labels based on the widget type and count. To give a widget a meaningful name, open its settings dialog, go to the Advanced tab, and fill in the Admin Label field.