From 9ff40d1e9e1323f5f68b9330ae5c452b28d0b781 Mon Sep 17 00:00:00 2001 From: grassblock Date: Fri, 6 Jun 2025 21:27:11 +0800 Subject: [PATCH 1/4] feat: add Bootstrap callout shortcode --- src/components/shortcodes/Callout.astro | 43 +++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 src/components/shortcodes/Callout.astro diff --git a/src/components/shortcodes/Callout.astro b/src/components/shortcodes/Callout.astro new file mode 100644 index 0000000..51d1cc6 --- /dev/null +++ b/src/components/shortcodes/Callout.astro @@ -0,0 +1,43 @@ +--- +const { icon, type = 'info'} = Astro.props; +--- +
+ {icon && {icon}} +
+ +
+
+ \ No newline at end of file From 9ecf25f3abd108ef5a32f41e620e1c69faf7caa7 Mon Sep 17 00:00:00 2001 From: grassblock Date: Fri, 6 Jun 2025 22:50:36 +0800 Subject: [PATCH 2/4] feat: more modern way to use 'reference' to get authors --- src/components/helper/authors/Info.astro | 9 ++++----- src/content/posts/_schemas.ts | 4 ++-- src/pages/post/[...slug].astro | 9 +++++---- src/pages/rss.xml.js | 11 ++++++++++- 4 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/components/helper/authors/Info.astro b/src/components/helper/authors/Info.astro index 806a143..ed37cb0 100644 --- a/src/components/helper/authors/Info.astro +++ b/src/components/helper/authors/Info.astro @@ -3,14 +3,13 @@ import {Image} from "astro:assets"; import {getEntry} from "astro:content"; import {siteConfig} from "../../../config"; -const { id } = Astro.props; +const { data } = Astro.props; // Get author data -const authorData = await getEntry('authors', id || ''); -const authorAvatar = authorData?.data.mcplayerid ? `/images/avatars/${id}.png` : null; -const authorName = authorData ? authorData.data.name : null; +const authorAvatar = data?.data.mcplayerid ? `/images/avatars/${data.id}.png` : null; +const authorName = data ? data.data.name : null; --- -{(siteConfig.displayAvatar && authorData) && +{(siteConfig.displayAvatar && data) && <> {authorAvatar && {`avatar} {authorName} @ diff --git a/src/content/posts/_schemas.ts b/src/content/posts/_schemas.ts index 2a535ff..daf11e5 100644 --- a/src/content/posts/_schemas.ts +++ b/src/content/posts/_schemas.ts @@ -1,4 +1,4 @@ -import { z } from 'astro:content'; +import { z, reference } from 'astro:content'; export const posts = ({ image }) => z.object({ title: z.string(), @@ -8,5 +8,5 @@ export const posts = ({ image }) => z.object({ categories: z.array(z.string()).default(['uncategorized']), tags: z.array(z.string()).optional(), cover: image().optional(), - author: z.string().optional(), + author: reference('authors').optional(), }); \ No newline at end of file diff --git a/src/pages/post/[...slug].astro b/src/pages/post/[...slug].astro index 886f4b2..da2b02a 100644 --- a/src/pages/post/[...slug].astro +++ b/src/pages/post/[...slug].astro @@ -19,10 +19,10 @@ const { entry } = Astro.props; const { Content } = await entry.render(); const noscript = siteConfig.noClientJavaScript const slug = Astro.params.slug; -const authorId = entry.data.author || siteConfig.defaultAuthor.id; +const author = entry.data.author || {collection: 'authors', id: siteConfig.defaultAuthor.id}; // Get author data -const authorData = await getEntry('authors', authorId); +const authorData = await getEntry(author); const authorInfo = authorData ? authorData.data : siteConfig.defaultAuthor; // get featured image and use it as og:image @@ -46,7 +46,7 @@ const cover = customFeaturedImage || matchedImage_src?.src || firstImageURL || ` author={authorInfo.name} >

{entry.data.title}

