smartblock/block.go
Alex Dunmow 057677ab7f refactor: replace any with concrete types where shapes are known (check-safety 2e)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 02:44:26 +08:00

84 lines
1.9 KiB
Go

package main
import (
"context"
"encoding/json"
"fmt"
"html"
"strings"
)
type smartBlockGeneration struct {
ID string `json:"id"`
Template string `json:"template"`
}
type smartBlockMeta struct {
Generations []smartBlockGeneration `json:"generations"`
CurrentGenerationID string `json:"currentGenerationId"`
}
// SmartBlockFunc renders a Smart Block by substituting {{field}} placeholders with content values.
func SmartBlockFunc(ctx context.Context, content map[string]any) string {
rawMeta, err := json.Marshal(content["_meta"])
if err != nil {
return renderEmptyState()
}
var meta smartBlockMeta
if err := json.Unmarshal(rawMeta, &meta); err != nil {
return renderEmptyState()
}
if len(meta.Generations) == 0 || meta.CurrentGenerationID == "" {
return renderEmptyState()
}
var template string
for _, gen := range meta.Generations {
if gen.ID == meta.CurrentGenerationID {
template = gen.Template
break
}
}
if template == "" {
return renderEmptyState()
}
// Replace {{field}} placeholders with content values
result := template
for key, value := range content {
// Skip meta fields
if strings.HasPrefix(key, "_") {
continue
}
placeholder := "{{" + key + "}}"
var valueStr string
switch v := value.(type) {
case string:
valueStr = html.EscapeString(v)
case float64:
valueStr = fmt.Sprintf("%v", v)
case int:
valueStr = fmt.Sprintf("%d", v)
case bool:
valueStr = fmt.Sprintf("%t", v)
default:
valueStr = fmt.Sprintf("%v", v)
}
result = strings.ReplaceAll(result, placeholder, valueStr)
}
return result
}
func renderEmptyState() string {
return `<div class="smart-block-empty p-8 border-2 border-dashed border-gray-300 rounded-lg text-center text-gray-500">
<p class="text-lg font-medium">Smart Block</p>
<p class="text-sm">Use the editor to generate content with AI</p>
</div>`
}