Layout
The layout resource defines the visual structure of the lab UI through columns and rows. Layouts organize how tabs (terminal, service, editor, etc.) and instructions are displayed to users.
HCL Syntax
Section titled “HCL Syntax”Basic Syntax
Section titled “Basic Syntax”resource "layout" "name" { column { instructions {} }
column { tab "terminal" { target = resource.terminal.main } }}
Full Syntax
Section titled “Full Syntax”resource "layout" "name" { column { width = "percentage"
tab "name" { target = resource.type.name title = "Display Title" active = true visible = true closeable = false movable = false }
instructions { title = "Instructions" active = false }
row { height = "percentage" # nested content } }}
Fields
Section titled “Fields”Core Configuration
Section titled “Core Configuration”Field | Required | Type | Description |
---|---|---|---|
column | ✓ | block | Column definitions (repeatable) |
Layout Structure
Section titled “Layout Structure”The layout resource uses a hierarchical structure:
- Columns: Vertical divisions of the layout
- Rows: Horizontal divisions within columns
- Tabs: Content panels that reference other resources
- Instructions: Special panel for lab instructions
Column Block
Section titled “Column Block”layout → column
A column is a vertical panel within the layout. Columns do not have names or IDs - they are anonymous blocks.
Column Fields
Section titled “Column Fields”Field | Required | Type | Description |
---|---|---|---|
width | string | Width of the column as a percentage (e.g., “50%”, “33%”). Defaults to equal distribution. | |
tab | block | Tab blocks defining content panels | |
instructions | block | Instructions panel configuration | |
row | block | Nested row blocks for further subdivision |
Row Block
Section titled “Row Block”A row is a horizontal panel within a column. Like columns, rows are anonymous blocks without names or IDs.
Row Fields
Section titled “Row Fields”Field | Required | Type | Description |
---|---|---|---|
height | string | Height of the row as a percentage. Defaults to equal distribution. | |
tab | block | Tab blocks defining content panels | |
instructions | block | Instructions panel configuration | |
column | block | Nested column blocks for further subdivision |
Tab Block
Section titled “Tab Block”layout → tab
Tabs define the actual content panels within the layout. Each tab must have a name (used as a label) and references a resource.
Tab Fields
Section titled “Tab Fields”Field | Required | Type | Description |
---|---|---|---|
name | ✓ | label | The identifier for the tab (becomes the label) |
title | string | Display title for the tab. Defaults to capitalized name. | |
target | ✓ | reference to terminal , service , editor , external_website , note | Reference to the resource to display |
active | bool | Whether the tab is initially active. Defaults to false. | |
visible | bool | Whether the tab is visible. Defaults to true. | |
closeable | bool | Whether users can close the tab. Defaults to false. | |
movable | bool | Whether users can move the tab. Defaults to false. |
Supported Tab Targets
Section titled “Supported Tab Targets”Resource Type | Description | Reference |
---|---|---|
terminal |
Interactive command-line interface | Terminal |
service |
Web applications and services | Service |
editor |
Code editing environment | Editor |
external_website |
External website integration | External Website |
note |
Reference materials and documentation | Note |
Instructions Block
Section titled “Instructions Block”layout → instructions
The instructions block configures the special instructions panel.
Instructions Fields
Section titled “Instructions Fields”Field | Required | Type | Description |
---|---|---|---|
title | string | Title of the instructions tab. Defaults to “Instructions”. | |
active | bool | Whether the tab is initially active. Defaults to false. | |
visible | bool | Whether the tab is visible. Defaults to true. | |
closeable | bool | Whether users can close the tab. Defaults to false. | |
movable | bool | Whether users can move the tab. Defaults to false. |
Validation Rules
Section titled “Validation Rules”- Tab names must be unique within a layout and follow identifier rules (alphanumeric and underscore only, cannot start with a number)
- The name “instructions” is reserved and cannot be used for tab names
- Tab targets must reference existing resources of supported types
- Width and height values must be valid CSS percentages (e.g., “50%”, “33.33%”)
- Percentages in a column/row should ideally sum to 100% for predictable layout behavior
Examples
Section titled “Examples”Two Column Layout
Section titled “Two Column Layout”resource "layout" "two_column" { column { width = "50%"
instructions {} }
column { width = "50%"
tab "terminal" { target = resource.terminal.main } }}
Complex Layout with Rows
Section titled “Complex Layout with Rows”resource "layout" "complex" { column { width = "40%"
instructions {} }
column { width = "60%"
row { height = "70%"
tab "terminal" { target = resource.terminal.main active = true }
tab "editor" { target = resource.editor.code } }
row { height = "30%"
tab "service" { target = resource.service.web } } }}
Three Column Layout
Section titled “Three Column Layout”resource "layout" "three_column" { column { width = "25%"
instructions {} }
column { width = "50%"
tab "terminal" { target = resource.terminal.main active = true }
tab "terminal2" { target = resource.terminal.secondary } }
column { width = "25%"
tab "notes" { target = resource.note.hints } }}
Nested Layout
Section titled “Nested Layout”resource "layout" "nested" { column { width = "30%"
row { height = "50%" instructions {} }
row { height = "50%" tab "notes" { target = resource.note.hints } } }
column { width = "70%"
row { height = "60%"
column { width = "60%" tab "terminal" { target = resource.terminal.main } }
column { width = "40%" tab "editor" { target = resource.editor.config } } }
row { height = "40%" tab "service" { target = resource.service.app } } }}
Migration Notes
Section titled “Migration Notes”Breaking Change: The layout format has changed significantly from earlier versions:
- Old format: Layout resources defined columns with IDs, tabs were configured separately in the lab resource referencing these column IDs
- New format: Layout resources define columns with tabs inline, no separate tab configuration needed
If migrating from the old format:
## OLD (no longer valid)resource "layout" "two_column" { column "terminal" {}
column "instructions" { width = 33 }}
# main.hclresource "lab" "example" { layout "two_column" { reference = resource.layout.two_column
tab "terminal" { panel = "terminal" # References column ID target = resource.terminal.shell }
instructions { panel = "instructions" # References column ID } }}
## NEW (current format)resource "layout" "two_column" { column { tab "terminal" { target = resource.terminal.shell } }
column { width = "33%"
tab "instructions" { type = "instructions" } }}
resource "lab" "example" { layout = resource.layout.two_column}
Best Practices
Section titled “Best Practices”- Start Simple: Begin with a two-column layout (instructions + terminal)
- Responsive Design: Consider how your layout will appear on different screen sizes
- Tab Organization: Group related tabs in the same column/row
- Active Tabs: Set one tab per column/row as active for better UX
- Avoid Deep Nesting: Limit nesting to 2-3 levels for maintainability