- + {new Date(entry.data.pubDate).toISOString().split('T')[0]}
@@ -59,4 +59,5 @@ const cover = customFeaturedImage || matchedImage_src?.src || firstImageURL || ` {noscript &&

Comments

}
- \ No newline at end of file + + diff --git a/src/pages/rss.xml.js b/src/pages/rss.xml.js index c3ba18d..bdef740 100644 --- a/src/pages/rss.xml.js +++ b/src/pages/rss.xml.js @@ -52,7 +52,16 @@ export async function GET(context) { }, sanitize({ dropElements: ["script", "style"] }), ]); - feedItems.push({ ...post.data, link: `/post/${post.slug}/`, content }); + + // Make sure each feed item has required properties with proper formatting + feedItems.push({ + title: post.data.title, + description: post.data.description || '', + pubDate: post.data.pubDate, + link: `${baseUrl}/post/${post.slug}`, + content, + }); + } // Return our RSS feed XML response. From 145ef1f2b4d73eb89f0446029a5cce22ce176d9c Mon Sep 17 00:00:00 2001 From: grassblock Date: Fri, 6 Jun 2025 22:55:20 +0800 Subject: [PATCH 3/4] feat: add table of contents to posts (WIP) --- astro.config.mjs | 6 ++- package.json | 5 ++- pnpm-lock.yaml | 104 ++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 101 insertions(+), 14 deletions(-) diff --git a/astro.config.mjs b/astro.config.mjs index d6c791c..ea1607a 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -3,6 +3,7 @@ import { defineConfig } from 'astro/config'; import sitemap from '@astrojs/sitemap'; import mdx from '@astrojs/mdx'; +import remarkToc from 'remark-toc'; import cloudflare from '@astrojs/cloudflare'; @@ -19,7 +20,10 @@ export default defineConfig({ shikiConfig: { theme: 'nord', wrap: true - } + }, + remarkPlugins: [ + [remarkToc, { heading: 'Contents', maxDepth: 3 }] + ] }, integrations: [sitemap(), mdx()], diff --git a/package.json b/package.json index e72833f..c42ec2d 100644 --- a/package.json +++ b/package.json @@ -11,14 +11,15 @@ "astro": "astro" }, "dependencies": { - "@astrojs/cloudflare": "^12.5.2", + "@astrojs/cloudflare": "^12.5.4", "@astrojs/mdx": "^4.2.6", - "@astrojs/node": "^9.2.1", + "@astrojs/node": "^9.2.2", "@astrojs/rss": "^4.0.1", "@astrojs/sitemap": "^3.3.1", "@fontsource-variable/jetbrains-mono": "^5.2.5", "astro": "^5.2.5", "ico-endec": "^0.1.6", + "remark-toc": "^9.0.0", "sharp": "^0.34.1", "ultrahtml": "^1.6.0" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4e77c2e..69bc3ba 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,14 +9,14 @@ importers: .: dependencies: '@astrojs/cloudflare': - specifier: ^12.5.2 - version: 12.5.2(@types/node@22.15.3)(astro@5.7.10(@azure/identity@4.9.1)(@types/node@22.15.3)(rollup@4.40.1)(typescript@5.8.3)(yaml@2.7.1))(yaml@2.7.1) + specifier: ^12.5.4 + version: 12.5.4(@types/node@22.15.3)(astro@5.7.10(@azure/identity@4.9.1)(@types/node@22.15.3)(rollup@4.40.1)(typescript@5.8.3)(yaml@2.7.1))(yaml@2.7.1) '@astrojs/mdx': specifier: ^4.2.6 version: 4.2.6(astro@5.7.10(@azure/identity@4.9.1)(@types/node@22.15.3)(rollup@4.40.1)(typescript@5.8.3)(yaml@2.7.1)) '@astrojs/node': - specifier: ^9.2.1 - version: 9.2.1(astro@5.7.10(@azure/identity@4.9.1)(@types/node@22.15.3)(rollup@4.40.1)(typescript@5.8.3)(yaml@2.7.1)) + specifier: ^9.2.2 + version: 9.2.2(astro@5.7.10(@azure/identity@4.9.1)(@types/node@22.15.3)(rollup@4.40.1)(typescript@5.8.3)(yaml@2.7.1)) '@astrojs/rss': specifier: ^4.0.1 version: 4.0.11 @@ -32,6 +32,9 @@ importers: ico-endec: specifier: ^0.1.6 version: 0.1.6 + remark-toc: + specifier: ^9.0.0 + version: 9.0.0 sharp: specifier: ^0.34.1 version: 0.34.1 @@ -48,8 +51,8 @@ importers: packages: - '@astrojs/cloudflare@12.5.2': - resolution: {integrity: sha512-zhqBJmy0zXqpniWuAbpWY6CCNdkq3Olm2LMHv0lryvY6CUFcZbDzTK225zgz//r5zPj8ty1qbvWRnXgCaiaaYQ==} + '@astrojs/cloudflare@12.5.4': + resolution: {integrity: sha512-WKUeMP2tIbddEu0tlVEPj8o9m/8CJB6who3a3jupuIyR56ltmW924ZOMYtp/C9uxH7KeDJXrMszRj3LHs9U97w==} peerDependencies: astro: ^5.0.0 @@ -68,8 +71,8 @@ packages: peerDependencies: astro: ^5.0.0 - '@astrojs/node@9.2.1': - resolution: {integrity: sha512-kEHLB37ooW91p7FLGalqa3jVQRIafntfKiZgCnjN1lEYw+j8NP6VJHQbLHmzzbtKUI0J+srGiTnGZmaHErHE5w==} + '@astrojs/node@9.2.2': + resolution: {integrity: sha512-PtLPuuojmcl9O3CEvXqL/D+wB4x5DlbrGOvP0MeTAh/VfKFprYAzgw1+45xsnTO+QvPWb26l1cT+ZQvvohmvMw==} peerDependencies: astro: ^5.3.0 @@ -1022,6 +1025,9 @@ packages: '@types/tmp@0.0.33': resolution: {integrity: sha512-gVC1InwyVrO326wbBZw+AO3u2vRXz/iRWq9jYhpG4W8LXyIgDv3ZmcLQ5Q4Gs+gFMyqx+viFoFT+l3p61QFCmQ==} + '@types/ungap__structured-clone@1.2.0': + resolution: {integrity: sha512-ZoaihZNLeZSxESbk9PUAPZOlSpcKx81I1+4emtULDVmBLkYutTcMlCj2K9VNlf9EWODxdO6gkAqEaLorXwZQVA==} + '@types/unist@2.0.11': resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} @@ -2124,6 +2130,9 @@ packages: mdast-util-to-string@4.0.0: resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + mdast-util-toc@7.1.0: + resolution: {integrity: sha512-2TVKotOQzqdY7THOdn2gGzS9d1Sdd66bvxUyw3aNpWfcPXCLYSJCCgfPy30sEtuzkDraJgqF35dzgmz6xlvH/w==} + mdn-data@2.12.2: resolution: {integrity: sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==} @@ -2622,6 +2631,9 @@ packages: remark-stringify@11.0.0: resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} + remark-toc@9.0.0: + resolution: {integrity: sha512-KJ9txbo33GjDAV1baHFze7ij4G8c7SGYoY8Kzsm2gzFpbhL/bSoVpMMzGa3vrNDSWASNd/3ppAqL7cP2zD6JIA==} + require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} @@ -3108,6 +3120,46 @@ packages: yaml: optional: true + vite@6.3.5: + resolution: {integrity: sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 + jiti: '>=1.21.0' + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + vitefu@1.0.6: resolution: {integrity: sha512-+Rex1GlappUyNN6UfwbVZne/9cYC4+R2XDk9xkNXBKMw6HQagdX9PgZ8V2v1WUSK1wfBLp7qbI1+XSNIlB1xmA==} peerDependencies: @@ -3252,14 +3304,14 @@ packages: snapshots: - '@astrojs/cloudflare@12.5.2(@types/node@22.15.3)(astro@5.7.10(@azure/identity@4.9.1)(@types/node@22.15.3)(rollup@4.40.1)(typescript@5.8.3)(yaml@2.7.1))(yaml@2.7.1)': + '@astrojs/cloudflare@12.5.4(@types/node@22.15.3)(astro@5.7.10(@azure/identity@4.9.1)(@types/node@22.15.3)(rollup@4.40.1)(typescript@5.8.3)(yaml@2.7.1))(yaml@2.7.1)': dependencies: '@astrojs/internal-helpers': 0.6.1 '@astrojs/underscore-redirects': 0.6.1 '@cloudflare/workers-types': 4.20250510.0 astro: 5.7.10(@azure/identity@4.9.1)(@types/node@22.15.3)(rollup@4.40.1)(typescript@5.8.3)(yaml@2.7.1) tinyglobby: 0.2.13 - vite: 6.3.4(@types/node@22.15.3)(yaml@2.7.1) + vite: 6.3.5(@types/node@22.15.3)(yaml@2.7.1) wrangler: 4.14.4(@cloudflare/workers-types@4.20250510.0) transitivePeerDependencies: - '@types/node' @@ -3325,7 +3377,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@astrojs/node@9.2.1(astro@5.7.10(@azure/identity@4.9.1)(@types/node@22.15.3)(rollup@4.40.1)(typescript@5.8.3)(yaml@2.7.1))': + '@astrojs/node@9.2.2(astro@5.7.10(@azure/identity@4.9.1)(@types/node@22.15.3)(rollup@4.40.1)(typescript@5.8.3)(yaml@2.7.1))': dependencies: '@astrojs/internal-helpers': 0.6.1 astro: 5.7.10(@azure/identity@4.9.1)(@types/node@22.15.3)(rollup@4.40.1)(typescript@5.8.3)(yaml@2.7.1) @@ -4168,6 +4220,8 @@ snapshots: '@types/tmp@0.0.33': {} + '@types/ungap__structured-clone@1.2.0': {} + '@types/unist@2.0.11': {} '@types/unist@3.0.3': {} @@ -5566,6 +5620,16 @@ snapshots: dependencies: '@types/mdast': 4.0.4 + mdast-util-toc@7.1.0: + dependencies: + '@types/mdast': 4.0.4 + '@types/ungap__structured-clone': 1.2.0 + '@ungap/structured-clone': 1.3.0 + github-slugger: 2.0.0 + mdast-util-to-string: 4.0.0 + unist-util-is: 6.0.0 + unist-util-visit: 5.0.0 + mdn-data@2.12.2: {} merge-stream@2.0.0: {} @@ -6287,6 +6351,11 @@ snapshots: mdast-util-to-markdown: 2.1.2 unified: 11.0.5 + remark-toc@9.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-toc: 7.1.0 + require-directory@2.1.1: {} requires-port@1.0.0: {} @@ -6818,6 +6887,19 @@ snapshots: fsevents: 2.3.3 yaml: 2.7.1 + vite@6.3.5(@types/node@22.15.3)(yaml@2.7.1): + dependencies: + esbuild: 0.25.4 + fdir: 6.4.4(picomatch@4.0.2) + picomatch: 4.0.2 + postcss: 8.5.3 + rollup: 4.40.1 + tinyglobby: 0.2.13 + optionalDependencies: + '@types/node': 22.15.3 + fsevents: 2.3.3 + yaml: 2.7.1 + vitefu@1.0.6(vite@6.3.4(@types/node@22.15.3)(yaml@2.7.1)): optionalDependencies: vite: 6.3.4(@types/node@22.15.3)(yaml@2.7.1) From 29b1fa4afbdfb3ee6df294b8160af78c344b70c3 Mon Sep 17 00:00:00 2001 From: grassblock Date: Fri, 6 Jun 2025 22:55:47 +0800 Subject: [PATCH 4/4] chore(doc): add markdown syntax example page --- src/content/posts/markdown-example/index.mdx | 153 +++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 src/content/posts/markdown-example/index.mdx diff --git a/src/content/posts/markdown-example/index.mdx b/src/content/posts/markdown-example/index.mdx new file mode 100644 index 0000000..c2edeb9 --- /dev/null +++ b/src/content/posts/markdown-example/index.mdx @@ -0,0 +1,153 @@ +--- +title: "Markdown Syntax Example" +pubDate: '2023-07-15T12:00:00Z' +description: "Sample article showcasing basic Markdown syntax and formatting for HTML elements." +tags: ["markdown", "css", "html", "sample"] +--- +import Callout from '/src/components/shortcodes/Callout.astro'; + +This article offers a sample of basic and extended Markdown formatting that can be used, also it shows how some basic HTML elements are decorated. + +## Theme Specifics +This theme came with a set of shortcodes that can be used to enhance the Markdown experience. These shortcodes are located in the `/src/components/shortcodes` directory and can be used to add custom functionality or styling to your Markdown content. + +To use these shortcodes, you should first rename the file to a MDX (.mdx) file. Once renamed, you can use the shortcodes in your content like this: + +```mdx +import ExampleShortcode from '/src/components/shortcodes/ExampleShortcode.astro'; + +your content here... + +``` + +### Callouts +You can use callouts to highlight important information or warnings in your content. Callouts are styled boxes that draw attention to specific parts of the text. + + This is an informational callout. It can be used to provide additional context or tips. + + + This is a warning callout. Use it to alert users about potential issues or important notes. + + + This is an error callout. It should be used to indicate critical issues that need immediate attention. + + +```mdx + + This is an informational callout. It can be used to provide additional context or tips. + + + This is a warning callout. Use it to alert users about potential issues or important notes. + + + This is an error callout. It should be used to indicate critical issues that need immediate attention. + +``` + + +## Headings + +The following HTML `

