Skip to content

Commit f5d0379

Browse files
committed
Update to Vitepress
1 parent 1df9829 commit f5d0379

19 files changed

+2904
-82
lines changed
+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
name: Build and Deploy
2+
run-name: ${{ github.actor }} is building a GitHub Pages site
3+
4+
on:
5+
push:
6+
branches: [ "main" ]
7+
8+
workflow_dispatch:
9+
10+
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
11+
permissions:
12+
contents: read
13+
pages: write
14+
id-token: write
15+
16+
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
17+
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
18+
concurrency:
19+
group: "pages"
20+
cancel-in-progress: false
21+
22+
jobs:
23+
# Build job
24+
build:
25+
runs-on: ubuntu-latest
26+
27+
steps:
28+
- name: Checkout
29+
uses: actions/checkout@v4
30+
31+
- uses: actions/setup-node@v3
32+
with:
33+
node-version: "18"
34+
35+
- name: Setup Pages
36+
uses: actions/configure-pages@v3
37+
38+
- name: Install dependencies
39+
run: npm install
40+
41+
- name: Build site
42+
run: npm run build -- --outDir _site
43+
44+
- name: Upload artifact
45+
uses: actions/upload-pages-artifact@v2
46+
47+
# Deployment job
48+
deploy:
49+
environment:
50+
name: github-pages
51+
url: ${{ steps.deployment.outputs.page_url }}
52+
runs-on: ubuntu-latest
53+
needs: build
54+
steps:
55+
- name: Deploy to GitHub Pages
56+
id: deployment
57+
uses: actions/deploy-pages@v2

.gitignore

+8-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,8 @@
1-
.vscode
1+
2+
.DS_Store
3+
node_modules
4+
5+
.vitepress/cache
6+
7+
dist
8+
_site

.vitepress/config.ts

