Convert the bundled backend/internal/plugins/smartblock package into a standalone reactor-mode wasm plugin: - package smartblock -> package main; add wasip1 main.go with wasmguest.Serve(Registration). - Add go.mod (module git.dev.alexdunmow.com/block/smartblock) pinning block/core v0.18.2; no replace directives. - Flesh out plugin.mod (scope=ninja, kind=plugin, categories, tags, display_name, description). - Point web/eslint.config.js at ../../../cms/web/eslint.config.js and switch @block-ninja/ui from workspace:* to the ^0.1.0 registry version; rebuild web/dist. - Add .gitignore (*.bnp, *.wasm, web/node_modules). Behavior unchanged: registers the "smart" block; assets served from web/dist. Builds to smartblock-1.0.0.bnp; check-safety passes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
81 lines
1.7 KiB
Go
81 lines
1.7 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"html"
|
|
"strings"
|
|
)
|
|
|
|
// SmartBlockFunc renders a Smart Block by substituting {{field}} placeholders with content values.
|
|
func SmartBlockFunc(ctx context.Context, content map[string]any) string {
|
|
// Get metadata
|
|
meta, ok := content["_meta"].(map[string]any)
|
|
if !ok {
|
|
return renderEmptyState()
|
|
}
|
|
|
|
generations, ok := meta["generations"].([]any)
|
|
if !ok || len(generations) == 0 {
|
|
return renderEmptyState()
|
|
}
|
|
|
|
currentID, _ := meta["currentGenerationId"].(string)
|
|
if currentID == "" {
|
|
return renderEmptyState()
|
|
}
|
|
|
|
// Find the current generation
|
|
var template string
|
|
for _, gen := range generations {
|
|
genMap, ok := gen.(map[string]any)
|
|
if !ok {
|
|
continue
|
|
}
|
|
if genMap["id"] == currentID {
|
|
template, _ = genMap["template"].(string)
|
|
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>`
|
|
}
|