Add Fun With Bookmarks post
This commit is contained in:
parent
005668b46f
commit
e88b2bd17a
76
src/app/resources/blog-posts/Fun-With-Bookmarks.md
Normal file
76
src/app/resources/blog-posts/Fun-With-Bookmarks.md
Normal file
@ -0,0 +1,76 @@
|
||||
---
|
||||
title: Fun With Bookmarks
|
||||
slug: Fun-With-Bookmarks
|
||||
date: 2025-01-09 07:30:00
|
||||
tags:
|
||||
- meta
|
||||
- markmark
|
||||
---
|
||||
|
||||
A while back, I started experimenting with a way of storing my bookmarks (read: my random text document full of untitled links) as a Markdown document, which I affectionately dubbed "[MarkMark](https://garrettmills.dev/markmark)" — a standard format for links, descriptive text, tags, and dates. Here's a sample from [my bookmarks](https://garrettmills.dev/links):
|
||||
|
||||
```markdown
|
||||
# Cycling
|
||||
|
||||
- Spencer McCullough's bike trip to 48 national parks (+ an excellent bike camping map)
|
||||
- https://onelongtrip.bike/
|
||||
- https://gobikecamping.com/map
|
||||
- Helmet Wind Straps
|
||||
- https://youtube.com/shorts/8-Ph6CjKopY?si=QGVb7HrKT7FejGZI
|
||||
- A love letter to bicycle maintenance and repair
|
||||
- https://tegowerk.eu/posts/bicycle-repair/
|
||||
```
|
||||
|
||||
I published MarkMark v1.0 back in November 2023 (!!), but I never fully started using it for two reasons:
|
||||
|
||||
|
||||
1. I wanted to be able to organize and syndicate links by date, and
|
||||
2. more importantly, adding a link meant committing a change to my [website code](https://code.garrettmills.dev/garrettmills/www/src/commit/c852fbd628bfd7903ef9814becfb8d8e77dfcb40/src/app/resources/markmark/links.mark.md) and fully re-deploying it every time.
|
||||
|
||||
Since I've been feeling the urge to tinker, I've made some changes to help with both.
|
||||
|
||||
|
||||
## v1.1: It's all about that date
|
||||
|
||||
I love RSS and the indie-web ([see here](https://garrettmills.dev/blog/feeds)) and one of the main ways I discover new parts of it is thanks to fantastic link blogs like [Jason Kottke](https://kottke.org/) and [LinkMachineGo](https://www.timemachinego.com/linkmachinego/).
|
||||
|
||||
While I'm not running a link blog, and I have no delusions of readership, I like the idea of being able to syndicate my bookmarks via RSS.
|
||||
|
||||
This would work if my MarkMark document was organized by date, but, since it's not, an [update to the spec](https://xkcd.com/927/) was required. MarkMark v1.1 introduces a date notation for links:
|
||||
|
||||
```markdown
|
||||
- A fantastic link title goes here (2025-01-09)
|
||||
- https://example.com/home
|
||||
```
|
||||
|
||||
The dates are optional, but give me a way to track when links were added to my bookmarks, which means I can now generate an [RSS feed](https://code.garrettmills.dev/garrettmills/www/src/commit/c852fbd628bfd7903ef9814becfb8d8e77dfcb40/src/app/services/blog/MarkMarkBlog.service.ts#L28).
|
||||
|
||||
My current implementation publishes feed entries for each link in my bookmarks that has a date, along with the title of its section, description, and URL(s).
|
||||
|
||||
![](https://static.garrettmills.dev/assets/blog-images/fun-with-mm-1.png)
|
||||
<center>You can find these feeds in RSS, Atom, and JSON format on the <a href="https://garrettmills.dev/links">links page</a>.</center>
|
||||
|
||||
|
||||
## Reading links from Outline
|
||||
|
||||
The deployment process for my website isn't *difficult*, but it does require a [Docker build](https://code.garrettmills.dev/garrettmills/www/src/branch/master/package.json#L44), which turns out to be too much work every time I just want to save a link.
|
||||
|
||||
As I mentioned in my [Default Apps 2024](https://garrettmills.dev/blog/2025/01/07/Default-Apps-2024/) post, my knowledge base of choice is the self-hosted version of [Outline](https://www.getoutline.com/), which I have found to be quite good. One of the things I like about Outline is that it stores document contents as Markdown internally and has a well-documented REST API (you can probably see where this is going).
|
||||
|
||||
![](https://static.garrettmills.dev/assets/blog-images/fun-with-mm-2.png)
|
||||
|
||||
The `/links` page now, with some caching, reads my MarkMark document directly from my Outline instance rather than a hard-coded file. Since MarkMark is just a subset of the [CommonMark](https://commonmark.org/) syntax, I can make use of Outline's markdown formatting for headers, lists, links, and code:
|
||||
|
||||
![](https://static.garrettmills.dev/assets/blog-images/fun-with-mm-3.png)
|
||||
<center>I did have to add some special logic to undo the escaping Outline adds to the MarkMark preamble (the lines starting with <code>[//]:</code>).</center>
|
||||
|
||||
This is *way* easier to add to/organize day-to-day, and the updates get pulled into my website and RSS feeds automatically.
|
||||
|
||||
|
||||
## Future Work
|
||||
|
||||
I want to build a Firefox extension for saving links to my MarkMark document in Outline — something where I can click the button on a webpage and pre-fill the title, description, and today's date. It'll have to use the Outline API to load the list of categories and tags, then my [MarkMark parser collection](https://code.garrettmills.dev/garrettmills/www/src/branch/master/src/markmark) to add the link and update the Outline document automatically.
|
||||
|
||||
More generally, I like this idea of building semi-dynamic integrations using Outline. I already use it to draft all my blog posts before publishing. It reminds me a lot of the [halcyon days of the old web](https://en.wikipedia.org/wiki/Microsoft_FrontPage). I wonder if there are any other uses.
|
||||
|
||||
One of my themes for 2025 is to work smaller — build smaller projects, write smaller (more frequent) posts, read smaller sources, &c. The MarkMark spec and its small collection of tools feels like a good way to start.
|
@ -24,7 +24,7 @@ export class MarkMarkService {
|
||||
let content = await this.cache.fetch('www-markmark-content')
|
||||
if ( !content || this.config.get('server.debug') ) {
|
||||
content = await this.readFromOutline()
|
||||
const expDateEpoch = (new Date).getTime() + (15 * 60 * 1000)
|
||||
const expDateEpoch = (new Date).getTime() + (60 * 60 * 1000) // cache for 1hr
|
||||
await this.cache.put('www-markmark-content', content, new Date(expDateEpoch))
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user