+109
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
import { defineConfig, createContentLoader } from 'vitepress';
2+
import path from 'node:path'
3+
import { writeFileSync } from 'node:fs'
4+
import { Feed } from 'feed'
5+
6+
import { formatPageContentForRSS } from './theme/utils';
7+
8+
const siteTitle = 'Neural Interfaces';
9+
const siteDescription = 'The Catalog of Brain-Responsive Applications';
10+
const blogDir = 'posts';
11+
12+
const hostName = 'https://neuralinterfaces.com';
13+
const author = [
14+
{
15+
name: 'Garrett Flynn',
16+
17+
link: `garrettflynn.com`
18+
}
19+
]
20+
21+
const siteCopyright = 'Copyright © 2024-present Garrett Flynn';
22+
23+
const formattedPagesForRSS: Record<string, string> = {};
24+
25+
// https://vitepress.dev/reference/site-config
26+
export default defineConfig({
27+
lang: 'en-US',
28+
title: siteTitle,
29+
description: siteDescription,
30+
31+
head: [['link', { rel: 'icon', href: '/favicon.ico' }]],
32+
33+
themeConfig: {
34+
35+
logo: '/logo_dark.png',
36+
37+
nav: [
38+
{ text: 'Home', link: '/' },
39+
{ text: 'Catalog', link: '/catalog' },
40+
{ text: 'Blog', link: '/posts' }
41+
],
42+
43+
socialLinks: [
44+
{ icon: 'github', link: 'https://github.com/neuralinterfaces' },
45+
],
46+
47+
footer: {
48+
message: 'Built with 🧠 by Garrett Flynn',
49+
copyright: siteCopyright
50+
}
51+
},
52+
53+
transformHtml(_code, _id, { content, pageData }) {
54+
const { filePath } = pageData;
55+
const dirname = path.dirname(filePath);
56+
const basename = path.basename(filePath, '.md');
57+
58+
if (dirname === blogDir) {
59+
const html = formatPageContentForRSS(content, hostName);
60+
if (html) {
61+
formattedPagesForRSS[`/${dirname}/${basename}`] = html;
62+
}
63+
}
64+
},
65+
66+
67+
buildEnd: async (config) => {
68+
69+
const feed = new Feed({
70+
title: siteTitle,
71+
description: siteDescription,
72+
id: hostName,
73+
link: hostName,
74+
copyright: siteCopyright,
75+
language: 'en',
76+
});
77+
78+
// Load data from all the blog markdown files, sorted by date
79+
const posts = await createContentLoader(`/${blogDir}/*.md`, {
80+
render: true,
81+
includeSrc: true,
82+
transform(rawData) {
83+
return rawData.sort((a, b) => {
84+
return +new Date(b.frontmatter.date).getTime() - +new Date(a.frontmatter.date).getTime()
85+
});
86+
}
87+
}).load();
88+
89+
for (const { url, excerpt, frontmatter, html } of posts) {
90+
91+
if (frontmatter.status === 'draft') continue;
92+
93+
const improvedHtml = formattedPagesForRSS[url];
94+
95+
feed.addItem({
96+
title: frontmatter.title,
97+
id: `${hostName}${url}`,
98+
link: `${hostName}${url}`,
99+
description: excerpt,
100+
content: improvedHtml || html,
101+
author,
102+
date: frontmatter.date
103+
});
104+
}
105+
106+
writeFileSync(path.join(config.outDir, 'feed.rss'), feed.rss2());
107+
}
108+
109+
})
+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<template>
2+
<header
3+
class="vp-doc"
4+
:data-image="frontmatter.image"
5+
v-bind:style="[frontmatter.image ? { 'background-image': 'linear-gradient(rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5)), url(' + frontmatter.image + ')' } : {} ]"
6+
>
7+
<h1 v-if="page.title">
8+
{{ page.title }}
9+
</h1>
10+
<h3 v-if="frontmatter.date">
11+
{{ formatDate( frontmatter.date ) }}
12+
</h3>
13+
</header>
14+
</template>
15+
16+
<script setup lang="ts">
17+
import { useData } from 'vitepress';
18+
import { formatDate } from '../utils';
19+
const { page, frontmatter } = useData();
20+
</script>
21+
22+
<style scoped>
23+
header {
24+
margin-bottom: 2rem;
25+
}
26+
27+
header[data-image] {
28+
color: white;
29+
padding: 5rem 2rem;
30+
background-size: cover;
31+
background-position: center;
32+
background-repeat: no-repeat;
33+
}
34+
35+
header h3 {
36+
font-weight: 300;
37+
margin-top: 0.25rem;
38+
color: lightgray;
39+
}
40+
41+
</style>

.vitepress/theme/index.ts

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// https://vitepress.dev/guide/custom-theme
2+
import { h } from 'vue'
3+
import type { Theme } from 'vitepress';
4+
import DefaultTheme from 'vitepress/theme';
5+
import PostLayout from './layouts/PostLayout.vue';
6+
import './style.css';
7+
8+
export default {
9+
extends: DefaultTheme,
10+
Layout: PostLayout,
11+
// Layout: () => {
12+
// return h(DefaultTheme.Layout, null, {
13+
// // https://vitepress.dev/guide/extending-default-theme#layout-slots
14+
// })
15+
// },
16+
enhanceApp({ app, router, siteData }) {
17+
// app.component( 'start', StartLayout );
18+
}
19+
} satisfies Theme
+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<script setup lang="ts">
2+
import DefaultTheme from 'vitepress/theme'
3+
import PostHeader from '../components/PostHeader.vue';
4+
const { Layout } = DefaultTheme
5+
</script>
6+
7+
<template>
8+
<Layout>
9+
<template #doc-before>
10+
<PostHeader />
11+
</template>
12+
13+
<template #layout-bottom>
14+
</template>
15+
</Layout>
16+
</template>
17+
18+
<style scoped>
19+
.Layout {
20+
min-height: 100dvh;
21+
}
22+
</style>

0 commit comments

Comments
 (0)