diff --git a/GET_FEATURED.md b/GET_FEATURED.md index 165f087..95da638 100644 --- a/GET_FEATURED.md +++ b/GET_FEATURED.md @@ -10,3 +10,29 @@ Looking to get yourself up there along with others? It's easy! - Open a "Get Featured" issue via https://github.com/fossunited/forklore/issues/new/choose - Add your information and responses to the questions in the issue template + +## Submit a blog post + +You can submit a blog post by creating a pull request that adds a Markdown file to the `content/blog/` directory. + +### Steps: + +1. Create markdown file: + +```sh +touch content/blog/.md +``` + +2. Add front-matter metadata to top of the file: + +```markdown +--- +title: TITLE +author: username # (if in maintainers list) or simple name to represent +date: 2025-10-17 # ISO format: YYYY-MM-DD +description: A short summary of your post that appears in previews. +tags: ["blog", "example", "topic"] # keep it short +--- +``` + +That's it, you can do `yarn run dev` to see the live changes in localhost:3000 or do a PR and let us take care! diff --git a/assets/css/main.css b/assets/css/main.css index a292206..61e3d29 100644 --- a/assets/css/main.css +++ b/assets/css/main.css @@ -1,4 +1,5 @@ @import "tailwindcss"; +@plugin "@tailwindcss/typography"; @custom-variant dark (&:where(.dark-mode, .dark-mode *)); @@ -35,6 +36,8 @@ --color-secondary-light: #18222a; --color-tertiary-dark: #3c4b4e; --color-tertiary-light: #eef0f1; + --color-quaternary-dark: #495B5F; + --color-quaternary-light: #DDE1E3; } html { @@ -108,6 +111,31 @@ html { .sans-text a { text-decoration: underline; } + + .tag-card { + @apply text-sm px-2 py-1; + background-color: var(--color-quaternary-light); + color: var(--color-secondary-light); + } + + .dark-mode .tag-card { + background-color: var(--color-quaternary-dark); + color: var(--color-secondary-dark); + } + + .prose h1 { + font-size: 1.6rem; + } + + .prose h1 > a, + .prose h2 > a, + .prose h3 > a, + .prose h4 > a, + .prose h5 > a, + .prose h6 > a { + text-decoration: none !important; + } + } @layer base { diff --git a/components/AuthorLink.vue b/components/AuthorLink.vue new file mode 100644 index 0000000..0d005aa --- /dev/null +++ b/components/AuthorLink.vue @@ -0,0 +1,44 @@ + + + diff --git a/components/HeaderLinks.vue b/components/HeaderLinks.vue index 4522234..62fe882 100644 --- a/components/HeaderLinks.vue +++ b/components/HeaderLinks.vue @@ -9,7 +9,11 @@ const navbarItems = [ href: "https://fossunited.org/grants", }, { - label: "Discussion Forum", + label: "Blog", + href: "/blog", + }, + { + label: "Forum", href: "https://forum.fossunited.org/c/maintainers/", }, ]; diff --git a/components/ProjectCard.vue b/components/ProjectCard.vue index dbfa744..3b45d86 100644 --- a/components/ProjectCard.vue +++ b/components/ProjectCard.vue @@ -19,7 +19,7 @@ defineProps(["project"]); -

+

{{ project.short_description }}

