The code and data behind xeiaso.net
5
fork

Configure Feed

Select the types of activity you want to include in your feed.

docs(skills/templ-syntax): adopt progressive disclosure resources

Restructure the skill into a short progressive-disclosure guide and move deeper syntax guidance into focused resource docs with templ.guide references.

Assisted-by: openai/gpt-5.3-codex via OpenCode
Signed-off-by: Xe Iaso <me@xeiaso.net>

Xe Iaso f6a51eea d3b42ddd

+205 -318
+38 -318
.claude/skills/templ-syntax/SKILL.md
··· 5 5 6 6 # Templ Syntax 7 7 8 - ## Overview 8 + Use this skill with progressive disclosure: start at Level 1, then read deeper sections only when needed. 9 9 10 - Templ syntax combines Go code with HTML markup in `.templ` files. Components are compiled to Go functions, giving you type safety and IDE support. 10 + ## Level 1: Fast Path 11 11 12 - ## When to Use This Skill 12 + Use this skill when you need to write or fix `.templ` syntax. 13 13 14 - Use when: 15 - 16 - - Writing `.templ` component files 17 - - Learning templ syntax and expressions 18 - - User mentions "templ syntax", "component definition", ".templ file" 19 - - Converting HTML to templ components 20 - 21 - ## Basic Syntax 22 - 23 - ### Component Definition 14 + 1. Define a component with typed params. 15 + 2. Render values with `{ expr }`. 16 + 3. Compose components with `@OtherComponent(...)`. 17 + 4. Use Go control flow (`if`, `for`, `switch`) directly in markup. 18 + 5. Keep business logic in Go helpers, not inline in templates. 24 19 25 20 ```templ 26 21 package components 27 22 28 - templ ComponentName(param1 type1, param2 type2) { 29 - <div>Content</div> 30 - } 31 - ``` 32 - 33 - **Rules:** 34 - 35 - - Start with `package` declaration 36 - - Use `templ` keyword for component 37 - - PascalCase for exported components 38 - - camelCase for internal components 39 - 40 - ### Expressions 41 - 42 - Output Go variables with `{ }`: 43 - 44 - ```templ 45 - templ Greeting(name string, age int) { 46 - <p>Hello, { name }!</p> 47 - <p>You are { strconv.Itoa(age) } years old</p> 48 - } 49 - ``` 50 - 51 - **Expression rules:** 52 - 53 - - `{ variable }` outputs text (auto-escaped) 54 - - Can call Go functions: `{ strings.ToUpper(name) }` 55 - - Must return string or implement `fmt.Stringer` 56 - 57 - ### HTML Elements 58 - 59 - Write HTML directly: 60 - 61 - ```templ 62 - templ Card(title string) { 63 - <div class="card"> 64 - <h2>{ title }</h2> 65 - <p>Content goes here</p> 66 - </div> 67 - } 68 - ``` 69 - 70 - ### Attributes 71 - 72 - Static attributes: 73 - 74 - ```templ 75 - <div class="container" id="main"> 76 - ``` 77 - 78 - Dynamic attributes: 79 - 80 - ```templ 81 - templ Button(id string, disabled bool) { 82 - <button 83 - id={ id } 84 - disabled?={ disabled } 85 - class={ getButtonClass() } 86 - > 87 - Click 88 - </button> 89 - } 90 - ``` 91 - 92 - **Attribute syntax:** 93 - 94 - - `attr={ value }` - dynamic value 95 - - `attr?={ bool }` - conditional attribute 96 - - Use quotes for static: `class="btn"` 97 - 98 - ### Conditional Rendering 99 - 100 - If/else: 101 - 102 - ```templ 103 - templ Alert(message string, isError bool) { 104 - if isError { 105 - <div class="alert-error">{ message }</div> 106 - } else { 107 - <div class="alert-info">{ message }</div> 108 - } 109 - } 110 - ``` 111 - 112 - Multiple conditions: 113 - 114 - ```templ 115 - templ Status(code int) { 116 - if code < 300 { 117 - <span class="success">Success</span> 118 - } else if code < 400 { 119 - <span class="redirect">Redirect</span> 120 - } else { 121 - <span class="error">Error</span> 122 - } 123 - } 124 - ``` 125 - 126 - ### Loops 127 - 128 - For loop: 129 - 130 - ```templ 131 - templ List(items []string) { 132 - <ul> 133 - for _, item := range items { 134 - <li>{ item }</li> 135 - } 136 - </ul> 137 - } 138 - ``` 139 - 140 - With index: 141 - 142 - ```templ 143 - templ NumberedList(items []string) { 144 - <ol> 145 - for i, item := range items { 146 - <li>{ strconv.Itoa(i+1) }. { item }</li> 147 - } 148 - </ol> 149 - } 150 - ``` 151 - 152 - ### Switch Statements 153 - 154 - ```templ 155 - templ Badge(status string) { 156 - switch status { 157 - case "active": 158 - <span class="badge-green">Active</span> 159 - case "pending": 160 - <span class="badge-yellow">Pending</span> 161 - case "inactive": 162 - <span class="badge-gray">Inactive</span> 163 - default: 164 - <span class="badge-default">Unknown</span> 165 - } 166 - } 167 - ``` 168 - 169 - ### Component Composition 170 - 171 - Call other components with `@`: 172 - 173 - ```templ 174 - templ Layout(title string) { 175 - <!DOCTYPE html> 176 - <html> 177 - <head> 178 - <title>{ title }</title> 179 - </head> 180 - <body> 181 - @Header() 182 - <main> 183 - { children... } 184 - </main> 185 - @Footer() 186 - </body> 187 - </html> 188 - } 189 - 190 - templ Header() { 191 - <header> 192 - <h1>My Site</h1> 193 - </header> 194 - } 195 - 196 - templ Footer() { 197 - <footer> 198 - <p>&copy; 2024</p> 199 - </footer> 200 - } 201 - ``` 202 - 203 - **Usage:** 204 - 205 - ```templ 206 - templ HomePage() { 207 - @Layout("Home") { 208 - <p>Welcome to home page</p> 23 + templ Greeting(name string, isAdmin bool) { 24 + <h1>Hello, { name }</h1> 25 + if isAdmin { 26 + <p>Admin mode</p> 209 27 } 210 28 } 211 29 ``` 212 30 213 - ### Children 214 - 215 - Accept child content: 216 - 217 - ```templ 218 - templ Card(title string) { 219 - <div class="card"> 220 - <h3>{ title }</h3> 221 - <div class="card-body"> 222 - { children... } 223 - </div> 224 - </div> 225 - } 226 - ``` 31 + ## Level 2: Core Rules 227 32 228 - Use: 229 - 230 - ```templ 231 - templ Profile() { 232 - @Card("User Profile") { 233 - <p>Name: John Doe</p> 234 - <p>Email: john@example.com</p> 235 - } 236 - } 237 - ``` 238 - 239 - ### CSS Blocks 240 - 241 - Inline styles: 242 - 243 - ```templ 244 - templ StyledComponent() { 245 - <style> 246 - .custom-class { 247 - color: blue; 248 - font-size: 16px; 249 - } 250 - </style> 251 - <div class="custom-class">Styled content</div> 252 - } 253 - ``` 254 - 255 - ### Script Blocks 256 - 257 - Inline JavaScript: 258 - 259 - ```templ 260 - templ Interactive() { 261 - <button id="myBtn">Click me</button> 262 - 263 - <script> 264 - document.getElementById('myBtn').addEventListener('click', function() { 265 - alert('Clicked!'); 266 - }); 267 - </script> 268 - } 269 - ``` 270 - 271 - ### Comments 33 + - **Output:** `{ value }` auto-escapes text. 34 + - **Dynamic attrs:** `class={ classes }`, `disabled?={ isDisabled }`. 35 + - **Children:** accept with `{ children... }`, pass with block syntax. 36 + - **Composition:** call components with `@Component(...)`. 37 + - **Safety:** URLs should use safe helpers (for example `templ.URL(...)`) when appropriate. 272 38 273 - Go-style comments: 39 + ## Level 3: Common Patterns 274 40 275 41 ```templ 276 - package components 277 - 278 - // Card component displays a card 279 42 templ Card(title string) { 280 - // Main card container 281 - <div class="card"> 282 - { /* This is a block comment */ } 283 - <h3>{ title }</h3> 284 - </div> 43 + <section class="card"> 44 + <h2>{ title }</h2> 45 + <div>{ children... }</div> 46 + </section> 285 47 } 286 - ``` 287 48 288 - ## Quick Reference 289 - 290 - | Syntax | Purpose | Example | 291 - | ----------------- | --------------------- | -------------------------------- | 292 - | `{ expr }` | Output expression | `{ name }` | 293 - | `attr={ val }` | Dynamic attribute | `id={ userId }` | 294 - | `attr?={ bool }` | Conditional attribute | `disabled?={ isDisabled }` | 295 - | `@Component()` | Call component | `@Header()` | 296 - | `{ children... }` | Accept children | `{ children... }` | 297 - | `if/else` | Conditional | `if isAdmin { }` | 298 - | `for range` | Loop | `for _, item := range items { }` | 299 - | `switch` | Switch statement | `switch status { case "ok": }` | 300 - 301 - ## Common Patterns 302 - 303 - ### Pattern 1: Conditional Classes 304 - 305 - ```templ 306 - templ Button(text string, isPrimary bool) { 307 - <button class={ templ.KV("btn-primary", isPrimary) }> 308 - { text } 309 - </button> 310 - } 311 - ``` 312 - 313 - ### Pattern 2: List with Empty State 314 - 315 - ```templ 316 - templ ItemList(items []string) { 317 - if len(items) == 0 { 318 - <p>No items found</p> 49 + templ UserList(users []string) { 50 + if len(users) == 0 { 51 + <p>No users</p> 319 52 } else { 320 53 <ul> 321 - for _, item := range items { 322 - <li>{ item }</li> 54 + for _, user := range users { 55 + <li>{ user }</li> 323 56 } 324 57 </ul> 325 58 } 326 59 } 327 60 ``` 328 61 329 - ### Pattern 3: Data Attributes 330 - 331 - ```templ 332 - templ DataCard(id string, value int) { 333 - <div 334 - data-id={ id } 335 - data-value={ strconv.Itoa(value) } 336 - > 337 - Content 338 - </div> 339 - } 340 - ``` 341 - 342 - ## Best Practices 62 + ## Escalate to Other Skills 343 63 344 - 1. **Keep components small** - One component, one purpose 345 - 2. **Use type-safe params** - Leverage Go's type system 346 - 3. **Avoid complex logic** - Move to Go functions 347 - 4. **Consistent naming** - PascalCase for exports 348 - 5. **Escape when needed** - Use `{ }` for auto-escaping 64 + - Building reusable UI APIs: use `templ-components`. 65 + - Wiring templates to handlers/routes: use `templ-http`. 66 + - Adding dynamic interactions: use `templ-htmx`. 349 67 350 - ## Next Steps 68 + ## References 351 69 352 - - **Build components** → Use `templ-components` skill 353 - - **Connect to HTTP** → Use `templ-http` skill 354 - - **Add interactivity** → Use `templ-htmx` skill 70 + - Foundations: `resources/foundations.md` 71 + - Patterns: `resources/patterns.md` 72 + - Reference: `resources/reference.md` 73 + - templ docs: https://templ.guide 74 + - Syntax and expressions: https://templ.guide/syntax-and-usage/
+40
.claude/skills/templ-syntax/resources/foundations.md
··· 1 + # Templ Syntax Foundations 2 + 3 + Use this when you need baseline templ syntax behavior. 4 + 5 + ## Component Shape 6 + 7 + ```templ 8 + package components 9 + 10 + templ Greeting(name string, age int) { 11 + <p>Hello, { name }!</p> 12 + <p>You are { strconv.Itoa(age) } years old</p> 13 + } 14 + ``` 15 + 16 + - Start with `package` and imports, then `templ Name(args...)` blocks. 17 + - Components compile to Go functions returning `templ.Component`. 18 + - Keep component inputs typed and narrow. 19 + 20 + ## Elements and Expressions 21 + 22 + - Close tags in templ source (`</tag>` or `/>`), even for void elements. 23 + - `{ expr }` renders escaped output with context-aware escaping. 24 + - `attr={ value }` sets dynamic attrs; `attr?={ bool }` toggles boolean attrs. 25 + 26 + ## Control Flow and Raw Go 27 + 28 + - Use normal Go flow directly: `if`, `switch`, `for`. 29 + - Use raw Go blocks with `{{ ... }}` for local variables or pre-compute steps. 30 + - Parser gotcha: raw text starting with `if`, `for`, or `switch` may parse as statements; rewrite text or wrap it in an expression. 31 + 32 + Keep heavy logic in Go helpers/services, not inline template logic. 33 + 34 + ## Sources 35 + 36 + - https://templ.guide/syntax-and-usage/basic-syntax 37 + - https://templ.guide/syntax-and-usage/elements 38 + - https://templ.guide/syntax-and-usage/expressions 39 + - https://templ.guide/syntax-and-usage/statements 40 + - https://templ.guide/syntax-and-usage/raw-go
+83
.claude/skills/templ-syntax/resources/patterns.md
··· 1 + # Templ Syntax Patterns 2 + 3 + ## Composition and Children 4 + 5 + ```templ 6 + templ Layout(title string) { 7 + <html> 8 + <head><title>{ title }</title></head> 9 + <body> 10 + @Header() 11 + <main>{ children... }</main> 12 + @Footer() 13 + </body> 14 + </html> 15 + } 16 + ``` 17 + 18 + - Call components with `@Component(...)`. 19 + - Accept nested content with `{ children... }`. 20 + 21 + Code-side composition helpers: 22 + 23 + - `templ.WithChildren(ctx, child)` injects children for downstream rendering. 24 + - `templ.GetChildren(ctx)` reads current children. 25 + - `templ.ClearChildren(ctx)` prevents accidental child forwarding. 26 + 27 + ## Component Parameters and Join 28 + 29 + ```templ 30 + templ Panel(header templ.Component) { 31 + <section> 32 + @header 33 + <div>{ children... }</div> 34 + </section> 35 + } 36 + ``` 37 + 38 + - Use `templ.Component` params for explicit slots. 39 + - Use `templ.Join(...)` in Go for rendering multiple components in order. 40 + 41 + ## Conditional List Rendering 42 + 43 + ```templ 44 + templ ItemList(items []string) { 45 + if len(items) == 0 { 46 + <p>No items found</p> 47 + } else { 48 + <ul> 49 + for _, item := range items { 50 + <li>{ item }</li> 51 + } 52 + </ul> 53 + } 54 + } 55 + ``` 56 + 57 + ## Conditional Class Pattern 58 + 59 + ```templ 60 + templ Button(text string, isPrimary bool) { 61 + <button class={ templ.KV("btn-primary", isPrimary) }>{ text }</button> 62 + } 63 + ``` 64 + 65 + ## Fragment Pattern 66 + 67 + ```templ 68 + templ UserPage(user User) { 69 + @templ.Fragment("user-card") { 70 + <article>{ user.Name }</article> 71 + } 72 + } 73 + ``` 74 + 75 + - Render selected fragments with `templ.WithFragments(ctx, "user-card")`. 76 + - Use `templ.RenderFragments` when writing outside normal HTTP handlers. 77 + - Fragment filtering trims output only; non-fragment template logic still executes. 78 + 79 + ## Sources 80 + 81 + - https://templ.guide/syntax-and-usage/template-composition 82 + - https://templ.guide/syntax-and-usage/fragments 83 + - https://templ.guide/syntax-and-usage/attributes
+44
.claude/skills/templ-syntax/resources/reference.md
··· 1 + # Templ Syntax Reference 2 + 3 + ## Quick Syntax Table 4 + 5 + | Syntax | Purpose | Example | 6 + | --- | --- | --- | 7 + | `{ expr }` | Output expression | `{ name }` | 8 + | `attr={ val }` | Dynamic attr | `id={ userID }` | 9 + | `attr?={ bool }` | Conditional attr | `disabled?={ busy }` | 10 + | `{ attrs... }` | Spread attrs | `{ attrs... }` | 11 + | `@Component()` | Component call | `@Header()` | 12 + | `{ children... }` | Child slot | `{ children... }` | 13 + | `{{ ... }}` | Raw Go block | `{{ n := len(items) }}` | 14 + | `@templ.Fragment(key)` | Named fragment | `@templ.Fragment("row") { ... }` | 15 + | `templ.WithFragments` | Select output fragments | `ctx = templ.WithFragments(ctx, "row")` | 16 + 17 + ## Best Practices 18 + 19 + 1. Keep components small and focused. 20 + 2. Move complex branching/formatting into Go helpers. 21 + 3. Use strongly typed inputs over ad-hoc maps. 22 + 4. Keep rendering deterministic and side-effect free. 23 + 24 + ## Safety APIs 25 + 26 + - `templ.URL(...)`: safe URL type for custom URL attrs (for example `hx-get`). 27 + - `templ.SafeURL(...)`: bypass URL sanitization only for trusted values. 28 + - `templ.Raw(...)`: inject trusted raw HTML only. 29 + - `templ.JSFuncCall(...)`: safe JS call construction for handler attrs. 30 + - `templ.JSONString(...)` and `templ.JSONScript(...)`: safer JSON embedding patterns. 31 + 32 + ## Cross-Skill Routing 33 + 34 + - Reusable component APIs: `templ-components` 35 + - HTTP integration: `templ-http` 36 + - Interactivity with partial swaps: `templ-htmx` 37 + 38 + ## Sources 39 + 40 + - https://templ.guide/syntax-and-usage/attributes 41 + - https://templ.guide/syntax-and-usage/raw-go 42 + - https://templ.guide/syntax-and-usage/fragments 43 + - https://templ.guide/syntax-and-usage/rendering-raw-html 44 + - https://templ.guide/syntax-and-usage/script-templates