Readme

A blog written, developed and hosted on val.town.

How ?

Each article on this blog is contained single val, with a #blog tag.

See this example article.

// #blog
// title: Example Post

import { article } from "https://esm.town/v/pomdtr/article";
import { extractValInfo } from "https://esm.town/v/pomdtr/extractValInfo";
import { html } from "https://esm.town/v/stevekrouse/html?v=5";

export async function examplePost(req: Request) {
  const { author, name } = extractValInfo(import.meta.url);
  return html(await article(author, name));
}

Each of these post work on it's own.

This val is able to:

  • list them with the /v1/search api (with a #blog query)
    • post with different author than the owner of this val will be filtered out
    • only public vals will be listed
  • render the readme of those vals using remark (with github styling)

This process run each time a user visit the web endpoint, so the blog is always up to date.

You can get your own instance of the blog by just forking this val.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
// title: How does this work ?
import { api } from "https://esm.town/v/pomdtr/api";
import { article } from "https://esm.town/v/pomdtr/article";
import { extractMetadata } from "https://esm.town/v/pomdtr/extractMetadata";
import { extractValInfo } from "https://esm.town/v/pomdtr/extractValInfo";
import { gfm } from "https://esm.town/v/pomdtr/gfm";
import { html } from "https://esm.town/v/stevekrouse/html?v=5";
import { Hono } from "npm:hono";
const app = new Hono();
const homepage = extractValInfo(import.meta.url);
app.get("/", async c => {
const articles = await findMyArticles();
const items = articles.map(val => {
const title = extractMetadata("title", val.code);
return `- [${title}](/articles/${val.name})`;
});
const markdown = `# @${homepage.author}'s blog
A blog written, developed and hosted on [***val.town***](https://www.val.town).
Get your own instance of this blog by [forking this val](https://www.val.town/v/pomdtr/blog/fork)!
## Posts
${items.join("\n")}
## Links
- [RSS Feed](/rss)
- [Github](https://github.com/pomdtr)
- [Twitter](https://twitter.com/pomdtrr)
`;
return c.html(await gfm(markdown, {title: "Blog"}));
});
app.get("/articles/:name", async (c) => {
const name = c.req.param("name");
return c.html(article(homepage.author, name));
});
app.get("/articles/:name/edit", async (c) => {
const name = c.req.param("name");
return c.redirect(`https://val.town/v/${homepage.author}/${name}`);
});
app.get("/edit", async (c) => {
return c.redirect(`https://val.town/v/${homepage.author}/${homepage.name}`);
});
app.get("/rss", async (c) => {
return c.text("TODO");
});
app.get("/new", async (c) => {
return c.redirect(`https://www.val.town/v/pomdtr/exampleArticle/fork`);
});
async function findMyArticles() {
let { data: articles } = await api(`/v1/search/vals?query=${encodeURIComponent("#blog")}`);
return articles.filter(val => {
const valhasSameAuthor = val.author.username == homepage.author;
const valIsPublic = val.privacy == "public";
return valhasSameAuthor && valIsPublic;
});
}
export const blog = app.fetch;
// #blog
👆 This is a val. Vals are TypeScript snippets of code, written in the browser and run on our servers. Create scheduled functions, email yourself, and persist small pieces of data — all from the browser.