Add menu support
This commit is contained in:
parent
fa2f463b75
commit
bb67021d17
5 changed files with 72 additions and 1 deletions
|
@ -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)
|
||||
}
|
||||
|
|
3
src/gloss/models/menu.gleam
Normal file
3
src/gloss/models/menu.gleam
Normal file
|
@ -0,0 +1,3 @@
|
|||
pub type MenuItem {
|
||||
MenuItem(url: String, name: String)
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
|
|
14
src/gloss/parser/menu.gleam
Normal file
14
src/gloss/parser/menu.gleam
Normal 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()
|
||||
}
|
|
@ -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)])])
|
||||
}),
|
||||
),
|
||||
])
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue