From 2094d1b57bfd40fb9781048d1ea3d116f9268670 Mon Sep 17 00:00:00 2001 From: Christine Tham Date: Fri, 3 Feb 2023 17:57:44 +1100 Subject: [PATCH] v2.1.0 --- README.md | 3 + package.json | 8 +- src/components/blogcard.astro | 27 ++--- src/components/bloghero.astro | 6 +- src/components/images.astro | 88 +++++++++++++++ src/components/latestarticles.astro | 12 +- src/components/nextprev.astro | 50 +++++++++ src/components/paginatecontrol.astro | 6 +- src/components/svgimg.astro | 6 - .../blog/2022-08-21-sample-gallery-post.mdx | 3 +- ...2022-08-22-sample-gallery-post-markdown.md | 25 +++++ src/content/blog/2022-08-27-how-to-use.md | 19 ++-- src/content/config.ts | 2 +- src/layouts/base.astro | 3 + src/layouts/blog.astro | 22 ++++ src/layouts/doc.astro | 35 +++++- src/pages/author/[author]/[...page].astro | 4 +- src/pages/blog/[...page].astro | 12 +- src/pages/category/[category]/[...page].astro | 14 +-- src/pages/tag/[tag]/[...page].astro | 4 +- yarn.lock | 106 +++++++++--------- 21 files changed, 333 insertions(+), 122 deletions(-) create mode 100644 src/components/images.astro create mode 100644 src/components/nextprev.astro create mode 100644 src/content/blog/2022-08-22-sample-gallery-post-markdown.md diff --git a/README.md b/README.md index efd576a..c8a0f50 100644 --- a/README.md +++ b/README.md @@ -135,3 +135,6 @@ All commands are run from the root of the project, from a terminal: - 2.0.0: New version supporting Astro collections! Also clarified that this is a multipurpose theme. Search can now include both Markdown and MDX pages! - 2.0.1: Updated screenshots, and improved landing page. +- 2.1.0: updated to latest packages, fixed dev links, backported features from + personal blog, including Next/Prev links, photo gallery support in Markdown, + and improved pagination control. \ No newline at end of file diff --git a/package.json b/package.json index 7e8bb0d..47df5e0 100644 --- a/package.json +++ b/package.json @@ -14,8 +14,8 @@ "devDependencies": { "@akebifiky/remark-simple-plantuml": "^1.0.2", "@astrojs/alpinejs": "^0.1.3", - "@astrojs/image": "^0.13.1", - "@astrojs/mdx": "^0.15.2", + "@astrojs/image": "^0.14.0", + "@astrojs/mdx": "^0.16.0", "@astrojs/sitemap": "^1.0.1", "@astrojs/tailwind": "^3.0.1", "@tailwindcss/aspect-ratio": "^0.4.2", @@ -26,7 +26,7 @@ "@types/leaflet": "^1.9.0", "@types/photoswipe": "^4.1.2", "alpinejs": "^3.11.1", - "astro": "2.0.4", + "astro": "2.0.6", "astro-robots-txt": "^0.3.11", "exifr": "^7.1.3", "mdast-util-to-string": "^3.1.1", @@ -45,7 +45,7 @@ "hero-patterns": "^2.1.0", "katex": "^0.16.4", "lunr": "^2.3.9", - "photoswipe": "^5.3.4", + "photoswipe": "^5.3.5", "photoswipe-dynamic-caption-plugin": "^1.2.7" } } diff --git a/src/components/blogcard.astro b/src/components/blogcard.astro index d3a6682..20b1f68 100644 --- a/src/components/blogcard.astro +++ b/src/components/blogcard.astro @@ -13,16 +13,15 @@ export interface Props { const { post } = Astro.props -const image = post.data.coverImage || post.data.socialImage || categoryDetail(post.data.categories && post.data.categories[0]).socialImage -const svgimg = post.data.coverSVG || (post.data.coverImage ? null : categoryDetail(post.data.categories && post.data.categories[0]).coverSVG) -console.log(import.meta.env.BASE_URL, post.slug, Astro.url.origin) +const image = post.data.coverImage || (post.data.images && post.data.images[0]) || post.data.socialImage || categoryDetail(post.data.categories && post.data.categories[0]).socialImage +const svgimg = post.data.coverSVG || ((post.data.coverImage || post.data.images) ? null : categoryDetail(post.data.categories && post.data.categories[0]).coverSVG) ---
- + { svgimg ? (
- +

@@ -54,17 +53,19 @@ console.log(import.meta.env.BASE_URL, post.slug, Astro.url.origin) class="text-gray-500 dark:text-gray-400 mr-3 inline-flex items-center leading-none text-xs pr-3 py-1 border-r-2 border-purple-200 dark:border-purple-600" > - {post.data.publishDate?.toString().slice(0, 10)} - - - - {post.data.minutesRead} + {post.data.publishDate.toDateString()} + {post.data.minutesRead && ( + + + {post.data.minutesRead} + + )} {post.data.author && ( @@ -61,7 +61,7 @@ const svgimg = frontmatter.coverSVG || (frontmatter.coverImage ? null : category - {frontmatter.publishDate?.toString().slice(0, 10)} + {new Date(frontmatter.publishDate).toString()} diff --git a/src/components/images.astro b/src/components/images.astro new file mode 100644 index 0000000..6751131 --- /dev/null +++ b/src/components/images.astro @@ -0,0 +1,88 @@ +--- +import { Image } from '@astrojs/image/components' +import exifr from 'exifr' +import 'photoswipe/style.css' +import 'photoswipe-dynamic-caption-plugin/photoswipe-dynamic-caption-plugin.css' + +export interface Props { + images: string[] +} + +const { images } = Astro.props + +const imageFiles = import.meta.glob('../images/**/*.{png,webp,jpg,jpeg}', { import: 'default', eager: true }) +const folderFiles = Object.keys(imageFiles).filter(image => images.includes(image)) +const imageSrc = images.map(image => imageFiles[image]) +const imagetitles = folderFiles.map(image => image.slice(0, image.lastIndexOf('.')).slice(image.lastIndexOf('/') + 1)) +// console.log(images) +const exifs = [] as Record[] +for (let i in folderFiles) { + const exif = await exifr.parse(folderFiles[i].replace('../', './src/')) + exifs.push(exif) +} +// console.log(exifs) + +--- + +

Please click on any photo to view in a lightbox. Use arrow keys or swipe to navigate.

+
+ diff --git a/src/components/latestarticles.astro b/src/components/latestarticles.astro index c4f6f65..da33803 100644 --- a/src/components/latestarticles.astro +++ b/src/components/latestarticles.astro @@ -48,7 +48,7 @@ const otherPosts = posts.slice(1, 5) - +

@@ -84,13 +84,13 @@ const otherPosts = posts.slice(1, 5)

- {newestPost.data.publishDate?.toISOString().slice(0, 10)} + {newestPost.data.publishDate?.toDateString()}

{newestPost.data.description}

Read more @@ -123,13 +123,13 @@ const otherPosts = posts.slice(1, 5) {post.data.categories && ( )} - +
{post.data.title}

- {post.data.publishDate?.toISOString().slice(0, 10)} + {post.data.publishDate?.toDateString()}

{post.data.description} diff --git a/src/components/nextprev.astro b/src/components/nextprev.astro new file mode 100644 index 0000000..0fe11b3 --- /dev/null +++ b/src/components/nextprev.astro @@ -0,0 +1,50 @@ +--- +import type { CollectionEntry } from 'astro:content' + +export interface Props { + base: string + prev: CollectionEntry<'blog'> + next: CollectionEntry<'blog'> +} + +const { base, prev, next } = Astro.props +--- + +

+ { + prev && ( + + ) + } + { + next && ( + + ) + } +
diff --git a/src/components/paginatecontrol.astro b/src/components/paginatecontrol.astro index ea7757f..f5afb2f 100644 --- a/src/components/paginatecontrol.astro +++ b/src/components/paginatecontrol.astro @@ -4,11 +4,12 @@ import type { CollectionEntry } from 'astro:content' import type { Page } from 'astro' export interface Props { + base: string page: Page> } // const { id } = Astro.params -const { page } = Astro.props +const { base, page } = Astro.props ---
@@ -56,7 +57,7 @@ const { page } = Astro.props {Array.from({ length: page.lastPage }, (_, index) => index + 1).map( i => ( 1 ? i : '')} + href={base + '/' + (i > 1 ? i : '')} aria-current="page" class:list={[ i == page.currentPage @@ -89,4 +90,5 @@ const { page } = Astro.props
) } +

Articles {page.start + 1}-{page.end + 1} (total {page.total})

diff --git a/src/components/svgimg.astro b/src/components/svgimg.astro index 2c3181b..cdf0f18 100644 --- a/src/components/svgimg.astro +++ b/src/components/svgimg.astro @@ -7,12 +7,6 @@ const { src, ...attrs } = Astro.props // ugly hack to circumvent astro issue with dynamic import // https://github.com/withastro/astro/issues/3373 const images = import.meta.glob('../svg/**/*', { import: 'default' }) -// console.log(images) -// for (const path in images) { -// images[path]().then((image) => { -// console.log(path, image) -// }) -// } const image = await images[src || DefaultSVG]() --- diff --git a/src/content/blog/2022-08-21-sample-gallery-post.mdx b/src/content/blog/2022-08-21-sample-gallery-post.mdx index 824d9f5..0bb3ac1 100644 --- a/src/content/blog/2022-08-21-sample-gallery-post.mdx +++ b/src/content/blog/2022-08-21-sample-gallery-post.mdx @@ -11,7 +11,6 @@ categories: tags: - mdx - sample -extra: ['gallery'] --- import Gallery from '../../components/gallery.astro' @@ -25,4 +24,4 @@ Apollo 11 at Barangaroo pays tribute to the diverse and under-appreciated heroes Sydney Festival has commissioned artworks and participatory experiences, free for the public to explore around Barangaroo, as part of a city-wide commemoration of Apollo 11, the 1969 space flight that first landed people on the moon. - + diff --git a/src/content/blog/2022-08-22-sample-gallery-post-markdown.md b/src/content/blog/2022-08-22-sample-gallery-post-markdown.md new file mode 100644 index 0000000..63893be --- /dev/null +++ b/src/content/blog/2022-08-22-sample-gallery-post-markdown.md @@ -0,0 +1,25 @@ +--- +layout: ../../layouts/blog.astro +title: Sample Gallery post (Markdown!) +description: Test post with a photo gallery and lightbox (using PhotoSwipe) +author: Chris Tham +publishDate: 2022-08-22T00:00:00.000Z +coverSVG: ../svg/undraw/undraw_portfolio.svg +socialImage: ../images/undraw/undraw_portfolio.png +gallery: apollo11 +categories: + - information +tags: + - mdx + - sample +--- + +## Gallery with Lightbox + +The following is a gallery of photos taken from the event Apollo 11 at Barangaroo, displayed in conjunction with the Sydney Festival 2019. + +The collective adventure that is space travel has many more heroes than the two men who walked on the moon in 1969. + +Apollo 11 at Barangaroo pays tribute to the diverse and under-appreciated heroes of space travel, from astronauts to mathematicians and beyond. + +Sydney Festival has commissioned artworks and participatory experiences, free for the public to explore around Barangaroo, as part of a city-wide commemoration of Apollo 11, the 1969 space flight that first landed people on the moon. diff --git a/src/content/blog/2022-08-27-how-to-use.md b/src/content/blog/2022-08-27-how-to-use.md index 666a6ed..d2f8057 100644 --- a/src/content/blog/2022-08-27-how-to-use.md +++ b/src/content/blog/2022-08-27-how-to-use.md @@ -19,11 +19,14 @@ tags: 3. The home (landing) page consists of a number of components (Hero, Feature, CTA, ...) - edit these components in `src/components` to customise. 4. The `/contact` page displays an OpenStreetMaps map via Leaflet - customise by changing to your preferred set of coordinates. 5. `src/config.ts` has all the site parameters and navigation links - edit to suit. -6. Create new Markdown or MDX pages in `src/pages/blog` (using either `.md` or `.mdx` extension). -7. Any content created in the `src/pages/blog` subdirectory will automatically be a blog post. Use `src/pages/post/2000-01-01-template.md` as a base for creating a new blog post. Remember to set the `default` property in the frontmatter to `false` when you want to publish the page. -8. If you create a new tag (eg. `newtag`) a new tag page will be created ie. `/tag/newtag`. The `/tags` page will enumerate all tags. -9. Similarly, a new category (eg. `newcat`) will create a page in `/category/newcat`. The `/categories` page will enumerate all categories. You can further customise categories to include an SVG cover image, social image and description by adding your new category in `CategoryDetail` in `src/config.ts`. -10. Blog, category, tag index pages support pagination. You can set the number of posts per page by changing `PAGE_SIZE` in `src/config.ts`. -11. If you want to change the header, edit `src/components/header.astro`. Similarly, edit `src/components/footer.astro` to customise the footer. -12. If you make a lot of changes, use `yarn lint` to check everything is okay. -13. `yarn format` will pretty-print all code in the `src` folder. +6. Create new Markdown or MDX pages in `src/content/blog` (using either `.md` or `.mdx` extension). +7. Any content created in the `src/content/blog` subdirectory will automatically be a blog post. Use `src/content/blog/2000-01-01-template.md` as a base for creating a new blog post. Remember to set the `draft` property in the frontmatter to `false` when you want to publish the page. +8. Documentation pages are also supported by creating content in `src/content/doc` subdirectory (use sample pages as guideline - remember to set `section` in frontmatter to create different sections and use `weight` in frontmatter to change ordering of pages) +9. Photo galleries are supported in Markdown posts without using MDX! Only one gallery (displayed at bottom of post) is supported. Specify the gallery using the `gallery` frontmatter (must name a subdirectory under `src/images/gallery`) +10. Multiple images at beginning of blog post (with lightbox support) is specified using `images` frontmatter - this is an array of relative image file names in `src/images`. The first image will be used as cover image (if `coverImage` is not separately set) +11. If you create a new tag (eg. `newtag`) a new tag page will be created ie. `/tag/newtag`. The `/tags` page will enumerate all tags. +12. Similarly, a new category (eg. `newcat`) will create a page in `/category/newcat`. The `/categories` page will enumerate all categories. You can further customise categories to include an SVG cover image, social image and description by adding your new category in `CategoryDetail` in `src/config.ts`. +13. Blog, category, tag index pages support pagination. You can set the number of posts per page by changing `PAGE_SIZE` in `src/config.ts`. +14. If you want to change the header, edit `src/components/header.astro`. Similarly, edit `src/components/footer.astro` to customise the footer. +15. If you make a lot of changes, use `yarn lint` to check everything is okay. +16. `yarn format` will pretty-print all code in the `src` folder. diff --git a/src/content/config.ts b/src/content/config.ts index 4af0476..0a68a85 100644 --- a/src/content/config.ts +++ b/src/content/config.ts @@ -30,7 +30,7 @@ const docCollection = defineCollection({ draft: z.boolean().optional(), layout: z.string(), section: z.string(), - weight: z.number().optional(), + weight: z.number().default(0), title: z.string(), description: z.string(), images: z.array(z.string()).optional(), diff --git a/src/layouts/base.astro b/src/layouts/base.astro index add1379..a83a491 100644 --- a/src/layouts/base.astro +++ b/src/layouts/base.astro @@ -3,6 +3,7 @@ import type { Frontmatter } from '../config' import SEO from '../components/seo.astro' import Header from '../components/header.astro' import Footer from '../components/footer.astro' +import Gallery from '../components/gallery.astro' export interface Props { frontmatter: Frontmatter @@ -62,6 +63,8 @@ const { frontmatter } = Astro.props }
+ {frontmatter.gallery && } +
{frontmatter.extra?.includes('markmap') && diff --git a/src/layouts/blog.astro b/src/layouts/blog.astro index 1147bef..37ba164 100644 --- a/src/layouts/blog.astro +++ b/src/layouts/blog.astro @@ -1,13 +1,33 @@ --- +import type { CollectionEntry } from 'astro:content' import type { Frontmatter } from '../config' +import { getCollection } from 'astro:content' import Base from '../layouts/base.astro' import BlogHero from '../components/bloghero.astro' +import NextPrev from '../components/nextprev.astro' +import Images from '../components/images.astro' export interface Props { frontmatter: Frontmatter } const { frontmatter } = Astro.props + +const currentPage = Astro.url.pathname +const allPosts = await getCollection('blog') +const posts = allPosts.sort((a, b) => +b.data.publishDate - +a.data.publishDate).filter(p => !p.data.draft) +let prev: CollectionEntry<'blog'> +let next: CollectionEntry<'blog'> +posts.forEach((post, i) => { + if (currentPage.search(post.slug) >= 0) { + if (i > 0) { + prev = posts[i - 1] + } + if (i < posts.length - 1) { + next = posts[i + 1] + } + } +}) --- @@ -19,8 +39,10 @@ const { frontmatter } = Astro.props
+ {frontmatter.images && }
+ diff --git a/src/layouts/doc.astro b/src/layouts/doc.astro index a8ce1c4..0f18e71 100644 --- a/src/layouts/doc.astro +++ b/src/layouts/doc.astro @@ -1,9 +1,12 @@ --- -import type { Frontmatter } from '../config' +import type { CollectionEntry } from 'astro:content' +import type { Frontmatter, Sidebar } from '../config' +import { getCollection } from 'astro:content' import Base from './base.astro' import PageContent from '../components/pagecontent.astro' import LeftSidebar from '../components/leftsidebar.astro' import RightSidebar from '../components/rightsidebar.astro' +import NextPrev from '../components/nextprev.astro' import * as CONFIG from '../config' import type { MarkdownHeading } from 'astro' @@ -14,14 +17,39 @@ type Props = { const { frontmatter, headings } = Astro.props const currentPage = Astro.url.toString() -const currentFile = `src/pages/${Astro.url.pathname.replace(import.meta.env.BASE_URL, '').replace(/\/$/, '')}.md` +const currentFile = `src/content/${Astro.url.pathname.replace(import.meta.env.BASE_URL, '').replace(/\/$/, '')}.md` const githubEditUrl = `${CONFIG.GITHUB_EDIT_URL}/${currentFile}` + +const allDocs = await getCollection('doc') +const docs = allDocs.sort((a, b) => a.data.weight - b.data.weight).filter(p => !p.data.draft) +const sections = Array.from( + new Set(docs.map(doc => doc.data.section)) +) as string[] +let sidebar = {} as Sidebar +sections.forEach( + section => + (sidebar[section] = docs + .filter(doc => doc.data.section == section) + .map(doc => ({ text: doc.data.title, link: import.meta.env.BASE_URL + "bio/" + doc.slug }))) +) +let prev: CollectionEntry<'doc'> +let next: CollectionEntry<'doc'> +docs.forEach((doc, i) => { + if (currentPage.search(doc.slug) >= 0) { + if (i > 0) { + prev = docs[i - 1] + } + if (i < docs.length - 1) { + next = docs[i + 1] + } + } +}) ---
+