Skip to content

Commit

Permalink
feat: add pageData option
Browse files Browse the repository at this point in the history
  • Loading branch information
egoist committed Nov 25, 2018
1 parent 1a7a6e5 commit 8984e11
Show file tree
Hide file tree
Showing 8 changed files with 137 additions and 34 deletions.
10 changes: 8 additions & 2 deletions src/components/EditLink.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<div v-if="editLinkBase" class="EditLink">
<div v-if="editLink" class="EditLink">
<a target="_blank" :href="`${editLink}`">
<svg class="icon" id="i-compose" viewBox="0 0 32 32" width="32" height="32" fill="none" stroke="currentcolor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M27 15 L27 30 2 30 2 5 17 5 M30 6 L26 2 9 19 7 25 13 23 Z M22 6 L26 10 Z M9 19 L13 23 Z" />
Expand All @@ -15,7 +15,13 @@ export default {
},
editLink() {
return this.editLinkBase + this.$store.state.env.file
const {editLink, file} = this.$store.state.page
if (editLink) {
return editLink
}
if (file) {
return /^https?:\/\//.test(file) ? file : this.editLinkBase + file
}
},
editLinkText() {
Expand Down
8 changes: 6 additions & 2 deletions src/components/PrevNextLinks.vue
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,15 @@ export default {
},
prevLinkItem() {
return this.sidebarLinks[this.currentLinkIndex - 1]
return (
this.currentLinkIndex && this.sidebarLinks[this.currentLinkIndex - 1]
)
},
nextLinkItem() {
return this.sidebarLinks[this.currentLinkIndex + 1]
return (
this.currentLinkIndex && this.sidebarLinks[this.currentLinkIndex + 1]
)
}
}
}
Expand Down
71 changes: 52 additions & 19 deletions src/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,38 +48,54 @@ const store = new Vuex.Store({
},

actions: {
async fetchFile({commit, getters, dispatch}, {path, text}) {
async fetchFile({commit, getters, dispatch}, path) {
commit('TOGGLE_SIDEBAR', false)
commit('SET_FETCHING', true)
const file = getFilenameByPath(getters.config.sourcePath, path)

let pageData = await getters.pageData
if (typeof pageData === 'function') {
pageData = await pageData(store)
}

let page = {
markdown: true,
...pageData
}

if (!page.content && !page.file) {
page.file = getFilenameByPath(getters.config.sourcePath, path)
}

await Promise.all([
!text &&
fetch(file)
!page.content &&
fetch(page.file)
.then(res => res.text())
.then(res => {
text = res
page.content = res
}),
dispatch('fetchPrismLanguages')
])

text = hooks.process('processMarkdown', text)
// TODO: remove processMarkdown hook
page.content = hooks.process('processMarkdown', page.content)
page = hooks.process('processPage', page)

const env = {
headings: [],
file
headings: []
}
let html = marked(text, {
renderer: markedRenderer(hooks),
highlight,
env
})
html = hooks.process('processHTML', html)
commit('SET_PAGE', {
title: env.title,
headings: env.headings,
html
})
if (page.markdown) {
page.content = marked(page.content, {
renderer: markedRenderer(hooks),
highlight,
env
})
}
page.content = hooks.process('processHTML', page.content)
page.headings = env.headings
if (!page.title) {
page.title = env.title
}
commit('SET_PAGE', page)
commit('SET_ENV', env)
commit('SET_FETCHING', false)
},
Expand Down Expand Up @@ -187,6 +203,23 @@ const store = new Vuex.Store({

centerContent(_, {config}) {
return config.centerContent !== false
},

pageData(
{
route: {path}
},
{config}
) {
return Promise.resolve(
typeof config.pageData === 'function'
? config.pageData(store)
: config.pageData
)
.then(pageData => {
return pageData && pageData[path]
})
.catch(console.error)
}
}
})
Expand Down
6 changes: 5 additions & 1 deletion src/utils/markedRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ export default hooks => {

if (level === 1) {
env.title = text
} else if (level === 2 || level === 3) {
// Remove h1 header
return ''
}

if (level === 2 || level === 3) {
env.headings.push({
level,
raw,
Expand Down
23 changes: 14 additions & 9 deletions src/views/Home.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
class="Main"
v-else>
<InjectedComponents position="main:start" />
<h1 class="page-title">{{ $store.state.page.title }}</h1>
<component :is="MarkdownBody" />
<EditLink />
<PrevNextLinks />
Expand Down Expand Up @@ -61,17 +62,13 @@ export default {
},
mounted() {
const initialTextNode = document.getElementById('docute-initial-text')
this.fetchFile({
path: this.$route.path,
text: initialTextNode && initialTextNode.textContent
})
this.fetchFile(this.$route.path)
},
beforeRouteUpdate(to, from, next) {
next()
if (to.path !== from.path) {
this.fetchFile({path: to.path})
this.fetchFile(to.path)
}
},
Expand All @@ -97,7 +94,7 @@ export default {
mixins: componentMixins || [],
name: 'MarkdownBody',
template: `<div class="markdown-body">${
this.$store.state.page.html
this.$store.state.page.content
}</div>`
}
Expand All @@ -108,8 +105,8 @@ export default {
},
methods: {
async fetchFile(opts) {
await this.$store.dispatch('fetchFile', opts)
async fetchFile(path) {
await this.$store.dispatch('fetchFile', path)
hooks.invoke('onContentWillUpdate', this)
await this.$nextTick()
hooks.invoke('onContentUpdated', this)
Expand Down Expand Up @@ -156,4 +153,12 @@ export default {
max-width: 100%;
}
}
.page-title {
font-size: 3rem;
margin: 0;
margin-bottom: 1.4rem;
font-weight: 300;
line-height: 1.1;
}
</style>
20 changes: 20 additions & 0 deletions website/docs/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,26 @@ The source path to fetch markdown files from, by default we load them from the r

It can also be a full URL like: `https://some-website/path/to/markdown/files` so that you can load files from a different domain.

## pageData

- Type: `PageData | (store: Vuex.Store) => Promise<PageData>`

Directly use page data from this option instead of fetching a file.

```ts
interface PageData {
[path: string]: PageDataItem | (store: Vuex.Store) => Promise<PageDataItem>
}

interface PageDataItem {
title?: string
content?: string
file?: string
markdown?: boolean
[k: string]?: any
}
```

## componentMixins

- Type: `Array<Object>`
Expand Down
20 changes: 20 additions & 0 deletions website/docs/zh/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,26 @@ interface ItemLink {
它也可以是完整的 URL,例如: `https://some-website/path/to/markdown/files`,以便于你可以从其他域名加载文件。


## pageData

- 类型: `PageData | (store: Vuex.Store) => Promise<PageData>`

直接从这个选项获取页面数据,而不是请求一个文件。

```ts
interface PageData {
[path: string]: PageDataItem | (store: Vuex.Store) => Promise<PageDataItem>
}

interface PageDataItem {
title?: string
content?: string
file?: string
markdown?: boolean
[k: string]?: any
}
```

## componentMixins

- 类型: `Array<Object>`
Expand Down
13 changes: 12 additions & 1 deletion website/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,18 @@ new Docute({
}
]
}
}
},
pageData: () => fetch('http://jsonplaceholder.typicode.com/posts')
.then(res => res.json())
.then(posts => {
return posts.reduce((result, post) => {
result['/post/' + post.id] = {
title: post.title,
content: post.body
}
return result
}, {})
})
})

Vue.component('ReverseText', {
Expand Down

0 comments on commit 8984e11

Please sign in to comment.