Current implementation notes for the Photos page, including PHOTOS_CONFIG, PhotosList, and getPhotos().
This document describes the current implementation of the Photos page.
Current file structureh2
src/pages/photos/index.astro- Reads page text from
PHOTOS_CONFIG - Reads timeline data from
PhotosList
- Reads page text from
src/config.ts- Stores
PHOTOS_CONFIG
- Stores
src/lib/photos.ts- Stores
PhotosList - Auto-imports photo files
- Converts one folder of images into
Photo[]withgetPhotos()
- Stores
src/types.ts- Defines
PhotoData,Photo, andPolaroidVariant
- Defines
src/components/photos/PolaroidCard.tsx- Maps each
variantto the actual card size
- Maps each
Page texth2
The page title and intro text come from src/config.ts.
export const PHOTOS_CONFIG: PhotosConfig = { title: 'Photos', description: 'Here I will record some photos taken in daily life.', introduce: 'Here I will record some photos taken in daily life.',}src/pages/photos/index.astro renders the page like this:
---import { PHOTOS_CONFIG } from '~/config'import { PhotosList } from '~/lib/photos'
const { title, description, introduce } = PHOTOS_CONFIG---
<Layout {title} {description}> <PageTitle {title} {introduce} /> <PhotoTimeline photoData={PhotosList} /></Layout>PhotosListh2
PhotosList is defined in src/lib/photos.ts. Each item is one timeline entry.
export const PhotosList: PhotoData[] = [ { title: 'Ningbo - Botanical Garden', icon: { type: 'emoji', value: '🌼' }, description: 'It was early spring, so I went to see the cherry blossoms.', date: '2026-03-07', travel: '', photos: getPhotos( '2026-03-07-botanicalGarden', 'Early spring cherry blossoms at the botanical garden', ['3x4', '3x4', '3x4', '3x4', '3x4', '3x4'] ), },]PhotoData fieldsh3
| Field | Meaning |
|---|---|
title | Timeline title |
icon | Left-side timeline icon |
description | Optional timeline description |
date | Timeline date |
travel | Optional extra label |
photos | Array of Photo objects |
How getPhotos() worksh2
Current implementation:
function getPhotos(dir: string, alt: string, variants: PolaroidVariant[]): Photo[] { return Object.entries(photoModules) .filter(([path]) => path.includes(`/${dir}/`)) .sort(([a], [b]) => a.localeCompare(b)) .map(([, mod], index) => { const img = mod.default return { src: img, alt, width: img.width, height: img.height, variant: variants[index] || '4x3', } })}Parameter meaningh3
| Parameter | Meaning |
|---|---|
dir | Folder name under src/assets/photos |
alt | Shared alt text for every image returned from that folder |
variants | Ratio list matched to the sorted images by index |
Important behaviorh3
getPhotos()first filters all imported images by folder name.- It then sorts the matched file paths with
localeCompare. - It creates the final
Photo[]in that sorted order. variants[index]is applied to the photo at the same index.- If one index is missing in
variants, that photo falls back to'4x3'.
How the third parameter is matchedh3
The third parameter is not random metadata. It is position-based.
For this code:
photos: getPhotos( '2026-03-07-botanicalGarden', 'Early spring cherry blossoms at the botanical garden', ['3x4', '3x4', '3x4', '3x4', '3x4', '3x4'])Assume the folder src/assets/photos/2026-03-07-botanicalGarden/ contains these files after sorting:
01.webp02.webp03.webp04.webp05.webp06.webpThen the mapping is:
| File | Applied variant |
|---|---|
01.webp | first item in the array -> 3x4 |
02.webp | second item in the array -> 3x4 |
03.webp | third item in the array -> 3x4 |
04.webp | fourth item in the array -> 3x4 |
05.webp | fifth item in the array -> 3x4 |
06.webp | sixth item in the array -> 3x4 |
So if you want the first photo in the folder to use 3x4, the first item in the third array must be 3x4.
If you want mixed ratios, write them in the same order as the sorted files:
photos: getPhotos('2025-03-01-dongqianhu', 'Ningbo - Dongqian Lake', ['4x5', '1x1', '4x3'])That means:
- first sorted image ->
4x5 - second sorted image ->
1x1 - third sorted image ->
4x3
If the folder contains more photos than the array length:
photos: getPhotos('example-folder', 'Example alt', ['3x4', '4x5'])Then:
- first sorted image ->
3x4 - second sorted image ->
4x5 - third sorted image and later -> default
4x3
Supported variantsh2
PolaroidVariant is currently:
export type PolaroidVariant = '1x1' | '4x5' | '4x3' | '3x4' | '9x16'Current size mapping in src/components/photos/PolaroidCard.tsx:
const polaroidVariants: Record<PolaroidVariant, string> = { '1x1': 'w-20 h-20', '4x5': 'w-20 h-24', '4x3': 'w-20 h-16', '3x4': 'w-[4.5rem] h-24', '9x16': 'w-20 h-32',}How to add a new timeline entryh2
- Create a folder under
src/assets/photos/, for example2026-04-01-spring-walk. - Put image files into that folder.
- Make sure the file names are in the order you want after sorting.
- Add one item to
PhotosListinsrc/lib/photos.ts. - Pass the third argument to
getPhotos()in the same order as the sorted files.
Example:
{ title: 'Spring Walk', icon: { type: 'emoji', value: '🌿' }, description: 'A short walk with a camera.', date: '2026-04-01', travel: '', photos: getPhotos( '2026-04-01-spring-walk', 'Photos from a spring walk', ['3x4', '4x3', '4x5', '4x3'] ),}Notesh2
altis applied to every photo returned from the same folder.- The order is determined by sorted file path, not by import order in the editor.
- If you rename files, the sort order may change, and the
variantsarray will then map to different photos.
Comments