Skip to content

Commit e52be91

Browse files
init
0 parents  commit e52be91

56 files changed

Lines changed: 13408 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.editorconfig

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
root=true
2+
3+
[*]
4+
charset = utf-8
5+
indent_style = space
6+
indent_size = 2
7+
end_of_line = lf
8+
insert_final_newline = true
9+
trim_trailing_whitespace = true
10+
11+
[*.md]
12+
trim_trailing_whitespace = false

.gitattributes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* text=auto eol=lf

.github/.gitkeep

Whitespace-only changes.

.github/workflows/deploy.yaml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
name: Multividas Engineering blog
2+
3+
on:
4+
push:
5+
branches: ['main']
6+
pull_request:
7+
branches: ['main']
8+
9+
workflow_dispatch:
10+
11+
jobs:
12+
build:
13+
runs-on: ubuntu-latest
14+
15+
steps:
16+
- name: Checkout code
17+
uses: actions/checkout@v2
18+
19+
- name: Install Node.js
20+
uses: actions/setup-node@v2
21+
with:
22+
node-version: '22'
23+
24+
- name: Install dependencies
25+
run: npm install
26+
27+
- name: Build static
28+
run: |
29+
npm run build
30+
touch .vitepress/dist/.nojekyll
31+
touch .vitepress/dist/favicon.ico

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
node_modules
2+
dist
3+
.vitepress/cache
4+
sitemap.xml
5+
data.json

.nvmrc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
22
2+
engine-strict=true

.prettierrc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
semi: false
2+
singleQuote: true
3+
printWidth: 80
4+
trailingComma: none

.vitepress/config.ts

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import { defineConfig } from 'vitepress'
2+
import { genFeed } from './genFeed.js'
3+
4+
export default defineConfig({
5+
lang: 'en-US',
6+
title: 'Multividas Engineering blog',
7+
description:
8+
'Creative engineers and developers building a world where you can belong anywhere, Multividas Engineering blog is a technical news resource for engineers interested in how we solve large-scale technical challenges at Multividas.',
9+
lastUpdated: true,
10+
cleanUrls: true,
11+
head: [
12+
['meta', { name: 'theme-color', content: '#0f4c81' }],
13+
// open graph SEO tips
14+
['meta', { property: 'og:locale', content: 'en_US' }],
15+
['meta', { property: 'og:type', content: 'Multividas Engineering blog' }],
16+
['meta', { property: 'og:title', content: 'Multividas Engineering blog' }],
17+
[
18+
'meta',
19+
{
20+
property: 'og:description',
21+
content:
22+
'With engineering.multividas.com, you can write and publish technical articles.'
23+
}
24+
],
25+
[
26+
'meta',
27+
{
28+
property: 'og:image',
29+
content:
30+
'logo-multividas-blogging-platform-multividas-social-media-blog-multividas-posts-threads-multividas-comments-discussions-multividas-short-texts-multividas-social-blogging.svg'
31+
}
32+
],
33+
['meta', { property: 'og:url', content: 'engineering.multividas.com' }],
34+
[
35+
'meta',
36+
{ property: 'og:site_name', content: 'Multividas Engineering blog' }
37+
],
38+
// multividas tags
39+
['meta', { property: 'multividas:card', description: 'summary' }],
40+
['meta', { property: 'multividas:site', description: 'multividaseng' }],
41+
[
42+
'meta',
43+
{
44+
property: 'multividas:title',
45+
description: 'Multividas Engineering blog'
46+
}
47+
],
48+
[
49+
'meta',
50+
{
51+
property: 'multividas:description',
52+
description:
53+
'With engineering.multividas.com, you can write and publish technical articles.'
54+
}
55+
],
56+
[
57+
'meta',
58+
{
59+
property: 'multividas:image',
60+
description: 'https://avatars.githubusercontent.com/u/137715137?v=4'
61+
}
62+
],
63+
// usefathom
64+
[
65+
'script',
66+
{
67+
src: 'https://cdn.usefathom.com/script.js',
68+
'data-site': 'NYHGSGQV',
69+
'data-spa': 'auto',
70+
defer: ''
71+
}
72+
],
73+
// favicon
74+
[
75+
'link',
76+
{
77+
rel: 'icon',
78+
type: 'image/svg+xml',
79+
src: 'https://developers.multividas.com/images/logo.svg'
80+
}
81+
]
82+
],
83+
sitemap: {
84+
hostname: 'https://engineering.multividas.com'
85+
},
86+
buildEnd: genFeed
87+
})

