Migrate jqhtml slot syntax from <#name> to <Slot:name>

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
root
2025-11-24 03:43:45 +00:00
parent 22df126977
commit 881425bed6
35 changed files with 124 additions and 122 deletions

View File

@@ -55,10 +55,10 @@ Indexes all files in `/rsx/` for automatic discovery and loading.
## JQHTML Named Slots (v2.2.112+)
Child template syntax changed from `<#slotname />` tags to `content('slotname')` function:
- Old: `<#header />` (deprecated)
Child template syntax changed from `<Slot:slotname />` tags to `content('slotname')` function:
- Old: `<Slot:header />` (deprecated)
- New: `<%= content('header') %>` (v2.2.112+)
- Parent syntax unchanged: `<#header>content</#header>`
- Parent syntax: `<Slot:header>content</Slot:header>`
## JQHTML Slot-Based Template Inheritance (v2.2.108+)

View File

@@ -53,9 +53,9 @@ class JqhtmlBladeCompiler
// If there's slot content, we need to output the div directly to allow blade processing of the content
if ($slot_content !== null && trim($slot_content) !== '') {
// Check for slot syntax - not allowed in Blade
if (preg_match('/<#[a-zA-Z0-9_]+/', $slot_content)) {
if (preg_match('/<Slot:[a-zA-Z0-9_]+/', $slot_content)) {
throw new \RuntimeException(
"JQHTML slot syntax (<#slotname>) is not allowed in Blade files.\n" .
"JQHTML slot syntax (<Slot:slotname>) is not allowed in Blade files.\n" .
"Component '{$component_name}' contains slot tags in its innerHTML.\n" .
"Use standard innerHTML with content() function instead.\n\n" .
"Blade usage:\n" .

View File

@@ -218,8 +218,8 @@ class Jqhtml_ManifestModule extends ManifestModule_Abstract
{
$slots = [];
// Match <#slotname> syntax
preg_match_all('/<#(\w+)>/', $content, $matches);
// Match <Slot:slotname> syntax
preg_match_all('/<Slot:(\w+)>/', $content, $matches);
foreach ($matches[1] as $slot) {
if ($slot && !in_array($slot, $slots)) {

View File

@@ -265,23 +265,23 @@ DATAGRID
$per_page=15
class="card DataGrid">
<#DG_Card_Header>
<Slot:DG_Card_Header>
<Card_Title>Client List</Card_Title>
<Card_Header_Right>
<Search_Input $sid="filter_input" $placeholder="Search..." />
</Card_Header_Right>
</#DG_Card_Header>
</Slot:DG_Card_Header>
<#DG_Table_Header>
<Slot:DG_Table_Header>
<tr>
<th data-sortby="id">ID</th>
<th data-sortby="name">Name</th>
<th data-sortby="created_at">Created</th>
<th>Actions</th>
</tr>
</#DG_Table_Header>
</Slot:DG_Table_Header>
<#row>
<Slot:row>
<tr data-href="<%= Rsx.Route('Clients_View_Action', row.id) %>">
<td><%= row.id %></td>
<td><%= row.name %></td>
@@ -297,7 +297,7 @@ DATAGRID
</div>
</td>
</tr>
</#row>
</Slot:row>
</Define:Clients_DataGrid>

View File

@@ -1316,25 +1316,25 @@ CONTENT AND SLOTS
</div>
</Define:Card_Layout>
Parent templates provide content using <#slotname> tags:
Parent templates provide content using <Slot:slotname> tags:
<!-- Use with named slots -->
<Card_Layout>
<#header><h3>User Profile</h3></#header>
<#body>
<Slot:header><h3>User Profile</h3></Slot:header>
<Slot:body>
<p>Name: <%= this.data.name %></p>
<p>Email: <%= this.data.email %></p>
</#body>
<#footer>
</Slot:body>
<Slot:footer>
<button class="btn">Save</button>
</#footer>
</Slot:footer>
</Card_Layout>
Critical rules:
- Cannot mix regular content with named slots
- If ANY named slots present, ALL content must be in slots
- Child template syntax: <%= content('slotname') %>
- Parent template syntax: <#slotname>content</#slotname>
- Parent template syntax: <Slot:slotname>content</Slot:slotname>
Decision Guide:
Use content() when:
@@ -1378,17 +1378,17 @@ CONTENT AND SLOTS
Child template - slot-only (Users_DataGrid.jqhtml):
<Define:Users_DataGrid>
<#header>
<Slot:header>
<th>ID</th>
<th>Name</th>
<th>Email</th>
</#header>
</Slot:header>
<#row>
<Slot:row>
<td><%= row.id %></td>
<td><%= row.name %></td>
<td><%= row.email %></td>
</#row>
</Slot:row>
</Define:Users_DataGrid>
Result: Users_DataGrid renders using DataGrid_Abstract HTML
@@ -1399,9 +1399,9 @@ CONTENT AND SLOTS
<%= content('slotname', data) %>
Child templates receive data via slot parameter:
<#row>
<Slot:row>
<td><%= row.id %></td>
</#row>
</Slot:row>
The slot parameter name matches the slot name automatically.
@@ -1409,9 +1409,9 @@ CONTENT AND SLOTS
Slot names cannot be JavaScript reserved words.
Parser rejects with fatal error:
<#function>Content</#function> <!-- ERROR: reserved word -->
<#if>Content</#if> <!-- ERROR: reserved word -->
<#header>Content</#header> <!-- Valid -->
<Slot:function>Content</Slot:function> <!-- ERROR: reserved word -->
<Slot:if>Content</Slot:if> <!-- ERROR: reserved word -->
<Slot:header>Content</Slot:header> <!-- Valid -->
Reserved words include: function, if, for, class, const, let,
var, while, switch, return, try, catch, and others.

View File

@@ -251,18 +251,18 @@ EXAMPLES
<Define:DataGrid class="datagrid">
<table>
<thead>
<#header>
<Slot:header>
<% for (let col of this.data.columns) { %>
<th><%= col.title %></th>
<% } %>
</#header>
</Slot:header>
</thead>
<tbody>
<% if (this.data.records.length === 0) { %>
<tr><td colspan="100"><#empty>No records</#empty></td></tr>
<tr><td colspan="100"><Slot:empty>No records</Slot:empty></td></tr>
<% } else { %>
<% for (let [idx, record] of this.data.records.entries()) { %>
<tr><#row /></tr>
<tr><Slot:row /></tr>
<% } %>
<% } %>
</tbody>

View File

@@ -28,9 +28,9 @@ Slot tags for components with multiple content areas:
```blade
{{-- Slot tags are highlighted specially --}}
<DataGrid>
<#header>Name | Email | Status</#header>
<#row><%= row.name %> | <%= row.email %></#row>
<#empty>No data found</#empty>
<Slot:header>Name | Email | Status</Slot:header>
<Slot:row><%= row.name %> | <%= row.email %></Slot:row>
<Slot:empty>No data found</Slot:empty>
</DataGrid>
```
@@ -65,7 +65,7 @@ The extension injects TextMate grammar rules into PHP and Blade files to:
1. **Identify Component Tags**: Patterns match tags starting with uppercase letters
2. **Highlight Component Names**: Apply distinctive coloring to component names
3. **Preserve Blade Syntax**: Handle Blade expressions within component attributes
4. **Support Slots**: Recognize and highlight `<#slotname>` syntax
4. **Support Slots**: Recognize and highlight `<Slot:slotname>` syntax
## Supported Patterns
@@ -138,7 +138,7 @@ The grammar is injected into:
### Pattern Matching
- Component opening tags: `(<)([A-Z][\\w_]*)(?=\\s|>)`
- Component closing tags: `(</)([A-Z][\\w_]*)(>)`
- Slot tags: `(<#)(\\w+)(>)` and `(</#)(\\w+)(>)`
- Slot tags: `(<Slot:)(\\w+)(>)` and `(</Slot:)(\\w+)(>)`
## Troubleshooting