Template Syntax
Collagraph uses a Vue-inspired template syntax. If you know Vue, you already know most of this. The key difference is that all expressions are Python instead of JavaScript.
For full Vue template syntax documentation, see: Vue Template Syntax
Prefer plain Python?
Everything on this page can also be expressed in pure Python, without a .cgx file. See Python Views.
File Format
A .cgx file has a template section and a <script> section:
<div>
<!-- template here -->
</div>
<script>
import collagraph as cg
class MyComponent(cg.Component):
pass
</script>
The template is everything outside the <script> tag. Unlike Vue, there's no <template> wrapper needed.
Multiple Root Nodes
Unlike Vue 2 (but like Vue 3), collagraph supports multiple root nodes in a template. There's no need to wrap everything in a single container element:
<label text="First" />
<label text="Second" />
<button text="Third" />
<script>
import collagraph as cg
class Multi(cg.Component):
pass
</script>
Text Interpolation
Elements can contain text content, with double curly braces for dynamic expressions:
Expressions inside {{ }} are evaluated as Python. Static and dynamic parts can be mixed freely, and multiline text is normalized (leading indentation after line breaks is stripped). To render literal braces, escape them with a backslash: \{{.
Renderer support
Text content requires the renderer to support text elements. The Pygfx renderer supports it inside <text> elements. The PySide6 renderer supports it inside widgets that display text, such as <label> and <button> (see PySide6 Renderer):
For other Qt widgets, set text via the text attribute instead:
Attribute Binding
Static attributes:
Dynamic attributes (prefix with :):
The expression after : is evaluated as Python. See Vue Attribute Bindings for the concept.
Event Handling
Prefix with @:
You can use inline expressions:
See Vue Event Handling for the concept.
Conditional Rendering
With v-else-if:
<label v-if="status == 'loading'" text="Loading..." />
<label v-else-if="status == 'error'" text="Error!" />
<label v-else text="Done" />
See Vue Conditional Rendering.
List Rendering
With index:
See Vue List Rendering.
Component Usage
Import and use components by their class name:
<TodoList :items="items" @clicked="handle_complete" />
<script>
from todo_list import TodoList
import collagraph as cg
class App(cg.Component):
pass
</script>
Component names in templates use PascalCase.
Slots
Define where child content goes:
Provide content to slots:
Named slots:
<!-- Layout.cgx -->
<widget>
<slot name="header" />
<slot />
<slot name="footer" />
</widget>
<!-- Usage -->
<Layout>
<label slot="header" text="Header" />
<label text="Body content" />
<label slot="footer" text="Footer" />
</Layout>
Comments
HTML comments are supported: