Compare commits
2
Commits
090af8aa68
...
a3400f401c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a3400f401c | ||
|
|
aebff49be9 |
+1
-2
@@ -11,9 +11,8 @@ export default defineContentConfig({
|
|||||||
schema: z.object({
|
schema: z.object({
|
||||||
date: z.date(),
|
date: z.date(),
|
||||||
img: z.string(),
|
img: z.string(),
|
||||||
sub: z.string(),
|
|
||||||
tags: z.array(z.string()),
|
tags: z.array(z.string()),
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|||||||
@@ -2,9 +2,12 @@
|
|||||||
title: "My First Blog Post"
|
title: "My First Blog Post"
|
||||||
description: "This is a test article."
|
description: "This is a test article."
|
||||||
navigation: true
|
navigation: true
|
||||||
sub: "C++20, GLSL, Lua"
|
|
||||||
img: "/img/personal-website/login.png"
|
|
||||||
date: "2025-03-01"
|
date: "2025-03-01"
|
||||||
|
img: "/img/personal-website/login.png"
|
||||||
|
tags:
|
||||||
|
- C++20
|
||||||
|
- GLSL
|
||||||
|
- Lua
|
||||||
---
|
---
|
||||||
|
|
||||||
Foobarbazbuz.
|
Foobarbazbuz.
|
||||||
|
|||||||
@@ -2,9 +2,12 @@
|
|||||||
title: "Personal Website"
|
title: "Personal Website"
|
||||||
description: "An open-source content management system, used for this website."
|
description: "An open-source content management system, used for this website."
|
||||||
navigation: false
|
navigation: false
|
||||||
sub: "PHP 7, MySQL, jQuery"
|
|
||||||
img: "/img/personal-website/admin-menu.png"
|
|
||||||
date: "2025-03-03"
|
date: "2025-03-03"
|
||||||
|
img: "/img/personal-website/admin-menu.png"
|
||||||
|
tags:
|
||||||
|
- PHP 7
|
||||||
|
- MySQL
|
||||||
|
- jQuery
|
||||||
---
|
---
|
||||||
|
|
||||||
<small>Open-source content management system.<br>
|
<small>Open-source content management system.<br>
|
||||||
|
|||||||
@@ -2,9 +2,10 @@
|
|||||||
title: "My Second Blog Post"
|
title: "My Second Blog Post"
|
||||||
description: "This is another article."
|
description: "This is another article."
|
||||||
navigation: false
|
navigation: false
|
||||||
sub: "Bash"
|
|
||||||
img: "/img/personal-website/reset-password.png"
|
|
||||||
date: "2025-03-02"
|
date: "2025-03-02"
|
||||||
|
img: "/img/personal-website/reset-password.png"
|
||||||
|
tags:
|
||||||
|
- Bash
|
||||||
---
|
---
|
||||||
|
|
||||||
This is another article.
|
This is another article.
|
||||||
|
|||||||
@@ -8,8 +8,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { withTrailingSlash, withLeadingSlash, joinURL } from "ufo"
|
import { computed } from "#imports"
|
||||||
import { useRuntimeConfig, computed } from "#imports"
|
|
||||||
|
|
||||||
import ImageComponent from "#build/mdc-image-component.mjs"
|
import ImageComponent from "#build/mdc-image-component.mjs"
|
||||||
|
|
||||||
@@ -43,17 +42,11 @@ const props = defineProps({
|
|||||||
type: String,
|
type: String,
|
||||||
default: "lazy" // eager, lazy
|
default: "lazy" // eager, lazy
|
||||||
},
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
const refinedSrc = computed(() => {
|
const refinedSrc = computed(() => {
|
||||||
if (props.src?.startsWith("/") && !props.src.startsWith("//")) {
|
return getPublicPath(props.src);
|
||||||
const _base = withLeadingSlash(withTrailingSlash(useRuntimeConfig().app.baseURL))
|
});
|
||||||
if (_base !== "/" && !props.src.startsWith(_base)) {
|
|
||||||
return joinURL(_base, props.src)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return props.src
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
<ArticlesTableOfContents v-if="article.navigation" :toc="article.body.toc" />
|
<ArticlesTableOfContents v-if="article.navigation" :toc="article.body.toc" />
|
||||||
|
|
||||||
<h1>{{ article.title }}</h1>
|
<h1>{{ article.title }}</h1>
|
||||||
|
<p><i><small>{{ prettyDate(article.date) }}</small></i></p>
|
||||||
<ContentRenderer :value="article" />
|
<ContentRenderer :value="article" />
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
|
|||||||
@@ -5,15 +5,18 @@
|
|||||||
<div class="row pt-5" v-for="article in articles" :key="article.path">
|
<div class="row pt-5" v-for="article in articles" :key="article.path">
|
||||||
<div class="col-5 col-lg-4 col-xl-3">
|
<div class="col-5 col-lg-4 col-xl-3">
|
||||||
<NuxtLink v-if="article.img" :to="article.path">
|
<NuxtLink v-if="article.img" :to="article.path">
|
||||||
<img class="img-fluid" :src="article.img as string" :alt="article.title" loading="lazy" :title="article.title">
|
<img class="img-fluid" :src="getPublicPath(article.img)" :alt="article.title" loading="lazy" :title="article.title">
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-7 col-lg-8 col-xl-9">
|
<div class="col-7 col-lg-8 col-xl-9">
|
||||||
<NuxtLink v-if="article.img" :to="article.path">
|
<NuxtLink v-if="article.img" :to="article.path">
|
||||||
<h4><strong>{{ article.title }}</strong></h4>
|
<h4 class="mb-0"><strong>{{ article.title }}</strong></h4>
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
{{ article.description }}<br>
|
<p><i><small>{{ prettyDate(article.date) }}</small></i></p>
|
||||||
<i><small>{{ article.sub }}</small></i>
|
<p>{{ article.description }}</p>
|
||||||
|
<template v-if="article.tags">
|
||||||
|
<p>Tags: <code>{{ article.tags.join(", ") }}</code></p>
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -38,10 +41,14 @@ a h4 {
|
|||||||
a h4:hover {
|
a h4:hover {
|
||||||
color: var(--bs-link-hover-color);
|
color: var(--bs-link-hover-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
color: var(--bs-link-color);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useAsyncData, queryCollection } from "#imports";
|
import { useAsyncData, queryCollection } from "#imports"
|
||||||
|
|
||||||
const { data: articles } = await useAsyncData("articles", () => queryCollection("content").order("date", "DESC").all())
|
const { data: articles } = await useAsyncData("articles", () => queryCollection("content").order("date", "DESC").all());
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1 +1,38 @@
|
|||||||
|
import { withTrailingSlash, withLeadingSlash, joinURL } from "ufo"
|
||||||
|
import { useRuntimeConfig } from "#imports"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns if environment is in development mode
|
||||||
|
*/
|
||||||
export const isDev = process.env.NODE_ENV === "development";
|
export const isDev = process.env.NODE_ENV === "development";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets URL path, taking into acount the baseURL
|
||||||
|
*/
|
||||||
|
export const getPublicPath = function (path: string): string {
|
||||||
|
if (path?.startsWith("/") && !path.startsWith("//")) {
|
||||||
|
const _base = withLeadingSlash(withTrailingSlash(useRuntimeConfig().app.baseURL));
|
||||||
|
if (_base !== "/" && !path.startsWith(_base)) {
|
||||||
|
return joinURL(_base, path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return date string in format "Feb 10, 2025"
|
||||||
|
*/
|
||||||
|
export const prettyDate = function (date: string | Date): string {
|
||||||
|
if (typeof date === "string") {
|
||||||
|
date = new Date(date);
|
||||||
|
}
|
||||||
|
|
||||||
|
const formatted = new Intl.DateTimeFormat("en-US", {
|
||||||
|
month: "short",
|
||||||
|
day: "numeric",
|
||||||
|
year: "numeric"
|
||||||
|
}).format(date);
|
||||||
|
|
||||||
|
return formatted;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user