diff --git a/.mxcli/widgets/gallery.def.json b/.mxcli/widgets/gallery.def.json index 2510aa9..d300c58 100644 --- a/.mxcli/widgets/gallery.def.json +++ b/.mxcli/widgets/gallery.def.json @@ -17,7 +17,8 @@ { "propertyKey": "itemSelection", "source": "Selection", - "operation": "selection" + "operation": "selection", + "default": "Single" }, { "propertyKey": "itemSelectionMode", @@ -78,7 +79,7 @@ }, { "propertyKey": "filtersPlaceholder", - "mdlContainer": "FILTERSPLACEHOLDER", + "mdlContainer": "FILTER", "operation": "widgets" } ] diff --git a/cmd/mxcli/cmd_widget.go b/cmd/mxcli/cmd_widget.go index a6f4fe1..4ec508a 100644 --- a/cmd/mxcli/cmd_widget.go +++ b/cmd/mxcli/cmd_widget.go @@ -5,6 +5,7 @@ package main import ( "encoding/json" "fmt" + "log" "os" "path/filepath" "strings" @@ -195,7 +196,9 @@ func runWidgetList(cmd *cobra.Command, args []string) error { // Load user definitions if project path available projectPath, _ := cmd.Flags().GetString("project") if projectPath != "" { - _ = registry.LoadUserDefinitions(projectPath) + if err := registry.LoadUserDefinitions(projectPath); err != nil { + log.Printf("warning: loading user widget definitions: %v", err) + } } defs := registry.All() diff --git a/cmd/mxcli/lsp_completion.go b/cmd/mxcli/lsp_completion.go index 95d1e09..7fa3a5f 100644 --- a/cmd/mxcli/lsp_completion.go +++ b/cmd/mxcli/lsp_completion.go @@ -4,6 +4,7 @@ package main import ( "context" + "log" "strings" "github.com/mendixlabs/mxcli/mdl/executor" @@ -89,8 +90,7 @@ func (s *mdlServer) widgetRegistryCompletions() []protocol.CompletionItem { return } if err := registry.LoadUserDefinitions(s.mprPath); err != nil { - // Non-fatal: user definitions are optional - _ = err + log.Printf("warning: loading user widget definitions for LSP: %v", err) } for _, def := range registry.All() { s.widgetCompletionItems = append(s.widgetCompletionItems, protocol.CompletionItem{ diff --git a/docs-site/book.toml b/docs-site/book.toml index 4aa87a6..6beb6a2 100644 --- a/docs-site/book.toml +++ b/docs-site/book.toml @@ -15,6 +15,7 @@ git-repository-url = "https://github.com/mendixlabs/mxcli" edit-url-template = "https://github.com/mendixlabs/mxcli/edit/main/docs-site/src/{path}" site-url = "/mxcli/" additional-css = ["theme/custom.css"] +additional-js = ["theme/mermaid-init.js"] [output.html.search] enable = true diff --git a/docs-site/theme/mermaid-init.js b/docs-site/theme/mermaid-init.js new file mode 100644 index 0000000..a38cec4 --- /dev/null +++ b/docs-site/theme/mermaid-init.js @@ -0,0 +1,24 @@ +// Render mermaid diagrams in mdbook. +// mdbook renders ```mermaid blocks as inside
.
+// This script loads mermaid from CDN and converts them to rendered SVG diagrams.
+(function () {
+  var blocks = document.querySelectorAll('code.language-mermaid');
+  if (blocks.length === 0) return;
+
+  var script = document.createElement('script');
+  script.src = 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js';
+  script.onload = function () {
+    mermaid.initialize({ startOnLoad: false, theme: 'default' });
+
+    blocks.forEach(function (code, i) {
+      var pre = code.parentElement;
+      var container = document.createElement('div');
+      container.className = 'mermaid';
+      container.textContent = code.textContent;
+      pre.parentElement.replaceChild(container, pre);
+    });
+
+    mermaid.run();
+  };
+  document.head.appendChild(script);
+})();
diff --git a/docs/plans/2026-03-25-pluggable-widget-engine-design.md b/docs/plans/2026-03-25-pluggable-widget-engine-design.md
index 4b4a712..9a10ade 100644
--- a/docs/plans/2026-03-25-pluggable-widget-engine-design.md
+++ b/docs/plans/2026-03-25-pluggable-widget-engine-design.md
@@ -1,23 +1,23 @@
-# Pluggable Widget Engine: 声明式 Widget 构建系统
+# Pluggable Widget Engine: Declarative Widget Build System
 
 **Date**: 2026-03-25
 **Status**: Implemented
 
 ## Problem
 
-当前每个 pluggable widget 都需要硬编码一个 Go builder 函数(`buildComboBoxV3`, `buildGalleryV3` 等),加上 switch case 注册。新增一个 widget 需要改 4 个地方:
+Each pluggable widget currently requires a hardcoded Go builder function (`buildComboBoxV3`, `buildGalleryV3`, etc.) plus a switch-case registration. Adding a new widget requires changes in 4 places:
 
-1. `sdk/pages/pages_widgets_advanced.go` — 添加 WidgetID 常量
-2. `sdk/widgets/templates/` — 添加 JSON 模板
-3. `mdl/executor/cmd_pages_builder_v3_pluggable.go` — 写专属 build 函数(50-200 行)
-4. `mdl/executor/cmd_pages_builder_v3.go` — 在 `buildWidgetV3()` switch 中添加 case
+1. `sdk/pages/pages_widgets_advanced.go` — Add WidgetID constant
+2. `sdk/widgets/templates/` — Add JSON template
+3. `mdl/executor/cmd_pages_builder_v3_pluggable.go` — Write a dedicated build function (50-200 lines)
+4. `mdl/executor/cmd_pages_builder_v3.go` — Add case in `buildWidgetV3()` switch
 
-这导致:
-- 用户无法自行添加 pluggable widget 支持
-- 大量重复代码(30+ builder 函数共享 ~80% 骨架)
-- 维护成本随 widget 数量线性增长
+This causes:
+- Users cannot add pluggable widget support on their own
+- Significant code duplication (30+ builder functions sharing ~80% boilerplate)
+- Maintenance cost grows linearly with widget count
 
-## Solution: 声明式 Widget 定义 + 通用构建引擎
+## Solution: Declarative Widget Definitions + Generic Build Engine
 
 ### Architecture
 
@@ -126,7 +126,7 @@ Gallery (with child slots):
   "childSlots": [
     {"propertyKey": "content", "mdlContainer": "TEMPLATE", "operation": "widgets"},
     {"propertyKey": "emptyPlaceholder", "mdlContainer": "EMPTYPLACEHOLDER", "operation": "widgets"},
-    {"propertyKey": "filtersPlaceholder", "mdlContainer": "FILTERSPLACEHOLDER", "operation": "widgets"}
+    {"propertyKey": "filtersPlaceholder", "mdlContainer": "FILTER", "operation": "widgets"}
   ]
 }
 ```