forked from shadowfacts/shadowfacts.net
Replace categories with tags
This commit is contained in:
parent
3fbd07aef9
commit
ada0463e75
|
@ -1,24 +0,0 @@
|
|||
import { Page, PostMetadata } from "../metadata";
|
||||
import generatePaginated from "./paginated";
|
||||
|
||||
export default async function(posts: Page[]): Promise<Map<string, Page[]>> {
|
||||
const categories = new Map<string, Page[]>();
|
||||
|
||||
for (const post of posts) {
|
||||
const category = (<PostMetadata>post.metadata).category;
|
||||
if (!categories.has(category)) {
|
||||
categories.set(category, []);
|
||||
}
|
||||
categories.get(category)!.push(post);
|
||||
}
|
||||
|
||||
categories.forEach((categoryPosts, category) => {
|
||||
generatePaginated(categoryPosts, `/${category}/`, "site/category.html.ejs", {
|
||||
category
|
||||
}, {
|
||||
title: `${category} posts`
|
||||
});
|
||||
});
|
||||
|
||||
return categories;
|
||||
}
|
|
@ -1,23 +1,23 @@
|
|||
import archive from "./archive";
|
||||
import categories from "./categories";
|
||||
import copy from "./copy";
|
||||
import css from "./css";
|
||||
import errors from "./errors";
|
||||
import homepage from "./homepage";
|
||||
import posts from "./posts";
|
||||
import * as rss from "./rss";
|
||||
import tags from "./tags";
|
||||
import tutorials from "./tutorials";
|
||||
import years from "./years";
|
||||
|
||||
export = {
|
||||
archive,
|
||||
categories,
|
||||
copy,
|
||||
css,
|
||||
errors,
|
||||
homepage,
|
||||
posts,
|
||||
rss,
|
||||
tags,
|
||||
tutorials,
|
||||
years,
|
||||
};
|
||||
|
|
|
@ -4,7 +4,7 @@ import { Page, PostMetadata } from "../metadata";
|
|||
import * as util from "../util";
|
||||
import { TutorialSeries } from "./tutorials";
|
||||
|
||||
async function generateFeed(posts: Page[], permalink: string, category?: string) {
|
||||
async function generateFeed(posts: Page[], permalink: string, tag?: string) {
|
||||
posts = posts.sort((a, b) => {
|
||||
const aDate = <Date>(<PostMetadata>a.metadata).date;
|
||||
const bDate = <Date>(<PostMetadata>b.metadata).date;
|
||||
|
@ -16,7 +16,7 @@ async function generateFeed(posts: Page[], permalink: string, category?: string)
|
|||
let text = (await fs.readFile("site/feed.xml.ejs")).toString();
|
||||
text = util.render(text, {
|
||||
posts,
|
||||
category,
|
||||
tag,
|
||||
permalink,
|
||||
feedPath: dest
|
||||
}, "site/feed.xml.ejs");
|
||||
|
@ -28,9 +28,9 @@ export async function posts(posts: Page[]) {
|
|||
generateFeed(posts, "/");
|
||||
}
|
||||
|
||||
export async function categories(categories: Map<string, Page[]>) {
|
||||
categories.forEach((posts, category) => {
|
||||
generateFeed(posts, `/${category}/`, category);
|
||||
export async function tags(tags: Map<string, Page[]>) {
|
||||
tags.forEach((posts, tag) => {
|
||||
generateFeed(posts, `/${tag}/`, tag);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
import { Page, PostMetadata } from "../metadata";
|
||||
import generatePaginated from "./paginated";
|
||||
|
||||
export default async function(posts: Page[]): Promise<Map<string, Page[]>> {
|
||||
const taggedPosts = new Map<string, Page[]>();
|
||||
|
||||
for (const post of posts) {
|
||||
const tags = (<PostMetadata>post.metadata).tags;
|
||||
for (const tag of tags) {
|
||||
if (!taggedPosts.has(tag)) {
|
||||
taggedPosts.set(tag, []);
|
||||
}
|
||||
taggedPosts.get(tag)!.push(post);
|
||||
}
|
||||
}
|
||||
|
||||
taggedPosts.forEach((tagPosts, tag) => {
|
||||
generatePaginated(tagPosts, `/${tag}/`, "site/tag.html.ejs", {
|
||||
tag
|
||||
}, {
|
||||
title: `${tag} posts`
|
||||
});
|
||||
});
|
||||
|
||||
return taggedPosts;
|
||||
}
|
|
@ -22,7 +22,7 @@ async function generate(): Promise<Page[]> {
|
|||
generators.homepage(posts);
|
||||
generators.years(posts);
|
||||
generators.rss.posts(posts)
|
||||
generators.categories(posts).then(generators.rss.categories);
|
||||
generators.tags(posts).then(generators.rss.tags);
|
||||
generators.archive(posts);
|
||||
|
||||
return posts;
|
||||
|
|
|
@ -16,7 +16,7 @@ export interface Metadata {
|
|||
export interface PostMetadata extends Metadata {
|
||||
title: string;
|
||||
slug: string;
|
||||
category: string;
|
||||
tags: string[];
|
||||
date: string | Date;
|
||||
readingTime?: number;
|
||||
wordCount?: number;
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<feed xmlns="http://www.w3.org/2005/Atom">
|
||||
<title>Shadowfacts<% if (category) { %> (<%= category %>)<% } %></title>
|
||||
<title>Shadowfacts<% if (tag) { %> (<%= tag %>)<% } %></title>
|
||||
<subtitle>
|
||||
<% if (category) { %>
|
||||
Only <%= category %> posts.
|
||||
<% if (tag) { %>
|
||||
Only <%= tag %> posts.
|
||||
<% } else { %>
|
||||
Just my various ramblings.
|
||||
<% } %>
|
||||
</subtitle>
|
||||
<% if (tag) { %>
|
||||
<category term="<%= tag %>" />
|
||||
<% } %>
|
||||
<link rel="alternate" type="text/html" href="https://shadowfacts.net<%= permalink %>" />
|
||||
<link rel="self" href="https://shadowfacts.net<%= feedPath %>" type="application/atom+xml" />
|
||||
<id>https://shadowfacts.net<%= feedPath %></id>
|
||||
|
@ -21,12 +24,14 @@
|
|||
<title><%= post.metadata.title %></title>
|
||||
<updated><%= post.metadata.date.toISOString() %></updated>
|
||||
<link rel="alternate" type="text/html" href="https://shadowfacts.net<%= post.metadata.permalink %>" />
|
||||
<% if (post.metadata.category) { %>
|
||||
<category term="<%= post.metadata.category %>" />
|
||||
<% if (post.metadata.tags) { %>
|
||||
<% for (const tag of post.metadata.tags) { %>
|
||||
<category term="<%= tag %>" />
|
||||
<% } %>
|
||||
<% } %>
|
||||
<content type="html"><![CDATA[
|
||||
<%- post.text %>
|
||||
]]></content>
|
||||
</entry>
|
||||
<% } %>
|
||||
</feed>
|
||||
</feed>
|
||||
|
|
|
@ -8,9 +8,11 @@
|
|||
<% const fullFormatted = formatDate(metadata.date, "hh:mm:ss A MMM Do, YYYY") %>
|
||||
<time itemprop="datePublished" datetime="<%= metadata.date.toISOString() %>" title="<%= fullFormatted %>"><%= formatted %></time>
|
||||
</span>
|
||||
<% if (metadata.category) { %>
|
||||
<% if (metadata.tags) { %>
|
||||
in
|
||||
<span itemprop="articleSection"><a href="/<%= metadata.category %>/" rel="category"><%= metadata.category %></a></span>
|
||||
<% for (let i = 0; i < metadata.tags.length; i++) { %>
|
||||
<span itemprop="articleSection"><a href="/<%= metadata.tags[i] %>/" rel="tag"><%= metadata.tags[i] %></a></span><%= i < metadata.tags.length - 1 ? ", " : "" %>
|
||||
<% } %>
|
||||
<% } else if (metadata.series) { %>
|
||||
in
|
||||
<span itemprop="articleSection"><a href="/tutorials/<%= metadata.series %>" rel="category"><%= metadata.seriesName %></a></span>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
```
|
||||
metadata.title = "Hello, World!"
|
||||
metadata.category = "meta"
|
||||
metadata.tags = ["meta"]
|
||||
metadata.date = "2016-05-06 11:13:18 -0400"
|
||||
metadata.oldPermalink = ["/meta/2016/06/07/hello-world/", "/meta/2016/hello-world/"]
|
||||
metadata.shortDesc = "Hello again, world! Welcome to the third iteration of my website."
|
||||
```
|
||||
|
||||
Hello again, world! Welcome to the third iteration of my website. Originally my site was hosted on GitHub pages and only available at [shadowfacts.github.io](https://shadowfacts.github.io). I wrote a couple of tutorials on using [Forge](http://minecraftforge.net) to mod 1.6.4, but never really finished anything other than super basic setup/recipes. Later, after I got [shadowfacts.net](https://shadowfacts.net), I decided to set up a propper website using [WordPress](https://wordpress.org). I copied over all of the old tutorials from my old GitHub pages site, but never really did anything else with it. After my website being offline for almost a year, I've finally decided to switch back to GitHub for the simplicity (also I <3 [Jekyll](https://jekyllrb.com)). Using Jekyll, I've got a structure in place that I can use to easily publish tutorials in a structured format. There is one tutorial series that I'm currently writing and that is [Forge Mods in 1.9](/tutorials/forge-modding-19/), and hopefully more series will follow.
|
||||
Hello again, world! Welcome to the third iteration of my website. Originally my site was hosted on GitHub pages and only available at [shadowfacts.github.io](https://shadowfacts.github.io). I wrote a couple of tutorials on using [Forge](http://minecraftforge.net) to mod 1.6.4, but never really finished anything other than super basic setup/recipes. Later, after I got [shadowfacts.net](https://shadowfacts.net), I decided to set up a propper website using [WordPress](https://wordpress.org). I copied over all of the old tutorials from my old GitHub pages site, but never really did anything else with it. After my website being offline for almost a year, I've finally decided to switch back to GitHub for the simplicity (also I <3 [Jekyll](https://jekyllrb.com)). Using Jekyll, I've got a structure in place that I can use to easily publish tutorials in a structured format. There is one tutorial series that I'm currently writing and that is [Forge Mods in 1.9](/tutorials/forge-modding-19/), and hopefully more series will follow.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
```
|
||||
metadata.title = "1.9.4 Porting Spree"
|
||||
metadata.category = "minecraft"
|
||||
metadata.tags = ["minecraft"]
|
||||
metadata.date = "2016-05-21 17:47:18 -0400"
|
||||
metadata.oldPermalink = ["/mods/2016/05/21/194-porting-spree/", "/minecraft/2016/1-9-4-porting-spree/"]
|
||||
metadata.shortDesc = "Now that Forge for 1.9.4 is out, I've begun the log and arduous process of porting my mods to 1.9.4 (if by long and arduous, you mean short and trivial)."
|
||||
|
@ -42,4 +42,4 @@ Now that Forge for 1.9.4 is [out](http://files.minecraftforge.net/maven/net/mine
|
|||
<h3 class="mod-name"><a href="http://minecraft.curseforge.com/projects/shadowtweaks">ShadowTweaks</a></h3>
|
||||
<span class="mod-version"><a href="http://minecraft.curseforge.com/projects/shadowtweaks/files/2302146">1.9.0</a></span>
|
||||
<p class="mod-desc">A little tweaks mod with a variety of client/server tweaks.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
```
|
||||
metadata.title = "Introducing RTFM"
|
||||
metadata.category = "minecraft"
|
||||
metadata.tags = ["minecraft"]
|
||||
metadata.date = "2016-06-29 12:00:00 -0400"
|
||||
metadata.oldPermalink = ["/meta/2016/06/29/introducing-rtfm/", "/minecraft/2016/introducing-rtfm/"]
|
||||
metadata.shortDesc = "RTFM is the brand new website that will contain the documentation for all of my projects, currently it only contains documentation for MC mods."
|
||||
|
@ -10,4 +10,4 @@ metadata.shortDesc = "RTFM is the brand new website that will contain the docume
|
|||
|
||||
<!-- excerpt-end -->
|
||||
|
||||
![XKCD #293 RTFM](https://imgs.xkcd.com/comics/rtfm.png)
|
||||
![XKCD #293 RTFM](https://imgs.xkcd.com/comics/rtfm.png)
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
```
|
||||
metadata.title = "Forge Modding Tutorials for 1.10.2"
|
||||
metadata.category = "minecraft"
|
||||
metadata.tags = ["minecraft"]
|
||||
metadata.date = "2016-06-30 10:35:00 -0400"
|
||||
metadata.oldPermalink = ["/meta/2016/06/30/forge-1102-tutorials/", "/minecraft/2016/forge-modding-tutorials-for-1-10-2"]
|
||||
metadata.shortDesc = "The Forge modding tutorials have all the been updated to MC 1.10.2 as has the GitHub repo."
|
||||
```
|
||||
|
||||
The Forge modding tutorials have all the been [updated to MC 1.10.2](/tutorials/forge-modding-1102/) as has the [GitHub repo](https://github.com/shadowfacts/TutorialMod/).
|
||||
The Forge modding tutorials have all the been [updated to MC 1.10.2](/tutorials/forge-modding-1102/) as has the [GitHub repo](https://github.com/shadowfacts/TutorialMod/).
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
```
|
||||
metadata.title = "Introducing Mirror"
|
||||
metadata.category = "java"
|
||||
metadata.tags = ["java"]
|
||||
metadata.date = "2016-07-28 16:45:00 -0400"
|
||||
metadata.oldPermalink = ["/java/2016/07/28/introducing-mirror/", "/java/2016/introducing-mirror/"]
|
||||
metadata.shortDesc = "Allow me to introduce my latest project, Mirror. Mirror is a reflection library for Java designed to take advantage of the streams, lambdas, and optionals introduced in Java 8."
|
||||
|
@ -148,4 +148,4 @@ Mirror.ofAllUnwrapped(Test.class, Test2.class) // create the stream of classes
|
|||
[enum]: https://shadowfacts.net/Mirror/net/shadowfacts/mirror/MirrorEnum.html
|
||||
[constructor]: https://shadowfacts.net/Mirror/net/shadowfacts/mirror/MirrorConstructor.html
|
||||
[method]: https://shadowfacts.net/Mirror/net/shadowfacts/mirror/MirrorMethod.html
|
||||
[field]: https://shadowfacts.net/Mirror/net/shadowfacts/mirror/MirrorField.html
|
||||
[field]: https://shadowfacts.net/Mirror/net/shadowfacts/mirror/MirrorField.html
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
```
|
||||
metadata.title = "Kotlin and Minecraft Forge"
|
||||
metadata.category = "minecraft"
|
||||
metadata.tags = ["minecraft"]
|
||||
metadata.date = "2016-08-06 16:45:30 -0400"
|
||||
metadata.oldPermalink = ["/forge/2016/08/06/kotlin-and-forge/", "/minecraft/2016/kotlin-and-minecraft-forge/"]
|
||||
metadata.shortDesc = "So, you wanna use Kotlin in your Forge mod? Well there's good news, I've just released Forgelin, a fork of Emberwalker's Forgelin, a library that provides utilities for using Kotlin with Minecraft/Forge. "
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
```
|
||||
metadata.title = "The Great Redesign"
|
||||
metadata.category = "meta"
|
||||
metadata.tags = ["meta"]
|
||||
metadata.date = "2016-08-07 15:39:48 -0400"
|
||||
metadata.oldPermalink = ["/meta/2016/08/07/the-great-redesign/", "/meta/2016/the-great-redesign/"]
|
||||
metadata.shortDesc = "Welcome to the fourth iteration of my website."
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
```
|
||||
metadata.title = "Type: A FOSS clone of typing.io"
|
||||
metadata.category = "misc"
|
||||
metadata.tags = ["misc"]
|
||||
metadata.date = "2016-10-08 17:29:42 -0400"
|
||||
metadata.oldPermalink = ["/misc/2016/10/08/type/", "/misc/2016/type/"]
|
||||
metadata.shortDesc = "I made an awesome FOSS clone of typing.io that you can check out at type.shadowfacts.net."
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
```
|
||||
metadata.title = "The Pretty Good Minor Update"
|
||||
metadata.category = "meta"
|
||||
metadata.tags = ["meta"]
|
||||
metadata.date = "2017-02-17 14:30:42 -0400"
|
||||
metadata.oldPermalink = ["/meta/2017/02/17/the-pretty-good-minor-update/", "/meta/2017/the-pretty-good-minor-update/"]
|
||||
metadata.shortDesc = "It's been about six months since the last time I redesigned the site, and while I didn't want to redesign it yet again, I felt it could use a little update to make sure everything's still good."
|
||||
|
@ -18,4 +18,4 @@ After reading this [blog post](http://jacquesmattheij.com/the-fastest-blog-in-th
|
|||
|
||||
|
||||
|
||||
Additionally, there's now a fallback `<noscript>` tag so that if the viewer has JavaScript disabled, the site will still look normal (JavaScript being disabled does mean the theme can't be changed, so the user will always see the light theme). And lastly, there's now a custom 404 page so if you end up at the wrong URL, you'll see something nicer than the default 404 page for GitHub Pages.
|
||||
Additionally, there's now a fallback `<noscript>` tag so that if the viewer has JavaScript disabled, the site will still look normal (JavaScript being disabled does mean the theme can't be changed, so the user will always see the light theme). And lastly, there's now a custom 404 page so if you end up at the wrong URL, you'll see something nicer than the default 404 page for GitHub Pages.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
```
|
||||
metadata.title = "Comments Powered by GitHub"
|
||||
metadata.category = "meta"
|
||||
metadata.tags = ["meta"]
|
||||
metadata.date = "2017-04-23 09:05:42 -0400"
|
||||
metadata.oldPermalink = ["/meta/2017/04/23/comments-powered-by-github/", "/meta/2017/comments-powered-by-git-hub/"]
|
||||
metadata.shortDesc = "I built a way of commenting on my static website using GitHub to store comments."
|
||||
|
@ -38,4 +38,4 @@ All of the code for this is open source. The front-end JS is available [here](ht
|
|||
|
||||
And that's it! So, do you like this system? Hate it? Have suggestions for how it could be improved? Well now you can leave a comment.
|
||||
|
||||
[orig]: http://donw.io/post/github-comments/
|
||||
[orig]: http://donw.io/post/github-comments/
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
```
|
||||
metadata.title = "Reincarnation"
|
||||
metadata.category = "meta"
|
||||
metadata.tags = ["meta"]
|
||||
metadata.date = "2019-09-18 10:34:42 -0400"
|
||||
metadata.shortDesc = "Stand by for reincarnation."
|
||||
metadata.oldPermalink = "/meta/2019/reincarnation/"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
```
|
||||
metadata.title = "ActivityPub Resources"
|
||||
metadata.category = "activitypub"
|
||||
metadata.tags = ["activitypub"]
|
||||
metadata.date = "2019-09-22 17:50:42 -0400"
|
||||
metadata.shortDesc = "A compilation of resources I found useful in learning/implementing ActivityPub."
|
||||
metadata.oldPermalink = "/activitypub/2019/activity-pub-resources/"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
```
|
||||
metadata.title = "Learning Elixir"
|
||||
metadata.category = "elixir"
|
||||
metadata.tags = ["elixir"]
|
||||
metadata.date = "2019-10-10 12:29:42 -0400"
|
||||
metadata.shortDesc = "How I learned Elixir and why I love it."
|
||||
metadata.oldPermalink = "/elixir/2019/learning-elixir/"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
```
|
||||
metadata.title = "Building a JavaScript-Free Slide-Over Menu"
|
||||
metadata.category = "web"
|
||||
metadata.tags = ["web"]
|
||||
metadata.date = "2019-11-11 21:08:42 -0400"
|
||||
metadata.shortDesc = "Building a slide-over hamburger menu without using JavaScript."
|
||||
metadata.oldPermalink = "/web/2019/js-free-hamburger-menu/"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
```
|
||||
metadata.title = "Mocking HTTP Requests for iOS App UI Tests"
|
||||
metadata.category = "swift"
|
||||
metadata.tags = ["swift"]
|
||||
metadata.date = "2019-12-22 19:12:42 -0400"
|
||||
metadata.shortDesc = "Integrating a tiny web server into your Xcode UI test target to mock HTTP requests."
|
||||
metadata.oldPermalink = "/ios/2019/mock-http-ios-ui-testing/"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
```
|
||||
metadata.title = "Faking the Mongo Eval Command"
|
||||
metadata.category = "swift"
|
||||
metadata.tags = ["swift"]
|
||||
metadata.date = "2020-01-28 19:33:42 -0400"
|
||||
metadata.shortDesc = "MongoDB 4.2 removed the eval command, which is a good security measure, but unfortunate for building database-viewing GUI."
|
||||
metadata.slug = "faking-mongo-eval"
|
||||
|
@ -81,4 +81,4 @@ let result = output.components(separatedBy: "\n").compactMap { (json) in
|
|||
}
|
||||
```
|
||||
|
||||
And there we have it, the data is finally in a form we can understand from the Swift side of things. If you want to see the whole source code for this, it's [part of MongoView](https://git.shadowfacts.net/shadowfacts/MongoView/src/commit/9488c108b693607e827ef77e5bc16f2cdd491f7c/MongoView/MongoEvaluator.swift). As far as I have come up with, that's about the best way of replicating the `eval` command of previous versions of Mongo. If you have any suggestions for how to improve this or make it more robust, let me know!
|
||||
And there we have it, the data is finally in a form we can understand from the Swift side of things. If you want to see the whole source code for this, it's [part of MongoView](https://git.shadowfacts.net/shadowfacts/MongoView/src/commit/9488c108b693607e827ef77e5bc16f2cdd491f7c/MongoView/MongoEvaluator.swift). As far as I have come up with, that's about the best way of replicating the `eval` command of previous versions of Mongo. If you have any suggestions for how to improve this or make it more robust, let me know!
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
```
|
||||
metadata.title = "Simple Swift Promises"
|
||||
metadata.category = "swift"
|
||||
metadata.tags = ["swift"]
|
||||
metadata.date = "2020-02-18 22:10:42 -0400"
|
||||
metadata.shortDesc = "Building a rudimentary implementation of asynchronous promises in Swift."
|
||||
metadata.slug = "simple-swift-promises"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
```
|
||||
metadata.title = "Writing a JavaScript Syntax Highlighter in Swift"
|
||||
metadata.category = "swift"
|
||||
metadata.tags = ["swift"]
|
||||
metadata.date = "2020-04-09 11:48:42 -0400"
|
||||
metadata.shortDesc = "Things I learned while building a tiny syntax highlighter."
|
||||
metadata.slug = "syntax-highlighting-javascript"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
```
|
||||
metadata.title = "The Sorry State of Thunderbolt 3 Docks"
|
||||
metadata.category = "computers"
|
||||
metadata.tags = ["computers"]
|
||||
metadata.date = "2020-04-13 17:19:42 -0400"
|
||||
metadata.shortDesc = "On a quest to find a Thunderbolt dock that meets my needs."
|
||||
metadata.slug = "thunderbolt-3"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
```
|
||||
metadata.title = "Switching to Vim"
|
||||
metadata.category = "editors"
|
||||
metadata.tags = ["editors"]
|
||||
metadata.date = "2020-05-21 18:22:42 -0400"
|
||||
metadata.shortDesc = "How I went about joining the cult of Vim."
|
||||
```
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
```
|
||||
metadata.title = "Algorithmic Bias"
|
||||
metadata.category = "misc"
|
||||
metadata.tags = ["misc"]
|
||||
metadata.date = "2020-06-05 09:55:42 -0400"
|
||||
metadata.shortDesc = ""
|
||||
```
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
```
|
||||
metadata.title = "Replicating Safari's Link Preview Animation"
|
||||
metadata.category = "swift"
|
||||
metadata.tags = ["swift"]
|
||||
metadata.date = "2020-07-03 16:28:42 -0400"
|
||||
metadata.shortDesc = ""
|
||||
metadata.slug = "uipreviewparameters-textlinerects"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
```
|
||||
metadata.title = "Implement a Gemini Protocol Client Using Network.framework"
|
||||
metadata.category = "swift"
|
||||
metadata.tags = ["swift", "gemini"]
|
||||
metadata.date = "2020-07-22 21:57:42 -0400"
|
||||
metadata.shortDesc = ""
|
||||
metadata.slug = "gemini-network-framework"
|
||||
|
@ -463,4 +463,4 @@ task.resume()
|
|||
|
||||
Network.framework is a super is useful tool for writing custom networking code and building abstractions on top of relatively low level protocols. The example I gave here isn't a hypothetical, I'm using Network.framework and almost this exact code to build a [Gemini browser](https://git.shadowfacts.net/shadowfacts/Gemini) app for Mac and iOS.
|
||||
|
||||
This post has barely scratched the surface, there's even more interesting stuff the framework is capable of, such as building peer-to-peer protocols. The documentation, in particular the [Tic-Tac-Toe sample project](https://developer.apple.com/documentation/network/building_a_custom_peer-to-peer_protocol) is great resource for seeing more of what's possible.
|
||||
This post has barely scratched the surface, there's even more interesting stuff the framework is capable of, such as building peer-to-peer protocols. The documentation, in particular the [Tic-Tac-Toe sample project](https://developer.apple.com/documentation/network/building_a_custom_peer-to-peer_protocol) is great resource for seeing more of what's possible.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
```
|
||||
metadata.title = "SwiftUI Auto-Expanding Text Views"
|
||||
metadata.category = "swift"
|
||||
metadata.tags = ["swift"]
|
||||
metadata.date = "2020-08-29 11:20:42 -0400"
|
||||
metadata.shortDesc = "Building a non-scrolling UITextView for use in SwiftUI layouts."
|
||||
metadata.slug = "swiftui-expanding-text-view"
|
||||
|
|
|
@ -3,9 +3,9 @@ metadata.layout = "default.html.ejs"
|
|||
```
|
||||
|
||||
<div class="main">
|
||||
<h1 class="page-heading"><%= category %> posts</h1>
|
||||
<h1 class="page-heading"><%= tag %> posts</h1>
|
||||
<p class="rss">
|
||||
Subscribe to just <%= category %> posts via <a href="/<%= category %>/feed.xml">RSS</a>.
|
||||
Subscribe to just <%= tag %> posts via <a href="/<%= tag %>/feed.xml">RSS</a>.
|
||||
</p>
|
||||
|
||||
<% for (const post of posts) { %>
|
Loading…
Reference in New Issue