mirror of
https://github.com/prdlk/website.git
synced 2026-08-02 17:31:41 +00:00
feat(content): add external article metadata and support for PESOS links
This commit is contained in:
@@ -32,6 +32,9 @@ const writing = defineCollection({
|
|||||||
ogImage: z.string().optional(),
|
ogImage: z.string().optional(),
|
||||||
tags: z.array(z.string()).default([]).transform(removeDupsAndLowerCase),
|
tags: z.array(z.string()).default([]).transform(removeDupsAndLowerCase),
|
||||||
experiences: experienceRefs,
|
experiences: experienceRefs,
|
||||||
|
// External articles (PESOS): link out to the publisher instead of a local page.
|
||||||
|
externalUrl: z.url().optional(),
|
||||||
|
publisher: z.string().optional(), // e.g. "Fast Company", "Medium"
|
||||||
publishDate: z
|
publishDate: z
|
||||||
.string()
|
.string()
|
||||||
.or(z.date())
|
.or(z.date())
|
||||||
@@ -82,14 +85,12 @@ const experience = defineCollection({
|
|||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
// Speaking = talks/presentations rendered with an embedded Cloudflare Stream
|
// Speaking = talks/presentations rendered with an embedded YouTube player.
|
||||||
// player, linking back to the original YouTube recording as the source.
|
|
||||||
const speaking = defineCollection({
|
const speaking = defineCollection({
|
||||||
loader: glob({ base: "./src/content/speaking", pattern: "**/*.{md,mdx}" }),
|
loader: glob({ base: "./src/content/speaking", pattern: "**/*.{md,mdx}" }),
|
||||||
schema: baseSchema.extend({
|
schema: baseSchema.extend({
|
||||||
description: z.string(),
|
description: z.string(),
|
||||||
videoId: z.string(), // Cloudflare Stream video UID
|
youtubeId: z.string(), // YouTube video ID
|
||||||
originalSource: z.url().optional(), // link to the original YouTube video
|
|
||||||
event: z.string().optional(),
|
event: z.string().optional(),
|
||||||
draft: z.boolean().default(false),
|
draft: z.boolean().default(false),
|
||||||
tags: z.array(z.string()).default([]).transform(removeDupsAndLowerCase),
|
tags: z.array(z.string()).default([]).transform(removeDupsAndLowerCase),
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ Markdown/MDX content for the four collections. Each subdirectory is a collection
|
|||||||
## Subdirectories
|
## Subdirectories
|
||||||
| Directory | Collection key | Route | Notes |
|
| Directory | Collection key | Route | Notes |
|
||||||
|-----------|----------------|-------|-------|
|
|-----------|----------------|-------|-------|
|
||||||
| `projects/` | `projects` | `/projects` | Things built. Fields: `title`, `startDate`, `endDate?` (omit = ongoing), `description?`, `link?`, `repo?`, `tags?` (skills; browsable at `/projects/tags/<tag>`), `experiences?`. Sorted by `endDate` desc, ongoing first. |
|
| `projects/` | `projects` | `/projects` | Things built. Fields: `title`, `startDate`, `endDate?` (omit = ongoing), `description?`, `link?`, `repo?`, `tags?` (skills; browsable site-wide at `/skills/<skill>`), `experiences?`. Sorted by `endDate` desc, ongoing first. |
|
||||||
| `writing/` | `writing` | `/writing` | Posts. Fields incl. `description`, `coverImage?`, `ogImage?`, `tags?`, `experiences?`, `draft`, `pinned`. |
|
| `writing/` | `writing` | `/writing` | Posts. Fields incl. `description`, `coverImage?`, `ogImage?`, `tags?`, `experiences?`, `draft`, `pinned`, `externalUrl?`/`publisher?` (PESOS — entry links out to the publisher, no local detail page). |
|
||||||
| `experience/` | `experience` | `/experience` | Resume entries + taxonomy. Fields: `title`, `organization`, `startDate`, `endDate?`, `role?`, `location?`, `url?`, `description?`. |
|
| `experience/` | `experience` | `/experience` | Resume entries + taxonomy. Fields: `title`, `organization`, `startDate`, `endDate?`, `role?`, `location?`, `url?`, `description?`. |
|
||||||
| `speaking/` | `speaking` | `/speaking` | Talks. Fields: `title`, `description`, `publishDate`, `videoId` (Cloudflare Stream UID), `originalSource?`, `event?`, `tags?`, `experiences?`, `draft`. |
|
| `speaking/` | `speaking` | `/speaking` | Talks. Fields: `title`, `description`, `publishDate`, `videoId` (Cloudflare Stream UID), `originalSource?`, `event?`, `tags?`, `experiences?`, `draft`. |
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ title: "Britetwist"
|
|||||||
organization: "Britetwist"
|
organization: "Britetwist"
|
||||||
role: "iOS Developer"
|
role: "iOS Developer"
|
||||||
location: "Ashburn, VA, USA"
|
location: "Ashburn, VA, USA"
|
||||||
|
tags: ["Executive Leadership", "iOS Development", "Game Development", "C#", "Unity", "Product Management", "User Interface Design"]
|
||||||
startDate: "2016-07-01"
|
startDate: "2016-07-01"
|
||||||
endDate: "2019-05-01"
|
endDate: "2019-05-01"
|
||||||
description: "Founded an independent mobile app studio, driving end-to-end product development—from ideation and UI/UX design to full-stack programming—for three successful applications."
|
description: "Founded an independent mobile app studio, driving end-to-end product development—from ideation and UI/UX design to full-stack programming—for three successful applications."
|
||||||
@@ -12,5 +13,3 @@ description: "Founded an independent mobile app studio, driving end-to-end produ
|
|||||||
- Scaled the company's portfolio to over 1 million total downloads, encompassing a peer-to-peer volunteer network (VolunTree) and highly engaging mobile games (Space Bolt, Yuē).
|
- Scaled the company's portfolio to over 1 million total downloads, encompassing a peer-to-peer volunteer network (VolunTree) and highly engaging mobile games (Space Bolt, Yuē).
|
||||||
- Achieved peak user engagement metrics, including 15,000 Daily Active Users (DAU) for Space Bolt and 1,250 Monthly Active Users (MAU) for VolunTree.
|
- Achieved peak user engagement metrics, including 15,000 Daily Active Users (DAU) for Space Bolt and 1,250 Monthly Active Users (MAU) for VolunTree.
|
||||||
- Fostered strong developer community engagement by authoring technical architecture and game development articles that accumulated over 40,000 reads.
|
- Fostered strong developer community engagement by authoring technical architecture and game development articles that accumulated over 40,000 reads.
|
||||||
|
|
||||||
**Skills:** Executive Leadership, iOS Development, Game Development, C#, Unity, Product Management, User Interface Design
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ title: "Hobsons"
|
|||||||
organization: "Hobsons"
|
organization: "Hobsons"
|
||||||
role: "Software Engineering Intern"
|
role: "Software Engineering Intern"
|
||||||
location: "Arlington, VA, USA"
|
location: "Arlington, VA, USA"
|
||||||
|
tags: ["Java", "AngularJS", "Spring Boot", "REST API", "Backend Development", "Algorithms"]
|
||||||
startDate: "2018-05-01"
|
startDate: "2018-05-01"
|
||||||
endDate: "2018-08-01"
|
endDate: "2018-08-01"
|
||||||
description: "Architected a robust backend monitoring system using Java and the Spring Boot framework to track data synchronization between CommonApp documents and the Naviance platform."
|
description: "Architected a robust backend monitoring system using Java and the Spring Boot framework to track data synchronization between CommonApp documents and the Naviance platform."
|
||||||
@@ -11,5 +12,3 @@ description: "Architected a robust backend monitoring system using Java and the
|
|||||||
- Architected a robust backend monitoring system using Java and the Spring Boot framework to track data synchronization between CommonApp documents and the Naviance platform.
|
- Architected a robust backend monitoring system using Java and the Spring Boot framework to track data synchronization between CommonApp documents and the Naviance platform.
|
||||||
- Built an internal frontend dashboard using JavaScript and AngularJS to seamlessly consume, display, and filter REST API JSON responses.
|
- Built an internal frontend dashboard using JavaScript and AngularJS to seamlessly consume, display, and filter REST API JSON responses.
|
||||||
- Empowered the sales team to independently troubleshoot and answer customer QA inquiries by creating self-serve tools, drastically reducing response times from several days to just a few minutes.
|
- Empowered the sales team to independently troubleshoot and answer customer QA inquiries by creating self-serve tools, drastically reducing response times from several days to just a few minutes.
|
||||||
|
|
||||||
**Skills:** Java, AngularJS, Spring Boot, REST API, Backend Development, Algorithms
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ title: "Leidos"
|
|||||||
organization: "Leidos"
|
organization: "Leidos"
|
||||||
role: "Mobile App Developer"
|
role: "Mobile App Developer"
|
||||||
location: "Herndon, VA, USA"
|
location: "Herndon, VA, USA"
|
||||||
|
tags: ["Flutter", "Dart", "Cross-Platform Development", "Mobile App Development", "Agile Methodologies", "Mobile Security"]
|
||||||
startDate: "2020-08-01"
|
startDate: "2020-08-01"
|
||||||
endDate: "2021-05-01"
|
endDate: "2021-05-01"
|
||||||
description: "Engineered and deployed features for the official Customs and Border Protection (CBP) Mobile Passport application, a high-visibility tool utilized by millions of travelers to expedite entry into the United States."
|
description: "Engineered and deployed features for the official Customs and Border Protection (CBP) Mobile Passport application, a high-visibility tool utilized by millions of travelers to expedite entry into the United States."
|
||||||
@@ -11,5 +12,3 @@ description: "Engineered and deployed features for the official Customs and Bord
|
|||||||
- Engineered and deployed features for the official Customs and Border Protection (CBP) Mobile Passport application, a high-visibility tool utilized by millions of travelers to expedite entry into the United States.
|
- Engineered and deployed features for the official Customs and Border Protection (CBP) Mobile Passport application, a high-visibility tool utilized by millions of travelers to expedite entry into the United States.
|
||||||
- Leveraged the Flutter framework and Dart to build and maintain a seamless, high-performance cross-platform experience for both iOS and Android users.
|
- Leveraged the Flutter framework and Dart to build and maintain a seamless, high-performance cross-platform experience for both iOS and Android users.
|
||||||
- Collaborated within a highly regulated, hybrid agile environment to ensure the application met strict federal security, privacy, and accessibility standards.
|
- Collaborated within a highly regulated, hybrid agile environment to ensure the application met strict federal security, privacy, and accessibility standards.
|
||||||
|
|
||||||
**Skills:** Flutter, Dart, Cross-Platform Development, Mobile App Development, Agile Methodologies, Mobile Security
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ organization: "Sonr"
|
|||||||
role: "Co-Founder / CEO"
|
role: "Co-Founder / CEO"
|
||||||
location: "New York, USA"
|
location: "New York, USA"
|
||||||
url: "https://sonr.io"
|
url: "https://sonr.io"
|
||||||
|
tags: ["Executive Leadership", "Startup Fundraising", "Cosmos SDK", "React Native", "Kubernetes", "Docker", "Google Cloud", "Terraform", "Ansible", "Protocol Buffers", "Decentralized Identifiers (DIDs)", "WebAuthn", "WebAssembly (WASM)", "IPFS", "Matrix Protocol", "Technology Strategy", "DevOps", "Linux Administration"]
|
||||||
startDate: "2021-03-01"
|
startDate: "2021-03-01"
|
||||||
description: "Founded the startup and successfully led executive fundraising efforts, securing $4.7M in capital to build a peer-to-peer identity and asset management system leveraging decentralized identifiers (DIDs), WebAuthn, and IPFS."
|
description: "Founded the startup and successfully led executive fundraising efforts, securing $4.7M in capital to build a peer-to-peer identity and asset management system leveraging decentralized identifiers (DIDs), WebAuthn, and IPFS."
|
||||||
---
|
---
|
||||||
@@ -16,5 +17,3 @@ description: "Founded the startup and successfully led executive fundraising eff
|
|||||||
- Orchestrated advanced DevOps and server deployments across Google Cloud (GCP), managing complex network infrastructure using Kubernetes (K8s), Docker, Terraform, Ansible, and comprehensive Linux administration.
|
- Orchestrated advanced DevOps and server deployments across Google Cloud (GCP), managing complex network infrastructure using Kubernetes (K8s), Docker, Terraform, Ansible, and comprehensive Linux administration.
|
||||||
- Drove massive open-source community growth, achieving the 4th highest global GitHub contributions (Oct 2021 – Oct 2022) for the platform's MVP, and successfully onboarding over 120 first-time blockchain developers to the Motor SDKs during DevNet.
|
- Drove massive open-source community growth, achieving the 4th highest global GitHub contributions (Oct 2021 – Oct 2022) for the platform's MVP, and successfully onboarding over 120 first-time blockchain developers to the Motor SDKs during DevNet.
|
||||||
- Actively shaped global web standards as a W3C Working Group Member for DIDs, WebAuthn, and WebAssembly (WASM).
|
- Actively shaped global web standards as a W3C Working Group Member for DIDs, WebAuthn, and WebAssembly (WASM).
|
||||||
|
|
||||||
**Skills:** Executive Leadership, Startup Fundraising, Cosmos SDK, React Native, Kubernetes, Docker, Google Cloud, Terraform, Ansible, Protocol Buffers, Decentralized Identifiers (DIDs), WebAuthn, WebAssembly (WASM), IPFS, Matrix Protocol, Technology Strategy, DevOps, Linux Administration
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ title: "Unissant"
|
|||||||
organization: "Unissant"
|
organization: "Unissant"
|
||||||
role: "Data Science Intern"
|
role: "Data Science Intern"
|
||||||
location: "Herndon, VA, USA"
|
location: "Herndon, VA, USA"
|
||||||
|
tags: ["Machine Learning", "Data Science", "AWS Lambda", "React.js", "AWS SageMaker", "Python", "Serverless Computing"]
|
||||||
startDate: "2019-05-01"
|
startDate: "2019-05-01"
|
||||||
endDate: "2019-08-01"
|
endDate: "2019-08-01"
|
||||||
description: "Engineered and deployed a machine learning fraud detection model utilizing AWS SageMaker to identify irregular patterns in healthcare data."
|
description: "Engineered and deployed a machine learning fraud detection model utilizing AWS SageMaker to identify irregular patterns in healthcare data."
|
||||||
@@ -13,5 +14,3 @@ description: "Engineered and deployed a machine learning fraud detection model u
|
|||||||
- Developed a custom, client-facing web application using React, integrated with serverless AWS Lambda functions to interact with the predictive model in real-time.
|
- Developed a custom, client-facing web application using React, integrated with serverless AWS Lambda functions to interact with the predictive model in real-time.
|
||||||
|
|
||||||
- Delivered a successful proof-of-concept (POC) to a consulting client, demonstrating the firm's technical capabilities in advanced data management and automated fraud prevention.
|
- Delivered a successful proof-of-concept (POC) to a consulting client, demonstrating the firm's technical capabilities in advanced data management and automated fraud prevention.
|
||||||
|
|
||||||
**Skills:** Machine Learning, Data Science, AWS Lambda, React.js, AWS SageMaker, Python, Serverless Computing
|
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
title: "Web3 will spell the end of cybercrime. Here's why"
|
||||||
|
description: "Sonr's CEO on why the solution to cybercrime isn't two-factor authentication or your mother's maiden name."
|
||||||
|
publishDate: "2022-10-16"
|
||||||
|
externalUrl: "https://www.fastcompany.com/90795682/web3-will-spell-the-end-of-cybercrime-heres-why"
|
||||||
|
publisher: "Fast Company"
|
||||||
|
tags: ["web3", "cybersecurity", "identity"]
|
||||||
|
experiences: ["sonr"]
|
||||||
|
---
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
title: "What Web3 can learn from the Mac and the iPhone"
|
||||||
|
description: "The world's most innovative developers are super-enthusiastic about Web3, but everyone else isn't."
|
||||||
|
publishDate: "2022-11-26"
|
||||||
|
externalUrl: "https://www.fastcompany.com/90814899/web3-lessons-mac-iphone"
|
||||||
|
publisher: "Fast Company"
|
||||||
|
tags: ["web3", "product design"]
|
||||||
|
experiences: ["sonr"]
|
||||||
|
---
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
title: "Why (and How) to Pivot Your Startup"
|
||||||
|
description: "A five-step framework for pivoting a startup — drawn from being rejected by Y Combinator and pivoting toward Web3."
|
||||||
|
publishDate: "2022-09-08"
|
||||||
|
externalUrl: "https://www.linkedin.com/pulse/why-how-pivot-your-startup-prad-nukala/"
|
||||||
|
publisher: "LinkedIn"
|
||||||
|
tags: ["entrepreneurship", "startups"]
|
||||||
|
experiences: ["sonr"]
|
||||||
|
---
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
title: "3 Simple Steps to Becoming a Masterful Self-Teacher"
|
||||||
|
description: "A practical methodology for self-directed learning: start broad, prioritize depth by goal, and study thought leaders through books to reach expertise."
|
||||||
|
publishDate: "2022-09-22"
|
||||||
|
externalUrl: "https://www.linkedin.com/pulse/3-simple-steps-becoming-masterful-self-teacher-prad-nukala/"
|
||||||
|
publisher: "LinkedIn"
|
||||||
|
tags: ["learning", "career"]
|
||||||
|
experiences: ["sonr"]
|
||||||
|
---
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
title: "Taking the Leap: On Quitting, Debt & Entrepreneurship"
|
||||||
|
description: "From leaving a secure federal job with $15K in savings to raising $5M for Sonr — how strategic risk-taking, relocating, and embracing rejection shaped my path."
|
||||||
|
publishDate: "2022-10-20"
|
||||||
|
externalUrl: "https://www.linkedin.com/pulse/taking-leap-what-quitting-my-job-moving-going-debt-taught-prad-nukala/"
|
||||||
|
publisher: "LinkedIn"
|
||||||
|
tags: ["entrepreneurship", "startups", "career"]
|
||||||
|
experiences: ["sonr"]
|
||||||
|
---
|
||||||
@@ -1,135 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Markdown Admonitions"
|
|
||||||
description: "This post showcases using the markdown admonition feature in Astro Cactus"
|
|
||||||
publishDate: "25 Aug 2024"
|
|
||||||
updatedDate: "4 July 2025"
|
|
||||||
tags: ["markdown", "admonitions"]
|
|
||||||
---
|
|
||||||
|
|
||||||
## What are admonitions
|
|
||||||
|
|
||||||
Admonitions (also known as “asides”) are useful for providing supportive and/or supplementary information related to your content.
|
|
||||||
|
|
||||||
## How to use them
|
|
||||||
|
|
||||||
To use admonitions in Astro Cactus, wrap your Markdown content in a pair of triple colons `:::`. The first pair should also include the type of admonition you want to use.
|
|
||||||
|
|
||||||
For example, with the following Markdown:
|
|
||||||
|
|
||||||
```md
|
|
||||||
:::note
|
|
||||||
Highlights information that users should take into account, even when skimming.
|
|
||||||
:::
|
|
||||||
```
|
|
||||||
|
|
||||||
Outputs:
|
|
||||||
|
|
||||||
:::note
|
|
||||||
Highlights information that users should take into account, even when skimming.
|
|
||||||
:::
|
|
||||||
|
|
||||||
## Admonition Types
|
|
||||||
|
|
||||||
The following admonitions are currently supported:
|
|
||||||
|
|
||||||
- `note`
|
|
||||||
- `tip`
|
|
||||||
- `important`
|
|
||||||
- `warning`
|
|
||||||
- `caution`
|
|
||||||
|
|
||||||
### Note
|
|
||||||
|
|
||||||
```md
|
|
||||||
:::note
|
|
||||||
Highlights information that users should take into account, even when skimming.
|
|
||||||
:::
|
|
||||||
```
|
|
||||||
|
|
||||||
:::note
|
|
||||||
Highlights information that users should take into account, even when skimming.
|
|
||||||
:::
|
|
||||||
|
|
||||||
### Tip
|
|
||||||
|
|
||||||
```md
|
|
||||||
:::tip
|
|
||||||
Optional information to help a user be more successful.
|
|
||||||
:::
|
|
||||||
```
|
|
||||||
|
|
||||||
:::tip
|
|
||||||
Optional information to help a user be more successful.
|
|
||||||
:::
|
|
||||||
|
|
||||||
### Important
|
|
||||||
|
|
||||||
```md
|
|
||||||
:::important
|
|
||||||
Crucial information necessary for users to succeed.
|
|
||||||
:::
|
|
||||||
```
|
|
||||||
|
|
||||||
:::important
|
|
||||||
Crucial information necessary for users to succeed.
|
|
||||||
:::
|
|
||||||
|
|
||||||
### Caution
|
|
||||||
|
|
||||||
```md
|
|
||||||
:::caution
|
|
||||||
Negative potential consequences of an action.
|
|
||||||
:::
|
|
||||||
```
|
|
||||||
|
|
||||||
:::caution
|
|
||||||
Negative potential consequences of an action.
|
|
||||||
:::
|
|
||||||
|
|
||||||
### Warning
|
|
||||||
|
|
||||||
```md
|
|
||||||
:::warning
|
|
||||||
Critical content demanding immediate user attention due to potential risks.
|
|
||||||
:::
|
|
||||||
```
|
|
||||||
|
|
||||||
:::warning
|
|
||||||
Critical content demanding immediate user attention due to potential risks.
|
|
||||||
:::
|
|
||||||
|
|
||||||
## Customising the admonition title
|
|
||||||
|
|
||||||
You can customise the admonition title using the following markup:
|
|
||||||
|
|
||||||
```md
|
|
||||||
:::note[My custom title]
|
|
||||||
This is a note with a custom title.
|
|
||||||
:::
|
|
||||||
```
|
|
||||||
|
|
||||||
Outputs:
|
|
||||||
|
|
||||||
:::note[My custom title]
|
|
||||||
This is a note with a custom title.
|
|
||||||
:::
|
|
||||||
|
|
||||||
## GitHub Repository Cards
|
|
||||||
|
|
||||||
You can add dynamic cards that link to GitHub repositories, on page load, the repository information is pulled from the GitHub API.
|
|
||||||
|
|
||||||
::github{repo="chrismwilliams/astro-theme-cactus"}
|
|
||||||
|
|
||||||
You can also link a Github user:
|
|
||||||
|
|
||||||
::github{user="withastro"}
|
|
||||||
|
|
||||||
To use this feature you just use the "Github" directive:
|
|
||||||
|
|
||||||
```markdown title="Linking a repo"
|
|
||||||
::github{repo="chrismwilliams/astro-theme-cactus"}
|
|
||||||
```
|
|
||||||
|
|
||||||
```markdown title="Linking a user"
|
|
||||||
::github{user="withastro"}
|
|
||||||
```
|
|
||||||
@@ -1,174 +0,0 @@
|
|||||||
---
|
|
||||||
title: "A post of Markdown elements"
|
|
||||||
description: "This post is for testing and listing a number of different markdown elements"
|
|
||||||
publishDate: "22 Feb 2023"
|
|
||||||
updatedDate: 22 Jan 2024
|
|
||||||
tags: ["test", "markdown"]
|
|
||||||
pinned: true
|
|
||||||
---
|
|
||||||
|
|
||||||
## This is a H2 Heading
|
|
||||||
|
|
||||||
### This is a H3 Heading
|
|
||||||
|
|
||||||
#### This is a H4 Heading
|
|
||||||
|
|
||||||
##### This is a H5 Heading
|
|
||||||
|
|
||||||
###### This is a H6 Heading
|
|
||||||
|
|
||||||
## Horizontal Rules
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Emphasis
|
|
||||||
|
|
||||||
**This is bold text**
|
|
||||||
|
|
||||||
_This is italic text_
|
|
||||||
|
|
||||||
~~Strikethrough~~
|
|
||||||
|
|
||||||
## Quotes
|
|
||||||
|
|
||||||
"Double quotes" and 'single quotes'
|
|
||||||
|
|
||||||
## Blockquotes
|
|
||||||
|
|
||||||
> Blockquotes can also be nested...
|
|
||||||
>
|
|
||||||
> > ...by using additional greater-than signs right next to each other...
|
|
||||||
|
|
||||||
## References
|
|
||||||
|
|
||||||
An example containing a clickable reference[^1] with a link to the source.
|
|
||||||
|
|
||||||
Second example containing a reference[^2] with a link to the source.
|
|
||||||
|
|
||||||
[^1]: Reference first footnote with a return to content link.
|
|
||||||
|
|
||||||
[^2]: Second reference with a link.
|
|
||||||
|
|
||||||
If you check out this example in `src/content/post/markdown-elements/index.md`, you'll notice that the references and the heading "Footnotes" are added to the bottom of the page via the [remark-rehype](https://github.com/remarkjs/remark-rehype#options) plugin.
|
|
||||||
|
|
||||||
## 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
|
|
||||||
|
|
||||||
4. You can use sequential numbers...
|
|
||||||
5. ...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));
|
|
||||||
```
|
|
||||||
|
|
||||||
### Expressive code examples
|
|
||||||
|
|
||||||
Adding a title
|
|
||||||
|
|
||||||
```js title="file.js"
|
|
||||||
console.log("Title example");
|
|
||||||
```
|
|
||||||
|
|
||||||
A bash terminal
|
|
||||||
|
|
||||||
```bash
|
|
||||||
echo "A base terminal example"
|
|
||||||
```
|
|
||||||
|
|
||||||
Highlighting code lines
|
|
||||||
|
|
||||||
```js title="line-markers.js" del={2} ins={3-4} {6}
|
|
||||||
function demo() {
|
|
||||||
console.log("this line is marked as deleted");
|
|
||||||
// This line and the next one are marked as inserted
|
|
||||||
console.log("this is the second inserted line");
|
|
||||||
|
|
||||||
return "this line uses the neutral default marker type";
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
[Expressive Code](https://expressive-code.com/) can do a ton more than shown here, and includes a lot of [customisation](https://expressive-code.com/reference/configuration/).
|
|
||||||
|
|
||||||
## 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. |
|
|
||||||
|
|
||||||
### Table Alignment
|
|
||||||
|
|
||||||
| Item | Price | # In stock |
|
|
||||||
| ------------ | :---: | ---------: |
|
|
||||||
| Juicy Apples | 1.99 | 739 |
|
|
||||||
| Bananas | 1.89 | 6 |
|
|
||||||
|
|
||||||
### Keyboard elements
|
|
||||||
|
|
||||||
| Action | Shortcut |
|
|
||||||
| --------------------- | ------------------------------------------ |
|
|
||||||
| Vertical split | <kbd>Alt+Shift++</kbd> |
|
|
||||||
| Horizontal split | <kbd>Alt+Shift+-</kbd> |
|
|
||||||
| Auto split | <kbd>Alt+Shift+d</kbd> |
|
|
||||||
| Switch between splits | <kbd>Alt</kbd> + arrow keys |
|
|
||||||
| Resizing a split | <kbd>Alt+Shift</kbd> + arrow keys |
|
|
||||||
| Close a split | <kbd>Ctrl+Shift+W</kbd> |
|
|
||||||
| Maximize a pane | <kbd>Ctrl+Shift+P</kbd> + Toggle pane zoom |
|
|
||||||
|
|
||||||
## Images
|
|
||||||
|
|
||||||
Image in the same folder: `src/content/post/markdown-elements/logo.png`
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## Links
|
|
||||||
|
|
||||||
[Content from markdown-it](https://markdown-it.github.io/)
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 3.6 KiB |
@@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
title: "A Deep Dive into Flutter (Part 2)"
|
||||||
|
description: "Part 2 of building Pool, an event-sharing app in Flutter — profile views, event detail screens, and multi-functional list views with minimal code."
|
||||||
|
publishDate: "2019-09-15"
|
||||||
|
externalUrl: "https://medium.com/flutter-community/a-deep-dive-into-flutter-the-22nd-century-frontend-framework-part-2-8964c02706b9"
|
||||||
|
publisher: "Medium"
|
||||||
|
tags: ["flutter", "dart"]
|
||||||
|
---
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
title: "A Deep Dive into Flutter"
|
||||||
|
description: "Exploring Flutter for cross-platform development — building a native-performance mobile UI with Dart and Flutter's widget architecture."
|
||||||
|
publishDate: "2019-08-08"
|
||||||
|
externalUrl: "https://medium.com/flutter-community/deep-dive-in-flutter-b0b827440a49"
|
||||||
|
publisher: "Medium"
|
||||||
|
tags: ["flutter", "dart", "cross-platform development"]
|
||||||
|
---
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
title: "How I Made My Minimum Amazing Product in a Day"
|
||||||
|
description: "Building a space-defense game in 26 hours with Unity3D — reusing assets and prioritizing simplicity to ship on an ambitious deadline."
|
||||||
|
publishDate: "2018-03-30"
|
||||||
|
externalUrl: "https://medium.com/swlh/map-day-84dd2fe11b1a"
|
||||||
|
publisher: "Medium"
|
||||||
|
tags: ["game development", "unity"]
|
||||||
|
experiences: ["britetwist"]
|
||||||
|
---
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
title: "A Simple Quote to Save Your Project from Complacency"
|
||||||
|
description: "How a Derek Jeter quote pushed me to refine my mobile game Yuē — improving procedural planet generation, controls, and difficulty balancing."
|
||||||
|
publishDate: "2019-02-01"
|
||||||
|
externalUrl: "https://medium.com/swlh/a-simple-quote-to-save-your-project-complacency-65f1cdd9ca23"
|
||||||
|
publisher: "Medium"
|
||||||
|
tags: ["game development", "game design"]
|
||||||
|
experiences: ["britetwist"]
|
||||||
|
---
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 591 KiB |
@@ -1,10 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Example Cover Image"
|
|
||||||
description: "This post is an example of how to add a cover/hero image"
|
|
||||||
publishDate: "04 July 2023"
|
|
||||||
updatedDate: "14 August 2023"
|
|
||||||
coverImage:
|
|
||||||
src: "./cover.png"
|
|
||||||
alt: "Astro build wallpaper"
|
|
||||||
tags: ["test", "image"]
|
|
||||||
---
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
---
|
|
||||||
title: "A working draft title"
|
|
||||||
description: "This post is for testing the draft post functionality"
|
|
||||||
publishDate: "10 March 2024"
|
|
||||||
tags: ["test"]
|
|
||||||
draft: true
|
|
||||||
---
|
|
||||||
|
|
||||||
If this is working correctly, this post should only be accessible in a dev environment, as well as any tags that are unique to this post.
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Lorem ipsum dolor sit, amet consectetur adipisicing elit. Id"
|
|
||||||
description: "This post is purely for testing if the css is correct for the title on the page"
|
|
||||||
publishDate: "01 Feb 2023"
|
|
||||||
tags: ["test"]
|
|
||||||
---
|
|
||||||
|
|
||||||
## Testing the title tag
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Example OG Social Image"
|
|
||||||
publishDate: "27 January 2023"
|
|
||||||
description: "An example post for Astro Cactus, detailing how to add a custom social image card in the frontmatter"
|
|
||||||
tags: ["example", "blog", "image"]
|
|
||||||
ogImage: "/social-card.png"
|
|
||||||
---
|
|
||||||
|
|
||||||
## Adding your own social image to a post
|
|
||||||
|
|
||||||
This post is an example of how to add a custom [open graph](https://ogp.me/) social image, also known as an OG image, to a blog post.
|
|
||||||
By adding the optional ogImage property to the frontmatter of a post, you opt out of [satori](https://github.com/vercel/satori) automatically generating an image for this page.
|
|
||||||
|
|
||||||
If you open this markdown file `src/content/post/social-image.md` you'll see the ogImage property set to an image which lives in the public folder[^1].
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
ogImage: "/social-card.png"
|
|
||||||
```
|
|
||||||
|
|
||||||
You can view the one set for this template page [here](https://astro-cactus.chriswilliams.dev/social-card.png).
|
|
||||||
|
|
||||||
[^1]: The image itself can be located anywhere you like.
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Adding Webmentions to Astro Cactus"
|
|
||||||
description: "This post describes the process of adding webmentions to your own site"
|
|
||||||
publishDate: "11 Oct 2023"
|
|
||||||
tags: ["webmentions", "astro", "social"]
|
|
||||||
updatedDate: 6 December 2024
|
|
||||||
pinned: true
|
|
||||||
---
|
|
||||||
|
|
||||||
## TLDR
|
|
||||||
|
|
||||||
1. Add a link on your homepage to either your GitHub profile and/or email address as per [IndieLogin's](https://indielogin.com/setup) instructions. You _could_ do this via `src/components/SocialList.astro`, just be sure to include `isWebmention` to the relevant link if doing so.
|
|
||||||
2. Create an account @ [Webmention.io](https://webmention.io/) by entering your website's address.
|
|
||||||
3. Add the link feed and api key to a `.env` file with the key `WEBMENTION_URL` and `WEBMENTION_API_KEY` respectively, you could rename `.env.example` found in this template. You can also add the optional `WEBMENTION_PINGBACK` link here too.
|
|
||||||
4. Go to [brid.gy](https://brid.gy/) and sign-in to each social account[s] you wish to link.
|
|
||||||
5. Publish and build your website, remember to add the api key, and it should now be ready to receive webmentions!
|
|
||||||
|
|
||||||
## What are webmentions
|
|
||||||
|
|
||||||
Put simply, it's a way to show users who like, comment, repost and more, on various pages on your website via social media.
|
|
||||||
|
|
||||||
This theme displays the number of likes, mentions and replies each blog post receives. There are a couple of more webmentions that I haven't included, like reposts, which are currently filtered out, but shouldn't be too difficult to include.
|
|
||||||
|
|
||||||
## Steps to add it to your own site
|
|
||||||
|
|
||||||
Your going to have to create a couple of accounts to get things up-and-running. But, the first thing you need to ensure is that your social links are correct.
|
|
||||||
|
|
||||||
### Add link(s) to your profile(s)
|
|
||||||
|
|
||||||
Firstly, you need to add a link on your site to prove ownership. If you have a look at [IndieLogin's](https://indielogin.com/setup) instructions, it gives you 2 options, either an email address and/or GitHub account. I've created the component `src/components/SocialList.astro` where you can add your details into the `socialLinks` array, just include the `isWebmention` property to the relevant link which will add the `rel="me authn"` attribute. Whichever way you do it, make sure you have a link in your markup as per IndieLogin's [instructions](https://indielogin.com/setup)
|
|
||||||
|
|
||||||
```html
|
|
||||||
<a href="https://github.com/your-username" rel="me">GitHub</a>
|
|
||||||
```
|
|
||||||
|
|
||||||
### Sign up to Webmention.io
|
|
||||||
|
|
||||||
Next, head over to [Webmention.io](https://webmention.io/) and create an account by signing in with your domain name, e.g. `https://astro-cactus.chriswilliams.dev/`. Please note that .app TLDs don't function correctly. Once in, it will give you a couple of links for your domain to accept webmentions. Make a note of these and create a `.env` file (this template include an example `.env.example` which you could rename). Add the link feed and api key with the key/values of `WEBMENTION_URL` and `WEBMENTION_API_KEY` respectively, and the optional `WEBMENTION_PINGBACK` url if required. Please try not to publish this to a repository!
|
|
||||||
|
|
||||||
:::note
|
|
||||||
You don't have to include the pingback link. Maybe coincidentally, but after adding it I started to receive a higher frequency of spam in my mailbox, informing me that my website could be better. TBH they're not wrong. I've now removed it, but it's up to you.
|
|
||||||
:::
|
|
||||||
|
|
||||||
### Sign up to Brid.gy
|
|
||||||
|
|
||||||
You're now going to have to use [brid.gy](https://brid.gy/). As the name suggests, it links your website to your social media accounts. For every account you want to set up (e.g. Mastodon), click on the relevant button and connect each account you want brid.gy to search. Just to note again, brid.gy currently has an issue with .app TLDs.
|
|
||||||
|
|
||||||
## Testing everything works
|
|
||||||
|
|
||||||
With everything set, it's now time to build and publish your website. **REMEMBER** to set your environment variables `WEBMENTION_API_KEY` & `WEBMENTION_URL` with your host.
|
|
||||||
|
|
||||||
You can check to see if everything is working by sending a test webmention via [webmentions.rocks](https://webmention.rocks/receive/1). Log in with your domain, enter the auth code, and then the url of the page you want to test. For example, to test this page I would add `https://astro-cactus.chriswilliams.dev/posts/webmentions/`. To view it on your website, rebuild or (re)start dev mode locally, and you should see the result at the bottom of your page.
|
|
||||||
|
|
||||||
You can also view any test mentions in the browser via their [api](https://github.com/aaronpk/webmention.io#api).
|
|
||||||
|
|
||||||
## Things to add, things to consider
|
|
||||||
|
|
||||||
- At the moment, fresh webmentions are only fetched on a rebuild or restarting dev mode, which obviously means if you don't update your site very often you wont get a lot of new content. It should be quite trivial to add a cron job to run the `getAndCacheWebmentions()` function in `src/utils/webmentions.ts` and populate your blog with new content. This is probably what I'll add next as a github action.
|
|
||||||
|
|
||||||
- I have seen some mentions have duplicates. Unfortunately, they're quite difficult to filter out as they have different id's.
|
|
||||||
|
|
||||||
- I'm not a huge fan of the little external link icon for linking to comments/replies. It's not particularly great on mobile due to its size, and will likely change it in the future.
|
|
||||||
|
|
||||||
## Acknowledgements
|
|
||||||
|
|
||||||
Many thanks to [Kieran McGuire](https://github.com/chrismwilliams/astro-theme-cactus/issues/107#issue-1863931105) for sharing this with me, and the helpful posts. I'd never heard of webmentions before, and now with this update hopefully others will be able to make use of them. Additionally, articles and examples from [kld](https://kld.dev/adding-webmentions/) and [ryanmulligan.dev](https://ryanmulligan.dev/blog/) really helped in getting this set up and integrated, both a great resource if you're looking for more information!
|
|
||||||
Reference in New Issue
Block a user