`—`

` elements represent six levels of section headings. `

` is the highest section level while `

` is the lowest. + +# H1 + +## H2 + +### H3 + +#### H4 + +##### H5 + +###### H6 + +## Paragraph + +Xerum, quo qui aut unt expliquam qui dolut labo. Aque venitatiusda cum, voluptionse latur sitiae dolessi aut parist aut dollo enim qui voluptate ma dolestendit peritin re plis aut quas inctum laceat est volestemque commosa as cus endigna tectur, offic to cor sequas etum rerum idem sintibus eiur? Quianimin porecus evelectur, cum que nis nust voloribus ratem aut omnimi, sitatur? Quiatem. Nam, omnis sum am facea corem alique molestrunt et eos evelece arcillit ut aut eos eos nus, sin conecerem erum fuga. Ri oditatquam, ad quibus unda veliamenimin cusam et facea ipsamus es exerum sitate dolores editium rerore eost, temped molorro ratiae volorro te reribus dolorer sperchicium faceata tiustia prat. + +Itatur? Quiatae cullecum rem ent aut odis in re eossequodi nonsequ idebis ne sapicia is sinveli squiatum, core et que aut hariosam ex eat. + +## Blockquotes + +The blockquote element represents content that is quoted from another source, optionally with a citation which must be within a `footer` or `cite` element, and optionally with in-line changes such as annotations and abbreviations. + +### Blockquote without attribution + +> Tiam, ad mint andaepu dandae nostion secatur sequo quae. +> **Note** that you can use _Markdown syntax_ within a blockquote. + +### Blockquote with attribution + +> Don't communicate by sharing memory, share memory by communicating.
+> — Rob Pike[^1] + +[^1]: The above quote is excerpted from Rob Pike's [talk `about` nothing](https://www.youtube.com/watch?v=PAAkCSZUG1c) during Gopherfest, November 18, 2015. + +## Tables + +Tables aren't part of the core Markdown spec, but Hugo supports supports them out-of-the-box. + +| Name | Age | +| ----- | --- | +| Bob | 27 | +| Alice | 23 | + +### Inline Markdown within tables + +| Italics | Bold | Code | +| --------- | -------- | ------ | +| _italics_ | **bold** | `code` | + +## Code Blocks + +### Code block with backticks + +```html + + + + + Example HTML5 Document + + +

Test

+ + +``` + + +## List Types + +### Ordered List + +1. First item +2. Second item +3. Third item + +### Unordered List + +- List item +- Another item +- And another item + +### Nested list + +- Fruit + - Apple + - Orange + - Banana +- Dairy + - Milk + - Cheese + +## Other Elements — abbr, sub, sup, kbd, mark + +GIF is a bitmap image format. + +H2O + +Xn + Yn = Zn + +Press CTRL+ALT+Delete to end the session. + +Most salamanders are nocturnal, and hunt for insects, worms, and other small creatures. \ No newline at end of file