import Foundation import HTML import Saga func renderArticles(context: ItemsRenderingContext) -> NodeConvertible { let dateFormatter = DateFormatter() dateFormatter.dateFormat = "yyyy" let articlesPerYear = Dictionary(grouping: context.items, by: { dateFormatter.string(from: $0.date) }) let sortedByYearDescending = articlesPerYear.sorted { $0.key > $1.key } return ArticleGrid( articles: sortedByYearDescending, canocicalURL: "/articles/", title: "Articles", rssLink: "", extraHeader: "", header: yearHeader(_:) ) } func renderTag(context: PartitionedRenderingContext) -> NodeConvertible { let extraHeader = link( href: "/articles/tag/\(context.key.slugified)/feed.xml", rel: "alternate", title: "\(SiteMetadata.name): articles with tag \(context.key)", type: "application/rss+xml" ) return baseRenderArticles( (context.key.slugified, context.items), canocicalURL: "/articles/tag/\(context.key.slugified)/", title: "Articles in \(context.key)", rssLink: "tag/\(context.key.slugified)/", extraHeader: extraHeader ) { tag in div(class: "border-b border-light mb-12 px-6 pt-6") { a(href: "/articles") { div(class: "flex flex-row gap-4") { img(src: "/static/img/tag.svg", width: "40") h1(class: "text-4xl font-extrabold") { tag } h1(class: "text-2xl font-extrabold") { "«" } } } } } } func renderYear(context: PartitionedRenderingContext) -> NodeConvertible { baseRenderArticles( (context.key.slugified, context.items), canocicalURL: "/articles/\(context.key)/", title: "Articles in \(context.key)", label: { year in div(class: "border-b border-light pt-6 w-full") { a(href: "/articles/") { div(class: "px-6 flex flex-row gap-4 ") { img(src: "/static/img/calendar.svg", width: "40") h1(class: "text-4xl font-extrabold pt-3") { year } h1(class: "text-2xl font-extrabold") { "«" } } } } } ) } private func yearHeader(_ year: String) -> Node { div(class: "border-b border-light pt-6 w-full") { div(class: "px-6 flex flex-row gap-4 ") { img(src: "/static/img/calendar.svg", width: "40") h1(class: "text-4xl font-extrabold pt-3") { year } } } } private func baseRenderArticles( _ articles: (key: String, value: [Item]), canocicalURL: String, title pageTitle: String, rssLink: String = "", extraHeader: NodeConvertible = Node.fragment([]), @NodeBuilder label: @escaping (String) -> Node = { _ in Node.fragment([]) } ) -> NodeConvertible { ArticleGrid( articles: [articles], canocicalURL: canocicalURL, title: pageTitle, rssLink: rssLink, extraHeader: extraHeader ) { key in label(key) } }