feat: Adds pocket id authentication to caddy, adds server management article.
All checks were successful
CI / release (push) Successful in 6m31s

This commit is contained in:
2025-04-11 08:26:51 -04:00
parent f43a191908
commit b986fe41c3
14 changed files with 295 additions and 144 deletions

View File

@@ -18,14 +18,16 @@ func renderArticles(context: ItemsRenderingContext<ArticleMetadata>) -> Node {
return baseLayout(canocicalURL: "/articles/", section: .articles, title: "Articles", rssLink: "", extraHeader: "") {
// TODO: Add list of tags here that can be navigated to.
sortedByYearDescending.map { year, articles in
div {
div(class: "border-b border-light flex flex-row gap-4 mb-12") {
img(src: "/static/img/calendar.svg", width: "40")
h1(class: "text-4xl font-extrabold pt-3") { year }
}
div(class: "mt-8 bg-slate-800") {
div(class: "pt-8 mx-10") {
div(class: "border-b border-light flex flex-row gap-4 mb-12") {
img(src: "/static/img/calendar.svg", width: "40")
h1(class: "text-4xl font-extrabold pt-3") { year }
}
div(class: "grid gap-10 mb-16") {
articles.map { renderArticleForGrid(article: $0) }
div(class: "grid gap-10 mb-16") {
articles.map { renderArticleForGrid(article: $0, border: false) }
}
}
}
}
@@ -63,60 +65,6 @@ func renderYear<T>(context: PartitionedRenderingContext<T, ArticleMetadata>) ->
baseRenderArticles(context.items, canocicalURL: "/articles/\(context.key)/", title: "Articles in \(context.key)")
}
private struct SearchData: Encodable {
let url: String
let title: String
let body: String
init(article: Item<ArticleMetadata>) throws {
self.url = article.url
self.title = article.title
let rawContent: String = try article.absoluteSource.read()
self.body = Self.parse(rawContent)
}
/// Grabs the metadata (wrapped within `---`), the first title, and the body of the document.
static func parts(from content: String) -> (String?, String?, String) {
let scanner = Scanner(string: content)
var header: String? = nil
var title: String? = nil
if scanner.scanString("---") == "---" {
header = scanner.scanUpToString("---")
_ = scanner.scanString("---")
}
if scanner.scanString("# ") == "# " {
title = scanner.scanUpToString("\n")
}
let body = String(scanner.string[scanner.currentIndex...])
return (header, title, body)
}
static func parse(_ content: String) -> String {
let (_, _, body) = parts(from: content)
return body
.replacingOccurrences(of: "\n", with: " ")
.replacingOccurrences(of: "#", with: "")
}
}
func renderJson(_ articles: ItemsRenderingContext<ArticleMetadata>) throws -> String {
print(articles.items.count)
print(articles.items)
let data = try jsonEncoder.encode(articles.items.map(SearchData.init(article:)))
return String(data: data, encoding: .utf8)!
}
private let jsonEncoder: JSONEncoder = {
let encoder = JSONEncoder()
encoder.outputFormatting = [.prettyPrinted, .sortedKeys]
return encoder
}()
private func baseRenderArticles(
_ articles: [Item<ArticleMetadata>],
canocicalURL: String,