Compare commits

...

10 commits

9 changed files with 157 additions and 11 deletions

View file

@ -9,11 +9,12 @@ description = {
} }
dependencies = { dependencies = {
"arrr ~> 2.2", "arrr ~> 2.2",
"glass ~> 1.3",
"cmark ~> 0.29", "cmark ~> 0.29",
"fun ~> 0.1", "fun ~> 0.1",
"glass ~> 1.3",
"lua-cjson ~> 2.1", "lua-cjson ~> 2.1",
"restia", "restia",
"rgbstr",
"scaffold ~> 1.1", "scaffold ~> 1.1",
"shapeshift ~> 1.1", "shapeshift ~> 1.1",
"skooma", "skooma",

70
css/site.css Normal file
View file

@ -0,0 +1,70 @@
blog-post[hidden] {
display: none;
}
.summary {
font-size: .8em;
font-style: italic;
opacity: .6;
transition: opacity .3s;
tab-stop: 0;
}
.summary:is(:hover, :focus) {
opacity: 1;
}
blog-post {
display: block;
}
blog-post + blog-post {
margin-top: 2em;
}
@layer post-tags {
post-tag > a {
position: relative;
text-decoration: none;
color: inherit;
padding: .2em;
line-height: 1em;
padding-left: 1.2em;
transition: all .3s;
display: inline-block;
}
post-tag > a::before, post-tag > a::after {
z-index: -1;
display: block;
content: '';
border-radius: .2em;
top: .4em;
left: .2em;
width: .6em;
height: .6em;
position: absolute;
background: var(--color);
transition: all .3s;
}
post-tag > a:hover {
color: white;
}
post-tag > a:hover::before {
display: block;
content: '';
border-radius: .2em;
top: 0;
left: 0;
width: 100%;
height: 100%;
position: absolute;
background: var(--color);
}
post-tag > a:hover::after {
background: color-mix(in srgb, var(--color) 60%, white);
}
}

18
javascript/BlogPost.js Normal file
View file

@ -0,0 +1,18 @@
import element from 'https://cdn.jsdelivr.net/gh/darkwiiplayer/js@3724b3e/element.js'
element(class BlogPost extends HTMLElement {
connectedCallback() {
this.filter()
}
get tags() {
return new Set(Array.from(this.querySelectorAll("post-tag")).map(e => e.innerText))
}
filter() {
const search = new URL(document.location).searchParams
if (search.has("tag")) {
this.hidden = !this.tags.has(search.get("tag"))
}
}
})

View file

@ -46,7 +46,11 @@ for file in restia.utils.files(params.input, "^./posts/.*%.md$") do
post.head.timestamp = parsedate(post.head.date) post.head.timestamp = parsedate(post.head.date)
if "string" == type(post.head.tags) then if "string" == type(post.head.tags) then
post.head.tags = string.split(post.head.tags, "%a+") post.head.tags = string.split(post.head.tags, "[%a-]+")
end
for key, tag in ipairs(post.head.tags) do
post.head.tags[key] = string.lower(tag)
end end
post.head.slug = post.head.title post.head.slug = post.head.title

25
lib/tags.lua Normal file
View file

@ -0,0 +1,25 @@
local html = require 'skooma.html'
local rgbstr = require 'rgbstr'
local function tag(name)
local colour = { rgbstr.bytes(name, 16, .3, .5) }
return html.postTag(html.a {
tabindex = 0;
name;
href = "/?tag="..name;
style = "--color: rgb("..table.concat(colour, ', ')..")";
})
end
return function(tags)
if tags then
local list = { gap=".4", style="justify-content: flex-start" }
for _, name in ipairs(tags) do
table.insert(list, tag(name))
end
return {
html.flexRow(list);
html.verticalSpacer();
}
end
end

View file

@ -1,16 +1,20 @@
rgbstr = require 'rgbstr'
slots, json = select 1, ... slots, json = select 1, ...
posts = require 'posts' posts = require 'posts'
tags = require 'tags'
post = => post = =>
a href: @head.uri, color = table.concat({rgbstr.bytes(@head.tags[1], 16, .3, .5)}, " ")
* flexColumn flexColumn class: "info box", style: "--color: rgb(#{color})"
* h2 @head.title, style: "view-transition-name: #{@head.slug}" * h2 a(@head.title, href: @head.uri), style: "view-transition-name: #{@head.slug}"
* tags(@head.tags)
* time is: 'local-date', datetime: @head.date, @head.date * time is: 'local-date', datetime: @head.date, @head.date
* @head.description * @head.description
slots.head title "Index" slots.head title "Index"
slots.head script type: 'module', src: "/javascript/LocalDate.js" slots.head script type: 'module', src: "/javascript/LocalDate.js"
slots.head script type: 'module', src: "/javascript/BlogPost.js"
return main return main
* h1 "Blog Posts" * h1 "Blog Posts"
* nav ul [li post p for p in *posts] * [blogPost post p for p in *posts]

View file

@ -10,6 +10,11 @@ local path = table.concat({
local cpath = path:gsub(".lua", ".so"):gsub("/share/", "/lib/") local cpath = path:gsub(".lua", ".so"):gsub("/share/", "/lib/")
task.clean {
description = "Removes local rocks";
'rm -r lua_modules';
}
task.build { task.build {
description = "Builds the page"; description = "Builds the page";
'mkdir -p .luarocks lua_modules'; 'mkdir -p .luarocks lua_modules';

View file

@ -27,6 +27,7 @@ html
* meta name: "viewport", content: "width=device-width" * meta name: "viewport", content: "width=device-width"
* css 'https://darkwiiplayer.github.io/css/all.css' * css 'https://darkwiiplayer.github.io/css/all.css'
* css 'https://darkwiiplayer.github.io/css/schemes/talia.css' * css 'https://darkwiiplayer.github.io/css/schemes/talia.css'
* css "/css/site.css"
* style styles * style styles
* slots.head * slots.head
* [ link rel: "modulepreload", href: module.url for module in *config.modules when module.preload ] * [ link rel: "modulepreload", href: module.url for module in *config.modules when module.preload ]
@ -38,3 +39,10 @@ html
* ul li a "Home", href: "/" * ul li a "Home", href: "/"
* main * main
* content slots, data * content slots, data
* ->
if #slots.footer > 0
footer class: "box"
* gridBox columns: math.min(#slots.footer, 3), class: 'content-padding'
* slots.footer
else
{}

View file

@ -1,3 +1,4 @@
tags = require 'tags'
import output from require 'params' import output from require 'params'
slots, post = select 1, ... slots, post = select 1, ...
@ -26,7 +27,7 @@ slots.head
positions = (input, character) -> positions = (input, character) ->
((last) => @find(character, last+1, true)), input, 1 ((last) => @find(character, last+1, true)), input, 1
breadcrumb = (href) -> li a :href, href\match('[^/]+$') breadcrumb = (href) -> li a :href, href\match('[^/]+$'), tabindex: 0
if src = post.head.cover_image if src = post.head.cover_image
slots.top pageHero cover: 60 slots.top pageHero cover: 60
@ -37,6 +38,9 @@ if src = post.head.cover_image
else else
slots.title h1(post.head.title, style: "view-transition-name: #{post.head.slug}") slots.title h1(post.head.title, style: "view-transition-name: #{post.head.slug}")
slots.summary div post.head.description, class: "summary", tabindex: 0
slots.summary verticalSpacer
slots.banner aside class: { 'box' } slots.banner aside class: { 'box' }
* b "Hey there!" * b "Hey there!"
* p raw [[ * p raw [[
@ -47,13 +51,20 @@ slots.banner aside class: { 'box' }
]] ]]
* p i "Thank you." * p i "Thank you."
slots.footer aside id: "contact"
* p raw "Got feedback?<br>Tag me on fedi!"
* a "@darkwiiplayer@tech.lgbt", href: 'https://tech.lgbt/@darkwiiplayer'
return (=>@) return (=>@)
* slots.banner
* article * article
* slots.title * slots.title
* slots.summary
* tags(post.head.tags)
* nav { class: "breadcrumbs" } * nav { class: "breadcrumbs" }
* ul * ul
* li a "Blog", href: url "/" * li a "Blog", tabindex: 0, href: url "/"
* [ breadcrumb post.head.uri\sub(1, number-1) for number in positions(post.head.uri, "/") ] * [ breadcrumb post.head.uri\sub(1, number-1) for number in positions(post.head.uri, "/") ]
* li post.head.title, class: 'active' * li post.head.title, class: 'active'
* verticalSpacer
* slots.banner
* raw post.body * raw post.body