diff --git a/layouts/_default/_markup/render-codeblock-checklist.html b/layouts/_default/_markup/render-codeblock-checklist.html index cd0f490ba..324b7fdbe 100644 --- a/layouts/_default/_markup/render-codeblock-checklist.html +++ b/layouts/_default/_markup/render-codeblock-checklist.html @@ -1,4 +1,53 @@ {{- $id := .Attributes.id | default "checklist" -}} -
{{ .Inner | htmlEscape | safeHTML }}
-{{ .Page.Store.Set "hasChecklist" true }}
+{{- $title := .Attributes.title | default "" -}}
+{{- $description := .Attributes.description | default "" -}}
+{{- $noInteractive := or (eq .Attributes.noInteractive "true") (eq .Attributes.nointeractive "true") -}}
+
+{{- /* Parse checklist items from markdown */ -}}
+{{- $items := slice -}}
+{{- $position := 0 -}}
+{{- range split .Inner "\n" -}}
+ {{- $line := trim . " " -}}
+ {{- if and (ne $line "") (hasPrefix $line "- [") -}}
+ {{- $position = add $position 1 -}}
+ {{- /* Extract link and text */ -}}
+ {{- $linkPattern := `\[([^\]]+)\]\(([^\)]+)\)` -}}
+ {{- $matches := findRE $linkPattern $line -}}
+ {{- if $matches -}}
+ {{- $fullMatch := index $matches 0 -}}
+ {{- $textMatch := findRE `\[([^\]]+)\]` $fullMatch -}}
+ {{- $urlMatch := findRE `\(([^\)]+)\)` $fullMatch -}}
+ {{- $text := trim (index $textMatch 0) "[]" -}}
+ {{- $url := trim (index $urlMatch 0) "()" -}}
+ {{- $item := dict "position" $position "name" $text "url" $url -}}
+ {{- $items = $items | append $item -}}
+ {{- else -}}
+ {{- /* Item without link */ -}}
+ {{- $text := replaceRE `^- \[[\sx]\]\s*` "" $line -}}
+ {{- $item := dict "position" $position "name" $text -}}
+ {{- $items = $items | append $item -}}
+ {{- end -}}
+ {{- end -}}
+{{- end -}}
+
+{{- /* Build metadata object */ -}}
+{{- $metadata := dict "type" "checklist" "id" $id "items" $items -}}
+{{- if ne $title "" -}}
+ {{- $metadata = merge $metadata (dict "title" $title) -}}
+{{- end -}}
+{{- if ne $description "" -}}
+ {{- $metadata = merge $metadata (dict "description" $description) -}}
+{{- end -}}
+{{- $metadata = merge $metadata (dict "$schema" "https://redis.io/schemas/checklist.json") -}}
+
+{{ $jsonMetadata := $metadata | jsonify (dict "indent" " ") }}
+
+{{ printf "" $jsonMetadata | safeHTML }}
+
+{{ printf "\n%s\n" $jsonMetadata | safeHTML }}
+
+{{- if not $noInteractive -}}
+ {{ .Inner | htmlEscape | safeHTML }}
+ {{ .Page.Store.Set "hasChecklist" true }}
+{{- end -}}
diff --git a/static/schemas/checklist.json b/static/schemas/checklist.json
new file mode 100644
index 000000000..21bd7bd7b
--- /dev/null
+++ b/static/schemas/checklist.json
@@ -0,0 +1,69 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "$id": "https://redis.io/schemas/checklist.json",
+ "title": "Redis Checklist Metadata",
+ "description": "Schema for checklist metadata in Redis documentation",
+ "type": "object",
+ "required": ["type", "id", "items"],
+ "properties": {
+ "$schema": {
+ "type": "string",
+ "description": "Reference to this schema"
+ },
+ "type": {
+ "type": "string",
+ "enum": ["checklist"],
+ "description": "The metadata type"
+ },
+ "id": {
+ "type": "string",
+ "description": "Unique identifier for the checklist"
+ },
+ "title": {
+ "type": "string",
+ "description": "Human-readable title of the checklist"
+ },
+ "description": {
+ "type": "string",
+ "description": "Description of what the checklist covers"
+ },
+ "items": {
+ "type": "array",
+ "description": "Array of checklist items",
+ "items": {
+ "type": "object",
+ "required": ["position", "name"],
+ "properties": {
+ "position": {
+ "type": "integer",
+ "description": "Order in the checklist (1-based)"
+ },
+ "name": {
+ "type": "string",
+ "description": "Item text"
+ },
+ "url": {
+ "type": "string",
+ "description": "Link to the relevant section (can be relative or absolute)"
+ },
+ "optional": {
+ "type": "boolean",
+ "description": "Whether this step is optional"
+ },
+ "estimatedTime": {
+ "type": "string",
+ "description": "Estimated time to complete this step (e.g., '5 minutes', '1 hour')"
+ },
+ "prerequisites": {
+ "type": "array",
+ "description": "List of prerequisite item positions that must be completed first",
+ "items": {
+ "type": "integer"
+ }
+ }
+ }
+ }
+ }
+ }
+}
+