feat: add git repo link and edit links (#55)

Co-authored-by: Shintaro Tanaka <s-tanaka@holmescloud.com>
Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com>
pull/90/head
tanasinn 4 years ago committed by GitHub
parent a90d971b40
commit 0ea34cbb1d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -12,7 +12,7 @@
/> />
<span>{{ $site.title }}</span> <span>{{ $site.title }}</span>
</a> </a>
<NavBarLinks class="hide-mobile"/> <NavBarLinks class="hide-mobile" />
</template> </template>
<script src="./NavBar"></script> <script src="./NavBar"></script>

@ -1,7 +1,12 @@
import { computed } from 'vue' import { computed } from 'vue'
import { useSiteDataByRoute } from 'vitepress' import { useSiteData, useSiteDataByRoute } from 'vitepress'
import NavBarLink from './NavBarLink.vue' import NavBarLink from './NavBarLink.vue'
import NavDropdownLink from './NavDropdownLink.vue' import NavDropdownLink from './NavDropdownLink.vue'
import { DefaultTheme } from '../config'
const platforms = ['GitHub', 'GitLab', 'Bitbucket'].map(
(platform) => [platform, new RegExp(platform, 'i')] as const
)
export default { export default {
components: { components: {
@ -10,13 +15,39 @@ export default {
}, },
setup() { setup() {
const siteDataByRoute = useSiteDataByRoute()
const siteData = useSiteData()
const repoInfo = computed(() => {
const theme = siteData.value.themeConfig as DefaultTheme.Config
const repo = theme.docsRepo || theme.repo
let text: string | undefined = theme.repoLabel
if (repo) {
const link = /^https?:/.test(repo) ? repo : `https://github.com/${repo}`
if (!text) {
// if no label is provided, deduce it from the repo url
const repoHosts = link.match(/^https?:\/\/[^/]+/)
if (repoHosts) {
const repoHost = repoHosts[0]
const foundPlatform = platforms.find(([_platform, re]) =>
re.test(repoHost)
)
text = foundPlatform && foundPlatform[0]
}
}
return { link, text: text || 'Source' }
}
return null
})
return { return {
navData: navData:
process.env.NODE_ENV === 'production' process.env.NODE_ENV === 'production'
? // navbar items do not change in production ? // navbar items do not change in production
useSiteDataByRoute().value.themeConfig.nav siteDataByRoute.value.themeConfig.nav
: // use computed in dev for hot reload : // use computed in dev for hot reload
computed(() => useSiteDataByRoute().value.themeConfig.nav) computed(() => siteDataByRoute.value.themeConfig.nav),
repoInfo
} }
} }
} }

@ -1,9 +1,12 @@
<template> <template>
<nav class="nav-links" v-if="navData"> <nav class="nav-links" v-if="navData || repoInfo">
<template v-for="item of navData"> <template v-if="navData">
<NavDropdownLink v-if='item.items' :item="item"/> <template v-for="item of navData">
<NavBarLink v-else :item="item"/> <NavDropdownLink v-if="item.items" :item="item" />
<NavBarLink v-else :item="item" />
</template>
</template> </template>
<NavBarLink v-if="repoInfo" :item="repoInfo" />
</nav> </nav>
</template> </template>

@ -2,13 +2,15 @@
<div class="content"> <div class="content">
<Content /> <Content />
<NextAndPrevLinks /> <NextAndPrevLinks />
<PageEdit />
</div> </div>
</template> </template>
<script> <script>
import NextAndPrevLinks from './NextAndPrevLinks.vue' import NextAndPrevLinks from './NextAndPrevLinks.vue'
import PageEdit from './PageEdit.vue'
export default { export default {
components:{ NextAndPrevLinks } components:{ NextAndPrevLinks, PageEdit }
} }
</script> </script>

@ -0,0 +1,81 @@
import { computed } from 'vue'
import OutboundLink from './icons/OutboundLink.vue'
import { endingSlashRE, isExternal } from '/@theme/utils'
import { usePageData, useSiteData } from 'vitepress'
import { DefaultTheme } from '../config'
function createEditLink(
repo: string,
docsRepo: string,
docsDir: string,
docsBranch: string,
path: string
) {
const bitbucket = /bitbucket.org/
if (bitbucket.test(repo)) {
const base = isExternal(docsRepo) ? docsRepo : repo
return (
base.replace(endingSlashRE, '') +
`/src` +
`/${docsBranch}/` +
(docsDir ? docsDir.replace(endingSlashRE, '') + '/' : '') +
path +
`?mode=edit&spa=0&at=${docsBranch}&fileviewer=file-view-default`
)
}
const base = isExternal(docsRepo)
? docsRepo
: `https://github.com/${docsRepo}`
return (
base.replace(endingSlashRE, '') +
`/edit` +
`/${docsBranch}/` +
(docsDir ? docsDir.replace(endingSlashRE, '') + '/' : '') +
path
)
}
export default {
components: {
OutboundLink
},
setup() {
const pageData = usePageData()
const siteData = useSiteData<DefaultTheme.Config>()
const editLink = computed(() => {
const showEditLink: boolean | undefined =
pageData.value.frontmatter.editLink == null
? siteData.value.themeConfig.editLinks
: pageData.value.frontmatter.editLink
const {
repo,
docsDir = '',
docsBranch = 'master',
docsRepo = repo
} = siteData.value.themeConfig
const { relativePath } = pageData.value
if (showEditLink && relativePath && repo) {
return createEditLink(
repo,
docsRepo || repo,
docsDir,
docsBranch,
relativePath
)
}
return null
})
const editLinkText = computed(
() => siteData.value.themeConfig.editLinkText || 'Edit this page'
)
return {
editLink,
editLinkText
}
}
}

@ -0,0 +1,28 @@
<template>
<footer class="page-edit">
<a
v-if="editLink"
:href="editLink"
target="_blank"
rel="noopener noreferrer"
>
{{ editLinkText }}
<OutboundLink />
</a>
</footer>
</template>
<script src="./PageEdit"></script>
<style>
.page-edit {
padding-top: 1rem;
padding-bottom: 1rem;
overflow: auto;
}
.page-edit a {
color: var(--text-color);
margin-right: 0.25rem;
}
</style>

@ -4,7 +4,48 @@ export namespace DefaultTheme {
nav?: NavItem[] | false nav?: NavItem[] | false
sidebar?: SideBarConfig | MultiSideBarConfig sidebar?: SideBarConfig | MultiSideBarConfig
search?: SearchConfig | false search?: SearchConfig | false
editLink?: EditLinkConfig | false
/**
* GitHub repository following the format <user>/<project>.
*
* @example vuejs/vue-next
*/
repo?: string
/**
* Customize the header label. Defaults to GitHub/Gitlab/Bitbucket depending
* on the provided repo
*
* @exampe `"Contribute!"`
*/
repoLabel?: string
/**
* If your docs are in a different repository from your main project
*
* @example `"vuejs/docs-next"`
*/
docsRepo?: string
/**
* If your docs are not at the root of the repo.
*
* @example `"docs"`
*/
docsDir?: string
/**
* If your docs are in a different branch. Defaults to `master`
* @example `"next"`
*/
docsBranch?: string
/**
* Enable links to edit pages at the bottom of the page
*/
editLinks?: boolean
/**
* Custom text for edit link. Defaults to "Edit this page"
*/
editLinkText?: string
lastUpdated?: string | boolean lastUpdated?: string | boolean
prevLink?: boolean prevLink?: boolean
nextLink?: boolean nextLink?: boolean
@ -70,13 +111,4 @@ export namespace DefaultTheme {
indexName: string indexName: string
} }
} }
// edit link -----------------------------------------------------------------
export interface EditLinkConfig {
repo: string
dir?: string
branch?: string
text?: string
}
} }

@ -2,6 +2,7 @@ import { useSiteData, Route } from 'vitepress'
export const hashRE = /#.*$/ export const hashRE = /#.*$/
export const extRE = /\.(md|html)$/ export const extRE = /\.(md|html)$/
export const endingSlashRE = /\/$/
export const outboundRE = /^[a-z]+:/i export const outboundRE = /^[a-z]+:/i
export function withBase(path: string) { export function withBase(path: string) {

@ -43,6 +43,7 @@ export function createMarkdownToVueRenderFn(
title: inferTitle(frontmatter, content), title: inferTitle(frontmatter, content),
frontmatter, frontmatter,
headers: data.headers, headers: data.headers,
relativePath: file.replace(/\\/g, '/'),
lastUpdated lastUpdated
} }

1
types/shared.d.ts vendored

@ -25,6 +25,7 @@ export interface PageData {
title: string title: string
frontmatter: Record<string, any> frontmatter: Record<string, any>
headers: Header[] headers: Header[]
relativePath: string
lastUpdated: number lastUpdated: number
next?: { text: string; link: string } next?: { text: string; link: string }
prev?: { text: string; link: string } prev?: { text: string; link: string }

Loading…
Cancel
Save