About
This Website
Generator and Backend
I use a static content generator called Hakyll, it is written in Haskell. I mostly wanted to try this language, but some features where particularly appealing to me:
Pandoc support:
Pandoc is a document converter written in Haskell, it is very complete and can convert most markup languages to HTML and PDF. One cool thing is that Hakyll as built-in rules for document conversion, so you can write your content in Markdown, AsciiDoc, Org-Mode, etc…
Haskell:
This language possesses some very interesting features, but mostly, it is purely functional, prevent unspecified side effects, and its foundations are laid on a strict theory.
Served by Caddy2:
The minimal loss in performances (compared to Nginx) is counterbalanced by the ease of use. My complete config file (even with specific HTTP headers and TLS ciphers) is about 20 lines.
Hosted on a VPS at OVH.
The future
I plan to move away from this Haskell generator, it has some advantages but I’m not happy with the ecosystem and its chain of dependecies. I envision to keep pandoc for the moment, as it is disponible on most distrubutions, but to replace hakyll by a lighter solution written in C (maybe this one: https://git.codemadness.org/saait/file/README.html).
Tags
I was able to add tags to Hakyll thanks to Javran’s tutorial.
Where are the Sources ?
I’m an advocate of FOSS, but I use separate branches to write posts, some of them may never be merged into the master, and I don’t want to make public the drafts.
From what I understand, there is no simple way to keep private a branch on a public repo:
Neither on Gitlab
Nor on Github
I like to keep things simple, so until I find a better solution than these ones, I will keep this repo private.
A last, you can click here to get my site.hs.
{-# LANGUAGE OverloadedStrings #-} import Hakyll postCtx :: Context String = dateField "date" "%B %e, %Y" <> defaultContext postCtx postCtxWithTags :: Tags -> Context String = tagsField "tags" tags <> postCtx postCtxWithTags tags rssFeed :: Rules () = do rssFeed let myFeedConfiguration = FeedConfiguration = "David Tabarie" { feedTitle = , feedDescription "A personal website/blog on tech and other things..." = "David Tabarie" , feedAuthorName = "david.tabarie@pm.me" , feedAuthorEmail = "http://dtabarie.com" , feedRoot } "rss.xml"] $ do create [ route idRoute$ do compile let feedCtx = postCtx `mappend` bodyField "description" <- fmap (take 10) . recentFirst =<< loadAllSnapshots "posts/*" "content" posts renderRss myFeedConfiguration feedCtx posts matchKeys :: Rules () = do matchKeys "keys/*" $ do match route idRoute compile copyFileCompiler matchRobotTxt :: Rules () = do matchRobotTxt "robots.txt" $ do match route idRoute compile copyFileCompiler matchImages :: Rules () = do matchImages "images/*" $ do match route idRoute compile copyFileCompiler matchFonts :: Rules () = do matchFonts "fonts/*" $ do match route idRoute compile copyFileCompiler matchCV :: Rules () = do matchCV "cv/*" $ do match route idRoute compile copyFileCompiler matchCSS :: Rules () = do matchCSS "css/*" $ do match route idRoute compile compressCssCompiler matchAbout :: Rules () = do matchAbout "about.org" $ do match $ setExtension "html" route $ compile >>= pandocCompiler "templates/default.html" defaultContext >>= loadAndApplyTemplate relativizeUrls matchContact :: Rules () = do matchContact "contact.org" $ do match $ setExtension "html" route $ compile >>= pandocCompiler "templates/default.html" defaultContext >>= loadAndApplyTemplate relativizeUrls matchCVFormats :: Rules () = do matchCVFormats "cv-formats.org" $ do match $ setExtension "html" route $ compile >>= pandocCompiler "templates/default.html" defaultContext >>= loadAndApplyTemplate relativizeUrls matchPosts :: Tags -> Rules () = do matchPosts tags "posts/*" $ do match $ setExtension "html" route $ compile >>= pandocCompiler "templates/post.html" (postCtxWithTags tags) >>= loadAndApplyTemplate "content" >>= saveSnapshot "templates/default.html" (postCtxWithTags tags) >>= loadAndApplyTemplate relativizeUrls createArchive :: Rules () = do createArchive "archive.html"] $ do create [ route idRoute$ do compile <- recentFirst =<< loadAll "posts/*" posts let archiveCtx = "posts" postCtx (return posts) <> listField "title" "Archives" <> defaultContext constField "" >>= loadAndApplyTemplate "templates/archive.html" archiveCtx >>= makeItem "templates/default.html" archiveCtx >>= loadAndApplyTemplate relativizeUrls matchIndex :: Rules () = do matchIndex "index.html" $ do match route idRoute$ do compile <- recentFirst =<< loadAll "posts/*" posts let indexCtx = "posts" postCtx (return posts) <> listField "title" "Home" <> defaultContext constField >>= applyAsTemplate indexCtx >>= getResourceBody "templates/default.html" indexCtx >>= loadAndApplyTemplate relativizeUrls matchTemplates :: Rules () = do matchTemplates "templates/*" $ compile templateBodyCompiler match makeTagPage :: Tags -> Rules () = do makeTagPage tags $ \tag tagpattern -> do tagsRules tags let title = "Posts tagged \"" ++ tag ++ "\"" route idRoute$ do compile <- recentFirst =<< loadAll tagpattern posts let ctx = "title" title <> constField "posts" (postCtxWithTags tags) (return posts) <> listField defaultContext"" >>= loadAndApplyTemplate "templates/tag.html" ctx >>= makeItem "templates/default.html" ctx >>= loadAndApplyTemplate relativizeUrls main :: IO () = main $ do hakyll matchKeys matchRobotTxt matchImages matchFonts matchCV matchCSS matchAbout matchContact matchCVFormats<- buildTags "posts/*" (fromCapture "tags/*.html") tags makeTagPage tags matchPosts tags createArchive matchIndex matchTemplates rssFeed
Anyway, feel free to ask me for the public code.
Cookies
I don’t use any, nor do I collect any of your data.
Donate
If you’re using Brave, you can tip me.
Using Monero:
Monero QR Code.
Using Wownero:
Wownero QR Code.
Using Oxen:
Oxen QR Code.
I don’t use Bitcoin, here are some reasons why (TLDR: it was a good proof of concept, but it serve no real use-case):
Rant incoming: As of 2022, I feel that most crypto projects are useless, some of them like the ones listed above win at least the argument of ensuring some anonymity and untracability (which may or may not be a good idea, but at least that’s better than a public ledger).
I had some optimism toward crypto-currencies in the past, but seeing now that the market is mostly inundated with scams and useless projects, I don’t think we will get something actually usable in the real world unless a massive crash reboot everything and clean the table (my guess is that the so-called “stable-coins” will help).
Just look at the top 10 coins with respect to market cap, and ask yourself for what would you use any of them in real life (a non speculative use):
- Bitcoin
- Ethereum
- Tether
- USD Coin
- Binance Coin
- Cardano
- XRP
- Binance USD
- Solana
- Dogecoin
The allocations of resources reflect the lacks of maturity in the space, maybe we will see some interesting innovations some day, but it will likely not come from some VC firm with shady allocations.
Another problem: for now, the mechanism of valuation of these assets reflect the one found in artistic works, which is quite problematic for currencies.
“Your CV theme looks like LaTeX ModernCV”
It’s the goal, but it’s pure HTML/CSS. That way it can be responsive, unlike a LaTeX to HTML conversion, and the source is written in Markdown.
It draws its inspiration from these two websites (a big thanks to them):
I adapted the CSS to be responsive, here is the current version.