Code Tree New
About 539 wordsAbout 2 min
2025-10-08
Overview
In Markdown, use the ::: code-tree
container or @[code-tree](dir_path)
syntax to display a code block area with a file tree.
Compared to code block grouping, code trees can more clearly present the organizational structure of code files and their dependency relationships.
Enable
This feature is disabled by default. You need to enable it in the theme
configuration.
export default defineUserConfig({
theme: plumeTheme({
markdown: {
codeTree: true,
}
})
})
Usage
The theme provides two usage methods:
code-tree Container
::: code-tree title="Project Name" height="400px" entry="filepath"
```lang title="filepath" :active
<!-- code content-->
```
```lang title="filepath"
<!-- code content-->
```
<!-- More code blocks -->
:::
Use the ::: code-tree
container to wrap multiple code blocks.
- Use
title="Project Name"
after::: code-tree
to declare the code tree title - Use
height="400px"
after::: code-tree
to declare the code tree height - Use
entry="filepath"
after::: code-tree
to declare the default expanded file path - Use
title="filepath"
after the code block``` lang
to declare the current code block's file path - If
entry="filepath"
is not declared in::: code-tree
, you can use:active
after the code block``` lang
to declare the current code block as expanded - If no expanded file path is specified, the first file will be expanded by default
Why use title="filepath"
instead of filepath="filepath"
on code blocks?
Because the theme already supports title syntax on code blocks. Continuing to use the existing syntax support reduces the learning curve.
Input:
::: code-tree title="Vue App" height="400px" entry="src/main.ts"
```vue title="src/components/HelloWorld.vue"
<template>
<div class="hello">
<h1>Hello World</h1>
</div>
</template>
```
```vue title="src/App.vue"
<template>
<div id="app">
<h3>vuepress-theme-plume</h3>
<HelloWorld />
</div>
</template>
```
```ts title="src/main.ts"
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')
```
```json title="package.json"
{
"name": "Vue App",
"scripts": {
"dev": "vite"
}
}
```
:::
Output:
src
components
HelloWorld.vue
App.vue
main.ts
package.json
<template>
<div class="hello">
<h1>Hello World</h1>
</div>
</template>
<template>
<div id="app">
<h3>vuepress-theme-plume</h3>
<HelloWorld />
</div>
</template>
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')
{
"name": "Vue App",
"scripts": {
"dev": "vite"
}
}
Importing code-tree from Directory
The theme supports importing code-tree
from a directory using the following syntax:
<!-- Simple import -->
@[code-tree](dir_path)
<!-- With additional configuration -->
@[code-tree title="Project Name" height="400px" entry="filepath"](dir_path)
dir_path: When an absolute path is provided (starting with
/
), the search begins from the source directory of the documentation site. When a relative path is provided (starting with.
), it is relative to the current Markdown file.title: Code tree title, optional, defaults to empty
height: Code tree height, optional, defaults to empty
entry: Default expanded file path, optional, defaults to the first file
Input:
<!-- This directory is the theme repository's `docs/.vuepress/collections/` -->
@[code-tree title="Collections Configuration" height="400px" entry="index.ts"](/.vuepress/collections)
Output:
en
index.ts
theme-config.ts
theme-guide.ts
tools.ts
zh
index.ts
theme-config.ts
theme-guide.ts
tools.ts
index.ts
import { defineCollections, type ThemeCollections } from 'vuepress-theme-plume'
import { themeConfig } from './theme-config.js'
import { themeGuide } from './theme-guide.js'
import { tools } from './tools.js'
export const enCollections: ThemeCollections = defineCollections([
themeGuide,
themeConfig,
tools,
])
import type { ThemeCollectionItem } from 'vuepress-theme-plume'
import { defineCollection } from 'vuepress-theme-plume'
export const themeConfig: ThemeCollectionItem = defineCollection({
type: 'doc',
title: 'Config',
dir: 'config',
linkPrefix: '/config/',
sidebar: [
{
text: 'Configuration',
collapsed: false,
items: [
'intro',
'theme',
'locales',
'navbar',
'sidebar',
'collections',
'markdown',
],
},
{
text: 'Page Configuration',
prefix: 'frontmatter',
collapsed: false,
items: [
'basic',
'home',
'post',
'friend',
],
},
{
text: 'Built-in Plugins',
prefix: 'plugins',
collapsed: false,
items: [
'',
'shiki',
'search',
'reading-time',
'markdown-enhance',
'markdown-power',
'markdown-image',
'markdown-math',
'markdown-include',
'watermark',
],
},
],
})
import type { ThemeCollectionItem } from 'vuepress-theme-plume'
import { defineCollection } from 'vuepress-theme-plume'
export const themeGuide: ThemeCollectionItem = defineCollection({
type: 'doc',
dir: 'guide',
title: 'Guide',
linkPrefix: '/guide/',
sidebar: [
{
text: 'Quick Start',
collapsed: false,
icon: 'carbon:idea',
prefix: 'quick-start',
items: [
'intro',
'usage',
'project-structure',
{
text: 'Collection',
link: 'collection',
items: ['collection-post', 'collection-doc'],
},
'sidebar',
'write',
'locales',
'deployment',
'optimize-build',
],
},
{
text: 'Write',
icon: 'fluent-mdl2:edit-create',
collapsed: false,
items: [
{
text: 'markdown',
icon: 'material-symbols:markdown-outline',
prefix: 'markdown',
collapsed: true,
items: [
'basic',
'extensions',
'icons',
'mark',
'plot',
'abbr',
'annotation',
'card',
'steps',
'file-tree',
'code-tree',
'field',
'tabs',
'timeline',
'demo-wrapper',
'flex',
'collapse',
'npm-to',
'caniuse',
'chat',
'include',
],
},
{
text: 'code block',
prefix: 'code',
icon: 'ph:code-bold',
collapsed: true,
items: [
'intro',
'features',
'copy-code',
'code-tabs',
'import',
'twoslash',
],
},
{
text: 'code repl',
prefix: 'repl',
icon: 'carbon:demo',
collapsed: true,
items: [
'frontend',
'rust',
'golang',
'kotlin',
'python',
'codepen',
'jsFiddle',
'codeSandbox',
'replit',
],
},
{
text: 'charts',
icon: 'mdi:chart-line',
prefix: 'chart',
collapsed: true,
items: [
'chart',
'echarts',
'mermaid',
'flowchart',
'markmap',
'plantuml',
],
},
{
text: 'resource embedded',
icon: 'dashicons:embed-video',
prefix: 'embed',
collapsed: true,
items: [
'pdf',
'bilibili',
'acfun',
'youtube',
'artplayer',
'audioReader',
],
},
],
},
{
text: 'Features',
icon: 'lucide:box',
collapsed: false,
prefix: 'features',
items: [
'icon',
'search',
'image-preview',
'comments',
'bulletin',
'encryption',
'contributors',
'changelog',
'copyright',
'watermark',
'friend-links',
'replace-assets',
'seo',
'sitemap',
],
},
{
text: 'Component',
prefix: 'components',
icon: 'uiw:component',
collapsed: false,
items: [
'badge',
'icon',
'plot',
'card',
'link-card',
'image-card',
'card-grid',
'card-masonry',
'home-box',
'repo-card',
'npm-badge',
'swiper',
],
},
{
text: 'Customization',
icon: 'material-symbols:dashboard-customize-outline-rounded',
collapsed: false,
prefix: 'custom',
items: [
'home',
'style',
'slots',
'component-overrides',
],
},
{
text: 'API',
icon: 'mdi:api',
prefix: 'api',
collapsed: false,
items: [
'client',
'node',
],
},
],
})
import type { ThemeCollectionItem } from 'vuepress-theme-plume'
import { defineCollection } from 'vuepress-theme-plume'
export const tools: ThemeCollectionItem = defineCollection({
type: 'doc',
dir: 'tools',
title: 'Theme Tools',
linkPrefix: '/tools/',
sidebar: [
{
text: 'Tools',
icon: 'tabler:tools',
items: [
'custom-theme',
'home-hero-tint-plate',
'caniuse',
],
},
],
})
import { defineCollections, type ThemeCollections } from 'vuepress-theme-plume'
import { themeConfig } from './theme-config.js'
import { themeGuide } from './theme-guide.js'
import { tools } from './tools.js'
export const zhCollections: ThemeCollections = defineCollections([
themeGuide,
themeConfig,
tools,
])
import type { ThemeCollectionItem } from 'vuepress-theme-plume'
import { defineCollection } from 'vuepress-theme-plume'
export const themeConfig: ThemeCollectionItem = defineCollection({
type: 'doc',
title: '配置',
dir: 'config',
linkPrefix: '/config/',
sidebar: [
{
text: '配置',
collapsed: false,
items: [
'intro',
'theme',
'locales',
'navbar',
'sidebar',
'collections',
'markdown',
],
},
{
text: '页面配置',
prefix: 'frontmatter',
collapsed: false,
items: [
'basic',
'home',
'post',
'friend',
],
},
{
text: '内置插件',
prefix: 'plugins',
collapsed: false,
items: [
'',
'shiki',
'search',
'reading-time',
'markdown-enhance',
'markdown-power',
'markdown-image',
'markdown-math',
'markdown-include',
'watermark',
],
},
],
})
import type { ThemeCollectionItem } from 'vuepress-theme-plume'
import { defineCollection } from 'vuepress-theme-plume'
export const themeGuide: ThemeCollectionItem = defineCollection({
type: 'doc',
dir: 'guide',
title: '指南',
linkPrefix: '/guide/',
sidebar: [
{
text: '从这里开始',
collapsed: false,
icon: 'carbon:idea',
prefix: 'quick-start',
items: [
'intro',
'usage',
'project-structure',
{
text: '集合',
link: 'collection',
items: ['collection-post', 'collection-doc'],
},
'sidebar',
'write',
'locales',
'deployment',
'optimize-build',
],
},
{
text: '写作',
icon: 'fluent-mdl2:edit-create',
collapsed: false,
items: [
{
text: 'markdown',
icon: 'material-symbols:markdown-outline',
prefix: 'markdown',
collapsed: true,
items: [
'basic',
'extensions',
'table',
'icons',
'mark',
'plot',
'abbr',
'annotation',
'card',
'steps',
'file-tree',
'code-tree',
'field',
'tabs',
'timeline',
'demo-wrapper',
'flex',
'collapse',
'npm-to',
'caniuse',
'chat',
'include',
],
},
{
text: '代码块',
prefix: 'code',
icon: 'ph:code-bold',
collapsed: true,
items: [
'intro',
'features',
'copy-code',
'code-tabs',
'import',
'twoslash',
],
},
{
text: '代码演示',
prefix: 'repl',
icon: 'carbon:demo',
collapsed: true,
items: [
'frontend',
'rust',
'golang',
'kotlin',
'python',
'codepen',
'jsFiddle',
'codeSandbox',
'replit',
],
},
{
text: '图表',
icon: 'mdi:chart-line',
prefix: 'chart',
collapsed: true,
items: [
'chart',
'echarts',
'mermaid',
'flowchart',
'markmap',
'plantuml',
],
},
{
text: '资源嵌入',
icon: 'dashicons:embed-video',
prefix: 'embed',
collapsed: true,
items: [
'pdf',
'bilibili',
'acfun',
'youtube',
'artplayer',
'audioReader',
],
},
],
},
{
text: '功能',
icon: 'lucide:box',
collapsed: false,
prefix: 'features',
items: [
'icon',
'search',
'image-preview',
'comments',
'bulletin',
'encryption',
'contributors',
'changelog',
'copyright',
'watermark',
'friend-links',
'replace-assets',
'seo',
'sitemap',
],
},
{
text: '组件',
prefix: 'components',
icon: 'uiw:component',
collapsed: false,
items: [
'badge',
'icon',
'plot',
'card',
'link-card',
'image-card',
'card-grid',
'card-masonry',
'home-box',
'repo-card',
'npm-badge',
'swiper',
],
},
{
text: '自定义',
icon: 'material-symbols:dashboard-customize-outline-rounded',
collapsed: false,
prefix: 'custom',
items: [
'home',
'style',
'slots',
'component-overrides',
],
},
{
text: 'API',
icon: 'mdi:api',
prefix: 'api',
collapsed: false,
items: [
'client',
'node',
],
},
],
})
import type { ThemeCollectionItem } from 'vuepress-theme-plume'
import { defineCollection } from 'vuepress-theme-plume'
export const tools: ThemeCollectionItem = defineCollection({
type: 'doc',
dir: 'tools',
title: '工具',
linkPrefix: '/tools/',
sidebar: [
{
text: '工具',
icon: 'tabler:tools',
items: [
'custom-theme',
'home-hero-tint-plate',
'caniuse',
],
},
],
})
export * from './en/index.js'
export * from './zh/index.js'