Add menu support

This commit is contained in:
Mikko Ahlroth 2024-04-07 20:05:56 +03:00
parent fa2f463b75
commit bb67021d17
5 changed files with 72 additions and 1 deletions

View file

@ -4,6 +4,7 @@ import gleam/option.{None, Some}
import gleam/order.{type Order}
import gloss/models/post.{type Post, type Tag}
import gloss/models/page.{type Page}
import gloss/models/menu.{type MenuItem}
import gloss/utils/date.{type Month}
import gloss/utils/ordered_tree.{type OrderedTree}
import gloss/utils/uniqid.{type Generator, type UniqID}
@ -28,6 +29,7 @@ pub opaque type Database {
Database(
posts: OrderedTree(PostWithID),
pages: List(Page),
menu: List(MenuItem),
tags: TagPosts,
years: YearPosts,
posts_by_id: Dict(PostID, Post),
@ -39,6 +41,7 @@ pub fn new() -> Database {
Database(
posts: new_tree(),
pages: [],
menu: [],
tags: dict.new(),
years: dict.new(),
posts_by_id: dict.new(),
@ -101,6 +104,10 @@ pub fn add_page(db: Database, page: Page) -> Database {
Database(..db, pages: [page, ..db.pages])
}
pub fn set_menu(db: Database, menu: List(MenuItem)) -> Database {
Database(..db, menu: menu)
}
pub fn tags(db: Database) {
db.tags
}
@ -120,6 +127,10 @@ pub fn pages(db: Database) {
db.pages
}
pub fn menu(db: Database) {
db.menu
}
fn new_tree() -> OrderedTree(PostWithID) {
ordered_tree.new(comparator)
}

View file

@ -0,0 +1,3 @@
pub type MenuItem {
MenuItem(url: String, name: String)
}

View file

@ -6,6 +6,7 @@ import gloss/models/database.{type Database}
import gloss/parser/common
import gloss/parser/post
import gloss/parser/page
import gloss/parser/menu
const default_data_path = "./data"
@ -15,11 +16,13 @@ pub type Parser =
pub type ParseError {
FileError(path: String, err: fs.FSError)
PostParseError(filename: String, err: common.ParseError)
MenuParseError
}
pub fn default_parse() -> Result(Database, ParseError) {
parse_posts(database.new(), post_path())
|> result.try(parse_pages(_, page_path()))
|> result.try(parse_menu(_, menu_path()))
}
pub fn parse_posts(db: Database, path: String) -> Result(Database, ParseError) {
@ -77,6 +80,26 @@ pub fn parse_pages(db: Database, path: String) -> Result(Database, ParseError) {
Ok(list.fold(pages, db, database.add_page))
}
pub fn parse_menu(db: Database, file: String) -> Result(Database, ParseError) {
case fs.exists(file) {
Ok(True) -> {
use contents <- result.try(
fs.read_file(file)
|> result.map_error(fn(err) { FileError(file, err) }),
)
use menu <- result.try(
menu.parse(contents)
|> result.replace_error(MenuParseError),
)
Ok(database.set_menu(db, menu))
}
_ -> Ok(db)
}
}
fn post_path() {
default_data_path <> "/posts"
}
@ -84,3 +107,7 @@ fn post_path() {
fn page_path() {
default_data_path <> "/pages"
}
fn menu_path() {
default_data_path <> "/menu"
}

View file

@ -0,0 +1,14 @@
import gleam/list
import gleam/string
import gleam/result
import gloss/models/menu.{MenuItem}
pub fn parse(content: String) {
string.split(content, "\n")
|> list.filter(fn(line) { string.length(line) != 0 })
|> list.map(fn(line) {
use #(url, name) <- result.try(string.split_once(line, " "))
Ok(MenuItem(url: url, name: name))
})
|> result.all()
}

View file

@ -11,6 +11,7 @@ import lustre/element/html.{
}
import lustre/attribute.{attribute, href, id, name, rel, role, style, value}
import gloss/models/database.{type Database}
import gloss/models/menu.{type MenuItem}
import gloss/utils/ordered_tree
import gloss/utils/date
import gloss/config.{type Configuration}
@ -37,7 +38,7 @@ fn pre_render(db, config) -> PreRendered {
}
fn view(
_db: Database,
db: Database,
config: Configuration,
pre_rendered: PreRendered,
inner: Element(Nil),
@ -71,6 +72,10 @@ fn view(
text(config.blog_name),
]),
]),
case database.menu(db) {
[] -> element.none()
m -> menu(m)
},
]),
main([], [inner]),
section([id("sidebar")], [
@ -192,3 +197,14 @@ fn archives(db: Database, config: Configuration) {
})
|> ul([], _)
}
fn menu(menu: List(MenuItem)) {
nav([], [
ul(
[],
list.map(menu, fn(item) {
li([], [a([href(item.url)], [text(item.name)])])
}),
),
])
}