Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Hakyll - Génération dynamique de sites statiques

Hakyll - Génération dynamique de sites statiques

Génération de sites statiques avec Hakyll

Clément Delafargue

April 16, 2013
Tweet

More Decks by Clément Delafargue

Other Decks in Programming

Transcript

  1. Pages perso en HTML statique Quelques pages, pas DRY, contenu

    en HTML Lourd, m´ elange contenu / pr´ esentation
  2. Le renouveau Markdown => contenu plus l´ eger Templating =>

    keep it DRY Github pages => easy to set up
  3. Workflow Full text -> developer friendly (vim, git, make, .

    . . ) Contributions: pull requests Publication: scp, git, dropbox, . . .
  4. Tout n’est pas rose. . . rigide pas adapt´ e

    ` a tout le monde pas de composante dynamique
  5. . . . mais on peut se d´ ebrouiller certains

    outils sont tr` es souples un peu d’´ education, ¸ ca marche utilisation de services externes
  6. Quels outils choisir ? Ruby: jekyll, nanoc, . . .

    Python: pelican, frozen flask, . . . Node: blacksmith, . . . Haskell: hakyll, gitit, yst, . . .
  7. Installation Haskell platform (ghc + cabal) Installe le compilo et

    l’outil de build / gestion de d´ ependances http://www.haskell.org/platform/ (Gnu/Linux, MacOS, Windows) Pour windows, Mingw + MSYS en plus
  8. Warming up Cr´ ee un blog + pages statiques hakyll-init

    blog cd blog ghc --make site.hs # compile le g´ en´ erateur ./site preview # serveur HTTP + reload Ne pas oublier de recompiler site.hs apr` es l’avoir modifi´ e
  9. Makefile On n’est pas des animaux, on utilise un Makefile

    recompilation automatique apr` es modification du haskell vidage du cache publication via git . . .
  10. Makefile all: build build: site ./site build site: site.hs ghc

    --make site.hs ./site clean preview: site ./site preview clean: site ./site clean check: site ./site check
  11. Makefile - publication publish: git add . git stash save

    git checkout publish || git checkout --orphan publish find . -maxdepth 1 ! -name '.' ! -name '.git*' ! -name -exec rm -rf {} + find _site -maxdepth 1 -exec mv {} . \; rmdir _site -git add -A && git commit -m "Publish" git push -f git+ssh://my-remote publish:master git checkout master git clean -fdx -git stash pop
  12. Makefile - like a boss make clean make preview make

    check # d´ etecte les liens cass´ es make publish
  13. Playing with Hakyll Concepts de base Ensemble de pipelines Input

    -> Output Matching -> Route -> Compilation -> Injection template Templates “purs” (pas de logique, juste des points d’injection)
  14. Playing with Hakyll Structure de base main :: IO ()

    main = hakyll $ do rule_1 ... rule_n helpers
  15. Playing with Hakyll Static Assets match "images/*" $ do route

    idRoute compile copyFileCompiler match "css/*" $ do route idRoute compile compressCssCompiler
  16. Playing with Hakyll Pages statiques match (fromList [ "about.rst" ,

    "contact.markdown" ]) $ do route $ setExtension "html" compile $ pandocCompiler >>= loadAndApplyTemplate "tpl/default.html" defaultCont >>= relativizeUrls
  17. Playing with Hakyll Templates Pas de route -> pas expos´

    e dans le site g´ en´ er´ e match "tpl/*" $ compile templateCompiler
  18. Playing with Hakyll Helpers postCtx :: Context String postCtx =

    dateField "date" "%B %e, %Y" `mappend` defaultContext postList :: ([Item String] -> Compiler [Item String]) -> Compiler String postList sortFilter = do posts <- sortFilter =<< loadAll "posts/*" itemTpl <- loadBody "tpl/post-item.html" list <- applyTemplateList itemTpl postCtx posts return list
  19. Playing with Hakyll Posts match "posts/*" $ do route $

    setExtension "html" compile $ pandocCompiler >>= loadAndApplyTemplate "tpl/post.html" postCtx >>= loadAndApplyTemplate "tpl/default.html" postCtx >>= relativizeUrls
  20. Playing with Hakyll Archive On peut cr´ eer des pages

    ex nihilo create ["archive.html"] $ do route idRoute compile $ do let ctx = field "posts" (\_ -> postList recentFirst) `mappend` constField "title" "Archives" `mappend` defaultContext makeItem "" >>= loadAndApplyTemplate "tpl/archive.html" ctx >>= loadAndApplyTemplate "tpl/default.html" ctx >>= relativizeUrls
  21. Playing with Hakyll Index match "index.html" $ do route idRoute

    compile $ do let indexCtx = field "posts" $ \_ -> postList $ fmap (take 3) . recentFi getResourceBody >>= applyAsTemplate indexCtx >>= loadAndApplyTemplate "tpl/default.html" postCtx >>= relativizeUrls
  22. Compilateur Permet de transformer un Item, en g´ erant les

    d´ ependances. Par exemple : pandocCompiler Monadique => traduit la nature s´ equentielle des compilations
  23. Compilateur On peut y mettre ce qu’on veut. En particulier,

    du shell match "assets/css/*.less" $ do route $ setExtension "css" compile $ getResourceString >>= withItemBody (unixFilter "lessc" ["-","--yui-compress",
  24. Contexte Donn´ ees inject´ ees dans un template. Par exemple,

    defaultContext injecte : m´ etadonn´ ees (title, author, . . . ) body
  25. Contexte Dans le fichier : --- title: Foo bar baz

    --- My awesome content Dans le template : <article> <h1>$title$</h1> $body </article>
  26. postCtx :: Context String postCtx = dateField "date" "%B %e,

    %Y" `mappend` defaultContext postCtx extrait la date du nom de fichier et l’injecte dans le template. mappend permet de combiner deux contextes (Context est un monoide)
  27. Possibilit´ e de construire ses propres contextes fonction Item a

    -> Compiler String donn´ ees statiques fonctions ($func arg$) date . . .
  28. Patterns courants i18n (sort of) Contenu s´ epar´ e dans

    des dossiers /en et /fr. Templates en commun Langue par d´ efaut ` a la racine du site g´ en´ er´ e
  29. i18n (sort of) langs = ["fr", "en"] defaultLang = "fr"

    -- Enl` eve automatiquement le "/fr" en d´ ebut d'URL langRoute = gsubRoute (defaultLang ++ "/") (const "") setHtmlLang = langRoute `composeRoutes` (setExtension "html
  30. i18n (sort of) Dans les routes : forM_ langs (\lang

    -> match $ (fromGlob $ lang ++ "/posts/*") do route setHtmlLang compile $ pandocCompiler >>= loadAndApplyTemplate "tpl/post.html" postCtx >>= loadAndApplyTemplate "tpl/default.html" postCtx >>= relativizeUrls )
  31. Disqus Ajouter Disqus ` a ses articles de blog tpl/disqus.html

    $body$ <section class="disqus"> <script type="text/javascript"> var page_url = "$url$"; <!-- Disqus stuff --> </script> </section>
  32. Disqus Modification des r` egles de compilation match "posts/*" $

    do route $ setExtension "html" compile $ pandocCompiler >>= loadAndApplyTemplate "tpl/post.html" postCtx >>= loadAndApplyTemplate "tpl/disqus.html" postCtx >>= loadAndApplyTemplate "tpl/default.html" postCtx >>= relativizeUrls
  33. On peut aller plus loin GUI avec prose.io http://prose.io/ Tags

    pour les articles de blog http: //jaspervdj.be/hakyll/reference/Hakyll-Web-Tags.html
  34. On peut aller plus loin Web2day 2013: i18n, factorisation, d´

    ependances inter-pages, g´ en´ eration de fichier ICS, blocs r´ eutilisables, . . . https://github.com/CompanyCampus/web2day2013 http://blog.clement.delafargue.name/posts/ 2013-04-03-web2day-powered-by-hakyll-part-1.html