Browse Source

Order articles by date DESC

master
Riyyi 2 weeks ago
parent
commit
551478d15a
  1. 20
      content.config.ts
  2. 3
      content/articles/first.md
  3. 27
      content/articles/personal-website.md
  4. 4
      content/articles/second.md
  5. 4
      src/assets/css/style.css
  6. 7
      src/pages/articles/[slug].vue
  7. 45
      src/pages/articles/index.vue
  8. 1
      src/utils/index.ts

20
content.config.ts

@ -1,13 +1,19 @@
import { defineContentConfig, defineCollection } from '@nuxt/content'
import { defineContentConfig, defineCollection, z } from '@nuxt/content'
// Lookup resolved from path: rootDir/content
// see: https://github.com/nuxt/content/issues/3161
export default defineContentConfig({
collections: {
content: defineCollection({
type: "page",
source: "**/*.md"
})
}
collections: {
content: defineCollection({
type: "page",
source: "**/*.md",
schema: z.object({
date: z.date(),
img: z.string(),
sub: z.string(),
tags: z.array(z.string()),
})
})
}
})

3
content/articles/first.md

@ -2,6 +2,9 @@
title: "My First Blog Post"
description: "This is a test article."
navigation: true
sub: "C++20, GLSL, Lua"
img: "/img/personal-website/login.png"
date: "2025-03-01"
---
Foobarbazbuz.

27
content/articles/personal-website.md

@ -1,7 +1,10 @@
---
title: "Personal Website"
description: "Open-source content management system."
description: "An open-source content management system, used for this website."
navigation: false
sub: "PHP 7, MySQL, jQuery"
img: "/img/personal-website/admin-menu.png"
date: "2025-03-03"
---
<small>Open-source content management system.<br>
@ -25,18 +28,18 @@ Features:
- CMS with CRUD functions for managing data
- ORM for mapping between PHP classes and data
- Login system
- Stay logged in using cookies
- Forget password with a generated link send using mail
- Stay logged in using cookies
- Forget password with a generated link send using mail
- Security mitigations
- Password hashing using BCrypt
- Per-user cryptographically secure generated salt
- SQL injection protection using prepared statements
- XSS
- Cookies set to 'HttpOnly'
- Escape rendered user input using: `htmlentities(ENT_QUOTES | ENT_HTML5, 'UTF-8');`
- CSRF
- Cookies 'SameSite' set to 'Strict'
- Token for each session used in POST/PUT/DELETE requests
- Password hashing using BCrypt
- Per-user cryptographically secure generated salt
- SQL injection protection using prepared statements
- XSS
- Cookies set to 'HttpOnly'
- Escape rendered user input using: `htmlentities(ENT_QUOTES | ENT_HTML5, 'UTF-8');`
- CSRF
- Cookies 'SameSite' set to 'Strict'
- Token for each session used in POST/PUT/DELETE requests
- Bootstrap
- jQuery

4
content/articles/second.md

@ -1,6 +1,10 @@
---
title: "My Second Blog Post"
description: "This is another article."
navigation: false
sub: "Bash"
img: "/img/personal-website/reset-password.png"
date: "2025-03-02"
---
This is another article.

4
src/assets/css/style.css

@ -26,7 +26,3 @@ body {
/* Main content */
/*----------------------------------------*/
a:hover {
color: var(--bs-link-color) !important;
}

7
src/pages/articles/[slug].vue

@ -29,11 +29,11 @@
/* Select any <a> inside a <h> */
:deep(:is(h1, h2, h3, h4, h5, h6) a) {
color: inherit;
color: var(--bs-body-color);
text-decoration: none;
}
/* Select <pre class="shiki"> */
/* Select <pre class="language-"> */
:deep(pre[class^="language-"]) {
display: flex;
justify-content: space-between;
@ -54,8 +54,7 @@
/* Select <code> */
:deep(code:not([class^="language-"]):not(pre code)) {
/* reset font to black */
color: inherit;
color: var(--bs-body-color);
}
</style>

45
src/pages/articles/index.vue

@ -1,18 +1,47 @@
<template>
<div>
<h1>Articles</h1>
<ul>
<li v-for="article in articles" :key="article.path">
<NuxtLink :to="article.path">{{ article.title }}</NuxtLink>
</li>
</ul>
<div v-for="article in articles" :key="article.path">
<pre>{{ article }}</pre>
<div class="row pt-5" v-for="article in articles" :key="article.path">
<div class="col-5 col-lg-4 col-xl-3">
<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">
</NuxtLink>
</div>
<div class="col-7 col-lg-8 col-xl-9">
<NuxtLink v-if="article.img" :to="article.path">
<h4><strong>{{ article.title }}</strong></h4>
</NuxtLink>
{{ article.description }}<br>
<i><small>{{ article.sub }}</small></i>
</div>
</div>
<template v-if="isDev">
<br>
<div v-for="article in articles" :key="article.path">
<pre>{{ article }}</pre>
</div>
</template>
</div>
</template>
<style scoped>
a {
text-decoration: none !important;
}
a h4 {
color: var(--bs-body-color);
}
a h4:hover {
color: var(--bs-link-hover-color);
}
</style>
<script setup lang="ts">
const { data: articles } = await useAsyncData("articles", () => queryCollection("content").all())
import { useAsyncData, queryCollection } from "#imports";
const { data: articles } = await useAsyncData("articles", () => queryCollection("content").order("date", "DESC").all())
</script>

1
src/utils/index.ts

@ -0,0 +1 @@
export const isDev = process.env.NODE_ENV === "development";
Loading…
Cancel
Save