Initial Hakyll and Nix commit
commit
c83f4c78d5
|
@ -0,0 +1,6 @@
|
||||||
|
_cache
|
||||||
|
_site
|
||||||
|
result
|
||||||
|
site
|
||||||
|
site.hi
|
||||||
|
site.o
|
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
title: About Me
|
||||||
|
---
|
||||||
|
I collect the seal photos
|
||||||
|
|
||||||
|
Haven't missed a day yet!
|
|
@ -0,0 +1,3 @@
|
||||||
|
nix-shell --pure -p \
|
||||||
|
"haskellPackages.ghcWithPackages (pkgs: with pkgs; [ hakyll ])" \
|
||||||
|
--command 'ghc --make site'
|
|
@ -0,0 +1,116 @@
|
||||||
|
# Edit this configuration file to define what should be installed on
|
||||||
|
# your system. Help is available in the configuration.nix(5) man page
|
||||||
|
# and in the NixOS manual (accessible by running ‘nixos-help’).
|
||||||
|
|
||||||
|
{ config, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
# List packages installed in system profile. To search, run:
|
||||||
|
# $ nix search wget
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
inetutils
|
||||||
|
mtr
|
||||||
|
sysstat
|
||||||
|
|
||||||
|
# For ACME Certificates
|
||||||
|
certbot
|
||||||
|
];
|
||||||
|
|
||||||
|
#######################################
|
||||||
|
# Security/networking important configs
|
||||||
|
#######################################
|
||||||
|
|
||||||
|
# Open ports for our domain
|
||||||
|
networking = {
|
||||||
|
domain = "cutesealfanpage.love";
|
||||||
|
firewall.allowedTCPPorts = [ 80 443 ];
|
||||||
|
};
|
||||||
|
|
||||||
|
# Add acme LetsEncrypt certs
|
||||||
|
security.acme = {
|
||||||
|
acceptTerms = true;
|
||||||
|
validMinDays = 999;
|
||||||
|
email = "admin@cutesealfanpage.love";
|
||||||
|
|
||||||
|
# uncomment this to use the staging server
|
||||||
|
server = "https://acme-staging-v02.api.letsencrypt.org/directory";
|
||||||
|
};
|
||||||
|
|
||||||
|
#######################################
|
||||||
|
# List services that you want to enable
|
||||||
|
#######################################
|
||||||
|
services = {
|
||||||
|
# Enable the OpenSSH daemon.
|
||||||
|
openssh = {
|
||||||
|
enable = true;
|
||||||
|
permitRootLogin = "no";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Enable the Longview Agent
|
||||||
|
# https://www.linode.com/docs/tools-reference/custom-kernels-distros/install-nixos-on-linode/#enable-longview-agent-optional
|
||||||
|
longview = {
|
||||||
|
enable = true;
|
||||||
|
apiKeyFile = "/var/lib/longview/apiKeyFile";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Nginx config
|
||||||
|
nginx = {
|
||||||
|
enable = true;
|
||||||
|
statusPage = true;
|
||||||
|
recommendedGzipSettings = true;
|
||||||
|
recommendedOptimisation = true;
|
||||||
|
recommendedProxySettings = true;
|
||||||
|
recommendedTlsSettings = true;
|
||||||
|
|
||||||
|
# https://nixos.org/nixos/manual/#module-security-acme-nginx
|
||||||
|
virtualHosts = {
|
||||||
|
|
||||||
|
"cutesealfanpage.love" = {
|
||||||
|
enableACME = true;
|
||||||
|
forceSSL = true;
|
||||||
|
locations."/" = { proxyPass = "http://127.0.0.1:8000"; };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#######################################
|
||||||
|
# Define a user account. Don't forget to set a password with ‘passwd’.
|
||||||
|
#######################################
|
||||||
|
users.users.alice = {
|
||||||
|
isNormalUser = true;
|
||||||
|
home = "/home/alice";
|
||||||
|
description = "Alice Foobar";
|
||||||
|
extraGroups = [
|
||||||
|
"wheel" # Enable ‘sudo’ for the user.
|
||||||
|
"networkmanager"
|
||||||
|
];
|
||||||
|
openssh.authorizedKeys.keys = [
|
||||||
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMeBlGnpJ7dTVcrDdYlMsXFhADIYLc4K/acgsxwbZPOA alice@foobar"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#######################################
|
||||||
|
# NixOS / Linode special options and/or incancations
|
||||||
|
#######################################
|
||||||
|
# This value determines the NixOS release from which the default
|
||||||
|
# settings for stateful data, like file locations and database versions
|
||||||
|
# on your system were taken. It‘s perfectly fine and recommended to leave
|
||||||
|
# this value at the release version of the first install of this system.
|
||||||
|
# Before changing this value read the documentation for this option
|
||||||
|
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
|
||||||
|
system.stateVersion = "20.03"; # Did you read the comment?
|
||||||
|
|
||||||
|
imports = [ # Include the results of the hardware scan.
|
||||||
|
./hardware-configuration.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
# special options and/or incancations
|
||||||
|
boot.loader.grub.enable = true;
|
||||||
|
boot.loader.grub.version = 2;
|
||||||
|
networking.useDHCP = false;
|
||||||
|
networking.interfaces.eth0.useDHCP = true;
|
||||||
|
networking.usePredictableInterfaceNames = false;
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
title: Contact
|
||||||
|
---
|
||||||
|
If you have a seal or seal photos, I'd love to post them!
|
||||||
|
|
||||||
|
Send yours to admin AT cutesealfanpage.love
|
|
@ -0,0 +1,141 @@
|
||||||
|
html {
|
||||||
|
font-size: 62.5%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-size: 1.6rem;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
header {
|
||||||
|
border-bottom: 0.2rem solid #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
nav {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
nav a {
|
||||||
|
font-size: 1.8rem;
|
||||||
|
font-weight: bold;
|
||||||
|
color: black;
|
||||||
|
text-decoration: none;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
margin-top: 3rem;
|
||||||
|
padding: 1.2rem 0;
|
||||||
|
border-top: 0.2rem solid #000;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
color: #555;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 2.4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
article .header {
|
||||||
|
font-size: 1.4rem;
|
||||||
|
font-style: italic;
|
||||||
|
color: #555;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo a {
|
||||||
|
font-weight: bold;
|
||||||
|
color: #000;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 319px) {
|
||||||
|
body {
|
||||||
|
width: 90%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0 5%;
|
||||||
|
}
|
||||||
|
header {
|
||||||
|
margin: 4.2rem 0;
|
||||||
|
}
|
||||||
|
nav {
|
||||||
|
margin: 0 auto 3rem;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
footer {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.logo {
|
||||||
|
text-align: center;
|
||||||
|
margin: 1rem auto 3rem;
|
||||||
|
}
|
||||||
|
.logo a {
|
||||||
|
font-size: 2.4rem;
|
||||||
|
}
|
||||||
|
nav a {
|
||||||
|
display: block;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 320px) {
|
||||||
|
body {
|
||||||
|
width: 90%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0 5%;
|
||||||
|
}
|
||||||
|
header {
|
||||||
|
margin: 4.2rem 0;
|
||||||
|
}
|
||||||
|
nav {
|
||||||
|
margin: 0 auto 3rem;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
footer {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.logo {
|
||||||
|
text-align: center;
|
||||||
|
margin: 1rem auto 3rem;
|
||||||
|
}
|
||||||
|
.logo a {
|
||||||
|
font-size: 2.4rem;
|
||||||
|
}
|
||||||
|
nav a {
|
||||||
|
display: inline;
|
||||||
|
margin: 0 0.6rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 640px) {
|
||||||
|
body {
|
||||||
|
width: 60rem;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
header {
|
||||||
|
margin: 0 0 3rem;
|
||||||
|
padding: 1.2rem 0;
|
||||||
|
}
|
||||||
|
nav {
|
||||||
|
margin: 0;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
nav a {
|
||||||
|
margin: 0 0 0 1.2rem;
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
footer {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
.logo {
|
||||||
|
margin: 0;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
.logo a {
|
||||||
|
float: left;
|
||||||
|
font-size: 1.8rem;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
{ pkgs ? import <nixpkgs> { } }:
|
||||||
|
|
||||||
|
pkgs.stdenv.mkDerivation rec {
|
||||||
|
pname = "test-blog";
|
||||||
|
version = "latest";
|
||||||
|
src = "./${pname}";
|
||||||
|
phases = "installPhase";
|
||||||
|
buildInputs =
|
||||||
|
[ "haskellPackages.ghcWithPackages (pkgs: with pkgs; [ hakyll ])" ];
|
||||||
|
installPhase = ''
|
||||||
|
echo Install Phase
|
||||||
|
'';
|
||||||
|
buildPhase = ''
|
||||||
|
ghc --make site
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
|
||||||
|
pkgs.run-command "my-example" {} ''
|
||||||
|
echo My example command is running
|
||||||
|
|
||||||
|
pwd
|
||||||
|
cd test-blog
|
||||||
|
|
||||||
|
./site watch
|
||||||
|
''
|
|
@ -0,0 +1,83 @@
|
||||||
|
# Deploy script
|
||||||
|
#
|
||||||
|
# Run with
|
||||||
|
# $ sudo ./deploy.sh
|
||||||
|
# and enter password
|
||||||
|
# Change up user and IP as appropriate
|
||||||
|
# for each site
|
||||||
|
# Add this for dry-run:
|
||||||
|
# --dry-run \
|
||||||
|
# time added for timing at the end. Check Real time
|
||||||
|
echo "rsycing the blog to remote"
|
||||||
|
echo "please enter remote alice password:"
|
||||||
|
time rsync \
|
||||||
|
--recursive \
|
||||||
|
--update \
|
||||||
|
--executability \
|
||||||
|
--times \
|
||||||
|
--compress \
|
||||||
|
--stats \
|
||||||
|
--rsh=ssh \
|
||||||
|
../seal-blog \
|
||||||
|
alice@172.105.4.234:/home/alice
|
||||||
|
|
||||||
|
# Move the configuration script
|
||||||
|
# scp configuration.nix alice@172.105.4.234:/etc/nixos/configuration.nix
|
||||||
|
|
||||||
|
# Restart NixOS
|
||||||
|
# ssh -t alice@172.105.4.234 sudo nixos-rebuild switch
|
||||||
|
|
||||||
|
# Kill the website
|
||||||
|
# ssh -t alice@172.105.4.234 pkill site
|
||||||
|
|
||||||
|
# Build the site
|
||||||
|
# ssh -t alice@172.105.4.234
|
||||||
|
echo -e "\n\nCopy files over finished!"
|
||||||
|
echo -e "\n\n\nAlice needs to do some steps"
|
||||||
|
echo "Enter her password so she can get to work:"
|
||||||
|
ssh -t alice@172.105.4.234 "
|
||||||
|
alias echo='echo -e'
|
||||||
|
|
||||||
|
echo 'Now enter her password for sudo inside the ssh'
|
||||||
|
sudo echo 'echo ULTIMATE POWER'
|
||||||
|
|
||||||
|
echo '\nMake sure we know where we are'
|
||||||
|
ls
|
||||||
|
pwd
|
||||||
|
|
||||||
|
echo '\ncd seal-blog'
|
||||||
|
cd seal-blog
|
||||||
|
|
||||||
|
echo 'copy the configuration over'
|
||||||
|
echo 'TODO: make this only if changed'
|
||||||
|
sudo mv configuration.nix /etc/nixos/configuration.nix
|
||||||
|
|
||||||
|
echo '\nRebuild NixOS'
|
||||||
|
echo 'TODO: make this only if changed'
|
||||||
|
echo sudo nixos-rebuild switch
|
||||||
|
|
||||||
|
echo '\npkill the site'
|
||||||
|
echo 'TODO: make this only if necessary'
|
||||||
|
echo pkill site
|
||||||
|
|
||||||
|
echo '\nBuild the site'
|
||||||
|
echo 'TODO: shouldnt need to build on deploy server'
|
||||||
|
echo ./build.sh
|
||||||
|
|
||||||
|
echo 'Start the site in the background using nohup'
|
||||||
|
echo 'TODO: make this only if necessary'
|
||||||
|
echo nohup 'site watch' >>/dev/null 2>>/dev/null &
|
||||||
|
echo site watch &
|
||||||
|
echo disown
|
||||||
|
echo '\n\nDeploy finished!\n\n'
|
||||||
|
"
|
||||||
|
|
||||||
|
# on alice
|
||||||
|
# ssh -t alice@172.105.4.234
|
||||||
|
# in a week (August 21st)
|
||||||
|
# need to run `sudo certbot certonly`
|
||||||
|
# get the cert for the site, and set it in nginx
|
||||||
|
|
||||||
|
# nohup
|
||||||
|
# https://superuser.com/a/38567
|
||||||
|
# https://en.wikipedia.org/wiki/Nohup
|
|
@ -0,0 +1,11 @@
|
||||||
|
name: seal-blog
|
||||||
|
version: 0.1.0.0
|
||||||
|
build-type: Simple
|
||||||
|
cabal-version: >= 1.10
|
||||||
|
|
||||||
|
executable site
|
||||||
|
main-is: site.hs
|
||||||
|
build-depends: base == 4.*
|
||||||
|
, hakyll == 4.13.*
|
||||||
|
ghc-options: -threaded
|
||||||
|
default-language: Haskell2010
|
|
@ -0,0 +1,222 @@
|
||||||
|
{-# LANGUAGE QuasiQuotes #-}
|
||||||
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
|
-- enter in repl:
|
||||||
|
-- :set -XOverloadedStrings
|
||||||
|
|
||||||
|
import System.IO.Unsafe ( unsafePerformIO )
|
||||||
|
import System.Random ( randomRIO )
|
||||||
|
import System.Directory ( listDirectory )
|
||||||
|
import Control.Monad ( forM, forM_, replicateM )
|
||||||
|
import Data.Text (Text)
|
||||||
|
import qualified Data.Text as T
|
||||||
|
import qualified Data.Text.IO as TIO
|
||||||
|
import Data.List
|
||||||
|
import Data.Time.Calendar
|
||||||
|
import Data.Time.Clock
|
||||||
|
import NeatInterpolation
|
||||||
|
-- https://hackage.haskell.org/package/neat-interpolation-0.3.2.1/docs/NeatInterpolation.html
|
||||||
|
|
||||||
|
|
||||||
|
{-
|
||||||
|
Gives a random number between from and to
|
||||||
|
Uses unsafeIO to get the number out of IO
|
||||||
|
It's safe because we're only shuffling
|
||||||
|
-}
|
||||||
|
randomNum from to =
|
||||||
|
unsafePerformIO $
|
||||||
|
randomRIO (from, to)
|
||||||
|
|
||||||
|
{-
|
||||||
|
Given a list, returns a random element
|
||||||
|
-}
|
||||||
|
randomPull lst = lst !! r'
|
||||||
|
where r' = randomNum 0 l
|
||||||
|
l = length lst - 1
|
||||||
|
|
||||||
|
blogPost
|
||||||
|
:: Text
|
||||||
|
-> Text
|
||||||
|
-> Text
|
||||||
|
-> Text
|
||||||
|
-> Text
|
||||||
|
-> Day
|
||||||
|
-> Text
|
||||||
|
blogPost title see adj1 adj2 seal date =
|
||||||
|
[text|
|
||||||
|
---
|
||||||
|
title: $title
|
||||||
|
---
|
||||||
|
|
||||||
|
$see this $adj1, $adj2 seal!
|
||||||
|
<img
|
||||||
|
src="/images/$seal"
|
||||||
|
alt="A picture of a $adj1, $adj2 seal! <3"
|
||||||
|
width="400"
|
||||||
|
/>
|
||||||
|
|]
|
||||||
|
|
||||||
|
-- Returns a filePath, and a corresponding random blog post
|
||||||
|
sealText :: Integer -> Day -> (FilePath, Text)
|
||||||
|
sealText n date = ( fileName', blogPost')
|
||||||
|
where
|
||||||
|
fileName' =
|
||||||
|
show date ++ "-"
|
||||||
|
++ "seal-post-"
|
||||||
|
++ show n
|
||||||
|
++ ".markdown"
|
||||||
|
date' = T.pack . show $ date
|
||||||
|
title = T.pack $ "Seal Post Number " ++ show n
|
||||||
|
title' = T.replace " " "-" title
|
||||||
|
blogPost' =
|
||||||
|
blogPost
|
||||||
|
title
|
||||||
|
(randomPull looks)
|
||||||
|
(randomPull adjectives)
|
||||||
|
(randomPull adjectives')
|
||||||
|
(randomPull sealImages)
|
||||||
|
date
|
||||||
|
|
||||||
|
|
||||||
|
-- Generating all the previous blog posts
|
||||||
|
-- Only need to do this once
|
||||||
|
-- Another function takes care of creating today's blog post
|
||||||
|
startDate = fromGregorian 1998 06 11
|
||||||
|
-- startDate = fromGregorian 2020 07 31
|
||||||
|
{-# NOINLINE today #-}
|
||||||
|
today = unsafePerformIO $ utctDay <$> getCurrentTime
|
||||||
|
daysSinceStart = diffDays today startDate
|
||||||
|
allDatesSinceStart = map (`addDays` startDate) [1..daysSinceStart]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
allBlogPosts = map f zipped
|
||||||
|
where
|
||||||
|
f = uncurry sealText
|
||||||
|
zipped = zip [1..] allDatesSinceStart
|
||||||
|
|
||||||
|
writeToFile (fp, txt) = write fp' txt
|
||||||
|
where
|
||||||
|
write = TIO.writeFile
|
||||||
|
fp' = "posts/" ++ fp
|
||||||
|
|
||||||
|
|
||||||
|
-- For all the blog posts
|
||||||
|
-- Write them to file
|
||||||
|
unsafeGenerateAllBlogs = forM_ allBlogPosts writeToFile
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
prettyPrint :: Show a => [a] -> IO ()
|
||||||
|
prettyPrint = putStr . unlines . map show
|
||||||
|
|
||||||
|
{-
|
||||||
|
Adjectives
|
||||||
|
-}
|
||||||
|
adjectives :: [Text]
|
||||||
|
adjectives =
|
||||||
|
[ "absorbing"
|
||||||
|
, "adorable"
|
||||||
|
, "alluring"
|
||||||
|
, "ambrosial"
|
||||||
|
, "amiable"
|
||||||
|
, "appealing"
|
||||||
|
, "attractive"
|
||||||
|
, "beautiful"
|
||||||
|
, "bewitching"
|
||||||
|
, "captivating"
|
||||||
|
, "charismatic"
|
||||||
|
, "charming"
|
||||||
|
, "choice"
|
||||||
|
, "cute"
|
||||||
|
, "dainty"
|
||||||
|
, "darling"
|
||||||
|
, "dear"
|
||||||
|
, "delectable"
|
||||||
|
, "delicate"
|
||||||
|
, "delicious"
|
||||||
|
, "delightful"
|
||||||
|
, "desirable"
|
||||||
|
, "dishy"
|
||||||
|
, "dreamy"
|
||||||
|
, "electrifying"
|
||||||
|
, "elegant"
|
||||||
|
, "enamoring"
|
||||||
|
, "engaging"
|
||||||
|
, "engrossing"
|
||||||
|
, "enthralling"
|
||||||
|
, "entrancing"
|
||||||
|
, "eye-catching"
|
||||||
|
, "fascinating"
|
||||||
|
, "fetching"
|
||||||
|
, "glamorous"
|
||||||
|
, "graceful"
|
||||||
|
, "heavenly"
|
||||||
|
, "infatuating"
|
||||||
|
, "inviting"
|
||||||
|
, "irresistible"
|
||||||
|
, "likable"
|
||||||
|
, "lovable"
|
||||||
|
, "lovely"
|
||||||
|
, "magnetizing"
|
||||||
|
, "nice"
|
||||||
|
, "pleasant"
|
||||||
|
, "precious"
|
||||||
|
, "pretty"
|
||||||
|
, "provocative"
|
||||||
|
, "rapturous"
|
||||||
|
, "ravishing"
|
||||||
|
, "seducing"
|
||||||
|
, "seductive"
|
||||||
|
, "suave"
|
||||||
|
, "sweet"
|
||||||
|
, "tantalizing"
|
||||||
|
, "tempting"
|
||||||
|
, "titillating"
|
||||||
|
, "winning"
|
||||||
|
, "winsome"
|
||||||
|
]
|
||||||
|
|
||||||
|
adjectives' :: [Text]
|
||||||
|
adjectives' =
|
||||||
|
[ "ample"
|
||||||
|
, "bearish"
|
||||||
|
, "big"
|
||||||
|
, "butterball"
|
||||||
|
, "buxom"
|
||||||
|
, "chunky"
|
||||||
|
, "fatty"
|
||||||
|
, "flabby"
|
||||||
|
, "fleshy"
|
||||||
|
, "full-figured"
|
||||||
|
, "hefty"
|
||||||
|
, "husky"
|
||||||
|
, "pleasingly plump"
|
||||||
|
, "plump"
|
||||||
|
, "plumpish"
|
||||||
|
, "podgy"
|
||||||
|
, "portly"
|
||||||
|
, "pudgy"
|
||||||
|
, "roly-poly"
|
||||||
|
, "rotund"
|
||||||
|
, "round"
|
||||||
|
, "stout"
|
||||||
|
, "tubby"
|
||||||
|
, "zaftig"
|
||||||
|
]
|
||||||
|
|
||||||
|
looks :: [Text]
|
||||||
|
looks =
|
||||||
|
[ "Look at"
|
||||||
|
, "Gaze upon"
|
||||||
|
, "Check out"
|
||||||
|
, "Witness!"
|
||||||
|
, "Look upon and tremble at"
|
||||||
|
, "Lookie here at"
|
||||||
|
, "Whoa! See"
|
||||||
|
]
|
||||||
|
|
||||||
|
sealImages :: [Text]
|
||||||
|
sealImages = map T.pack
|
||||||
|
. sort
|
||||||
|
. unsafePerformIO
|
||||||
|
$ listDirectory "images/seals"
|
|
@ -0,0 +1,16 @@
|
||||||
|
---
|
||||||
|
title: Seal Blog!
|
||||||
|
---
|
||||||
|
|
||||||
|
<h2>Welcome</h2>
|
||||||
|
|
||||||
|
<img src="/images/seal1.jpg" style="float: right; margin: 10px;" width="200px"/>
|
||||||
|
|
||||||
|
<p>Welcome to my seal blog!</p>
|
||||||
|
|
||||||
|
<p>Here's a list of recent posts for your reading pleasure:</p>
|
||||||
|
|
||||||
|
<h2>Seal Posts</h2>
|
||||||
|
$partial("templates/post-list.html")$
|
||||||
|
|
||||||
|
<p>…or you can find more in the <a href="/archive.html">archives</a>.</p>
|
|
@ -0,0 +1,67 @@
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
|
import Data.Monoid (mappend)
|
||||||
|
import Hakyll
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
main :: IO ()
|
||||||
|
main = hakyll $ do
|
||||||
|
match "images/*" $ do
|
||||||
|
route idRoute
|
||||||
|
compile copyFileCompiler
|
||||||
|
|
||||||
|
match "css/*" $ do
|
||||||
|
route idRoute
|
||||||
|
compile compressCssCompiler
|
||||||
|
|
||||||
|
match (fromList ["about.rst", "contact.markdown"]) $ do
|
||||||
|
route $ setExtension "html"
|
||||||
|
compile $ pandocCompiler
|
||||||
|
>>= loadAndApplyTemplate "templates/default.html" defaultContext
|
||||||
|
>>= relativizeUrls
|
||||||
|
|
||||||
|
match "posts/*" $ do
|
||||||
|
route $ setExtension "html"
|
||||||
|
compile $ pandocCompiler
|
||||||
|
>>= loadAndApplyTemplate "templates/post.html" postCtx
|
||||||
|
>>= loadAndApplyTemplate "templates/default.html" postCtx
|
||||||
|
>>= relativizeUrls
|
||||||
|
|
||||||
|
create ["archive.html"] $ do
|
||||||
|
route idRoute
|
||||||
|
compile $ do
|
||||||
|
posts <- recentFirst =<< loadAll "posts/*"
|
||||||
|
let archiveCtx =
|
||||||
|
listField "posts" postCtx (return posts) `mappend`
|
||||||
|
constField "title" "Archives" `mappend`
|
||||||
|
defaultContext
|
||||||
|
|
||||||
|
makeItem ""
|
||||||
|
>>= loadAndApplyTemplate "templates/archive.html" archiveCtx
|
||||||
|
>>= loadAndApplyTemplate "templates/default.html" archiveCtx
|
||||||
|
>>= relativizeUrls
|
||||||
|
|
||||||
|
|
||||||
|
match "index.html" $ do
|
||||||
|
route idRoute
|
||||||
|
compile $ do
|
||||||
|
posts <- recentFirst =<< loadAll "posts/*"
|
||||||
|
let indexCtx =
|
||||||
|
listField "posts" postCtx (return posts) `mappend`
|
||||||
|
constField "title" "Home" `mappend`
|
||||||
|
defaultContext
|
||||||
|
|
||||||
|
getResourceBody
|
||||||
|
>>= applyAsTemplate indexCtx
|
||||||
|
>>= loadAndApplyTemplate "templates/default.html" indexCtx
|
||||||
|
>>= relativizeUrls
|
||||||
|
|
||||||
|
match "templates/*" $ compile templateBodyCompiler
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
postCtx :: Context String
|
||||||
|
postCtx =
|
||||||
|
dateField "date" "%B %e, %Y" `mappend`
|
||||||
|
defaultContext
|
|
@ -0,0 +1,2 @@
|
||||||
|
Here you can find all my previous posts:
|
||||||
|
$partial("templates/post-list.html")$
|
|
@ -0,0 +1,33 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title>My Seal Blog - $title$</title>
|
||||||
|
<link rel="stylesheet" href="/css/default.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<header>
|
||||||
|
<div class="logo">
|
||||||
|
<a href="/">My Seal Blog</a>
|
||||||
|
</div>
|
||||||
|
<nav>
|
||||||
|
<a href="/">Home</a>
|
||||||
|
<a href="/about.html">About</a>
|
||||||
|
<a href="/contact.html">Contact</a>
|
||||||
|
<a href="/archive.html">Archive</a>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<main role="main">
|
||||||
|
<h1>$title$</h1>
|
||||||
|
$body$
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<footer>
|
||||||
|
Site proudly generated by
|
||||||
|
<a href="http://jaspervdj.be/hakyll">Hakyll</a>
|
||||||
|
</footer>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,7 @@
|
||||||
|
<ul>
|
||||||
|
$for(posts)$
|
||||||
|
<li>
|
||||||
|
<a href="$url$">$title$</a> - $date$
|
||||||
|
</li>
|
||||||
|
$endfor$
|
||||||
|
</ul>
|
|
@ -0,0 +1,11 @@
|
||||||
|
<article>
|
||||||
|
<section class="header">
|
||||||
|
Posted on $date$
|
||||||
|
$if(author)$
|
||||||
|
by $author$
|
||||||
|
$endif$
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
$body$
|
||||||
|
</section>
|
||||||
|
</article>
|
Loading…
Reference in New Issue