提交 b50ff521 编写于 作者: E Evan You

fix nested README

上级 aef30e54
......@@ -14,20 +14,21 @@ module.exports = {
{
title: 'Guide',
children: [
['/', 'Home'],
'/getting-started',
'/markdown',
'/assets',
'/using-vue',
'/config',
'/default-theme'
'/default-theme',
'/theming',
'/deploy'
]
},
{
title: 'API Reference',
title: 'Config Reference',
children: [
['/markdown#emoji', 'MMMMM'],
'/theming',
'/deploy'
'/config',
'/test/'
]
}
],
......
# Test Page
hello dude
......@@ -16,13 +16,15 @@ export default {
updateMeta()
},
render (h) {
const componentName = this.$page.path === '/'
? 'index'
: this.$page.path
.replace(/^\//, '')
.replace(/\.html$/, '')
.replace(/\//g, '-')
return h('page-' + componentName)
return h(pathToComponentName(this.$page.path))
}
}
function pathToComponentName (path) {
if (path.charAt(path.length - 1) === '/') {
return `page${path.replace(/\//g, '-') + 'index'}`
} else {
return `page${path.replace(/\//g, '-').replace(/\.html$/, '')}`
}
}
......
......@@ -2,9 +2,7 @@
<div class="sidebar">
<ul>
<li v-for="(item, i) in sidebarItems">
<router-link v-if="item.type === 'page'" :to="item.path">
{{ item.title || item.path }}
</router-link>
<SidebarLink v-if="item.type === 'page'" :item="item"/>
<SidebarGroup v-else-if="item.type === 'group'"
:item="item"
:first="i === 0"
......@@ -17,9 +15,10 @@
<script>
import SidebarGroup from './SidebarGroup.vue'
import SidebarLink, { isActive, normalize, ensureExt } from './SidebarLink.vue'
export default {
components: { SidebarGroup },
components: { SidebarGroup, SidebarLink },
data () {
return {
openGroupIndex: 0
......@@ -42,6 +41,9 @@ export default {
methods: {
toggleGroup (index) {
this.openGroupIndex = index === this.openGroupIndex ? -1 : index
},
isActive (page) {
return isActive(this.$route, page)
}
}
}
......@@ -49,18 +51,12 @@ export default {
function resolveOpenGroupIndex (route, items) {
for (let i = 0; i < items.length; i++) {
const item = items[i]
if (item.type === 'group' && item.children.some(c => isActive(route, c.path))) {
if (item.type === 'group' && item.children.some(c => isActive(route, c))) {
return i
}
}
}
function isActive (route, path) {
// TODO refine
const routePath = route.path
return routePath.indexOf(path) === 0
}
function resolveSidebar (route, site) {
const { pages, themeConfig } = site
const sidebarConfig = themeConfig.sidebar
......@@ -98,7 +94,7 @@ function resolveItem (item, pages, isNested) {
})
} else {
if (isNested) {
throw new Error(
console.error(
'[vuepress] Nested sidebar groups are not supported. ' +
'Consider using navbar + categories instead.'
)
......@@ -123,46 +119,15 @@ function resolvePage (pages, rawPath) {
})
}
}
}
const hashRE = /#.*$/
const extRE = /\.(md|html)$/
const slashRE = /\/$/
function normalize (path) {
return path
.replace(hashRE, '')
.replace(extRE, '')
}
function ensureExt (path) {
if (slashRE.test(path)) {
return path
}
const hashMatch = path.match(hashRE)
const hash = hashMatch ? hashMatch[0] : ''
return normalize(path) + '.html' + hash
console.error(`[vuepress] No matching page found for sidebar item "${rawPath}"`)
return {}
}
</script>
<style lang="stylus">
@import './styles/config.stylus'
.sidebar
ul
padding 0
margin 0
list-style-type none
a
display inline-block
color $textColor
border-left 0.25rem solid transparent
padding 0.25rem
padding-left 1.25rem
&:hover
color $accentColor
&.router-link-active
font-weight 600
color $accentColor
border-left-color $accentColor
</style>
......@@ -7,9 +7,7 @@
<transition name="sidebar-group" @enter="setHeight">
<ul class="sidebar-group-items" ref="items" v-if="open">
<li v-for="child in item.children">
<router-link v-if="child.type === 'page'" :to="child.path">
{{ child.title || child.path }}
</router-link>
<SidebarLink v-if="child.type === 'page'" :item="child"/>
</li>
</ul>
</transition>
......@@ -17,9 +15,12 @@
</template>
<script>
import SidebarLink from './SidebarLink.vue'
export default {
name: 'SidebarGroup',
props: ['item', 'first', 'open'],
components: { SidebarLink },
mounted () {
const { items } = this.$refs
if (items) this.setHeight(items)
......
<script>
export default {
functional: true,
props: ['item'],
render (h, { parent: { $route }, props: { item }}) {
return h('router-link', {
props: {
to: item.path,
activeClass: '',
exactActiveClass: ''
},
class: {
'sidebar-link': true,
// use custom active class matching logic
// due to edge case of paths ending with / + hash
active: isActive($route, item)
}
}, [item.title || item.path])
}
}
const hashRE = /#.*$/
const extRE = /\.(md|html)$/
const slashRE = /\/$/
export function isActive (route, page) {
const routePath = normalize(route.path)
const pagePath = normalize(page.path)
if (routePath === '/' || pagePath === '/') {
return routePath === pagePath
} else {
return routePath.indexOf(pagePath) === 0
}
}
export function normalize (path) {
return path
.replace(hashRE, '')
.replace(extRE, '')
}
export function ensureExt (path) {
if (slashRE.test(path)) {
return path
}
const hashMatch = path.match(hashRE)
const hash = hashMatch ? hashMatch[0] : ''
return normalize(path) + '.html' + hash
}
</script>
<style lang="stylus">
@import './styles/config.stylus'
a.sidebar-link
display inline-block
color $textColor
border-left 0.25rem solid transparent
padding 0.25rem
padding-left 1.25rem
&:hover
color $accentColor
&.active
font-weight 600
color $accentColor
border-left-color $accentColor
</style>
......@@ -104,15 +104,12 @@ async function resolveOptions (sourceDir) {
// resolve pages
const pagesData = options.pageFiles.map(file => {
const urlPath = isIndexFile(file)
? '/'
: `/${file.replace(/\.md$/, '').replace(/\\/g, '/')}.html`
const content = fs.readFileSync(path.resolve(sourceDir, file), 'utf-8')
const data = {
path: urlPath
path: fileToPath(file)
}
// extract yaml frontmatter
const content = fs.readFileSync(path.resolve(sourceDir, file), 'utf-8')
const frontmatter = yaml.loadFront(content)
// infer title
const title = inferTitle(frontmatter)
......@@ -140,7 +137,7 @@ async function resolveOptions (sourceDir) {
async function genComponentRegistrationFile ({ sourceDir, pageFiles }) {
function genImport (file) {
const name = toComponentName(file)
const name = fileToComponentName(file)
const baseDir = /\.md$/.test(file)
? sourceDir
: path.resolve(sourceDir, '.vuepress/components')
......@@ -154,17 +151,34 @@ async function genComponentRegistrationFile ({ sourceDir, pageFiles }) {
return `import Vue from 'vue'\n` + all.map(genImport).join('\n')
}
function toComponentName (file) {
const isPage = /\.md$/.test(file)
const isIndex = isIndexFile(file)
const normalizedName = isIndex
? 'index'
: file.replace(/\.(vue|md)$/, '').replace(/\/|\\/g, '-')
return isPage ? `page-${normalizedName}` : normalizedName
const indexRE = /\breadme\.md$/i
const extRE = /\.(vue|md)$/
function fileToPath (file) {
if (isIndexFile(file)) {
// README.md -> /
// foo/README.md -> /foo/
return '/' + file.replace(indexRE, '')
} else {
// foo.md -> /foo.html
// foo/bar.md -> /foo/bar.html
return `/${file.replace(extRE, '').replace(/\\/g, '/')}.html`
}
}
function fileToComponentName (file) {
let normalizedName = file
.replace(/\/|\\/g, '-')
.replace(extRE, '')
if (isIndexFile(file)) {
normalizedName = normalizedName.replace(/readme$/i, 'index')
}
const pagePrefix = /\.md$/.test(file) ? `page-` : ``
return `${pagePrefix}${normalizedName}`
}
function isIndexFile (file) {
return /^(index|readme)\.md$/i.test(file)
return indexRE.test(file)
}
async function resolveComponents (sourceDir) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册