From 261d89ebed13691e72312f44339063fee93130ac Mon Sep 17 00:00:00 2001 From: Joe Carstairs <65492573+Sycamost@users.noreply.github.com> Date: Sat, 30 Mar 2024 16:32:17 +0000 Subject: Astro initial commit --- src/components/BaseHead.astro | 44 ++++ src/components/BlogFeed.astro | 76 ++++++ src/components/FormattedDate.astro | 21 ++ src/components/Me.astro | 43 ++++ src/consts.ts | 2 + src/content/blog/2024/01/14/sapiens_on_religion.md | 77 ++++++ .../2024/01/29/euhwc_toast_to_the_lasses_2024.md | 261 +++++++++++++++++++++ src/content/blog/2024/03/30/easter.md | 108 +++++++++ src/content/config.ts | 19 ++ src/env.d.ts | 2 + src/layouts/BlogPost.astro | 47 ++++ src/layouts/Page.astro | 17 ++ src/pages/blog/[...slug].astro | 20 ++ src/pages/blog/index.astro | 17 ++ src/pages/error.astro | 14 ++ src/pages/index.astro | 11 + src/pages/rss.xml.js | 17 ++ 17 files changed, 796 insertions(+) create mode 100644 src/components/BaseHead.astro create mode 100644 src/components/BlogFeed.astro create mode 100644 src/components/FormattedDate.astro create mode 100644 src/components/Me.astro create mode 100644 src/consts.ts create mode 100644 src/content/blog/2024/01/14/sapiens_on_religion.md create mode 100644 src/content/blog/2024/01/29/euhwc_toast_to_the_lasses_2024.md create mode 100644 src/content/blog/2024/03/30/easter.md create mode 100644 src/content/config.ts create mode 100644 src/env.d.ts create mode 100644 src/layouts/BlogPost.astro create mode 100644 src/layouts/Page.astro create mode 100644 src/pages/blog/[...slug].astro create mode 100644 src/pages/blog/index.astro create mode 100644 src/pages/error.astro create mode 100644 src/pages/index.astro create mode 100644 src/pages/rss.xml.js (limited to 'src') diff --git a/src/components/BaseHead.astro b/src/components/BaseHead.astro new file mode 100644 index 0000000..e8e44ab --- /dev/null +++ b/src/components/BaseHead.astro @@ -0,0 +1,44 @@ +--- +interface Props { + title: string; + description: string; + image?: string; +} + +const canonicalURL = new URL(Astro.url.pathname, Astro.site); + +const { title, description, image = '/images/headshot.jpg' } = Astro.props; +--- + + + + + + + + + + + + + + + + +{title} + + + + + + + + + + + + + + + + diff --git a/src/components/BlogFeed.astro b/src/components/BlogFeed.astro new file mode 100644 index 0000000..d785524 --- /dev/null +++ b/src/components/BlogFeed.astro @@ -0,0 +1,76 @@ +--- +import type { CollectionEntry } from 'astro:content'; +import { getCollection } from 'astro:content'; + +export interface Props { + headingLevel?: 1 | 2 | 3 | 4 | 5 | 6, + hideAuthor?: boolean, +}; + +const { headingLevel = 2, hideAuthor = false } = Astro.props; + +const posts = (await getCollection('blog')); + +const distinctYears: number[] = posts + .map(post => post.data.pubDate.year) + .reduce((acc, curr) => acc.includes(curr) ? acc : [...acc, curr], []) + .sort((a, b) => b - a); + +function matchesYear(year: number) { + return (post: CollectionEntry<'blog'>) => post.data.pubDate.year === year; +} + +function sortByPubDateDescending(post1: CollectionEntry<'blog'>, post2: CollectionEntry<'blog'>) { + const year1 = post1.data.pubDate.year; + const year2 = post2.data.pubDate.year; + const month1 = post1.data.pubDate.month; + const month2 = post2.data.pubDate.month; + const day1 = post1.data.pubDate.day; + const day2 = post2.data.pubDate.day; + + if (year1 !== year2) { + return year2 - year1; + } else if (month1 !== month2) { + return month2 - month1; + } else { + return day2 - day1; + } +} + +const headingElem = `h${headingLevel}`; + +const canonicalUrl = new URL(Astro.url.pathname, Astro.site) +--- + +
+ + My blog + + `} /> + + + +
    + { distinctYears.map(year => ( +
  • + {year} +
      + { posts.filter(matchesYear(year)).sort(sortByPubDateDescending).map(post => ( +
    • + {post.data.title} +
    • + )) } +
    +
  • + )) } +
+
\ No newline at end of file diff --git a/src/components/FormattedDate.astro b/src/components/FormattedDate.astro new file mode 100644 index 0000000..bb7a2c0 --- /dev/null +++ b/src/components/FormattedDate.astro @@ -0,0 +1,21 @@ +--- +interface Props { + className?: string; + date: Date | string; +} + +let { className, date } = Astro.props; +if (typeof(date) === 'string') { + date = new Date(date); +} +--- + + diff --git a/src/components/Me.astro b/src/components/Me.astro new file mode 100644 index 0000000..c9af587 --- /dev/null +++ b/src/components/Me.astro @@ -0,0 +1,43 @@ +--- +--- + +
+ + +
+

+ + Joe Carstairs + +

+ +

+ Hi! 👋 My name is Joe + Carstairs. I’m a + software developer at + Scott Logic, a + graduate of Philosophy and Mathematics at the University of Edinburgh, + a committed Christian and a pretty rubbish poet. +

+ +

+ I’m also the secretary of the + Scots Language Society. + Help me maintain our website! +

+ +

+ Email me at + joeacarstairs@gmail.com + with your thoughts on metaethics, Scots verse and eschatology. +

+ +

+ Or get me on + Facebook, + Mastodon, + LinkedIn, + or GitHub. +

+
+
\ No newline at end of file diff --git a/src/consts.ts b/src/consts.ts new file mode 100644 index 0000000..461043d --- /dev/null +++ b/src/consts.ts @@ -0,0 +1,2 @@ +export const SITE_TITLE = 'Joe Carstairs'; +export const SITE_DESCRIPTION = 'Joe’s personal website.'; \ No newline at end of file diff --git a/src/content/blog/2024/01/14/sapiens_on_religion.md b/src/content/blog/2024/01/14/sapiens_on_religion.md new file mode 100644 index 0000000..b484557 --- /dev/null +++ b/src/content/blog/2024/01/14/sapiens_on_religion.md @@ -0,0 +1,77 @@ +--- +title: Harari’s Sapiens on Religion +description: >- + In which I discuss why I think Harari’s characterisation of religion + is inadequate because it’s too materialistic. +pubDate: + year: 2024 + month: 01 + day: 14 +--- + +I’ve been slowly re-reading Yuval Noah Harari’s 2014 classic, +Sapiens, +which apart from being ridiculously over-scoped and hilariously +under-evidenced, is proving delightfully entertaining. + +I’ve just finished chapter 12, covering the world history of all +religion in thirty pages. Of course, at that level of brevity, +there will be many deficiencies. But here’s some thoughts - not +terribly well organised - which stand out to me. + +Hurari generally assumes a materialist metaphysic (a problem which +blights the book more generally). Nothing exists except physical stuff. +This gives him severe tunnel vision. As a consequence of this +restricting metaphysic, he is forced to adopt limiting accounts of what +the role of religion is in world history, and therefore what religion is. + +> The crucial historical role of religion has been to give superhuman +> legitimacy to [all social orders and hierarchies]. +> Religion can thus be defined as a system of human norms and +> values that is founded on a belief in a superhuman order. +> + +It might seem a little unfair to criticise Harari for giving a +materialist account of religion. Sapiens is, after all, a +materialist world history. + +But this account is just one extreme example of how that project, to +give a materialist account of world history, will inevitably lack the +metaphysical resources to really understand the human story. + +On Harari’s view, any human enterprise which attempts to understand +that which transcends direct human experience is at best an effort in +imaginative story-telling. All scientific theory, theology, ethics and +metaphysics either contorted out of all recognition into a pragmatic +fiction or is cast to the flames. + +In particular, it’s a view which is incapable of taking seriously some +of the most important questions human beings have grappled with in the +course of their history. Those who know me won’t be surprised at which +ones I’m going to pick out: who was the being which made their covenant +with Abraham? How is that promise being fulfilled? And who the heck was +Jesus of Nazareth? + +If Harari’s characterisation of religion is adequate - and the Abrahamic +faiths come under that banner - then those questions are reduced to +nothing more profound than Doctor Who fans arguing over ‘canon’. The +question of who God is becomes a mere tool for the organisation of +society, rather than a substantial and important question on a matter +of fact. + +This is a shortcoming for its own sake: a materialist account of +religion cannot adequately account for the phenomenon of religion +itself. + +But it is also a shortcoming even by its own lights. Without giving +serious consideration to the substantial matter of what Harari calls +‘religion’ (which, to his mind, includes the Abrahamic faiths, +Hinduism, paganism, animism, Buddhism, Shintoism, Confucianism, +capitalism, communism and Nazism), even the material facts are +inexplicable. Why would, as Harari is keen to point out, out, people +fight and die over and over again for a fiction? + +The material facts themselves prove that ‘religion’ as he construes it +is not window dressing to the real story of history. It cannot merely +serve as a mechanism in the churning of material history. It is itself +the centre of the story. diff --git a/src/content/blog/2024/01/29/euhwc_toast_to_the_lasses_2024.md b/src/content/blog/2024/01/29/euhwc_toast_to_the_lasses_2024.md new file mode 100644 index 0000000..8641a5d --- /dev/null +++ b/src/content/blog/2024/01/29/euhwc_toast_to_the_lasses_2024.md @@ -0,0 +1,261 @@ +--- +title: EUHWC Toast to the Lassies 2024 +description: >- + At the EUHWC Burns meet in + Ullapool last weekend, I had the last privilege of giving the Toast to + the Lassies. Particularly for the benefit of those who weren’t there, + here it is in full! +pubDate: + year: 2024 + month: 01 + day: 29 +--- + +Had Burns, instead of his sweet bonnie Jean,
+his skills poetical for to mature
+had any one of our club’s lassies seen
+he would forever have remained obscure.
+If he had nothing but this box of worms
+Scotia would have been poorer, that I’m sure.
+Now none of us can claim to be a Burns,
+I’m no poetic master, still, I’ll have a punt,
+though let’s be clear, I’ll do it on my terms.
+I’ve everywhere avoided being blunt -
+politeness matters more than any schema -
+but it is hard when Isla’s such a cunt.
+It was a challenge to produce a terza rima
+I could recite withouten snoring;
+you’ve been so stiff I thought youse had oedema.
+The bother is this year is you’ll all been boring:
+no drugs, no sex, no gossiping or lies,
+no rock and roll, and hardly any whoring.
+But hey well, rules is rules, I’ve had to try!
+At least it can’t be worse than the reply.
+ +I’ll start with Audrey, the club’s senior member,
+for if there’s something that I say which disconcerts her,
+it’s fine: the poor old girl, she won’t remember.
+She likes to let us think she’s a hard worker
+but we’re electing a third social sec…
+it’s pretty clear she’s just another shirker.
+This lady, half American, half Czech,
+for study, moved to Scotland for to do
+American history – really, what the heck?
+The club is so much louder thanks to you:
+impressive vocals for just five foot two.
+ +That woman, Willow, reggles is bespeckled
+with her sickle and her fishing tackle
+shackled by the shins while she is heckled;
+the way that Willow waddles maks me cackle
+like a speckled jackal getting tickles,
+worth a shekel in the tabernacle;
+I chuckle muckle at her love of pickles
+which she wiggles when she has the heart
+while work for the Committee’s fickle trickles.
+Her modus operandi: you can’t rush art.
+Her reimbursements programme’s going great;
+any day now, she’ll maybe even start.
+She cannot walk without Audrey, her mate:
+I wonder when they’re going to consummate.
+ +Although they make them pretty tough in Peebles,
+the thought of actually going up a peak
+fills Shona Lewis with the heeble-jeebles.
+New car? We miss your beautiful antique!
+How long before this one’s also up a creek?
+ +Once there was a lass called Hannah Collier
+whom even hell below regarded nasty,
+deeply despised by all that dwells there.
+Dating’s proceeding slowly for our lassie;
+not far from giving up til she beguiles
+a hot Italian in Southsider: classy!
+At first, Michaelo seems to be all smiles
+till it transpires he’s one of Dante’s demons…
+I guess it’s back to posters of Harry Styles.
+One day you’ll get a decent boy, keep dreamin;
+somewhere there waits a handsome Mr Collier.
+Hopefully when she meets him she’ll no be steamin.
+Hannah, I’m not sure why you chose to maul your
+poor skeleton at Subway (she’s still tetchy)
+and then abandon what remains of all your
+dignity at Ryvoan with a Frenchie!
+I think he wishes that he never met ye.
+ +And has a quiet Felicia e’er been seen?
+The energy she has is frankly wild.
+I’ve never seen a hillwalker so keen!
+Ssie ischt raschtlos und nie gelangweilt.
+She eats raw oats with soggy protein powder:
+a camping pot has ne’er been worse defiled.
+She uses what her Maker has endowed her
+with: her recorder skills are off the charts;
+youse think I’m joking, but I wouldn’t doubt her!
+This lass of the land of the Rot-Gold-Schwarz
+will soon depart, though long we might beseech ya
+to stay. Of course, you’ll break all of our hearts,
+but mine most of all. Any time, Felicia,
+Creag Meagaidh calls, I know routes up the rear
+dark and under-explored that I can teach you!
+I won’t deny I think it’s rather queer
+the things you do with chickpeas, but no matter.
+You’re keen, you’re quick, you’re cool, that much is clear.
+In fact, I think you’d make a damn good faffer:
+swoop down on distilleries like the Luftwaffe.
+ +And now we come to our girl Emily Topness!
+You’re keen for social sec. You’d suit the role
+because… I’m not quite sure, it’s embdy’s guess.
+We met your sister, and she was just as dull.
+No, please drone on about Icelandic soil!
+Poor Joe here down the front’s bored out his skull.
+And since I mentioned Joe – I hate to spoil
+it for you – but you’ve got the inferior Joe,
+by Jove, no joke, it’s Jock here’s got the style!
+Nah, write the boy a sonnet, get in the flow,
+Whatever you produce’ll beat by thrice
+your Masters thesis. What’d you got to show
+for months of hunting for the butterflies?
+‘There weren’t any.’ Oh, and have some sense,
+cos I’ve heard rumours – I assume they’re lies –
+you’ve called yourself the ‘poet in residence.’
+You know you can’t compete, drop the pretence.
+ +Tereza was our gear sec for last year.
+She helped herself to stuff: that’s factual.
+Now when she asks to loan a bit club gear
+we have to ask her to provide collateral.
+She picked up tin whistle pretty sharp!
+Which is to say, she’s not a natural.
+She’s nowhere happier than under tarp
+gazing up at the moon and stars alone
+somewhere distant and remote like Glen Tarff.
+Now what to say about Lucy Ma-the-soooon....
+she likes… to faff… mm hmmm… well, moving on!
+ +And now we come to Emilie the French.
+She seems to be nice on the trips we see her
+but my distrust of frogs will ne’er be quenched.
+Claims she’s a ‘pharmacist’? So she’s a dealer.
+Need some pills in a pinch? You call, she’s there
+at your door in her rally-approved four-wheeler.
+One question we have is, why are you here?
+Most folk are in uni, you’ve no refutin
+you were kicked out after second year!
+Now the Engineering grad, Sophia Newton.
+Your namesake, Isaac, was a man convicted,
+constructed calculus; but no computin,
+not even Isaac’s, could’ve e’er predicted
+you’d drop the Eng for creative writing!
+now that’s what I would call a self-inflicted
+inflection point! It must be quite enlightening,
+but that doesn’t excuse when you give us an earful.
+The blood boils in our veins, the rage heightening,
+and you’re an American, that makes me fearful.
+What’s your secret? You have us knackered!
+What are you on to always be so cheerful?
+Now we approach the topic of Merzbacher.
+Wait, she’s not here? Abandoned ship?
+She says she’s informatics: so she’s a hacker?
+She has strong views, she lets her anger rip.
+Poor George got an earful, full of future advice,
+but why hasn’t she been on another club trip?
+We’re cruel to focus on this list of vice;
+the fact remains: she’s headstrong and nice.
+ +On Skye, a lady gave her poles to Sasha,
+which was really nice - I mean just the best -
+but Sasha really didn’t have to flash her.
+Quick history lesson: way back, RBS
+led the banking system to self-destruct
+and left taxpayers to pick up the mess.
+Since then, the name’s so irredeemably fucked
+they’ve had to ditch the brand once and for all.
+There’s one lassie who I need not instruct
+What, these days, the Royal Bank is called
+cos NatWest’s nasty history of scandal
+didn’t stop Booth from working there at all.
+Nothing motivates her more than to trample
+upon the working class. They set her free.
+She sank the pound quicker than the Belgrano,
+because ‘there is no such thing as society,’
+that’s how it is, is it? All right, I see.
+ +Now, coming all the way from Glenmore Lodge,
+it’s Ellie’s turn! We have done what we can,
+although I’m scared what she’ll put in my squash.
+She wasn’t into Benji, but listen man,
+you’re lucky that you dodged her drunken benders.
+You’ll wake up in a tent in Kyrgystan,
+as for how you got there, no-one remembers,
+and if you’d known you’d be sleeping next to Ellie,
+you would’ve brought some fucking ear defenders.
+She’ll wrap you in bubblewrap, from your ears to your belly,
+cotton clothes for none, and no complaining,
+applying safety to the max, spare socks in your wellies.
+She’s always at her Mountain Leader training,
+practicing her night nav in the locale,
+pursuing QMDs - unless it’s raining.
+But some water should not scare our gal!
+She’s had much experience with the wet as of late:
+after all, she got on well with our navy pal.
+What was the age of that particular first mate?
+Older than your ex - always part of the plan?
+Ah, of course! He was a spry twenty-eight!
+Youth’s for the losers, let’s get you a real man,
+mature and rugged, but kind and astute?
+Just make sure he’s not as old as your gran.
+One request we all have is you ditch the uke:
+never have strings been pluckèd quite so shitely;
+we would all much rather be hit by a nuke.
+And please shut up about your nice society.
+We are all glad you had a fun summer,
+but bringing it up throws us right back to sobriety.
+To lose you of course would be a bummer:
+that is, for your carefully groomed newcomers.
+ +Now time for the main woman, El Presidente!
+To here, it’s been like getting stones to bleed,
+but in Isla Burslem’s case we’ve material aplenty!
+As Holy Scripture says, ‘let those who lead
+well be worthy of double honour,’ so
+your bit is double length – it’s quite the screed!
+I’ll start off with her brilliant boyfriend – oh!
+Not boyfriend! Friend? To me this rather smacks
+of low commitment, but what do I know?
+So far, he’s disappointing, but on track.
+What’s he up to Isla: seven minutes? neat!
+Despite that, he is never holding back
+your blossoming romance with Dr Peat.
+Don’t deny it, that launch was pretty hard!
+It’s fifth base next: that’s photos of his feet.
+It’s fair to say her reputation’s marred.
+We all regret that we did once anoint
+her President: her premiership’s ill-starred.
+Hey - you’re meant to be in charge of this joint!
+You’re seldom seen cos of the mountaineering
+meets that you’re always on. You’d made your point
+before you chose to go off disappearing
+to New Zealand… we get the message! Plus
+we’ve had enough of all your domineering:
+maybe it’s time we put you on a bus!
+Nah, I’m just joking. All I’ve said’s refutable.
+But the boys, we mean this next bit, all of us,
+so stop me Isla if this isn’t suitable
+but honestly we think your mum is beautiful.
+ +Alas, I have to bring an end to this rhyme.
+I know it wasn’t much, in our defence,
+the fact you used ChatGPT’s a crime.
+I hope I’ve not caused over much offence
+don’t worry, that is it, I’ve said my bit,
+so I’ll turn from the ladies to the gents.
+Yeah, don’t look away now, we wrote this shit!
+I see you looking at your laces, Chris!
+Wit without real goodwill is not legit,
+so boys, don’t send sincerity to piss!
+Why did God say he’d take our hearts of stone
+and give us hearts of flesh? For this, for this!
+Here is flesh of our flesh, bone of our bone;
+love, and love nothing more but God alone.
diff --git a/src/content/blog/2024/03/30/easter.md b/src/content/blog/2024/03/30/easter.md new file mode 100644 index 0000000..01d4c5b --- /dev/null +++ b/src/content/blog/2024/03/30/easter.md @@ -0,0 +1,108 @@ +--- +title: Why Easter is the best week of the year +description: >- + Based on a talk given to my colleagues at + Scott Logic for Maundy + Thursday, 2024. +pubDate: + year: 2024 + month: 03 + day: 30 +--- + +As you might have noticed, it is Easter this week! So I'd like to take five or +five minutes of your time to share why I – and about two billion other humans +going about the place just now – think Easter is the best week of the year. And +it's got something to do with a special Christian ritual called Communion. + +Communion, at its heart, is about as simple a ritual as you can get. You get +together with a bunch of other people. You share some bread, and you share some +wine. + +And it’s because of this ritual that so many people regard Easter as the best +week of the year. I want to explain to you why that is, and more than that, I +want to convince you that Easter is the best week of the year for you, too! + +If you’ve passed by _The Hub_ at the top of Johnstone Terrace here in +Edinburgh recently, you might have notice the banner which is draped over +the railings just now – reading, ‘RITUALS THAT UNITE US.’ + +Now, that might seem like an odd idea. But wouldn’t that be great, if we +actually had a ritual which could unite us? Because the world could surely do +with a bit more unity right now. The world seems so divided, and sometimes it +seems like there’s no hope for real unity. + +We can see that in our politics. We’re divided about foreign policy, about +taxation policy, about trade policy, about environmental policy. + +And the conflicts that we have in this country seem pretty trivial when we +remember the conflicts that are playing out in other parts of the world right +now. In Israel and Gaza. In Sudan. In Russia and Ukraine. + +And there’s plenty of conflict happening on the small scale, too. Often it’s the +smallest-scale conflicts which hurt us the most deeply. Your landlord pushes you +around. That friend you trusted like no-one else in the world lets you down. The +partner or spouse you loved like no-one else in the world – you end up fighting. + +It’s possible that you’re going to be reading this right now with a heavy heart +because of a broken relationship in their life. And doesn’t that hurt more than +anything else we know? + +When the world is groaning so heavily under the weight of conflict, and some +banner on _The Hub_ tells us a ritual can unite us, that seems so out of +proportion to the scale of the problem, doesn’t it? What can a ritual do? A bit +of old superstition? An excuse to divide people, maybe – what can a ritual do +to unite us? + +Well, two thousand years ago, a man had a meal with his friends. Together, they +shared a meal of bread and wine – which, in that time and place, was the most +ordinary meal imaginable. + +And yet, in that most ordinary event imaginable, something was happening which +was totally unimaginable. As this man, Jesus, shared the elements of this meal, +he made some extraordinary statements about what he was doing: ‘take, eat, this +is my body’ – ‘drink this, all of you; this is my blood of the new covenant.’ +(The word ‘covenant’ means a promise.) + +He told them he wasn’t just giving them bread and wine, he was giving his body +and his blood, and a promise. + +Before Jesus ate another meal, he was flogged and nailed to a cross. His blood +was spilt and his body broken, even to death. + +And yet, that wasn’t the end of the Easter story. Because three days later, +mourners turned up at Jesus’ tomb to pay their respects, and found the tomb +empty, the stone rolled away. Then they became the first of crowds of +incredulous eyewitnesses to see Jesus, the same Jesus who was killed on a cross, +alive. + +Some magic trick, right? But this matters a hell of a lot more than just some +magic trick. Because Jesus became the first person in history to prove that you +really can both have your cake and eat it. He gave his life, and lived! As a +result, we can have his life and our own. We can join with Jesus through the +ritual of Communion which he established, and thereby, through Jesus’ body, join +together with everyone else who takes part in that ritual, as one body. Then we +can start living our brand-new, full-fat, original-recipe life overflowing with +generosity where we too can both give our life to others and enjoy it ourselves. +Indeed, Jesus taught us and showed us that it’s precisely by giving our lives to +others that we get to truly live ourselves. + +This is why, in spite of all the division which persists in the world today, two +billion people regard this week as the best week of the year. Two billion +people, from every nation on Earth, speaking thousands of languages, of every +age and culture and gender and race, who defy the divisions of this world to +insist on joining together as one body in Jesus. + +That includes Edinburgh’s thriving and diverse Christian community, many of whom +will be taking part in the ritual of Communion at some point this week. And if +you want to hear more about how Jesus gave his life for us and why that matters +for all of us, I’m sure every church in Edinburgh will have their doors open at +some point this week and would be delighted to have you. My own church, +Bruntsfield Evangelical, will be having a service tomorrow, Good Friday at +twelve noon, and also at eleven o’ clock on Sunday – I’d especially recommend this +one if you’re new to church or haven’t been in a while. You’d be very welcome to +join me there! + +Because Jesus’ new covenant, his promise to all of us, is that in an apparently +hopelessly divided world, there exists real hope for unity. And that’s why +Easter is the best week of the year. diff --git a/src/content/config.ts b/src/content/config.ts new file mode 100644 index 0000000..58dbc00 --- /dev/null +++ b/src/content/config.ts @@ -0,0 +1,19 @@ +import { defineCollection, z } from 'astro:content'; + +const dateSchema = z.object({ + year: z.number(), + month: z.number(), + day: z.number(), +}); + +const blog = defineCollection({ + type: 'content', + schema: z.object({ + title: z.string(), + description: z.string(), + pubDate: dateSchema, + updatedDate: z.optional(dateSchema), + }), +}); + +export const collections = { blog }; diff --git a/src/env.d.ts b/src/env.d.ts new file mode 100644 index 0000000..acef35f --- /dev/null +++ b/src/env.d.ts @@ -0,0 +1,2 @@ +/// +/// diff --git a/src/layouts/BlogPost.astro b/src/layouts/BlogPost.astro new file mode 100644 index 0000000..25f76e6 --- /dev/null +++ b/src/layouts/BlogPost.astro @@ -0,0 +1,47 @@ +--- +import type { CollectionEntry } from 'astro:content'; +import BaseHead from '../components/BaseHead.astro'; +import FormattedDate from '../components/FormattedDate.astro'; + +type Props = CollectionEntry<'blog'>['data']; + +const { title, description, pubDate, updatedDate } = Astro.props; + +const canonicalUrl = new URL(Astro.url.pathname, Astro.site); + +const pubDateStr = `${pubDate.year}-${pubDate.month}-${pubDate.day}`; +const updatedDateStr = updatedDate ? + `${updatedDate.year}-${updatedDate.month}-${updatedDate.day}` + : pubDateStr; +--- + + + + + + + + +
+ + +

{title}

+ +

+ +

+ +
+
+ + diff --git a/src/layouts/Page.astro b/src/layouts/Page.astro new file mode 100644 index 0000000..4e5f3bb --- /dev/null +++ b/src/layouts/Page.astro @@ -0,0 +1,17 @@ +--- +import BaseHead from "../components/BaseHead.astro"; + +const { title, description } = Astro.props; +--- + + + + + + + + + + + + diff --git a/src/pages/blog/[...slug].astro b/src/pages/blog/[...slug].astro new file mode 100644 index 0000000..800c534 --- /dev/null +++ b/src/pages/blog/[...slug].astro @@ -0,0 +1,20 @@ +--- +import { type CollectionEntry, getCollection } from 'astro:content'; +import BlogPost from '../../layouts/BlogPost.astro'; + +export async function getStaticPaths() { + const posts = await getCollection('blog'); + return posts.map((post) => ({ + params: { slug: post.slug }, + props: post, + })); +} +type Props = CollectionEntry<'blog'>; + +const post = Astro.props; +const { Content } = await post.render(); +--- + + + + \ No newline at end of file diff --git a/src/pages/blog/index.astro b/src/pages/blog/index.astro new file mode 100644 index 0000000..0c617bd --- /dev/null +++ b/src/pages/blog/index.astro @@ -0,0 +1,17 @@ +--- +import BaseHead from '../../components/BaseHead.astro'; +import { SITE_TITLE, SITE_DESCRIPTION } from '../../consts'; +import BlogFeed from '../../components/BlogFeed.astro'; +--- + + + + + + + +
+ +
+ + diff --git a/src/pages/error.astro b/src/pages/error.astro new file mode 100644 index 0000000..fc84122 --- /dev/null +++ b/src/pages/error.astro @@ -0,0 +1,14 @@ +--- +import Page from '../layouts/Page.astro'; +--- + + +
+

Got lost?

+ +

+ If you’re on this page, something’s probably gone wrong. Try going to + my homepage instead. +

+
+
diff --git a/src/pages/index.astro b/src/pages/index.astro new file mode 100644 index 0000000..74cf934 --- /dev/null +++ b/src/pages/index.astro @@ -0,0 +1,11 @@ +--- +import BlogFeed from '../components/BlogFeed.astro'; +import Me from '../components/Me.astro'; +import { SITE_TITLE, SITE_DESCRIPTION } from '../consts'; +import Page from '../layouts/Page.astro'; +--- + + + + + \ No newline at end of file diff --git a/src/pages/rss.xml.js b/src/pages/rss.xml.js new file mode 100644 index 0000000..79da596 --- /dev/null +++ b/src/pages/rss.xml.js @@ -0,0 +1,17 @@ +import rss from '@astrojs/rss'; +import { getCollection } from 'astro:content'; +import { SITE_TITLE, SITE_DESCRIPTION } from '../consts'; + +export async function GET(context) { + const posts = await getCollection('blog'); + return rss({ + title: SITE_TITLE, + description: SITE_DESCRIPTION, + site: context.site, + items: posts.map((post) => ({ + ...post.data, + link: `/blog/${post.slug}/`, + pubDate: new Date(post.data.pubDate.year, post.data.pubDate.month - 1, post.data.pubDate.day), + })), + }); +} -- cgit v1.2.3