Skip to content

Commit 11c6528

Browse files
committed
wip: sidebar order and nesting
1 parent 404a0a1 commit 11c6528

File tree

7 files changed

+173
-96
lines changed

7 files changed

+173
-96
lines changed

Diff for: README.md

+12
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,15 @@
33
# VuePress
44

55
> Minimalistic docs generator with Vue component based layout system
6+
7+
## Why
8+
9+
- **Writing First**: minimal setup, all you need is a markdown file.
10+
11+
- **Vue-powered**: Use custom Vue components inside markdown, and develop custom themes using Vue single file components.
12+
13+
- **Great Dev Experience**: enjoy the same enjoyable development experience of a Vue app. Leverage the full power of webpack (hot-reload, pre-processors), generate SEO-friendly static HTML, and works as an SPA after initial page load.
14+
15+
- **Optimized for Docs**: many [built-in markdown extensions](./markdown.md) and default theme features for writing great documentation.
16+
17+
- **GitHub Friendly**: source markdown files can link to each other using relative links that ends in `.md` so they are also readable on GitHub, auto-generates page edit links if a repo is provided.

Diff for: docs/.vuepress/config.js

+28-3
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,40 @@ module.exports = {
99
['link', { rel: 'icon', href: `${base}logo.png` }]
1010
],
1111
themeConfig: {
12+
// sidebar config
1213
sidebar: [
13-
'/',
14+
'/getting-started',
1415
'/markdown',
1516
'/assets',
1617
'/using-vue',
1718
'/config',
1819
'/default-theme',
1920
'/theming',
20-
'/deploy'
21-
]
21+
'/deploy',
22+
// nesting
23+
['Nesting', [
24+
'/markdown',
25+
'/assets'
26+
]]
27+
],
28+
29+
// multi-category sidebar config
30+
31+
// sidebar: {
32+
// '*': [/* ... */],
33+
// '/guide/': [/* ... */],
34+
// '/tutorial/': [/* ... */],
35+
// '/api/': [/* ... */]
36+
// },
37+
38+
// navbar config
39+
40+
// nav: [
41+
// {
42+
// title: 'Guide',
43+
// link: '/getting-started',
44+
// },
45+
// // ...
46+
// ]
2247
}
2348
}

Diff for: docs/README.md

-60
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
---
2-
navTitle: Getting Started
3-
---
4-
51
# VuePress
62

73
> Minimalistic docs generator with Vue component based layout system
@@ -17,59 +13,3 @@ navTitle: Getting Started
1713
- **Optimized for Docs**: many [built-in markdown extensions](./markdown.md) and default theme features for writing great documentation.
1814

1915
- **GitHub Friendly**: source markdown files can link to each other using relative links that ends in `.md` so they are also readable on GitHub, auto-generates page edit links if a repo is provided.
20-
21-
## Quickstart
22-
23-
``` bash
24-
# install globally
25-
npm install -g vuepress
26-
27-
# create a markdown file
28-
echo "# Hello VuePress!" > index.md
29-
30-
# start writing
31-
vuepress dev .
32-
33-
# build
34-
vuepress build .
35-
```
36-
37-
## Inside an Existing Project
38-
39-
``` bash
40-
# install as a dependency
41-
npm install -D vuepress
42-
43-
# create a docs directory
44-
mkdir docs
45-
# create a markdown file
46-
echo "# Hello VuePress!" > docs/index.md
47-
48-
# start writing
49-
npx vuepress dev docs
50-
```
51-
52-
Or, add some scripts to `package.json`:
53-
54-
``` json
55-
{
56-
"scripts": {
57-
"docs:dev": "vuepress dev docs",
58-
"docs:build": "vuepress build docs"
59-
}
60-
}
61-
```
62-
63-
Then you can start writing with:
64-
65-
``` bash
66-
npm run docs:dev
67-
```
68-
69-
To generate static assets, run:
70-
71-
``` bash
72-
npm run docs:build
73-
```
74-
75-
By default the built files will be in `.vuepress/dist`. The files can be deployed to any static file server. See [Deployment Guide](./deploy.md) for guides on deploying to popular services.

Diff for: docs/getting-started.md

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# Getting Started
2+
3+
## Quickstart
4+
5+
``` bash
6+
# install globally
7+
npm install -g vuepress
8+
9+
# create a markdown file
10+
echo "# Hello VuePress!" > index.md
11+
12+
# start writing
13+
vuepress dev .
14+
15+
# build
16+
vuepress build .
17+
```
18+
19+
## Inside an Existing Project
20+
21+
``` bash
22+
# install as a dependency
23+
npm install -D vuepress
24+
25+
# create a docs directory
26+
mkdir docs
27+
# create a markdown file
28+
echo "# Hello VuePress!" > docs/index.md
29+
30+
# start writing
31+
npx vuepress dev docs
32+
```
33+
34+
Or, add some scripts to `package.json`:
35+
36+
``` json
37+
{
38+
"scripts": {
39+
"docs:dev": "vuepress dev docs",
40+
"docs:build": "vuepress build docs"
41+
}
42+
}
43+
```
44+
45+
Then you can start writing with:
46+
47+
``` bash
48+
npm run docs:dev
49+
```
50+
51+
To generate static assets, run:
52+
53+
``` bash
54+
npm run docs:build
55+
```
56+
57+
By default the built files will be in `.vuepress/dist`. The files can be deployed to any static file server. See [Deployment Guide](./deploy.md) for guides on deploying to popular services.

