mirror of https://github.com/vuejs/vitepress
commit
59cbd25547
@ -0,0 +1,13 @@
|
|||||||
|
# App Config: Carbon Ads
|
||||||
|
|
||||||
|
VitePress has built in native support for [Carbon Ads](https://www.carbonads.net). By defining the Carbon Ads credentials in config, VitePress will display ads on the page.
|
||||||
|
|
||||||
|
```js
|
||||||
|
module.exports = {
|
||||||
|
carbonAds: {
|
||||||
|
carbon: 'your-carbon-key',
|
||||||
|
custom: 'your-carbon-custom',
|
||||||
|
placement: 'your-carbon-placement'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
@ -0,0 +1,35 @@
|
|||||||
|
# Asset Handling
|
||||||
|
|
||||||
|
All Markdown files are compiled into Vue components and processed by [Vite](https://github.com/vitejs/vite). You can, **and should**, reference any assets using relative URLs:
|
||||||
|
|
||||||
|
```md
|
||||||
|

|
||||||
|
```
|
||||||
|
|
||||||
|
You can reference static assets in your markdown files, your `*.vue` components in the theme, styles and plain `.css` files either using absolute public paths (based on project root) or relative paths (based on your file system). The latter is similar to the behavior you are used to if you have used `vue-cli` or webpack's `file-loader`.
|
||||||
|
|
||||||
|
Common image, media, and font filetypes are detected and included as assets automatically.
|
||||||
|
|
||||||
|
All referenced assets, including those using absolute paths, will be copied to the dist folder with a hashed file name in the production build. Never-referenced assets will not be copied. Similar to `vue-cli`, image assets smaller than 4kb will be base64 inlined.
|
||||||
|
|
||||||
|
All **static** path references, including absolute paths, should be based on your working directory structure.
|
||||||
|
|
||||||
|
## Public Files
|
||||||
|
|
||||||
|
Sometimes you may need to provide static assets that are not directly referenced in any of your Markdown or theme components (for example, favicons and PWA icons). The `public` directory under project root can be used as an escape hatch to provide static assets that either are never referenced in source code (e.g. `robots.txt`), or must retain the exact same file name (without hashing).
|
||||||
|
|
||||||
|
Assets placed in `public` will be copied to the root of the dist directory as-is.
|
||||||
|
|
||||||
|
Note that you should reference files placed in `public` using root absolute path - for example, `public/icon.png` should always be referenced in source code as `/icon.png`.
|
||||||
|
|
||||||
|
## Base URL
|
||||||
|
|
||||||
|
If your site is deployed to a non-root URL, you will need to set the `base` option in `.vitepress/config.js`. For example, if you plan to deploy your site to `https://foo.github.io/bar/`, then `base` should be set to `'/bar/'` (it should always start and end with a slash).
|
||||||
|
|
||||||
|
With a base URL, to reference an image in `public`, you'd have to use URLs like `/bar/image.png`. But this is brittle if you ever decide to change the base. To help with that, VitePress provides a built-in helper `$withBase` (injected onto Vue's prototype) that generates the correct path:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<img :src="$withBase('/foo.png')" alt="foo">
|
||||||
|
```
|
||||||
|
|
||||||
|
Note you can use the above syntax not only in theme components, but in your Markdown files as well.
|
@ -0,0 +1,81 @@
|
|||||||
|
# Global Computed
|
||||||
|
|
||||||
|
In VitePress, some core [computed properties](https://v3.vuejs.org/guide/computed.html#computed-properties) can be used by the default theme or custom themes. Or directly in Markdown pages using vue, for example using `$frontmatter.title` to access the title defined in the frontmatter section of the page.
|
||||||
|
|
||||||
|
## $site
|
||||||
|
|
||||||
|
This is the `$site` value of the site you're currently reading:
|
||||||
|
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
base: '/',
|
||||||
|
lang: 'en-US',
|
||||||
|
title: 'VitePress',
|
||||||
|
description: 'Vite & Vue powered static site generator.',
|
||||||
|
head: [],
|
||||||
|
locales: {},
|
||||||
|
themeConfig: $themeConfig
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## $themeConfig
|
||||||
|
|
||||||
|
Refers to `$site.themeConfig`.
|
||||||
|
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
locales: {},
|
||||||
|
repo: 'vuejs/vitepress',
|
||||||
|
docsDir: 'docs',
|
||||||
|
editLinks: true,
|
||||||
|
editLinkText: 'Edit this page on GitHub',
|
||||||
|
lastUpdated: 'Last Updated',
|
||||||
|
nav: [...],
|
||||||
|
sidebar: { ... }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## $page
|
||||||
|
|
||||||
|
This is the `$page` value of the page you're currently reading:
|
||||||
|
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
relativePath: 'guide/global-computed.md',
|
||||||
|
title: 'Global Computed',
|
||||||
|
headers: [
|
||||||
|
{ level: 2, title: '$site', slug: 'site' },
|
||||||
|
{ level: 2, title: '$page', slug: '$page' },
|
||||||
|
...
|
||||||
|
],
|
||||||
|
frontmatter: $frontmatter,
|
||||||
|
lastUpdated: 1606297645000
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## $frontmatter
|
||||||
|
|
||||||
|
Reference of `$page.frontmatter`.
|
||||||
|
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
title: 'Docs with VitePress',
|
||||||
|
editLink: true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## $title
|
||||||
|
|
||||||
|
Value of the `<title>` label used for the current page.
|
||||||
|
|
||||||
|
## $description
|
||||||
|
|
||||||
|
The content value of the `<meta name= "description" content= "...">` for the current page.
|
||||||
|
|
||||||
|
## $withBase
|
||||||
|
|
||||||
|
Helper method to generate correct path by prepending the `base` path configured in `.vitepress/config.js`. It's useful when you want to link to [public files with base path](./assets#public-files).
|
||||||
|
|
||||||
|
```html
|
||||||
|
<img :src="$withBase('/foo.png')" alt="foo">
|
||||||
|
```
|
@ -1,8 +1,11 @@
|
|||||||
import { computed } from 'vue'
|
import { Ref, computed } from 'vue'
|
||||||
import { useRoute } from '../router'
|
import { PageData } from '/@types/shared'
|
||||||
|
import { Route, useRoute } from '../router'
|
||||||
|
|
||||||
export function usePageData() {
|
export type PageDataRef = Ref<PageData>
|
||||||
const route = useRoute()
|
|
||||||
|
|
||||||
return computed(() => route.data)
|
export function usePageData(route?: Route) {
|
||||||
|
const r = route || useRoute()
|
||||||
|
|
||||||
|
return computed(() => r.data)
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
import { resolveSiteDataByRoute } from '/@shared/config'
|
import { resolveSiteDataByRoute } from '/@shared/config'
|
||||||
import { siteDataRef } from './siteData'
|
import { siteDataRef } from './siteData'
|
||||||
import { useRoute } from '../router'
|
import { Route, useRoute } from '../router'
|
||||||
|
|
||||||
|
export function useSiteDataByRoute(route?: Route) {
|
||||||
|
const r = route || useRoute()
|
||||||
|
|
||||||
export function useSiteDataByRoute(route = useRoute()) {
|
|
||||||
return computed(() => {
|
return computed(() => {
|
||||||
return resolveSiteDataByRoute(siteDataRef.value, route.path)
|
return resolveSiteDataByRoute(siteDataRef.value, r.path)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,73 @@
|
|||||||
|
import { App } from 'vue'
|
||||||
|
import { joinPath } from './utils'
|
||||||
|
import { SiteDataRef } from './composables/siteData'
|
||||||
|
import { PageDataRef } from './composables/pageData'
|
||||||
|
import { Content } from './components/Content'
|
||||||
|
import Debug from './components/Debug.vue'
|
||||||
|
|
||||||
|
export function mixinGlobalComputed(
|
||||||
|
app: App,
|
||||||
|
site: SiteDataRef,
|
||||||
|
siteByRoute: SiteDataRef,
|
||||||
|
page: PageDataRef
|
||||||
|
): void {
|
||||||
|
Object.defineProperties(app.config.globalProperties, {
|
||||||
|
$site: {
|
||||||
|
get() {
|
||||||
|
return site.value
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
$siteByRoute: {
|
||||||
|
get() {
|
||||||
|
return siteByRoute.value
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
$themeConfig: {
|
||||||
|
get() {
|
||||||
|
return siteByRoute.value.themeConfig
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
$page: {
|
||||||
|
get() {
|
||||||
|
return page.value
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
$frontmatter: {
|
||||||
|
get() {
|
||||||
|
return page.value.frontmatter
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
$title: {
|
||||||
|
get() {
|
||||||
|
return page.value.title
|
||||||
|
? page.value.title + ' | ' + siteByRoute.value.title
|
||||||
|
: siteByRoute.value.title
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
$description: {
|
||||||
|
get() {
|
||||||
|
return page.value.description || siteByRoute.value.description
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
$withBase: {
|
||||||
|
value(path: string) {
|
||||||
|
return joinPath(site.value.base, path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function mixinGlobalComponents(app: App) {
|
||||||
|
const isProd = process.env.NODE_ENV === 'production'
|
||||||
|
|
||||||
|
app.component('Content', Content)
|
||||||
|
|
||||||
|
app.component('Debug', isProd ? () => null : Debug)
|
||||||
|
}
|
@ -0,0 +1,146 @@
|
|||||||
|
<template>
|
||||||
|
<div class="buy-sell-ads">
|
||||||
|
<div class="bsa-cpc" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { defineProps, onMounted } from 'vue'
|
||||||
|
|
||||||
|
// global _bsa
|
||||||
|
const ID = 'bsa-cpc-script'
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
var _bsa: BSA | undefined
|
||||||
|
|
||||||
|
interface BSA {
|
||||||
|
init(
|
||||||
|
name: string,
|
||||||
|
code: string,
|
||||||
|
placement: string,
|
||||||
|
options: {
|
||||||
|
target: string
|
||||||
|
align: string
|
||||||
|
disable_css?: 'true' | 'false'
|
||||||
|
}
|
||||||
|
): void
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const { code, placement } = defineProps<{
|
||||||
|
code: string
|
||||||
|
placement: string
|
||||||
|
}>()
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
if (!document.getElementById(ID)) {
|
||||||
|
const s = document.createElement('script')
|
||||||
|
|
||||||
|
s.id = ID
|
||||||
|
s.src = '//m.servedby-buysellads.com/monetization.js'
|
||||||
|
|
||||||
|
document.head.appendChild(s)
|
||||||
|
|
||||||
|
s.onload = () => { load() }
|
||||||
|
} else {
|
||||||
|
load()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
function load() {
|
||||||
|
if (typeof _bsa !== 'undefined' && _bsa) {
|
||||||
|
_bsa.init('default', code, `placement:${placement}`, {
|
||||||
|
target: '.bsa-cpc',
|
||||||
|
align: 'horizontal',
|
||||||
|
disable_css: 'true'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.buy-sell-ads {
|
||||||
|
margin: 0 auto;
|
||||||
|
padding-top: 2rem;
|
||||||
|
font-size: .85rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bsa-cpc {
|
||||||
|
border-radius: 6px;
|
||||||
|
background-color: #f8f8f8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bsa-cpc ::v-deep(a._default_) {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: flex-start;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
padding: 12px;
|
||||||
|
text-decoration: none;
|
||||||
|
line-height: 1.4;
|
||||||
|
font-weight: 400;
|
||||||
|
color: var(--c-text-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 512px) {
|
||||||
|
.bsa-cpc ::v-deep(a._default_) {
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bsa-cpc ::v-deep(.default-ad) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bsa-cpc ::v-deep(a._default_ .default-image) {
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin-right: 12px;
|
||||||
|
width: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bsa-cpc ::v-deep(a._default_ .default-image img) {
|
||||||
|
border-radius: 4px;
|
||||||
|
height: 24px;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bsa-cpc ::v-deep(._default_::after) {
|
||||||
|
border: 1px solid #1c90f3;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-top: 8px;
|
||||||
|
margin-left: 36px;
|
||||||
|
padding: 0 8px;
|
||||||
|
line-height: 22px;
|
||||||
|
font-size: .85em;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #1c90f3;
|
||||||
|
content: 'Sponsored';
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 512px) {
|
||||||
|
.bsa-cpc ::v-deep(._default_::after) {
|
||||||
|
margin-top: 0px;
|
||||||
|
margin-left: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bsa-cpc ::v-deep(.default-text) {
|
||||||
|
flex-grow: 1;
|
||||||
|
align-self: center;
|
||||||
|
width: calc(100% - 36px);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 512px) {
|
||||||
|
.bsa-cpc ::v-deep(.default-text) {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bsa-cpc ::v-deep(.default-title) {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bsa-cpc ::v-deep(.default-description) {
|
||||||
|
padding-left: 8px;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,102 @@
|
|||||||
|
<template>
|
||||||
|
<div class="carbon-ads" ref="el" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { defineProps, ref, onMounted } from 'vue'
|
||||||
|
|
||||||
|
const { code, placement } = defineProps<{
|
||||||
|
code: string
|
||||||
|
placement: string
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const el = ref()
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
const s = document.createElement('script')
|
||||||
|
s.id = '_carbonads_js'
|
||||||
|
s.src = `//cdn.carbonads.com/carbon.js?serve=${code}&placement=${placement}`
|
||||||
|
el.value.appendChild(s)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.carbon-ads {
|
||||||
|
padding: 1.75rem 0 0;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin: 0 auto;
|
||||||
|
max-width: 280px;
|
||||||
|
font-size: .75rem;
|
||||||
|
background-color: rgba(255, 255, 255, .8);
|
||||||
|
}
|
||||||
|
|
||||||
|
.carbon-ads::after {
|
||||||
|
clear: both;
|
||||||
|
display: block;
|
||||||
|
content: "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 420px) {
|
||||||
|
.carbon-ads {
|
||||||
|
position: relative;
|
||||||
|
right: -8px;
|
||||||
|
z-index: 1;
|
||||||
|
float: right;
|
||||||
|
margin: -8px -8px 24px 24px;
|
||||||
|
padding: 8px;
|
||||||
|
width: 146px;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 1400px) {
|
||||||
|
.carbon-ads {
|
||||||
|
position: fixed;
|
||||||
|
top: auto;
|
||||||
|
right: 8px;
|
||||||
|
bottom: 8px;
|
||||||
|
float: none;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.carbon-ads ::v-deep(.carbon-img) {
|
||||||
|
float: left;
|
||||||
|
margin-right: .75rem;
|
||||||
|
max-width: 100px;
|
||||||
|
border: 1px solid var(--c-divider);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 420px) {
|
||||||
|
.carbon-ads ::v-deep(.carbon-img) {
|
||||||
|
float: none;
|
||||||
|
display: block;
|
||||||
|
margin-right: 0;
|
||||||
|
max-width: 130px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.carbon-ads ::v-deep(.carbon-img img) {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 420px) {
|
||||||
|
.carbon-ads ::v-deep(.carbon-text) {
|
||||||
|
padding-top: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.carbon-ads ::v-deep(.carbon-text) {
|
||||||
|
display: block;
|
||||||
|
font-weight: 400;
|
||||||
|
color: var(--c-text-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
.carbon-ads ::v-deep(.carbon-poweredby) {
|
||||||
|
display: block;
|
||||||
|
padding-top: 2px;
|
||||||
|
font-weight: 400;
|
||||||
|
color: var(--c-text-lighter);
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,14 @@
|
|||||||
|
import { useSiteData } from 'vitepress'
|
||||||
|
import { joinPath } from '/@app/utils'
|
||||||
|
|
||||||
|
export function useUrl() {
|
||||||
|
const site = useSiteData()
|
||||||
|
|
||||||
|
function withBase(path: string): string {
|
||||||
|
return joinPath(site.value.base, path)
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
withBase
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in new issue