diff --git a/content.config.ts b/content.config.ts index 9602570..d0172a7 100644 --- a/content.config.ts +++ b/content.config.ts @@ -1,4 +1,5 @@ -import { defineCollection, defineContentConfig, z } from "@nuxt/content"; +import { defineCollection, defineContentConfig, property } from "@nuxt/content"; +import { z } from 'zod' const maintainerSchema = z.object({ username: z.string(), @@ -37,5 +38,21 @@ export default defineContentConfig({ source: "maintainers/**.json", schema: maintainerSchema, }), + blog: defineCollection({ + type: 'page', + source: 'blog/*.md', + schema: z.object({ + title: z.string(), + author: z.string(), + description: z.optional(z.string()), + date: z.date(), + draft: z.optional(z.boolean()), + tags: z.optional(z.array(z.string())), + hero: z.object({ + image: property(z.string()).editor({ input: 'media' }), + caption: z.optional(z.string()) + }) + }) + }) }, }); diff --git a/content/sample-blog.md b/content/sample-blog.md new file mode 100644 index 0000000..7cf911c --- /dev/null +++ b/content/sample-blog.md @@ -0,0 +1,80 @@ +--- +title: TITLE +author: username (if in maintainers list or simply name) +date: 2025-10-17 (ISO format YYYY-MM-DD) +description: Content appears as small description. +tags: ["blog", "hello"] +--- + +NOTE: Please start writing heading from level-2 (##) + +## Heading One + +Welcome to the **prose formatting demo**. This blog post covers most of the Markdown formatting styles you'll use. + +## Heading Two + +Lorem ipsum dolor sit amet, *consectetur* adipiscing elit. `Inline code` looks like this. + +Here’s a simple [link to Nuxt](https://nuxt.com). + +### Heading Three (`h3`) + +> This is a blockquote. +> It supports multiple lines and renders with indentation. + +#### Heading Four + +- Unordered list item 1 +- Unordered list item 2 + - Nested item + - Another nested item +- Final unordered item + +1. Ordered list item one +2. Ordered list item two +3. Ordered list item three + +--- + +## πŸ“Έ Images + +![forklore logo](../public/logo/logo.svg) + +--- + +## 🧠 Code Blocks + +### JavaScript Example + +```js +export default defineNuxtConfig({ + modules: ['@nuxt/content'], +}) +``` + + +### Html + +```html +
+

Hello world

+
+``` + +## Table + +| Key | Type | Description | +| --- | --------- | ----------- | +| 1 | Wonderful | Table | +| 2 | Wonderful | Data | +| 3 | Wonderful | Website | + + +| Feature | Supported | Notes | +|----------------|-----------|----------------------------| +| Headings | βœ… | `#`, `##`, `###`, etc. | +| Lists | βœ… | Ordered + unordered | +| Code blocks | βœ… | Syntax highlighting works | +| Blockquotes | βœ… | Fully styled | +| Tables | βœ… | Supported by Markdown | diff --git a/cspell.json b/cspell.json index de6a3ba..9da664e 100644 --- a/cspell.json +++ b/cspell.json @@ -26,6 +26,7 @@ "**/*.svg", "package.json", "content/sample.json", + "content/sample-blog.md", "**/*.ts" ] } diff --git a/nuxt.config.ts b/nuxt.config.ts index 769d339..babf5a8 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -7,14 +7,26 @@ export default defineNuxtConfig({ modules: ["@nuxt/content", "@nuxtjs/color-mode"], css: ["/assets/css/main.css"], vite: { - plugins: [tailwindcss()], + plugins: [tailwindcss(), require("@tailwindcss/typography")], }, colorMode: { - storage: 'cookie', + storage: "cookie", + }, + content: { + build: { + markdown: { + toc: { + depth: 2, + }, + highlight: { + theme: 'one-dark-pro', + }, + }, + }, }, app: { head: { - viewport: 'width=device-width, initial-scale=1', + viewport: "width=device-width, initial-scale=1", htmlAttrs: { lang: "en", @@ -31,10 +43,15 @@ export default defineNuxtConfig({ }, }, compatibilityDate: "2025-05-15", + routeRules: { + "/maintainers": { + redirect: "/", + }, + }, nitro: { - prerender: { + prerender: { crawlLinks: true, - routes: ['/rss'] - } - } + routes: ["/rss"], + }, + }, }); diff --git a/package.json b/package.json index f30c657..e2b2ecf 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "@nuxt/content": "^3.7.1", "@nuxtjs/color-mode": "3.5.2", "@tailwindcss/vite": "^4.1.15", + "@tailwindcss/typography": "^0.5.19", "better-sqlite3": "^12.4.1", "feed": "^5.1.0", "minisearch": "^7.2.0", diff --git a/pages/blog/[slug].vue b/pages/blog/[slug].vue new file mode 100644 index 0000000..e83842d --- /dev/null +++ b/pages/blog/[slug].vue @@ -0,0 +1,75 @@ + + + diff --git a/pages/blog/index.vue b/pages/blog/index.vue new file mode 100644 index 0000000..5710e21 --- /dev/null +++ b/pages/blog/index.vue @@ -0,0 +1,67 @@ + + +