Diff for: lib/default-theme/Layout.vue

+19-29
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,20 @@
22
<div class="theme-container">
33
<div class="sidebar">
44
<ul>
5-
<li v-for="page in sortedPages">
6-
<router-link :to="page.path">
7-
{{ page.frontmatter.navTitle || page.title || page.path }}
5+
<li v-for="item in sidebarItems">
6+
<router-link v-if="item.type === 'page'" :to="item.path">
7+
{{ item.title || item.path }}
88
</router-link>
9+
<div class="sidebar-group" v-else-if="item.type === 'heading'">
10+
<p class="sidebar-heading">{{ item.title }}</p>
11+
<ul>
12+
<li v-for="child in item.children">
13+
<router-link v-if="child.type === 'page'" :to="child.path">
14+
{{ child.title || child.path }}
15+
</router-link>
16+
</li>
17+
</ul>
18+
</div>
919
</li>
1020
</ul>
1121
</div>
@@ -18,36 +28,16 @@
1828
import nprogress from 'nprogress'
1929
import Index from './Index.vue'
2030
import Page from './Page.vue'
21-
22-
function normalize (path) {
23-
return path.replace(/\.(md|html)$/, '')
24-
}
25-
26-
function findIndex (order, page) {
27-
const pagePath = normalize(page.path)
28-
for (let i = 0; i < order.length; i++) {
29-
if (normalize(order[i]) === pagePath) {
30-
return i
31-
}
32-
}
33-
return Infinity
34-
}
31+
import resolveSidebar from './resolveSidebar'
3532
3633
export default {
3734
components: { Index, Page },
3835
computed: {
39-
sortedPages () {
40-
const pages = this.$site.pages
41-
const order = this.$site.themeConfig.sidebar
42-
if (!order) {
43-
return pages
44-
} else {
45-
return pages.slice().sort((a, b) => {
46-
const aIndex = findIndex(order, a)
47-
const bIndex = findIndex(order, b)
48-
return aIndex - bIndex
49-
})
50-
}
36+
sidebarItems () {
37+
return resolveSidebar(
38+
this.$route,
39+
this.$site
40+
)
5141
}
5242
},
5343
mounted () {

Diff for: lib/default-theme/resolveSidebar.js

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
export default function resolveSidebar (route, site) {
2+
const { pages, themeConfig } = site
3+
const sidebarConfig = themeConfig.sidebar
4+
if (!sidebarConfig) {
5+
return pages
6+
} else {
7+
const matchingConfig = Array.isArray(sidebarConfig)
8+
? sidebarConfig
9+
: resolveMatchingSidebar(route, sidebarConfig)
10+
return matchingConfig.map(item => resolveItem(item, site.pages))
11+
}
12+
}
13+
14+
function resolveMatchingSidebar (route, sidebarConfig) {
15+
for (const base in sidebarConfig) {
16+
if (ensureEndingSlash(route.path).indexOf(base) === 0) {
17+
return sidebarConfig[base]
18+
}
19+
}
20+
}
21+
22+
function ensureEndingSlash (path) {
23+
return /(\.html|\/)$/.test(path)
24+
? path
25+
: path + '/'
26+
}
27+
28+
function resolveItem (item, pages) {
29+
if (typeof item === 'string') {
30+
return Object.assign({ type: 'page' }, findPage(pages, item))
31+
} else if (Array.isArray(item)) {
32+
return {
33+
type: 'heading',
34+
title: item[0],
35+
children: (item[1] || []).map(child => resolveItem(child, pages))
36+
}
37+
} else {
38+
throw new Error(`Invalid sidebar item config: ${item}`)
39+
}
40+
}
41+
42+
function findPage (pages, path) {
43+
path = normalize(path)
44+
for (let i = 0; i < pages.length; i++) {
45+
if (normalize(pages[i].path) === path) {
46+
return pages[i]
47+
}
48+
}
49+
}
50+
51+
function normalize (path) {
52+
return path.replace(/\.(md|html)$/, '')
53+
}

Diff for: lib/default-theme/theme.stylus

+4-4
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,13 @@ body
3131
padding-left 1.25em
3232
&:hover
3333
color darken(#41b883, 5%)
34-
&.router-link-exact-active
34+
&.router-link-active
3535
font-weight 600
3636
color darken(#41b883, 5%)
3737
border-left-color darken(#41b883, 5%)
3838

3939
.markdown
40-
max-width 720px
40+
max-width 760px
4141
margin 2em auto
4242
padding 0 2em
4343

@@ -151,7 +151,7 @@ p
151151
border 1px solid #ddd
152152
border-radius 4px
153153

154-
@media (max-width: 879px)
154+
@media (max-width: 959px)
155155
body
156156
font-size 15px
157157
.sidebar
@@ -163,7 +163,7 @@ p
163163
margin 1.5em 0
164164
padding 0 1.5em
165165

166-
@media (max-width: 639px)
166+
@media (max-width: 719px)
167167
body
168168
font-size 15px
169169
.sidebar

0 commit comments

Comments
 (0)