@@ -1,16 +1,67 @@
import { defineConfig } from 'vitepress'
import fs from 'node:fs'
import path from 'node:path'
import type { HeadConfig , SiteConfig , TransformContext } from 'vitepress'
const siteUrl = 'https://seotest.gongxue100.com'
const siteName = '恭学教育集团'
const defaultOgImage = 'https://fenxiang-1304851894.cos.ap-nanjing.myqcloud.com/%E5%B0%81%E9%9D%A2.png'
const defaultKeywords = '天津专升本,专升本培训,恭学教育,天津专升本刷题,专升本网校,天津专升本教材,专升本辅导,天津专升本报名,专升本真题,天津专升本课程'
/**
* 将 Markdown 相对路径转换为站点 URL 路径
* - index.md -> /
* - books.md -> /books
* - knowledge/index.md -> /knowledge/
* - knowledge/sample-article.md -> /knowledge/sample-article
*/
function relativePathToUrl ( relativePath : string ) : string {
let route = relativePath . replace ( /\.md$/ , '' )
route = route . replace ( /(^|\/)index$/ , '' )
if ( ! route . startsWith ( '/' ) ) {
route = ` / ${ route } `
}
return route || '/'
}
function formatDate ( date : Date ) : string {
return date . toISOString ( ) . split ( 'T' ) [ 0 ]
}
function getPageLastmod ( relativePath : string ) : string | undefined {
const filePath = path . resolve ( './docs' , relativePath )
try {
const content = fs . readFileSync ( filePath , 'utf-8' )
const fmMatch = content . match ( /^---\s*\n([\s\S]*?)\n---/ )
if ( fmMatch ) {
const dateMatch = fmMatch [ 1 ] . match ( /^publishedAt:\s*(.+)$/m ) || fmMatch [ 1 ] . match ( /^date:\s*(.+)$/m )
if ( dateMatch ) {
const d = new Date ( dateMatch [ 1 ] . trim ( ) )
if ( ! isNaN ( d . getTime ( ) ) ) {
return formatDate ( d )
}
}
}
const stat = fs . statSync ( filePath )
return formatDate ( stat . mtime )
} catch {
return undefined
}
}
export default defineConfig ( {
cleanUrls : 'with-subfolders' ,
title : '恭学教育集团' ,
titleTemplate : false ,
description : '恭学教育集团是天津专升本培训领军品牌, 专注天津专升本7年, 已服务21万+学员。提供专业刷题系统、在线网校、权威教材和一对一升学规划, 真题覆盖率100%,助你轻松升本成功!' ,
lang : 'zh-CN' ,
head : [
[ 'link' , { rel : 'icon' , href : '/logo.png' } ] ,
[ 'meta ' , { name : 'keywords' , content : '天津专升本,专升本培训,恭学教育,天津专升本刷题,专升本网校,天津专升本教材,专升本辅导,天津专升本报名,专升本真题,天津专升本课程 ' } ] ,
[ 'meta' , { property : 'og:image' , content : defaultOgImage } ] ,
[ 'link ' , { rel : 'apple-touch-icon' , href : '/logo.png ' } ] ,
[ 'meta' , { name : 'author' , content : '恭学教育集团' } ] ,
[ 'meta' , { property : 'og:site_name' , content : siteName } ] ,
[ 'meta' , { property : 'og:locale' , content : 'zh_CN' } ] ,
[ 'meta' , { name : 'twitter:card' , content : 'summary_large_image' } ] ,
] ,
themeConfig : {
logo : '/logo.png' ,
@@ -41,13 +92,115 @@ export default defineConfig({
} ,
] ,
} ,
transformHead ( { pageData } ) {
const keywords = pageData . frontmatter . keywords
if ( keywords && Array . isArray ( keywords ) ) {
return [
[ 'me ta' , { name : 'keywords' , content : keywords.join ( ',' ) } ] ,
]
transformHead ( { pageData , siteData } : TransformContext ) {
const isNotFound = pageData . relativePath === '404.md'
const isArticle =
pageData . relativePath . startsWith ( 'knowledge/' ) &&
pageDa ta. relativePath !== 'knowledge/index.md' &&
pageData . frontmatter . publishedAt
const url = ` ${ siteUrl } ${ relativePathToUrl ( pageData . relativePath ) } `
const title = pageData . title || siteName
const description = pageData . description || siteData . description || ''
const keywords = Array . isArray ( pageData . frontmatter . keywords )
? pageData . frontmatter . keywords . join ( ',' )
: defaultKeywords
const ogImage = pageData . frontmatter . coverImage || defaultOgImage
const tags : HeadConfig [ ] = [
[ 'link' , { rel : 'canonical' , href : url } ] ,
[ 'meta' , { name : 'robots' , content : isNotFound ? 'noindex, nofollow' : 'index, follow' } ] ,
[ 'meta' , { name : 'keywords' , content : keywords } ] ,
[ 'meta' , { property : 'og:title' , content : title } ] ,
[ 'meta' , { property : 'og:description' , content : description } ] ,
[ 'meta' , { property : 'og:url' , content : url } ] ,
[ 'meta' , { property : 'og:image' , content : ogImage } ] ,
[ 'meta' , { property : 'og:type' , content : isArticle ? 'article' : 'website' } ] ,
[ 'meta' , { name : 'twitter:title' , content : title } ] ,
[ 'meta' , { name : 'twitter:description' , content : description } ] ,
[ 'meta' , { name : 'twitter:image' , content : ogImage } ] ,
]
const organizationLd = {
'@context' : 'https://schema.org' ,
'@type' : 'Organization' ,
'@id' : ` ${ siteUrl } /#organization ` ,
name : siteName ,
url : siteUrl ,
logo : ` ${ siteUrl } /logo.png ` ,
image : defaultOgImage ,
description :
'恭学教育集团是天津专升本培训领军品牌,专注天津专升本培训、刷题系统、在线网校、权威教材和升学规划服务。' ,
sameAs : [ ] ,
}
return [ ]
const ldScripts : HeadConfig [ ] = [
[ 'script' , { type : 'application/ld+json' } , JSON . stringify ( organizationLd ) ] ,
]
if ( isArticle ) {
const fm = pageData . frontmatter
const articleLd = {
'@context' : 'https://schema.org' ,
'@type' : 'Article' ,
headline : title ,
description ,
url ,
image : ogImage ,
author : {
'@type' : fm . author ? 'Person' : 'Organization' ,
name : fm.author || siteName ,
} ,
publisher : {
'@id' : ` ${ siteUrl } /#organization ` ,
} ,
datePublished : fm.publishedAt ,
dateModified : fm.publishedAt ,
keywords : Array.isArray ( fm . tags ) ? fm . tags . join ( ',' ) : keywords ,
mainEntityOfPage : {
'@type' : 'WebPage' ,
'@id' : url ,
} ,
}
ldScripts . push ( [ 'script' , { type : 'application/ld+json' } , JSON . stringify ( articleLd ) ] )
} else {
const webPageLd = {
'@context' : 'https://schema.org' ,
'@type' : 'WebPage' ,
name : title ,
description ,
url ,
isPartOf : {
'@id' : ` ${ siteUrl } /#organization ` ,
} ,
}
ldScripts . push ( [ 'script' , { type : 'application/ld+json' } , JSON . stringify ( webPageLd ) ] )
}
return [ . . . tags , . . . ldScripts ]
} ,
buildEnd ( siteConfig : SiteConfig ) {
const pages = siteConfig . pages . filter ( ( p ) = > p !== '404.md' )
const urls = pages
. map ( ( p ) = > ( {
loc : ` ${ siteUrl } ${ relativePathToUrl ( p ) } ` ,
lastmod : getPageLastmod ( p ) ,
changefreq : p === 'index.md' ? 'daily' : 'weekly' ,
priority : p === 'index.md' ? '1.0' : '0.8' ,
} ) )
. sort ( ( a , b ) = > a . loc . localeCompare ( b . loc ) )
const sitemap = ` <?xml version="1.0" encoding="UTF-8"?> \ n<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> \ n ${ urls
. map (
( u ) = >
` <url> \ n <loc> ${ u . loc } </loc> \ n ${ u . lastmod ? ` <lastmod> ${ u . lastmod } </lastmod> \ n ` : '' } <changefreq> ${ u . changefreq } </changefreq> \ n <priority> ${ u . priority } </priority> \ n </url> ` ,
)
. join ( '\n' ) } \ n</urlset> \ n `
fs . mkdirSync ( siteConfig . outDir , { recursive : true } )
fs . writeFileSync ( path . join ( siteConfig . outDir , 'sitemap.xml' ) , sitemap )
const robots = ` User-agent: * \ nAllow: / \ nDisallow: /404 \ n \ nSitemap: ${ siteUrl } /sitemap.xml \ n `
fs . writeFileSync ( path . join ( siteConfig . outDir , 'robots.txt' ) , robots )
} ,
} )