My personal website, in gleam+lustre!
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Clean up the sitemap page a bit

Signed-off-by: MLC Bloeiman <mar@strawmelonjuice.com>

+128 -50
+126 -48
src/homepage.gleam
··· 435 435 Index, 436 436 "Homepage", 437 437 Date(2026, March, 16), 438 - NotFound(uri.empty), 438 + NotFound(""), 439 439 "Welcome to my personal site!", 440 440 ), 441 441 Entry( ··· 484 484 Index, 485 485 "Homepage", 486 486 Date(2026, March, 16), 487 - NotFound(uri.empty), 487 + NotFound(""), 488 488 "Welcome to my personal site!", 489 489 ), 490 490 Entry( ··· 846 846 // No hidden tags to be included. 847 847 use <- bool.guard(tag |> string.starts_with("."), Error(Nil)) 848 848 Ok(Entry( 849 - title: to_title(Tagged(tag)), 849 + title: to_title(Tagged(tag)) |> string.drop_end(13), 850 850 last_updated: post.revised |> option.unwrap(post.published), 851 851 parent: Posts, 852 852 route: Tagged(tag), ··· 858 858 859 859 // One entry for the one category 860 860 list.wrap(Entry( 861 - title: to_title(Category(category)), 861 + title: to_title(Category(category)) |> string.drop_end(13), 862 862 last_updated: post.revised |> option.unwrap(post.published), 863 863 parent: Posts, 864 864 route: Category(category), ··· 891 891 892 892 // For now we render a boring with-depth list, plan is to create a whole graph out of this! 893 893 fn render_sitemap_recursively(start_entry entry: Entry, level level: Int) { 894 + let fake_posts_tags = NotFound("/posts/tagged") 895 + let fake_posts_post = NotFound("/posts/post") 896 + let fake_posts_cats = NotFound("/posts/category") 894 897 let children = 895 - list.filter(sitemap(), fn(maybe_child) { maybe_child.parent == entry.route }) 896 - html.li([], [ 897 - html.a( 898 - [href(entry.route), attribute.class("link link-secondary-content ps-2")], 899 - [element.text(entry.title)], 900 - ), 901 - 902 - case children { 903 - [] -> element.none() 904 - _ -> { 905 - list.map(children, fn(child) { 906 - case child.route == Sitemap { 907 - False -> render_sitemap_recursively(child, level + 1) 908 - // A CHILD OF MY OWN?! 909 - True -> 910 - html.li([], [ 911 - html.span([attribute.class("text-info-content ps-2")], [ 912 - element.text(child.title), 913 - ]), 914 - element.text(" <--- You are here"), 915 - ]) 916 - } 917 - }) 918 - |> html.ul( 898 + sitemap() 899 + |> fn(items) { 900 + use item <- list.map(items) 901 + case item.route { 902 + Tagged(..) -> Entry(..item, parent: fake_posts_tags) 903 + Category(..) -> Entry(..item, parent: fake_posts_cats) 904 + PostById(..) -> Entry(..item, parent: fake_posts_post) 905 + _ -> item 906 + } 907 + } 908 + |> list.prepend(Entry( 909 + route: fake_posts_tags, 910 + title: "", 911 + last_updated: calendar.Date(2003, October, 08), 912 + parent: Posts, 913 + description: "", 914 + )) 915 + |> list.prepend(Entry( 916 + route: fake_posts_post, 917 + title: "", 918 + last_updated: calendar.Date(2003, October, 08), 919 + parent: Posts, 920 + description: "", 921 + )) 922 + |> list.prepend(Entry( 923 + route: fake_posts_cats, 924 + title: "", 925 + last_updated: calendar.Date(2003, October, 08), 926 + parent: Posts, 927 + description: "", 928 + )) 929 + |> list.filter(fn(maybe_child) { maybe_child.parent == entry.route }) 930 + let rendered_children = case children { 931 + [] -> element.none() 932 + _ -> { 933 + list.map(children, fn(child) { 934 + case child.route { 935 + // A CHILD OF MY OWN?! 936 + Sitemap -> 937 + html.li([], [ 938 + html.span([attribute.class("text-info-content ps-2")], [ 939 + element.text(child.title), 940 + ]), 941 + element.text(" <--- You are here"), 942 + ]) 943 + _ -> render_sitemap_recursively(child, level + 1) 944 + } 945 + }) 946 + |> html.ul( 947 + [ 948 + attribute.class( 949 + { 950 + case level, entry.route { 951 + 0, _ -> "list-['===>']" 952 + // Index 953 + 1, _ -> "list-['======>']" 954 + 2, route if route == fake_posts_post -> "list-['----Post:']" 955 + 2, _ -> "list-['=========>']" 956 + _, _ -> "list-disc" 957 + } 958 + } 959 + <> " list-inside mb-2", 960 + ), 961 + ], 962 + _, 963 + ) 964 + } 965 + } 966 + html.li([], case entry.route { 967 + route if route == fake_posts_post -> { 968 + [ 969 + html.span([attribute.class("text-secondary-content font-bold ps-1")], [ 970 + element.text("Posts"), 971 + ]), 972 + rendered_children, 973 + ] 974 + } 975 + route if route == fake_posts_cats -> { 976 + [ 977 + html.span([attribute.class("text-secondary-content font-bold ps-1")], [ 978 + element.text("Categories"), 979 + ]), 980 + rendered_children, 981 + ] 982 + } 983 + route if route == fake_posts_tags -> { 984 + [ 985 + html.span([attribute.class("text-secondary-content font-bold ps-1")], [ 986 + element.text("Tags"), 987 + ]), 988 + html.details( 919 989 [ 920 990 attribute.class( 921 - { 922 - case level, entry.route { 923 - 0, _ -> "list-['===>']" 924 - // Index 925 - 1, Posts -> "list-['----Post:']" 926 - 1, _ -> "list-['======>']" 927 - 2, _ -> "list-['=========>']" 928 - _, _ -> "list-disc" 929 - } 930 - } 931 - <> " list-inside mb-2", 991 + "collapse collapse-plus bg-base-300/10 border-base-300 border p-0 m-0", 932 992 ), 933 993 ], 934 - _, 935 - ) 936 - } 937 - }, 938 - ]) 994 + [ 995 + html.summary([attribute.class("collapse-title font-semibold")], [ 996 + html.text("Click to show"), 997 + ]), 998 + html.div([attribute.class("collapse-content")], [ 999 + rendered_children, 1000 + ]), 1001 + ], 1002 + ), 1003 + ] 1004 + } 1005 + _ -> [ 1006 + html.a( 1007 + [ 1008 + href(entry.route), 1009 + attribute.class("link link-secondary-content ps-2"), 1010 + ], 1011 + [element.text(entry.title)], 1012 + ), 1013 + rendered_children, 1014 + ] 1015 + }) 939 1016 } 940 1017 941 1018 fn post_normalize(takes: Post) -> NormalizedPost { ··· 1054 1131 result.or(dict.get(model.aliases, post_id), int.parse(post_id)), 1055 1132 PostById, 1056 1133 ), 1057 - NotFound(uri:), 1134 + NotFound(path: uri.path), 1058 1135 ) 1059 1136 1060 1137 ["me"] -> Me ··· 1072 1149 1073 1150 ["everything"] -> AllAndEverything 1074 1151 1075 - _ -> NotFound(uri:) 1152 + _ -> NotFound(path: uri.path) 1076 1153 } 1077 1154 } 1078 1155 ··· 1084 1161 CuriculumVitae(True) -> "MLC Bloeiman / Mijn Curiculum Vitae" 1085 1162 PersonalStartPage -> "Startpage" 1086 1163 Links -> "My links and profiles" |> m 1087 - Category(c) -> "Posts about '" <> c <> "'" |> m 1164 + Category(c) -> "Categorised: '" <> c <> "'" |> m 1088 1165 AllAndEverything -> "...Everything!" |> m 1089 - NotFound(uri:) -> "Not found: " <> uri |> uri.to_string() |> m 1166 + NotFound(path:) -> "Not found: " <> path |> m 1090 1167 Portfolio -> "Portfolio" |> m 1091 1168 Me -> "Me" |> m 1092 1169 PostById(id:) -> { ··· 1098 1175 _ -> "Post" |> m 1099 1176 } 1100 1177 } 1178 + Tagged(a) -> "#" <> a |> m 1101 1179 Posts -> "Posts" |> m 1102 1180 Index -> n 1103 1181 _ -> n
+2 -2
src/homepage/stuff.gleam
··· 5 5 import gleam/option.{type Option} 6 6 import gleam/result 7 7 import gleam/time/calendar 8 - import gleam/uri.{type Uri} 8 + import gleam/uri 9 9 import lustre/attribute.{type Attribute} 10 10 import lustre/element.{type Element as LustreElement} 11 11 ··· 123 123 PostById(id: Int) 124 124 Me 125 125 Portfolio 126 - NotFound(uri: Uri) 126 + NotFound(path: String) 127 127 AllAndEverything 128 128 Sitemap 129 129 Category(String)