big kahuna

This commit is contained in:
2026-08-15 23:05:57 -06:00
parent 6fec70c7c8
commit 84893662ca
25 changed files with 3886 additions and 27 deletions

134
lib/CW/Layout/Default.pm Normal file
View File

@@ -0,0 +1,134 @@
package CW::Layout::Default;
use Moo;
extends 'CW::Layout';
my $HACKERSPACE_LINK = "https://en.wikipedia.org/wiki/Hackerspace";
sub render {
my ($self) = @_;
my $ctx = $self->ctx // {};
if ( !$ctx->{nav} ) {
$ctx->{nav} = [];
my @path = split '/', $ctx->{env}->{PATH_INFO};
if (@path) {
my $nav = [];
for ( 0 .. $#path ) {
my $text = $path[$_];
my @prev = @path[ 0 .. $_ ];
push @$nav,
{
text => $text,
path => '/' . join( '/', ( @prev, $text ) )
};
}
}
}
my @additional_links;
if ( !$ctx->{user} ) {
push @additional_links, $self->_make_nav_link("login");
}
else {
if ( $ctx->{user}->is_admin ) {
push @additional_links, $self->_make_nav_link("admin");
}
push @additional_links, $self->_make_nav_link("logout");
}
my $board = $ctx->{board} // 'cw';
return [
head => [
title => [ $self->ctx->{title} ],
meta => { charset => 'UTF-8' },
meta => {
name => 'viewport',
content => 'width=device-width, initial-scale=1.0'
},
meta => {
name => 'description',
content => (
$self->ctx->{description}
// 'compiled.world, a gated hackerspace '
. 'for humans to interact with humans'
)
},
meta => {
name => 'robots',
content => 'index, follow'
},
link => {
href => '/static/css/shared.css',
rel => 'stylesheet'
},
link => {
href => '/static/css/' . $board . '.css',
rel => 'stylesheet'
}
],
body => [
header => [
div => [
div => {
class => "header-wrapper"
} => [
img => {
src => "/static/images/$board.svg",
class => "logo"
},
div => [
a => {
href => "/",
style => "text-decoration: none"
} => [
h1 => { style => "margin: 0" } =>
["compiled.world"]
],
p => { style => "margin-top: 0" } => [
"A digital ",
a => {
href => $HACKERSPACE_LINK
} => ["hackerspace"],
" for human beings"
],
nav => { class => "navbar" } => [
(
map { $self->_make_nav_link($_) }
qw(recent popular badges about)
),
@additional_links,
]
]
],
]
],
main => [
nav => { class => "quicknav" } => [
map {
(
li => [
"/",
a => { href => $_->{path} } => [ $_->{text} ]
]
)
} @{ $ctx->{nav} }
],
div => $self->template->render
],
footer => []
]
];
}
sub _make_nav_link {
my ( $self, $text ) = @_;
return a => { class => "navbar-link", href => "/$text" } => [$text];
}
1;