{{- /* Renders an interactive file tree structure from inline content, resources, data files, or filesystem See https://fixit.lruihao.cn/documentation/content-management/shortcodes/extended/file-tree/ @param {string} [path="/"] - The path to scan in filesystem (relative to project root or contentDir) @param {int} [level=1] - The expand level of the tree (expand all: -1, collapse all: 0) @param {boolean} [folderSlash=false] - Whether to append a trailing "/" to folder names. @param {string} [file] - The path of a data file in page resources or assets. (JSON/YAML/TOML) @param {string} [data] - The name of the data file in data/filetree/ directory. (JSON/YAML/TOML) @param {string} [ignoreList=""] - List of file or folder names to ignore, separated by commas @param {string} [highlightList=""] - List of file or folder names to highlight, separated by commas @param {string} [name] - Project name for the root node, if set to `{path}`, uses the full root path Priority order (highest to lowest): 1. Inline content (shortcode body) - Parse tree data from shortcode body 2. Resources files (file parameter) - Read data file from page bundle or asset 3. Data files (data parameter) - Load data file from data/filetree/ directory 4. Actual Filesystem (path parameter) - Scan actual directory structure (default) Fallback mechanism: If the current mode fails (e.g., file not found, invalid format), the shortcode will automatically fall back to the next available mode in the priority order. @example {{< file-tree "content" 2 />}} {{< file-tree path="content" level=2 folderSlash=true />}} {{< file-tree file="data/example.yml" />}} {{< file-tree data="example" />}} {{< file-tree >}} - name: my-project type: dir children: - name: src type: dir - name: package.json type: file {{< /file-tree >}} Data format note: YAML and JSON support direct array format, while TOML requires a root key 'filetree' due to format limitations. Example TOML structure: ```file-tree [[filetree]] name = "src" type = "dir" [[filetree.children]] name = "index.ts" type = "file" [[filetree]] name = "README.md" type = "file" ``` */ -}} {{- $config := dict | merge .Page.Params.filetree | merge .Site.Params.filetree -}} {{- $root := cond .IsNamedParams (.Get "path") (.Get 0) | default "/" -}} {{- $level := cond .IsNamedParams (.Get "level") (.Get 1) -}} {{- $config = cond ((eq $level 0) | or $level) (dict "level" $level | merge $config) $config -}} {{- $level = cond (isset $config "level") ($config.level | int) 1 -}} {{- $folderSlash := cond .IsNamedParams (.Get "folderSlash") (.Get 2) | default $config.folderslash | default false -}} {{- $fileName := .Get "file" -}} {{- $dataName := .Get "data" -}} {{- $supportExts := slice ".yml" ".yaml" ".json" ".toml" -}} {{- $ignoreList := union (apply (split (.Get "ignoreList" | default "") ",") "trim" "." " ") $config.ignorelist -}} {{- $highlightList := apply (split (.Get "highlightList" | default "") ",") "trim" "." " " -}} {{- /* Shortcode body */ -}} {{- $content := strings.TrimSpace .Inner | default "" -}} {{- /* File Data */ -}} {{- if $fileName | and (eq $content "") -}} {{- $ext := path.Ext $fileName | lower -}} {{- if in $supportExts $ext -}} {{- with dict "Path" $fileName "Resources" $.Page.Resources | partial "function/resource.html" }} {{- $content = .Content -}} {{- else -}} {{- warnidf "warning-file-tree" "[%s]: no such data file: %s. See %s" $.Name $fileName $.Position -}} {{- end -}} {{- else -}} {{- warnidf "warning-file-tree" "[%s]: Unsupported file format '%s'. Use %s. See %s" $.Name $ext (delimit $supportExts ", " " or ") $.Position -}} {{- end -}} {{- end -}} {{- /* Parse structured data from content or file */ -}} {{- $treeData := slice -}} {{- with $content -}} {{- $treeData = . | unmarshal -}} {{- if reflect.IsMap $treeData -}} {{- $treeData = $treeData.filetree -}} {{- end -}} {{- end -}} {{- /* Hugo Data: load from data/filetree/ */ -}} {{- if $dataName | and (not $treeData) -}} {{- with index hugo.Data.filetree (printf "%v.%v" $dataName .Page.Language) | default (index hugo.Data.filetree $dataName) -}} {{- $treeData = . -}} {{- else -}} {{- $exts := delimit (apply $supportExts "trim" "." "\\.") "|" -}} {{- warnidf "warning-file-tree" "[%s]: Data file 'data/filetree/%s.{%s}' not found. See %s" $.Name $dataName $exts $.Position -}} {{- end -}} {{- end -}} {{- /* Filesystem mode: build structured tree data from filesystem */ -}} {{- if not $treeData -}} {{- $buildOptions := dict "root" $root "ignoreList" $ignoreList "name" (.Get "name") "lang" .Page.Language -}} {{- with partial "function/get-file-tree.html" $buildOptions -}} {{- $treeData = . -}} {{- else -}} {{- warnidf "warning-file-tree" "[%s]: The root path does not exist: %s. See %s" .Name $root .Position -}} {{- end -}} {{- end -}} {{- /* Render the file tree */ -}} {{- $options := dict "items" $treeData "level" $level "folderSlash" $folderSlash "ignoreList" $ignoreList "highlightList" $highlightList -}} {{- partial "plugin/file-tree.html" $options -}}