.vitepress/genFeed.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import path from 'path'
2+
import { Feed } from 'feed'
3+
import fsExtra from 'fs-extra'
4+
import { createContentLoader, type SiteConfig } from 'vitepress'
5+
6+
const baseUrl = `https://engineering.multividas.com`
7+
8+
const { ensureDirSync, writeFileSync } = fsExtra
9+
10+
export async function genFeed(config: SiteConfig) {
11+
const feed = new Feed({
12+
title: 'Multividas Engineering blog',
13+
description: 'Creative engineers and developers building a world where you can belong anywhere, Multividas Engineering blog is a technical news resource for engineers interested in how we solve large-scale technical challenges at Multividas.',
14+
id: baseUrl,
15+
link: baseUrl,
16+
language: 'en',
17+
image: 'https://developers.multividas.com/images/logo.svg',
18+
favicon: `https://developers.multividas.com/images/logo.svg`,
19+
copyright: `Copyright © ${new Date().getFullYear()}-present Soulaimane Yahya`
20+
})
21+
22+
const posts = await createContentLoader('posts/*.md', {
23+
excerpt: true,
24+
render: true
25+
}).load()
26+
27+
posts.sort(
28+
(a, b) => +new Date(b.frontmatter.date as string) - +new Date(a.frontmatter.date as string)
29+
)
30+
31+
for (const { url, excerpt, frontmatter, html } of posts) {
32+
feed.addItem({
33+
title: frontmatter.title,
34+
id: `${baseUrl}${url}`,
35+
link: `${baseUrl}${url}`,
36+
description: excerpt,
37+
content: html?.replaceAll('​', ''),
38+
author: [
39+
{
40+
name: frontmatter.author,
41+
link: frontmatter.twitter ? `https://twitter.com/${frontmatter.twitter}` : undefined
42+
}
43+
],
44+
date: new Date(frontmatter.date),
45+
image: frontmatter.image
46+
})
47+
}
48+
49+
ensureDirSync(config.outDir!)
50+
writeFileSync(path.join(config.outDir!, 'feed.rss'), feed.rss2())
51+
writeFileSync(path.join(config.outDir!, 'feed.json'), feed.json1())
52+
writeFileSync(path.join(config.outDir!, 'feed.atom'), feed.atom1())
53+
}

.vitepress/theme/Article.vue

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<script setup lang="ts">
2+
import Date from './Date.vue'
3+
import Author from './Author.vue'
4+
import Thumbnail from './Thumbnail.vue'
5+
import { computed } from 'vue'
6+
import { useData, useRoute } from 'vitepress'
7+
import { data as posts } from './posts.data.js'
8+
9+
const { frontmatter: data } = useData()
10+
11+
const route = useRoute()
12+
13+
function findCurrentIndex() {
14+
return posts.findIndex((p) => p.url === route.path)
15+
}
16+
17+
// use the customData date which contains pre-resolved date info
18+
const date = computed(() => posts[findCurrentIndex()].date)
19+
const nextPost = computed(() => posts[findCurrentIndex() - 1])
20+
const prevPost = computed(() => posts[findCurrentIndex() + 1])
21+
</script>
22+
23+
<template>
24+
<article class="xl:divide-y xl:divide-gray-200 dark:xl:divide-slate-200/5">
25+
<header class="pt-6 xl:pb-10 space-y-1 text-center">
26+
<Date :date="date" />
27+
<h1
28+
class="text-3xl leading-9 font-extrabold text-gray-900 dark:text-white tracking-tight sm:text-4xl sm:leading-10 md:text-5xl md:leading-14">
29+
{{ data.title }}
30+
</h1>
31+
</header>
32+
33+
<div
34+
class="divide-y xl:divide-y-0 divide-gray-200 dark:divide-slate-200/5 xl:grid xl:grid-cols-4 xl:gap-x-10 pb-16 xl:pb-20"
35+
style="grid-template-rows: auto 1fr">
36+
<Author />
37+
<div class="divide-y divide-gray-200 dark:divide-slate-200/5 xl:pb-0 xl:col-span-3 xl:row-span-2">
38+
<div class="post-thumbnail" v-if="data.image">
39+
<Thumbnail :src="data.image" />
40+
</div>
41+
42+
<Content class="prose dark:prose-invert max-w-none pt-6 pb-8" />
43+
</div>
44+
45+
<footer
46+
class="text-sm font-medium leading-5 divide-y divide-gray-200 dark:divide-slate-200/5 xl:col-start-1 xl:row-start-2">
47+
<div v-if="nextPost" class="py-8">
48+
<h2 class="text-xs tracking-wide uppercase text-gray-500 dark:text-white">
49+
Next Article
50+
</h2>
51+
<div class="link">
52+
<a :href="nextPost.url">{{ nextPost.title }}</a>
53+
</div>
54+
</div>
55+
<div v-if="prevPost" class="py-8">
56+
<h2 class="text-xs tracking-wide uppercase text-gray-500 dark:text-white">
57+
Previous Article
58+
</h2>
59+
<div class="link">
60+
<a :href="prevPost.url">{{ prevPost.title }}</a>
61+
</div>
62+
</div>
63+
<div class="pt-8">
64+
<a class="link" href="/">← Back to the blog</a>
65+
</div>
66+
</footer>
67+
</div>
68+
</article>
69+
</template>

0 commit comments

Comments
 (0)