templ-syntax
Learn and write templ component syntax including expressions, conditionals, loops, and Go integration. Use when writing .templ files, learning templ syntax, or mentions 'templ component', 'templ expressions', or '.templ file syntax'.
When & Why to Use This Skill
This Claude skill provides comprehensive support for mastering and implementing Templ syntax, a language that merges Go logic with HTML markup. It enables developers to build type-safe, reusable UI components with features like dynamic expressions, conditional rendering, and efficient component composition, significantly enhancing the development workflow for Go-based web applications.
Use Cases
- Case 1: Creating type-safe, reusable UI components in Go web applications to ensure compile-time errors instead of runtime template failures.
- Case 2: Converting legacy HTML snippets into structured .templ files while integrating Go variables and logic directly into the markup.
- Case 3: Implementing complex server-side rendering logic, such as conditional attribute handling and dynamic list generation, using Go's native control structures within templates.
- Case 4: Building modular web layouts through component composition, allowing for nested children and shared header/footer structures across multiple pages.
| name | templ-syntax |
|---|---|
| description | Learn and write templ component syntax including expressions, conditionals, loops, and Go integration. Use when writing .templ files, learning templ syntax, or mentions 'templ component', 'templ expressions', or '.templ file syntax'. |
Templ Syntax
Overview
Templ syntax combines Go code with HTML markup in .templ files. Components are compiled to Go functions, giving you type safety and IDE support.
When to Use This Skill
Use when:
- Writing
.templcomponent files - Learning templ syntax and expressions
- User mentions "templ syntax", "component definition", ".templ file"
- Converting HTML to templ components
Basic Syntax
Component Definition
package components
templ ComponentName(param1 type1, param2 type2) {
<div>Content</div>
}
Rules:
- Start with
packagedeclaration - Use
templkeyword for component - PascalCase for exported components
- camelCase for internal components
Expressions
Output Go variables with { }:
templ Greeting(name string, age int) {
<p>Hello, { name }!</p>
<p>You are { strconv.Itoa(age) } years old</p>
}
Expression rules:
{ variable }outputs text (auto-escaped)- Can call Go functions:
{ strings.ToUpper(name) } - Must return string or implement
fmt.Stringer
HTML Elements
Write HTML directly:
templ Card(title string) {
<div class="card">
<h2>{ title }</h2>
<p>Content goes here</p>
</div>
}
Attributes
Static attributes:
<div class="container" id="main">
Dynamic attributes:
templ Button(id string, disabled bool) {
<button
id={ id }
disabled?={ disabled }
class={ getButtonClass() }
>
Click
</button>
}
Attribute syntax:
attr={ value }- dynamic valueattr?={ bool }- conditional attribute- Use quotes for static:
class="btn"
Conditional Rendering
If/else:
templ Alert(message string, isError bool) {
if isError {
<div class="alert-error">{ message }</div>
} else {
<div class="alert-info">{ message }</div>
}
}
Multiple conditions:
templ Status(code int) {
if code < 300 {
<span class="success">Success</span>
} else if code < 400 {
<span class="redirect">Redirect</span>
} else {
<span class="error">Error</span>
}
}
Loops
For loop:
templ List(items []string) {
<ul>
for _, item := range items {
<li>{ item }</li>
}
</ul>
}
With index:
templ NumberedList(items []string) {
<ol>
for i, item := range items {
<li>{ strconv.Itoa(i+1) }. { item }</li>
}
</ol>
}
Switch Statements
templ Badge(status string) {
switch status {
case "active":
<span class="badge-green">Active</span>
case "pending":
<span class="badge-yellow">Pending</span>
case "inactive":
<span class="badge-gray">Inactive</span>
default:
<span class="badge-default">Unknown</span>
}
}
Component Composition
Call other components with @:
templ Layout(title string) {
<!DOCTYPE html>
<html>
<head>
<title>{ title }</title>
</head>
<body>
@Header()
<main>
{ children... }
</main>
@Footer()
</body>
</html>
}
templ Header() {
<header>
<h1>My Site</h1>
</header>
}
templ Footer() {
<footer>
<p>© 2024</p>
</footer>
}
Usage:
templ HomePage() {
@Layout("Home") {
<p>Welcome to home page</p>
}
}
Children
Accept child content:
templ Card(title string) {
<div class="card">
<h3>{ title }</h3>
<div class="card-body">
{ children... }
</div>
</div>
}
Use:
templ Profile() {
@Card("User Profile") {
<p>Name: John Doe</p>
<p>Email: john@example.com</p>
}
}
CSS Blocks
Inline styles:
templ StyledComponent() {
<style>
.custom-class {
color: blue;
font-size: 16px;
}
</style>
<div class="custom-class">Styled content</div>
}
Script Blocks
Inline JavaScript:
templ Interactive() {
<button id="myBtn">Click me</button>
<script>
document.getElementById('myBtn').addEventListener('click', function() {
alert('Clicked!');
});
</script>
}
Comments
Go-style comments:
package components
// Card component displays a card
templ Card(title string) {
// Main card container
<div class="card">
{ /* This is a block comment */ }
<h3>{ title }</h3>
</div>
}
Quick Reference
| Syntax | Purpose | Example |
|---|---|---|
{ expr } |
Output expression | { name } |
attr={ val } |
Dynamic attribute | id={ userId } |
attr?={ bool } |
Conditional attribute | disabled?={ isDisabled } |
@Component() |
Call component | @Header() |
{ children... } |
Accept children | { children... } |
if/else |
Conditional | if isAdmin { } |
for range |
Loop | for _, item := range items { } |
switch |
Switch statement | switch status { case "ok": } |
Common Patterns
Pattern 1: Conditional Classes
templ Button(text string, isPrimary bool) {
<button class={ templ.KV("btn-primary", isPrimary) }>
{ text }
</button>
}
Pattern 2: List with Empty State
templ ItemList(items []string) {
if len(items) == 0 {
<p>No items found</p>
} else {
<ul>
for _, item := range items {
<li>{ item }</li>
}
</ul>
}
}
Pattern 3: Data Attributes
templ DataCard(id string, value int) {
<div
data-id={ id }
data-value={ strconv.Itoa(value) }
>
Content
</div>
}
Best Practices
- Keep components small - One component, one purpose
- Use type-safe params - Leverage Go's type system
- Avoid complex logic - Move to Go functions
- Consistent naming - PascalCase for exports
- Escape when needed - Use
{ }for auto-escaping
Next Steps
- Build components → Use
templ-componentsskill - Connect to HTTP → Use
templ-httpskill - Add interactivity → Use
templ-htmxskill