#!/usr/bin/env perl use 5.016; use Mojolicious::Lite -signatures; use Mojo::SQLite; use Carp qw(croak); croak qq{No AUTH_HEADER value in environment.} unless exists $ENV{AUTH_HEADER}; croak qq{No AUTH_KEY value in environment.} unless exists $ENV{AUTH_KEY}; my $sql = Mojo::SQLite->new('sqlite:site.db'); helper db => sub { state $db = $sql->db }; $sql->migrations->name('posts_table')->from_string(<migrate; -- 1 up CREATE TABLE IF NOT EXISTS posts ( id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, content TEXT, slug TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- 1 down DROP TABLE posts; EOF $sql->migrations->name('posts_index')->from_string(<migrate; -- 2 up CREATE INDEX IF NOT EXISTS slug_idx ON posts (slug); -- 2 down DROP INDEX slug_idx; EOF get '/' => sub { my $c = shift; $c->reply->static('index.html'); }; get '/blog' => sub { my $c = shift; $c->stash( posts => [ $c->db->select('posts')->hashes->each ] ); $c->render; }; get '/blog/:post' => sub { my $c = shift; my $post = $c->db->select( 'posts', [ 'title', 'content', 'slug' ], { slug => $c->param('post') } )->hash; return $c->render( template => 'not_found', status => 404 ) unless $post; $c->stash( post => $post ); $c->render( template => 'post' ); }; post '/blog' => sub { my $c = shift; my $auth = $c->req->headers->to_hash->{ $ENV{AUTH_HEADER} }; return $c->rendered(400) unless $auth and ( $auth eq $ENV{AUTH_KEY} ); if ( my $old_post = $c->db->select( 'posts', ['id'], { slug => $c->req->json->{slug} } ) ->hash ) { $c->db->update( 'posts', $c->req->json, { id => $old_post->{id} } ); $c->rendered(204); } else { $c->db->insert( 'posts', $c->req->json ); $c->rendered(201); } }; app->start; __DATA__ @@ not_found.html.ep %= include '_header', title => '404 Not Found' %= include '_nav'

404 - Not Found

@@ post.html.ep % use Text::Markdown qw(markdown); <%= $post->{title} %>

<%= $post->{title} %>

<%== markdown($post->{content}) %>
@@ blog.html.ep %= include '_header', title => 'Blog' %= include '_nav'

Blog

This is my blog; it represents my opinions, not that of my employer(s) past, present or future. My blog is made up of Functional Programming, Perl & Raku, Rants, Politics, and whatever else I dream up. If you are prone to becoming upset about things, this might not be the best place for you.

All content is licensed under the Creative-Commons Attribution-ShareALike 3.0 license unless specified otherwise.

Title

Publish Date

% for (@$posts) {
<%= $_->{title} %>
<%= $_->{created_at} %>
% } %= include '_footer' @@ _header.html.ep <%= $title %> @@ _footer.html.ep
Rawley.xyz is powered by:
The Perl Programming Language Alpine Linux
@@ _nav.html.ep