diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/content/blog/hello.md | 241 | ||||
| -rw-r--r-- | src/content/config.ts | 16 | ||||
| -rw-r--r-- | src/layouts/BlogPost.astro | 50 | ||||
| -rw-r--r-- | src/layouts/Default.astro | 17 | ||||
| -rw-r--r-- | src/layouts/PageMarkdown.astro | 8 | ||||
| -rw-r--r-- | src/pages/blog/[...slug].astro | 22 | ||||
| -rw-r--r-- | src/pages/blog/index.astro | 8 | ||||
| -rw-r--r-- | src/pages/rss.xml.js | 31 |
8 files changed, 386 insertions, 7 deletions
diff --git a/src/content/blog/hello.md b/src/content/blog/hello.md new file mode 100644 index 0000000..d24552d --- /dev/null +++ b/src/content/blog/hello.md @@ -0,0 +1,241 @@ +--- +title: Hello world +description: This is a test post +date: 2024-01-24 +tags: ["tag1", "tag2"] +slug: hello-world +--- + +# h1 Heading 8-) +## h2 Heading +### h3 Heading +#### h4 Heading +##### h5 Heading +###### h6 Heading + + +## Horizontal Rules + +___ + +--- + +*** + + +## Typographic replacements + +Enable typographer option to see result. + +(c) (C) (r) (R) (tm) (TM) (p) (P) +- + +test.. test... test..... test?..... test!.... + +!!!!!! ???? ,, -- --- + +"Smartypants, double quotes" and 'single quotes' + + +## Emphasis + +**This is bold text** + +__This is bold text__ + +*This is italic text* + +_This is italic text_ + +~~Strikethrough~~ + + +## Blockquotes + + +> Blockquotes can also be nested... +>> ...by using additional greater-than signs right next to each other... +> > > ...or with spaces between arrows. + + +## Lists + +Unordered + ++ Create a list by starting a line with `+`, `-`, or `*` ++ Sub-lists are made by indenting 2 spaces: + - Marker character change forces new list start: + * Ac tristique libero volutpat at + + Facilisis in pretium nisl aliquet + - Nulla volutpat aliquam velit ++ Very easy! + +Ordered + +1. Lorem ipsum dolor sit amet +2. Consectetur adipiscing elit +3. Integer molestie lorem at massa + + +1. You can use sequential numbers... +1. ...or keep all the numbers as `1.` + +Start numbering with offset: + +57. foo +1. bar + + +## Code + +Inline `code` + +Indented code + + // Some comments + line 1 of code + line 2 of code + line 3 of code + + +Block code "fences" + +``` +Sample text here... +``` + +Syntax highlighting + +``` js +var foo = function (bar) { + return bar++; +}; + +console.log(foo(5)); +``` + +## Tables + +| Option | Description | +| ------ | ----------- | +| data | path to data files to supply the data that will be passed into templates. | +| engine | engine to be used for processing templates. Handlebars is the default. | +| ext | extension to be used for dest files. | + +Right aligned columns + +| Option | Description | +| ------:| -----------:| +| data | path to data files to supply the data that will be passed into templates. | +| engine | engine to be used for processing templates. Handlebars is the default. | +| ext | extension to be used for dest files. | + + +## Links + +[link text](http://dev.nodeca.com) + +[link with title](http://nodeca.github.io/pica/demo/ "title text!") + +Autoconverted link https://github.com/nodeca/pica (enable linkify to see) + + +## Images + + + + +Like links, Images also have a footnote style syntax + +![Alt text][id] + +With a reference later in the document defining the URL location: + +[id]: https://octodex.github.com/images/dojocat.jpg "The Dojocat" + + +## Plugins + +The killer feature of `markdown-it` is very effective support of +[syntax plugins](https://www.npmjs.org/browse/keyword/markdown-it-plugin). + + +### [Emojies](https://github.com/markdown-it/markdown-it-emoji) + +> Classic markup: :wink: :cry: :laughing: :yum: +> +> Shortcuts (emoticons): :-) :-( 8-) ;) + +see [how to change output](https://github.com/markdown-it/markdown-it-emoji#change-output) with twemoji. + + +### [Subscript](https://github.com/markdown-it/markdown-it-sub) / [Superscript](https://github.com/markdown-it/markdown-it-sup) + +- 19^th^ +- H~2~O + + +### [\<ins>](https://github.com/markdown-it/markdown-it-ins) + +++Inserted text++ + + +### [\<mark>](https://github.com/markdown-it/markdown-it-mark) + +==Marked text== + + +### [Footnotes](https://github.com/markdown-it/markdown-it-footnote) + +Footnote 1 link[^first]. + +Footnote 2 link[^second]. + +Inline footnote^[Text of inline footnote] definition. + +Duplicated footnote reference[^second]. + +[^first]: Footnote **can have markup** + + and multiple paragraphs. + +[^second]: Footnote text. + + +### [Definition lists](https://github.com/markdown-it/markdown-it-deflist) + +Term 1 + +: Definition 1 +with lazy continuation. + +Term 2 with *inline markup* + +: Definition 2 + + { some code, part of Definition 2 } + + Third paragraph of definition 2. + +_Compact style:_ + +Term 1 +~ Definition 1 + +Term 2 +~ Definition 2a +~ Definition 2b + + +### [Abbreviations](https://github.com/markdown-it/markdown-it-abbr) + +This is HTML abbreviation example. + +It converts "HTML", but keep intact partial entries like "xxxHTMLyyy" and so on. + +*[HTML]: Hyper Text Markup Language + +### [Custom containers](https://github.com/markdown-it/markdown-it-container) + +::: warning +*here be dragons* +::: diff --git a/src/content/config.ts b/src/content/config.ts new file mode 100644 index 0000000..694e87d --- /dev/null +++ b/src/content/config.ts @@ -0,0 +1,16 @@ +import { defineCollection, z } from "astro:content"; +import { rssSchema } from '@astrojs/rss'; + +const blogCollection = defineCollection({ + type: 'content', + schema: z.object({ + title: z.string(), + description: z.string(), + date: z.date(), + tags: z.array(z.string()), + }), +}); + +export const collections = { + blog: blogCollection, +}; diff --git a/src/layouts/BlogPost.astro b/src/layouts/BlogPost.astro new file mode 100644 index 0000000..60baee6 --- /dev/null +++ b/src/layouts/BlogPost.astro @@ -0,0 +1,50 @@ +--- +import Layout from './Default.astro'; +const { title, description } = Astro.props; +--- + +<Layout title=`${title} - Andrew Lee` description={description}> + <header> + <h1 class="header-text">{title}</h1> + <h2 class="header-text">{description}</h2> + </header> + <div class="container"> + <main> + <article> + <slot /> + </article> + </main> + </div> +</Layout> + +<style> + header { + display: flex; + flex-direction: column; + gap: 0.5em; + margin: 0; + text-align: center; + padding: 0 0 1em; + } + + .header-text { + font-size: 2em; + margin: 0; + } + + h2.header-text { + font-size: 1.5em; + font-weight: 300; + } + + .container { + margin: 1em 10em 1em 10em; + } + + @media (max-width: 992px) { + .container { + margin: 10px 20px 10px 20px; + } + } + +</style> diff --git a/src/layouts/Default.astro b/src/layouts/Default.astro index cc05e25..185a807 100644 --- a/src/layouts/Default.astro +++ b/src/layouts/Default.astro @@ -4,7 +4,7 @@ interface Props { description: string; } -const { title, description } = Astro.props; +const { title = "Andrew Lee", description = "Andrew Lee Website" } = Astro.props; import { ViewTransitions, slide } from 'astro:transitions'; import Navbar from '../components/Navbar.vue'; --- @@ -13,17 +13,25 @@ import Navbar from '../components/Navbar.vue'; <html lang="en"> <head> <meta charset="UTF-8" /> - <meta name="title" content={title} /> - <meta name="description" content={description} /> <meta name="viewport" content="width=device-width" /> + + <link rel="alternate" type="application/rss+xml" title="RSS Feed" href="/rss.xml" /> <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link href="https://fonts.googleapis.com/css2?family=Exo+2:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap" rel="stylesheet"> <link rel="icon" type="image/svg+xml" href="/favicon.svg" /> + + <!-- Default Metadata --> + <meta name="title" content={title} /> + <meta name="description" content={description} /> + + <!-- Open Graph Metadata --> <meta property="og:title" content={title} /> <meta property="og:description" content={description} /> <meta property="og:image" content="/profile.png" /> - <meta name="theme-color" content="#0e8106"/> + <meta property="og:type" content="website" /> + + <meta name="theme-color" content="#1B291F"/> <meta name="generator" content={Astro.generator} /> <ViewTransitions /> <title>{title}</title> @@ -33,6 +41,7 @@ import Navbar from '../components/Navbar.vue'; <div transition:animate={slide({ duration: '0.2s' })}> <slot /> <footer> + <p>Made with {Astro.generator} and Hosted on Vercel</p> <p>Copyright © 2024 Andrew Lee</p> </footer> </div> diff --git a/src/layouts/PageMarkdown.astro b/src/layouts/PageMarkdown.astro index 1250dd5..f6e76ab 100644 --- a/src/layouts/PageMarkdown.astro +++ b/src/layouts/PageMarkdown.astro @@ -9,9 +9,11 @@ const { frontmatter } = Astro.props; <h2 class="header-text">{frontmatter.description}</h2> </header> <div class="container"> - <article> - <slot /> - </article> + <main> + <article> + <slot /> + </article> + </main> </div> </Layout> diff --git a/src/pages/blog/[...slug].astro b/src/pages/blog/[...slug].astro new file mode 100644 index 0000000..7db75bb --- /dev/null +++ b/src/pages/blog/[...slug].astro @@ -0,0 +1,22 @@ +--- +import Page from '../../layouts/BlogPost.astro'; +import { getEntry } from 'astro:content'; +const { slug } = Astro.params; + +if (slug === undefined) { + throw new Error('Slug is required'); +} + +const entry = await getEntry('blog', slug); + +if(entry === undefined) { + return Astro.redirect('/404'); +} + +const { Content } = await entry.render(); +--- +<Page title={entry.data.title} description={entry.data.description}> + <main> + <Content /> + </main> +</Page> diff --git a/src/pages/blog/index.astro b/src/pages/blog/index.astro new file mode 100644 index 0000000..556be15 --- /dev/null +++ b/src/pages/blog/index.astro @@ -0,0 +1,8 @@ +--- +import Page from "../../layouts/Page.astro"; +--- +<Page title="Blog" description="Where I post can be anything!"> + <main> + + </main> +</Page> diff --git a/src/pages/rss.xml.js b/src/pages/rss.xml.js new file mode 100644 index 0000000..df0645d --- /dev/null +++ b/src/pages/rss.xml.js @@ -0,0 +1,31 @@ +import rss from '@astrojs/rss'; +import { getCollection } from "astro:content"; +import sanitizeHtml from 'sanitize-html'; +import MarkdownIt from 'markdown-it'; +const parser = new MarkdownIt(); + +export async function GET(context) { + const blog = await getCollection('blog'); + return rss({ + // `<title>` field in output xml + title: 'Andrew Lee', + // `<description>` field in output xml + description: 'Andrew Lee\'s Personal Blog', + // Pull in your project "site" from the endpoint context + // https://docs.astro.build/en/reference/api-reference/#contextsite + site: context.site, + // Array of `<item>`s in output xml + // See "Generating items" section for examples using content collections and glob imports + items: blog.map((post) => ({ + title: post.data.title, + pubDate: post.data.date, + description: post.data.description, + // Compute RSS link from post `slug` + // This example assumes all posts are rendered as `/blog/[slug]` routes + link: `/blog/${post.slug}/`, + content: sanitizeHtml(parser.render(post.body)), + // (optional) inject custom xml + customData: `<language>en-us</language>`, + })), + }); +} |
