packages feed

hakyll-contrib-i18n (empty) → 0.1.0.0

raw patch · 37 files changed

+1384/−0 lines, 37 filesdep +basedep +binary-instancesdep +bytestringbinary-added

Dependencies added: base, binary-instances, bytestring, filepath, hakyll, hakyll-contrib-i18n, pandoc, pandoc-include-code, pandoc-types, text, time, time-locale-compat, unordered-containers, yaml

Files

+ CHANGELOG.md view
@@ -0,0 +1,5 @@+# Revision history for hakyll-contrib-i18n++## 0.1.0.0 -- 2020-11-21++* First version. Released on an unsuspecting world.
+ LICENSE view
@@ -0,0 +1,1 @@+This work is under the same license as the Hakyll library.
+ data/assets/images/haskell-logo.png view

binary file changed (absent → 5674 bytes)

+ data/css/default.css view
@@ -0,0 +1,181 @@+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;+}++main header {+  border-bottom: none;+}++main footer {+  border-top: none;+  margin-top: 0;+  padding: 0;+}++h1 {+  font-size: 2.4rem;+  text-transform: capitalize;+}++h2 {+  font-size: 2rem;+  text-transform: capitalize;+}++article .header {+  font-size: 1.4rem;+  font-style: italic;+  color: #555;+}++.logo a {+  font-weight: bold;+  color: #000;+  text-decoration: none;+}++a {+    color: #000;+    font-weight: bold;+    text-decoration: none;+}++ul li a {+    text-transform: capitalize;+}++#header li a {+    text-transform: capitalize;+}++textarea {+  width: 100%;+  min-height: 15em;+}++@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;+  }+  main header {+    margin: 0;+  }+  main main {+    margin: 0;+  }+  main main p {+    margin: 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;+  }+}
+ data/css/syntax.css view
@@ -0,0 +1,61 @@+a.sourceLine { display: inline-block; line-height: 1.25; }+a.sourceLine { pointer-events: none; color: inherit; text-decoration: inherit; }+a.sourceLine:empty { height: 1.2em; }+.sourceCode { overflow: visible; }+code.sourceCode { white-space: pre; position: relative; }+div.sourceCode { margin: 1em 0; }+pre.sourceCode { margin: 0; }+@media screen {+	div.sourceCode { overflow: auto; }+}+@media print {+	code.sourceCode { white-space: pre-wrap; }+	a.sourceLine { text-indent: -1em; padding-left: 1em; }+}+pre.numberSource a.sourceLine+{ position: relative; left: -4em; }+pre.numberSource a.sourceLine::before+{ content: attr(title);+	position: relative; left: -1em; text-align: right; vertical-align: baseline;+	border: none; pointer-events: all; display: inline-block;+	-webkit-touch-callout: none; -webkit-user-select: none;+	-khtml-user-select: none; -moz-user-select: none;+	-ms-user-select: none; user-select: none;+	padding: 0 4px; width: 4em;+	color: #aaaaaa;+}+pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa;  padding-left: 4px; }+div.sourceCode+{  }+@media screen {+	a.sourceLine::before { text-decoration: underline; }+}+code span.al { color: #ff0000; font-weight: bold; } /* Alert */+code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */+code span.at { color: #7d9029; } /* Attribute */+code span.bn { color: #40a070; } /* BaseN */+code span.bu { } /* BuiltIn */+code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */+code span.ch { color: #4070a0; } /* Char */+code span.cn { color: #880000; } /* Constant */+code span.co { color: #60a0b0; font-style: italic; } /* Comment */+code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */+code span.do { color: #ba2121; font-style: italic; } /* Documentation */+code span.dt { color: #902000; } /* DataType */+code span.dv { color: #40a070; } /* DecVal */+code span.er { color: #ff0000; font-weight: bold; } /* Error */+code span.ex { } /* Extension */+code span.fl { color: #40a070; } /* Float */+code span.fu { color: #06287e; } /* Function */+code span.im { } /* Import */+code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */+code span.kw { color: #007020; font-weight: bold; } /* Keyword */+code span.op { color: #666666; } /* Operator */+code span.ot { color: #007020; } /* Other */+code span.pp { color: #bc7a00; } /* Preprocessor */+code span.sc { color: #4070a0; } /* SpecialChar */+code span.ss { color: #bb6688; } /* SpecialString */+code span.st { color: #4070a0; } /* String */+code span.va { color: #19177c; } /* Variable */+code span.vs { color: #4070a0; } /* VerbatimString */+code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
+ data/en/about.rst view
@@ -0,0 +1,11 @@+---+title: About+---++Mauris varius fringilla augue quis ullamcorper. Phasellus eget ornare diam. Quisque hendrerit, dolor vel iaculis tempor, sem mauris imperdiet augue, non molestie sem velit quis diam. Mauris eu ante est. Donec feugiat nunc sollicitudin nibh vehicula, sit amet sollicitudin urna vehicula. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque non est vel lectus volutpat pellentesque a pulvinar risus. Nullam turpis lectus, malesuada non mi ac, efficitur vulputate justo. Curabitur faucibus neque tellus. Quisque nulla purus, aliquet bibendum dignissim nec, posuere in velit. Integer at nisl in eros cursus porttitor in sed libero. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc vel cursus arcu, ac sollicitudin tortor.++Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Maecenas et sem sit amet nibh viverra semper at nec lacus. Aliquam vitae pellentesque tellus, a elementum est. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed accumsan posuere sem sed luctus. Donec feugiat tortor nec urna scelerisque efficitur. Donec rhoncus ullamcorper velit a imperdiet. Nulla venenatis imperdiet dapibus. Vestibulum sit amet semper lacus.++Mauris nec porttitor nisl, pulvinar ornare nibh. Proin interdum nulla vel blandit iaculis. Vestibulum faucibus egestas vulputate. Pellentesque et faucibus turpis. Integer eget purus lacus. Praesent feugiat ante purus, eu tempor augue elementum eget. Nullam feugiat mauris ac eros pellentesque, vitae malesuada nunc blandit. Pellentesque venenatis ex nulla, in interdum magna dictum sed. Duis tincidunt ex in vulputate bibendum.++Etiam faucibus rutrum mi vel feugiat. Nam finibus posuere risus in pharetra. Cras augue arcu, consequat quis turpis eget, efficitur suscipit massa. Cras gravida felis quis orci maximus sagittis. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Quisque bibendum nunc mollis tristique consequat. Mauris in neque at enim sollicitudin imperdiet eget a orci. Nunc nec velit dui. In hac habitasse platea dictumst. Praesent eleifend iaculis metus ut molestie. Vestibulum et lorem maximus, malesuada neque sit amet, congue mauris. Nunc interdum tincidunt sem, a finibus urna commodo sed. 
+ data/en/index.md view
@@ -0,0 +1,18 @@+---+title: Home+---++## Welcome++<img src="/assets/images/haskell-logo.png" style="float: right; margin: 10px;" />++Welcome on the English version on my site.+The French one can be found [here](/fr).++I've reproduced a list of recent posts here for your reading pleasure :++## Posts :++$partial("templates/post-list.html")$++... or you can find more in the [archive](/$language$/archive).
+ data/en/posts/category01/article01.md view
@@ -0,0 +1,16 @@+---+title: Proin tristique facilisis+date: 2020-01-01+description: Pellentesque rhoncus metus libero, ac+tags: tag01, tag02+---++Integer commodo purus nisl, et condimentum leo scelerisque a. Quisque a ligula ipsum. Morbi vel sapien sem. Nam pharetra pellentesque justo vel cursus. Proin ultrices consequat lacus nec ullamcorper. Donec pharetra aliquet ipsum vitae ornare. Vivamus finibus interdum eros in imperdiet. Aliquam erat volutpat. Nam in rhoncus nibh, nec eleifend enim. Fusce vulputate lectus luctus turpis malesuada interdum.++<!--more-->++Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum massa dolor, luctus eu tellus sit amet, egestas cursus enim. Suspendisse semper tortor ac ex efficitur, et tincidunt turpis lacinia. Nunc egestas lorem quis condimentum blandit. Pellentesque cursus vulputate enim, ac porta massa accumsan vel. Vestibulum efficitur nunc ut mi ultrices, nec lacinia mi tincidunt. Vestibulum a maximus ipsum. Suspendisse ultrices euismod tortor, vitae finibus nisi placerat vitae. Praesent ut odio turpis. Vestibulum feugiat erat eros, nec gravida erat faucibus non. Ut et erat lacinia, placerat enim id, ornare augue. Aenean vel justo sed lectus vehicula congue. Nullam sit amet quam convallis, tincidunt ipsum sit amet, convallis est. Aliquam dapibus odio et sem aliquet tincidunt. Donec nec suscipit nisi. Nam sollicitudin purus et venenatis mollis.++Suspendisse semper fermentum orci, vel rhoncus neque rhoncus at. Cras orci metus, aliquam vitae tortor vel, consequat posuere tortor. Vestibulum volutpat dictum augue sed feugiat. Cras malesuada non elit sed commodo. Pellentesque sapien orci, vestibulum in ante vel, sodales volutpat quam. Aenean at dictum lorem. Quisque ac luctus elit, eget rutrum dolor. Curabitur at mollis orci, a varius tortor. Nam tempus magna vehicula turpis egestas, eu efficitur ipsum malesuada. Nullam diam eros, volutpat ut augue a, rhoncus congue mauris. Suspendisse in blandit sapien. Fusce non venenatis nulla. In vitae lorem quis leo sollicitudin iaculis ac id sem.++Nunc eget dui hendrerit, placerat lorem et, consequat lorem. Aliquam erat volutpat. Nulla facilisi. Pellentesque in purus magna. Suspendisse quis purus sit amet nunc volutpat mattis id id risus. Aliquam sit amet molestie quam. Cras sollicitudin elit at dui accumsan blandit ut sed ante. Nulla varius quam at orci varius, et venenatis ligula facilisis. Proin ut felis ac neque commodo accumsan. Donec vitae lorem feugiat, convallis ex at, congue tellus. In porttitor porta porttitor. Mauris imperdiet fringilla vestibulum. Nullam pretium lacus et est dignissim, eu lobortis nunc cursus. Donec sollicitudin gravida est ac pharetra. 
+ data/en/posts/category01/article02.md view
@@ -0,0 +1,18 @@+---+title: Etiam placerat aliquet+date: 2020-02-02+description: Sed consequat arcu at faucibus+tags: tag02, tag03+---++Pellentesque leo risus, hendrerit ac ante id, hendrerit tincidunt ex. Vestibulum sit amet pulvinar tortor. Pellentesque elementum urna lacus, facilisis fermentum arcu condimentum gravida. Maecenas mauris nulla, pulvinar a enim quis, porta sollicitudin velit. Aenean hendrerit magna sit amet dapibus semper. Vivamus vel lectus turpis. Sed pharetra quam eu diam eleifend placerat. Suspendisse ac velit quam. Suspendisse eget felis sit amet sem interdum volutpat id sit amet tellus.+ + <!--more-->++Nulla tincidunt leo ipsum, eget blandit velit egestas non. Vivamus sem eros, tincidunt id vestibulum vel, faucibus in odio. Nullam quis metus enim. Etiam viverra vestibulum leo, non dictum massa elementum ut. Duis ut molestie nisi. Nunc placerat finibus ultricies. Morbi finibus, est ac sagittis hendrerit, purus tellus pretium nisl, at ultrices mi orci euismod sem. Sed nunc justo, gravida ut felis at, pretium viverra quam. Fusce a arcu imperdiet, venenatis sem at, rutrum est. Donec at sem erat. Sed eget sagittis ex, eu hendrerit ipsum. Morbi cursus pellentesque tortor ut suscipit.++Aliquam congue quam ac efficitur auctor. Vestibulum eu libero et erat luctus egestas vel non nisi. Pellentesque sed massa sit amet augue eleifend consequat. Sed tincidunt lobortis blandit. Nam tempor justo non nisi tempor, ut pulvinar est interdum. Vivamus id hendrerit quam, vitae aliquet orci. Donec vel ullamcorper sem. Phasellus non tellus id enim iaculis bibendum. Pellentesque sit amet lectus auctor, aliquam ex non, maximus purus. Ut nibh magna, sagittis nec dolor ac, tincidunt rutrum est. Quisque nisi erat, mollis a luctus hendrerit, tempus eget massa. Aenean rutrum ipsum quis neque pellentesque, ut volutpat eros accumsan. Donec sem turpis, rutrum vel est ac, aliquam posuere orci.++Etiam quis arcu sed magna porttitor auctor. Mauris rhoncus tortor id lacus ullamcorper commodo. Sed quis vestibulum nisl. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nulla faucibus viverra velit, et consequat felis luctus vel. Sed tempus suscipit nisi. Aenean ac tincidunt odio. Maecenas accumsan pharetra purus, bibendum finibus odio iaculis nec. In urna massa, suscipit sit amet placerat ut, gravida eu tortor.++Duis hendrerit lacus et neque convallis malesuada. Quisque at pulvinar diam. Nam vehicula molestie mollis. Praesent facilisis blandit leo, at elementum nisi convallis at. Proin vestibulum posuere leo, ut congue massa iaculis nec. Morbi sed suscipit odio. Curabitur pulvinar aliquam urna ut sodales. 
+ data/en/posts/category01/article03.md view
@@ -0,0 +1,18 @@+---+title: Cras euismod tempor+date: 2020-03-03+description: Sed mauris arcu, maximus vitae+tags: tag02, tag04+---++Nunc dapibus vitae ante scelerisque congue. Pellentesque in sagittis diam, in venenatis tortor. Proin in dapibus arcu. Curabitur ligula velit, scelerisque varius tempus in, luctus vitae lacus. Phasellus ut ex et mauris cursus laoreet quis id metus. Duis venenatis nisl magna, eu ornare lacus condimentum nec. Aenean in fringilla magna, at euismod ligula. Aliquam posuere nisl urna, sed tincidunt magna ultricies nec. Aenean pellentesque blandit lorem, sit amet hendrerit turpis fermentum finibus.+ + <!--more-->++Maecenas mattis lorem tempus, facilisis lectus non, efficitur dolor. Sed consequat turpis in urna accumsan commodo. Sed lobortis euismod erat malesuada elementum. Fusce id aliquet ipsum. Maecenas venenatis bibendum sollicitudin. Integer pulvinar libero et dui dignissim efficitur. Vivamus vehicula accumsan dolor sit amet dictum.++Cras eget justo purus. Fusce quis nisl suscipit, suscipit massa vel, pretium ante. Ut non eros sit amet lacus efficitur ultricies eu vel nisi. Phasellus interdum justo eu facilisis interdum. Aliquam ut nisi luctus, convallis ligula et, fermentum lorem. Aliquam erat volutpat. Ut nisl purus, consectetur sit amet lectus non, sagittis ultrices massa. Aenean convallis orci tellus, et lacinia nisi convallis iaculis. Nunc eu mi rhoncus, vulputate orci eget, mattis felis. Curabitur sollicitudin pharetra metus quis consectetur. Praesent tempor est vel dignissim aliquet. Cras auctor nisi sed leo maximus, at efficitur augue finibus.++Nunc sit amet lacinia nisi. Donec ut convallis nisl. Morbi sollicitudin lobortis pretium. Donec fermentum urna quis leo tincidunt, ut lobortis tellus pellentesque. Mauris sollicitudin libero sit amet dui blandit, sed condimentum elit pharetra. Etiam gravida volutpat lorem, facilisis aliquam tortor lobortis nec. Suspendisse vitae ultrices odio. Pellentesque iaculis elit sit amet eros iaculis scelerisque. Vivamus pulvinar pellentesque justo, ac consectetur elit. Praesent sit amet augue facilisis, vehicula purus id, dictum sapien. Nunc vel magna vel elit imperdiet pellentesque et non magna. Maecenas sed arcu sit amet elit molestie eleifend quis in lorem. Integer interdum venenatis magna, sed tempus ipsum.++Etiam ut sollicitudin elit. Ut sit amet mollis ex. In hac habitasse platea dictumst. Praesent id sem ante. Sed varius urna nibh, at efficitur erat dignissim ac. Ut eu nulla lacinia, varius ex vitae, pellentesque quam. Nam dictum neque id orci semper, at accumsan turpis rutrum. 
+ data/en/posts/category02/article04.md view
@@ -0,0 +1,18 @@+---+title: Aliquam sit amet+date: 2020-01-15+description: Quisque lectus justo, semper vel+tags: tag01, tag04+---++Phasellus et rhoncus velit. Vestibulum venenatis elementum dui at efficitur. Integer vitae urna eu nisl laoreet scelerisque. Ut viverra nisi libero, at volutpat dolor eleifend ac. Aliquam eget augue orci. Curabitur vel auctor mi. Donec ex diam, semper eu varius ut, dignissim eget nunc. Ut ac nunc non massa laoreet viverra. Aenean bibendum massa nunc, vitae posuere massa semper et.+ + <!--more-->++Aenean viverra eget eros eu elementum. Nulla diam nisl, condimentum sed tortor et, tincidunt mattis dolor. Donec hendrerit enim lectus, nec convallis dolor convallis vel. Vestibulum at ligula id tortor facilisis eleifend non eu ipsum. Donec vitae mattis ante. Duis porta egestas nisl non efficitur. Suspendisse aliquam quis urna id vulputate. In tincidunt consectetur tincidunt. Aenean non purus tincidunt, sagittis odio ac, eleifend lorem. Mauris felis nibh, egestas sit amet porta eget, consectetur varius quam. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Proin nec turpis eget purus commodo aliquam.++Nulla facilisi. Aenean ipsum ipsum, dignissim cursus risus quis, auctor eleifend purus. Nunc vulputate tristique nisl ut tempus. Phasellus dui quam, venenatis ut faucibus ac, gravida sed turpis. Proin suscipit ultricies eros in euismod. Curabitur elementum porttitor lacinia. Nunc ac libero est. Duis ornare arcu malesuada, ultrices leo vitae, pharetra orci.++Fusce lobortis est turpis, eu pretium enim euismod quis. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec elementum nunc dui, et bibendum dui vestibulum vel. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nunc porttitor tincidunt ultrices. Donec quis facilisis nibh. Proin cursus semper risus, fringilla viverra neque fermentum in. Sed finibus arcu tincidunt, pretium mi et, ultrices velit. Phasellus mattis ultrices velit non sodales. In tincidunt sapien ut diam dictum, nec sagittis leo elementum. Ut suscipit est facilisis cursus eleifend. Aenean interdum sit amet velit a facilisis. Donec eleifend lacus libero, nec lacinia lectus vestibulum a. Nulla facilisi. Integer libero elit, scelerisque id blandit a, elementum vel felis. Vestibulum in nisl ex.++Morbi euismod molestie diam id tincidunt. Praesent vel interdum elit. Proin in justo ac nibh euismod pharetra ac non turpis. Praesent bibendum ut ex vitae porta. Donec ac scelerisque quam. Duis sollicitudin augue eu ex condimentum varius. Duis aliquet dictum tellus vel imperdiet. 
+ data/en/posts/category02/article05.md view
@@ -0,0 +1,16 @@+---+title: Pellentesque viverra magna+date: 2020-02-15+description: Integer vitae dui venenatis, faucibus+tags: tag03+---++Fusce venenatis turpis sit amet ullamcorper aliquam. Phasellus dolor mauris, bibendum vitae arcu sit amet, ornare pulvinar nisi. In metus mi, luctus a dolor nec, condimentum pulvinar nibh. Maecenas venenatis ac tellus a condimentum. Nulla convallis velit ac tempor molestie. Aenean molestie purus non quam venenatis, et bibendum felis blandit. Nunc nisi ex, vehicula nec ante vitae, consequat tempus metus. Vestibulum porta turpis vitae cursus placerat.++<!--more-->++Fusce sed fringilla ligula, sit amet commodo mauris. Etiam quis felis sed sem scelerisque feugiat. Morbi sit amet est in lorem commodo facilisis. Ut nec feugiat libero, ut aliquet quam. Vestibulum sollicitudin hendrerit pellentesque. Suspendisse potenti. Donec dictum vehicula aliquam. Duis nec augue quis nunc rutrum fringilla sit amet non urna. Vivamus ultrices est nibh, eu semper risus varius non. Aliquam posuere fermentum volutpat. Maecenas eu nibh in dolor varius elementum. Donec sapien nisl, pellentesque at turpis a, mattis tristique orci.++Pellentesque vcitur efficitur. Duis eu molestie enim. Praesent gravida, mauris id interdum pharetra, velit sapien fermentum erat, ut fermentum nulla orci at arcu.++In dictum interdum elit, et accumsan nisl elementum vitae. Vestibulum in faucibus nunc. Aliquam in turpis condimentum ante mattis interdum. Ut et felis commodo, pretium dolor eget, hendrerit justo. Proin et augue leo. Mauris metus lectus, ornare ut dignissim id, accumsan vitae tellus. Donec ornare, enim at lobortis porttitor, dui libero fermentum ligula, vel consequat tellus ligula a lectus. Duis blandit, turpis convallis imperdiet elementum, tortor dolor tempus neque, et rutrum metus tellus a enim. Curabitur porttitor sit amet lectus id facilisis. 
+ data/en/translation.yml view
@@ -0,0 +1,26 @@+---+#+# Translations for the English language.+# It has higher precedence than the one in the templates directory+#+# /!\ This file must exist /!\+#++translation:+  ALL_POSTS_IN_EVERY_LANGUAGES         : All posts in every languages+  ALL_POSTS_IN_LANGUAGE                : All posts in English+  DATE_FORMAT                          : "%Y/%m/%d"+  FEED_DESCRIPTION                     : SWI18NG in English+  NAV_ABOUT                            : about+  NAV_ARCHIVE                          : archive+  NAV_CONTACT                          : contact+  NAV_HOME                             : home+  POSTS_IN_EVERY_LANGUAGES             : Posts in every languages+  POSTS_IN_EVERY_LANGUAGES_IN_CATEGORY : Posts in every languages in category+  POSTS_IN_EVERY_LANGUAGES_TAGGED      : Posts in every laguages tagged+  POSTS_IN_LANGUAGE_IN_CATEGORY        : Posts in English in category+  POSTS_IN_LANGUAGE_ONLY               : Posts in English only+  POSTS_IN_LANGUAGE_TAGGED             : Posts in English tagged+  SITE_TITLE                           : I18n Hakyll+  category01                           : first category+  tag02                                : second tag
+ data/fr/a_propos.md view
@@ -0,0 +1,11 @@+---+title: À propos+---++Aenean euismod purus sapien, et pretium quam posuere ut. Vivamus aliquet eros nec dapibus facilisis. Curabitur vulputate sapien non magna faucibus, elementum consectetur felis facilisis. Ut molestie dignissim justo at faucibus. Maecenas non magna ac ligula porttitor suscipit at vitae ipsum. Cras sed dictum metus. Maecenas massa mi, tincidunt ac sem vel, eleifend placerat augue. Maecenas bibendum tempor mi sit amet finibus. Quisque vel urna quis arcu pellentesque aliquet vel id lectus. Nulla lorem magna, sollicitudin ornare mattis ut, aliquet non ex. Proin pretium tortor nisi, et mattis augue porttitor sed. Nunc in orci risus. Suspendisse eu lacus semper, tincidunt mi ut, maximus felis. Integer efficitur lectus id mattis tempus. Proin semper lacinia felis, at dictum nisi sollicitudin at.++Donec metus felis, ullamcorper eget eleifend sed, ultricies in ligula. Aliquam efficitur massa a iaculis accumsan. Phasellus est quam, laoreet vel tincidunt a, porttitor eget ante. Pellentesque dapibus arcu quis orci varius ornare. Ut vitae sapien sit amet arcu ultrices pretium. Vivamus fermentum magna a sodales pretium. Maecenas porta, odio ac aliquam tempor, augue ex feugiat orci, eu vehicula leo augue sed ipsum. Maecenas sit amet nisl sit amet erat gravida convallis. Maecenas id erat et risus posuere malesuada at dapibus nisi. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Ut mollis est eu tempor tincidunt. Proin et aliquam erat. Etiam et vestibulum ex. Quisque non quam tortor. Duis consequat, ex in euismod fermentum, leo arcu sagittis justo, et pulvinar eros turpis eu nulla. Lorem ipsum dolor sit amet, consectetur adipiscing elit.++Vestibulum et nibh vitae ligula sodales placerat. Pellentesque in venenatis risus, a condimentum tellus. Ut at porttitor risus, eu convallis lacus. Integer pharetra sem neque, ac pellentesque ex pharetra dictum. Duis enim lacus, vulputate eget ipsum quis, iaculis maximus dui. Maecenas ut porttitor turpis, eget posuere orci. Nam placerat sapien aliquet elit ornare, id ultricies massa vulputate.++Curabitur eu elit vel est vestibulum interdum. Proin accumsan, leo ut efficitur maximus, diam nisl hendrerit arcu, quis gravida eros ligula sagittis tellus. Sed finibus orci ullamcorper sapien mattis dapibus. In bibendum vehicula nisi sed lobortis. Aliquam congue mi non ligula blandit, at luctus arcu viverra. Praesent leo urna, porta at sem lobortis, mollis hendrerit odio. Proin sed pharetra odio, congue mollis est. 
+ data/fr/index.md view
@@ -0,0 +1,18 @@+---+title: Home+---++## Bienvenue++<img src="/assets/images/haskell-logo.png" style="float: right; margin: 10px;" />++Bienvenue sur la version française de mon site.+La version anglaise se trouve [ici](/en).++Vous trouverez ci-dessous la liste de mes derniers articles.++## Billets :++$partial("templates/post-list.html")$++... Vous trouverez l'intégralité de mes publications dans les [archives](/$language$/archive).
+ data/fr/posts/category01/article01.md view
@@ -0,0 +1,18 @@+---+title: Nunc maximus velit+date: 2020-03-15+description: Pellentesque fermentum hendrerit dui quis+tags: tag01, tag04+---++Cras id ipsum mauris. Nullam eget lobortis lacus, nec sollicitudin nibh. In hac habitasse platea dictumst. Cras augue arcu, hendrerit vel dapibus ut, dapibus vel dolor. Maecenas tincidunt lorem ac nulla blandit auctor. Ut condimentum neque a eleifend posuere. Nunc sagittis purus nec interdum tincidunt. Pellentesque a mollis est. Maecenas et dui ut tortor molestie tristique. Suspendisse suscipit sagittis rutrum. Vestibulum ultricies at augue sed sagittis. Phasellus lacinia, ipsum id tristique elementum, mauris lectus tristique mi, a tincidunt mi sem vitae nulla. Integer pretium posuere dolor, nec consectetur urna finibus quis. Fusce vel gravida mauris. Pellentesque efficitur augue eu ipsum vestibulum viverra. Vestibulum id urna nec turpis sollicitudin aliquet id ultrices lacus.+ +<!--more-->++Morbi ut sem rutrum, dictum ipsum a, ultrices lorem. Nam mauris mi, aliquet in aliquet eu, efficitur sed arcu. Maecenas facilisis quam a diam molestie euismod. Aliquam sagittis lacus id quam vestibulum, at posuere nulla fermentum. Donec id dignissim est. Praesent vitae porttitor orci. Sed venenatis nunc nec vehicula pretium. Praesent hendrerit faucibus ante vitae ultricies. Sed neque enim, volutpat sit amet interdum sit amet, mattis semper lectus. Vivamus faucibus velit libero, sed interdum lacus hendrerit sit amet. Donec et felis sed nibh gravida vestibulum. Cras imperdiet elit at ultrices tincidunt. Suspendisse mattis maximus dolor, in condimentum leo maximus eu. Donec aliquam libero eu eros varius, ac malesuada mauris ullamcorper.++Suspendisse lorem tortor, pretium in interdum feugiat, molestie in mauris. Integer condimentum felis est, ac consequat mauris vestibulum dignissim. In est leo, aliquam eget neque pharetra, malesuada volutpat orci. Donec suscipit mattis nibh, ut dignissim neque porta sit amet. Aliquam neque nibh, fermentum eu felis nec, tristique mollis nisi. Morbi eu posuere ante. Curabitur vulputate blandit efficitur. Morbi fringilla eros nisi, nec hendrerit lectus laoreet ac. Duis egestas vel nisl non euismod. Nullam eget orci leo. Cras vulputate tortor ac laoreet efficitur. Cras ex justo, interdum sit amet vehicula eget, mattis aliquam mi. Integer sollicitudin tristique felis vel malesuada. Sed eleifend ultrices nibh, vel congue neque hendrerit iaculis.++Mauris ut tristique libero. Proin venenatis lobortis turpis eget blandit. Integer imperdiet egestas nunc, suscipit blandit nunc. Sed tristique enim hendrerit magna facilisis accumsan. Nam consectetur orci a luctus laoreet. Duis gravida lobortis erat. Nulla sollicitudin ex at nunc eleifend, vel vulputate nisl mollis. Fusce vitae est faucibus, pharetra erat nec, laoreet lacus. Phasellus congue nisi vel sollicitudin vehicula. Ut molestie neque sapien. Duis sem dolor, fringilla sit amet aliquam ullamcorper, auctor id nunc. In feugiat metus justo.++Vestibulum placerat condimentum nunc nec egestas. Sed commodo sed urna ac aliquam. Donec blandit nulla erat, ut sodales nulla cursus eu. Suspendisse facilisis enim nibh, sed mattis magna dapibus ac. Sed blandit eros ac nulla imperdiet pretium. Pellentesque congue tincidunt nulla, vel facilisis sem gravida nec. Integer tellus nibh, rhoncus non nisl at, gravida eleifend neque. Ut eget mi tempus libero posuere hendrerit nec a nisi. Nullam eget orci purus. 
+ data/fr/posts/category01/article02.md view
@@ -0,0 +1,18 @@+---+title: Interdum et malesuada+date: 2020-01-28+description: Curabitur imperdiet nibh eget pellentesque+tags: tag02, tag04+---++Donec lacus velit, dignissim sit amet consequat elementum, varius vitae tortor. Etiam eu quam tincidunt, rhoncus erat ut, pretium tortor. Praesent nulla quam, placerat quis placerat ac, tincidunt sit amet orci. Etiam tempor tempus vestibulum. Aliquam erat volutpat. Interdum et malesuada fames ac ante ipsum primis in faucibus. Duis quis venenatis felis. Quisque euismod, nisi varius luctus auctor, mi magna finibus nisl, sed condimentum eros eros et purus. Duis id orci in ipsum egestas varius quis vel tortor. Vestibulum mattis finibus ligula. Nullam metus ligula, feugiat quis lectus et, tincidunt eleifend sem. Quisque commodo elit id tellus rhoncus, ornare finibus velit tempor. Proin non placerat orci. Mauris egestas ullamcorper eros, ut posuere dui. Sed est metus, pellentesque sed pulvinar sit amet, elementum cursus metus.++<!--more-->++Curabitur lectus purus, consectetur eget volutpat at, euismod eget nunc. Cras ornare turpis eu turpis cursus bibendum vitae in lacus. Maecenas ultricies luctus magna a ultrices. Proin eget ligula eu nisi suscipit lacinia vitae ultrices nisi. Nam et lectus eu augue tincidunt condimentum quis quis dui. Sed placerat, tortor at iaculis lobortis, ante nibh aliquet libero, luctus suscipit eros est accumsan orci. Quisque condimentum felis vel ligula ullamcorper accumsan. Etiam sapien est, faucibus vitae vestibulum sed, lacinia ac nulla. Aliquam erat volutpat. Integer at lectus sit amet neque pellentesque varius. Etiam non condimentum eros. Nullam et tortor quis nunc molestie elementum. Curabitur suscipit eget nisl non pulvinar.++Duis ut sodales neque, et rhoncus odio. Nullam ut tristique leo. Etiam sed auctor metus. Donec cursus arcu dolor. Vivamus eget lorem posuere, imperdiet sapien at, vehicula nisi. Etiam congue eu quam ac varius. Cras mauris elit, tincidunt ac massa sed, egestas congue erat. Sed eu sem varius, suscipit diam non, volutpat justo. Cras vulputate, purus non feugiat placerat, nisi lectus aliquam ante, at consequat odio arcu a tortor. Morbi lorem diam, consequat ut tincidunt ut, faucibus a sem. Donec vitae justo id elit semper vehicula. Etiam bibendum vulputate lorem, eu eleifend diam condimentum in. Vestibulum ultricies diam vitae lacus imperdiet hendrerit. Proin at dui arcu. Quisque justo enim, suscipit at ornare nec, pharetra in metus.++Integer non bibendum est, quis faucibus elit. Suspendisse nec varius massa. Morbi pharetra, ex id varius pulvinar, nulla odio scelerisque metus, vitae lacinia nulla dolor vitae eros. Proin vitae ipsum et neque fringilla facilisis. Nulla nec massa felis. In eu sem ultricies, dictum massa eget, vestibulum sem. Nullam aliquam id magna eget bibendum. Quisque laoreet velit risus, vitae vestibulum neque tempus nec. Pellentesque porta, leo ut suscipit interdum, purus enim suscipit felis, a finibus sem nunc in nunc.++Sed scelerisque laoreet odio, eu maximus leo posuere in. Sed vel auctor ante. Vestibulum eu justo et mi ultrices bibendum. Nam ex dolor, gravida vitae viverra ac, efficitur sit amet tellus. Mauris vel mollis odio. Duis volutpat tortor felis, et pharetra felis hendrerit sed. Vestibulum convallis neque ut odio cursus ultricies. Quisque sagittis, libero at mollis ornare, sapien risus dignissim ex, eu accumsan lectus dolor vehicula nisl. Sed ac nisl venenatis, aliquet tellus vel, convallis nisl. Nam tortor enim, suscipit ut vehicula eu, volutpat in felis. Duis vitae odio sit amet lacus vehicula congue quis ac ipsum. Maecenas non justo fringilla, efficitur odio sit amet, congue lectus. Ut libero quam, commodo non sem vitae, vestibulum mattis risus. Quisque felis lorem, vulputate non felis at, sodales cursus purus. Quisque tincidunt metus ante, eget porta nisi lobortis et. Etiam ante est, interdum et rhoncus ut, tincidunt nec ante. 
+ data/fr/posts/category02/article03.md view
@@ -0,0 +1,18 @@+---+title: Integer consectetur, odio+date: 2020-02-05+description: Fusce id ante lectus. In+tags: tag02+---++Morbi tortor nulla, venenatis in dictum suscipit, gravida vel elit. Vestibulum id mattis libero, id rutrum dolor. Integer tempus enim justo, auctor fringilla quam molestie vitae. Aliquam odio nibh, pulvinar at nisi ac, suscipit interdum massa. Vestibulum id condimentum risus. Suspendisse pulvinar sapien elit, non aliquet arcu aliquet id. Aliquam placerat, mi eget malesuada auctor, dolor sapien vehicula turpis, id ultrices arcu massa et dolor. Nullam commodo augue turpis. Sed ullamcorper tortor turpis, ut porttitor est dapibus sit amet. Suspendisse nec lacus elementum, sagittis nisl sollicitudin, accumsan augue. Aliquam consectetur est quis odio lacinia mollis in eu quam. Mauris vitae eleifend ex, non tempor ex. Curabitur mattis justo in mauris blandit, a dapibus erat tempor. Donec quis facilisis diam.++<!--more-->++Fusce maximus risus in ante interdum sodales. Cras massa sapien, faucibus vitae gravida non, consequat ac eros. Vivamus at pellentesque lacus. Pellentesque gravida varius ligula, nec cursus quam consectetur vitae. Aliquam erat volutpat. Maecenas luctus fringilla justo, eget molestie erat congue at. Duis id tellus turpis. Morbi vel velit ultrices libero feugiat dictum non nec lacus. Nullam elementum eleifend sem et pretium. Mauris fermentum suscipit mauris. Pellentesque ut justo imperdiet, congue eros at, pellentesque nibh.++Quisque tempus, purus non vehicula pulvinar, dui ligula ultricies metus, id eleifend tellus sapien id justo. Pellentesque mattis tortor velit, ac tempor dolor vestibulum pellentesque. Phasellus sed auctor magna, et vestibulum justo. Sed hendrerit, enim ornare elementum maximus, lorem lorem porttitor risus, eu eleifend nunc dolor eget turpis. Pellentesque at tellus eget metus euismod convallis eget non justo. Morbi quis dolor commodo, tempor ante ut, tincidunt ex. Cras finibus, metus in sodales mollis, velit lorem fringilla mi, eu sodales tortor urna id dui. Ut vulputate nisi a metus commodo accumsan. Sed fermentum blandit mi sed finibus. Ut eget erat ac urna bibendum luctus et non erat.++Suspendisse potenti. Pellentesque at ultricies ligula, eu cursus mi. Curabitur convallis tincidunt dui, vel bibendum justo cursus nec. Sed elementum enim dui, at varius sem faucibus aliquam. Nunc euismod, orci sed hendrerit malesuada, est dolor pretium sem, quis pharetra ligula ante et quam. Vestibulum a turpis dictum, molestie purus nec, vestibulum ipsum. Integer congue hendrerit sagittis. Sed metus ante, sodales eget blandit et, finibus ut felis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec ac tellus a enim interdum volutpat nec eu tellus.++Nunc sed sapien porttitor, posuere mauris et, viverra ex. Fusce convallis est nisi, non imperdiet neque elementum vel. In lobortis, dolor in mattis elementum, lectus leo aliquet massa, nec posuere augue risus non velit. Integer non efficitur turpis, sed tempor augue. Curabitur dignissim blandit hendrerit. Quisque et mauris ac libero luctus ullamcorper. Vivamus iaculis auctor lorem sed sollicitudin. Nunc tristique tincidunt ullamcorper. Nunc ipsum urna, sodales nec diam laoreet, molestie placerat purus. Aenean sollicitudin lobortis arcu commodo consectetur. Sed consectetur congue ex, accumsan malesuada nulla dapibus id. Aenean eu eros porta, ullamcorper felis nec, tempus nunc. Etiam feugiat semper dui at elementum. 
+ data/fr/posts/category02/article04.md view
@@ -0,0 +1,18 @@+---+title: Orci varius natoque+date: 2019-12-24+description: Nunc sit amet lacinia turpis+tags: tag01, tag03+---++Nam viverra ut nunc vel dictum. Nam aliquet elementum purus vitae facilisis. Etiam id felis egestas, imperdiet mi at, ornare sem. Morbi semper rutrum tellus, sit amet vestibulum orci pellentesque sed. Donec ut mollis velit, vel auctor turpis. Maecenas id dui quam. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Integer condimentum, nunc sit amet eleifend faucibus, tellus ex pretium felis, vel maximus dolor dolor vel felis. Pellentesque fermentum nulla in tellus rutrum maximus. Curabitur orci quam, fermentum vel justo sit amet, rutrum pretium augue. Vestibulum dapibus mauris sit amet nunc consectetur, eu mollis leo fringilla. Fusce pretium tempus velit non fringilla. Proin sagittis elit eget magna gravida suscipit id vel libero. In facilisis a purus at mattis. Duis vitae enim non orci sagittis eleifend a sit amet metus. Sed egestas facilisis condimentum.++<!--more-->++Donec neque lacus, ultricies porta egestas non, ultrices ac tellus. Sed non vulputate augue. Aenean pulvinar odio at ipsum scelerisque pellentesque. Proin dui quam, vestibulum et gravida vel, elementum at mi. Nam tincidunt id sapien in gravida. Quisque bibendum sapien at enim fringilla, ac imperdiet augue condimentum. Nunc nec massa at odio varius condimentum. Praesent posuere dolor quis nisi vulputate, nec consequat erat sagittis. Sed a sapien ac ligula blandit sodales quis id justo. Duis bibendum dolor et ipsum eleifend, ut pretium justo eleifend. Vivamus tincidunt cursus elit, vel volutpat est malesuada ac. Praesent quis diam tincidunt, dignissim ante quis, vehicula enim. Vestibulum lorem nibh, aliquet sed tincidunt ac, semper et velit.++Phasellus eget lacus egestas, consectetur quam non, malesuada magna. Phasellus aliquam maximus orci, sit amet pellentesque leo fermentum vel. Pellentesque eu vulputate metus. Nulla ac neque in odio placerat dapibus. Praesent quis nibh magna. Suspendisse ac ultrices mauris, a eleifend lorem. Aliquam eu dui lectus. Nulla consequat eros sit amet arcu sollicitudin lobortis. Mauris orci dui, tempus ut libero tincidunt, lobortis finibus ipsum.++Praesent rutrum ipsum vitae purus tempor, eget egestas elit efficitur. Morbi nec est et massa mattis facilisis vel scelerisque dolor. In vel neque turpis. Etiam sagittis nunc et libero sollicitudin venenatis. Aliquam maximus hendrerit arcu id pulvinar. Vestibulum nisl ex, consectetur vitae sodales non, elementum a purus. Nulla in lacus arcu. Cras vel urna in enim pellentesque fermentum. Curabitur quis mauris et metus posuere ullamcorper a quis tortor. Quisque sit amet erat vel nulla vestibulum imperdiet. Praesent fermentum metus non leo convallis gravida. Maecenas sagittis consectetur ipsum, quis malesuada lectus luctus nec.++Cras vel erat et ligula blandit blandit eget eu orci. Ut at ipsum tincidunt, laoreet urna sit amet, elementum ligula. Mauris id dignissim nisi. Nulla fringilla laoreet nunc, sit amet dignissim urna accumsan sed. Quisque ut massa finibus, commodo dolor sodales, dictum nisi. Phasellus sapien mauris, congue non congue a, laoreet nec dui. Etiam est purus, eleifend at interdum vel, condimentum in nibh. Vestibulum pharetra dapibus libero quis pellentesque. Morbi vel ex efficitur, bibendum neque et, lobortis metus. Vestibulum efficitur a velit nec venenatis. Suspendisse potenti. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent risus dolor, facilisis sed euismod ac, ultrices at sem. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. 
+ data/fr/posts/category03/article05.md view
@@ -0,0 +1,18 @@+---+title: Sed venenatis nunc+date: 2020-02-04+description: Nullam sit amet efficitur leo+tags: tag02+---++Ut venenatis pellentesque viverra. Cras porttitor leo a massa lobortis sollicitudin. Pellentesque blandit nunc non metus tempor suscipit id in augue. Mauris a neque vel lectus vehicula aliquet. Fusce vitae dictum nulla. Sed auctor vel massa ac consequat. Suspendisse id venenatis nibh. Curabitur pharetra rhoncus viverra. Quisque pellentesque pharetra magna vestibulum congue. Donec nec risus eu odio dapibus lacinia at vel nunc. Quisque eget facilisis sapien. Donec consectetur enim a hendrerit venenatis. Sed turpis diam, aliquet sed justo a, consectetur eleifend ipsum.++<!--more-->++Sed dictum turpis quis vestibulum semper. Proin non fermentum orci. Vestibulum accumsan enim sed elit semper sagittis. Suspendisse potenti. In ultrices velit arcu, ac sollicitudin felis aliquet eget. Integer quis sagittis enim. Donec sed consectetur felis. Cras sed sapien vel sapien iaculis sodales a et velit. Aliquam ultricies condimentum enim, in tempor magna aliquet a. Proin tincidunt quam id felis commodo finibus. Praesent nec dignissim ex, in sollicitudin enim. Phasellus non sodales lectus. Aenean erat urna, lobortis sit amet semper ac, sollicitudin ut nisi.++Sed elementum est id dolor mollis, quis lacinia elit porta. Donec blandit dolor nec ante facilisis, vitae suscipit turpis dictum. Duis finibus tempus diam, sit amet vestibulum lorem vulputate eu. Donec ullamcorper, magna sed interdum ultricies, lacus ligula cursus diam, a dignissim velit ligula nec elit. Phasellus finibus nec nisl in mollis. Mauris consequat eget felis et finibus. Duis semper orci commodo, maximus mauris in, gravida lorem. Sed ultrices diam lorem, eu interdum diam sodales non. Duis fermentum sem et nulla placerat, vel dignissim sem vulputate. Sed laoreet ipsum ac leo consectetur, et gravida ligula dictum. Suspendisse a odio gravida, porttitor sem id, volutpat felis. Donec sit amet auctor orci. Donec quis lacinia justo, vel gravida dui. Duis mollis lectus eget ligula interdum, a imperdiet urna varius. Ut fringilla, ante at facilisis mattis, tortor nulla sollicitudin nibh, rutrum euismod neque massa vitae ante.++Nullam blandit sem leo, non sollicitudin nisl tempor in. Nullam ipsum sem, scelerisque tincidunt tristique quis, consequat et metus. Vivamus ut venenatis diam, vel sollicitudin massa. Duis ac lacus eu neque gravida feugiat et fermentum lorem. Sed sit amet sollicitudin sapien, nec pretium lorem. Morbi id massa non urna maximus commodo. Donec in urna cursus, semper libero nec, egestas magna. Ut efficitur condimentum eros in consectetur. Morbi efficitur diam eget dui posuere, non consequat sapien dignissim. Aliquam pellentesque dui dolor, sit amet ultrices lorem elementum nec. Vestibulum malesuada, erat eget varius pharetra, justo risus finibus justo, aliquam viverra erat mi eget purus. Vivamus luctus, mi quis venenatis bibendum, nisi massa accumsan nulla, vel accumsan justo ante in urna. Aenean vel congue quam, ac pulvinar elit. Morbi ultrices in lacus non feugiat. Praesent venenatis molestie ante non volutpat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae;++Proin sit amet libero nisl. Ut egestas condimentum nisi, sit amet condimentum lectus varius in. Aliquam vel finibus ex. Ut a erat ultrices, volutpat nisi at, venenatis est. Etiam sed enim consectetur, sodales urna eget, aliquet dui. Morbi ut sapien dictum, rhoncus neque non, gravida quam. Morbi fermentum est tincidunt, vehicula dolor eget, hendrerit sapien. Nulla sapien diam, elementum id nibh fringilla, dictum sollicitudin sem. Fusce mattis arcu neque, at tincidunt arcu sodales placerat. 
+ data/fr/translation.yml view
@@ -0,0 +1,41 @@+---+#+# Translations for the French language.+# It has higher precedence than the one in the templates directory+#+# /!\ This file must exist /!\+#++translation:+  ALL_POSTS_IN_EVERY_LANGUAGES            : Tous les articles dans tous les langages+  ALL_POSTS_IN_LANGUAGE                   : Tous les articles en français+  All posts in English                    : Tous les articles en français+  All posts in all languages              : Tous les articles dans toutes les langues+  DATE_FORMAT                             : "%d/%m/%Y"+  EMail from SWI18NG                      : EMail depuis SWI18NG+  FEED_DESCRIPTION                        : SWI18NG en français+  Message sent                            : Message envoyé+  NAV_ABOUT                               : à propos+  NAV_ARCHIVE                             : archive+  NAV_CONTACT                             : contact+  NAV_HOME                                : accueil+  POSTS_IN_EVERY_LANGUAGES                : Articles dans toutes les langues+  POSTS_IN_EVERY_LANGUAGES_IN_CATEGORY    : Articles dans toutes les langues dans+  POSTS_IN_EVERY_LANGUAGES_TAGGED         : Articles dans tous les langages tagués+  POSTS_IN_LANGUAGE_IN_CATEGORY           : Articles en français dans+  POSTS_IN_LANGUAGE_ONLY                  : Articles en français seulement+  POSTS_IN_LANGUAGE_TAGGED                : Articles en français tagués+  Posted on                               : Publié le+  Read more                               : Lire plus+  SITE_TITLE                              : Hakyll I18n+  Send                                    : Envoyer+  Site proudly generated by               : Sité généré avec+  a_propos                                : à propos+  about                                   : à propos de+  address@e.mail                          : adresse@e.mail+  by                                      : par+  in                                      : dans+  posted on                               : publié le+  category01                              : Autruche catégorie+  category02                              : deuxième catégorie+  tag04                                   : quatrième tag
+ data/templates/archive.html view
@@ -0,0 +1,15 @@+<main>+    <h1>$translate(title)$</h1>+    <aside>+        <a href="$switch$">+            $if(single)$+                $translate("POSTS_IN_EVERY_LANGUAGES")$+            $else$+                $translate("POSTS_IN_LANGUAGE_ONLY")$+            $endif$+        </a>+    </aside>+    <section>+        $partial("templates/post-list.html")$+    </section>+</main>
+ data/templates/category.html view
@@ -0,0 +1,21 @@+<main>+    <h1>+      $if(single)$+        $translate("POSTS_IN_LANGUAGE_IN_CATEGORY", title)$+      $else$+        $translate("POSTS_IN_EVERY_LANGUAGES_IN_CATEGORY", title)$+      $endif$+    </h1>+    <aside>+        <a href="$switch$">+            $if(single)$+                $translate("POSTS_IN_EVERY_LANGUAGES")$+            $else$+                $translate("POSTS_IN_LANGUAGE_ONLY")$+            $endif$+        </a>+    </aside>+    <section>+        $partial("templates/post-list.html")$+    </section>+</main>
+ data/templates/contact.html view
@@ -0,0 +1,36 @@+<form id="form">+  <label for="email">$translate("E-Mail")$ :</label> +  <input type="email" id="email" name="email" placeholder="$translate("address@e.mail")$" required> ++  <br>+  +  <label for="message">$translate("Message")$ :</label> +  <br>+  <textarea id="message" name="message" required></textarea>++  <br>++  <input type="button" value="$translate("Send")$" onclick="sendEmail()">+</form>++<script>+function sendEmail() {+    var form = document.getElementById("form");++    var email = form.elements.namedItem("email");+    if (!email.validity.valid) { return; }++    var message = form.elements.namedItem("message");+    if (!message.validity.valid) { return; }++    Email.send({+        SecureToken : "$translate("SECURE_TOKEN")$",+        To : "$translate("FEED_AUTHOR_EMAIL")$",+        From : email.value,+        Subject : "$translate("EMail from SWI18NG")$",+        Body : message.value+    }).then(+        message => alert(message)+    );+}+</script>
+ data/templates/default.html view
@@ -0,0 +1,21 @@+<!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>$translate("SITE_TITLE")$ - $title$</title>+        <link rel="stylesheet" href="/css/default.css" />+    </head>+    <body>+        $partial("templates/header.html")$+        $body$+        $partial("templates/footer.html")$++        $if(scripts)$+            $for(scripts)$+            <script src="$script$" async></script>+            $endfor$+        $endif$+    </body>+</html>
+ data/templates/footer.html view
@@ -0,0 +1,3 @@+<footer>+    $translate("Site proudly generated by")$ <a href="http://jaspervdj.be/hakyll">Hakyll</a>+</footer>
+ data/templates/header.html view
@@ -0,0 +1,12 @@+<header>+    <div class="logo">+        <a href="/$language$/">$translate("SITE_TITLE")$</a>+    </div>+    <nav>+        <a href="/$language$/">$translate("NAV_HOME")$</a>+        <a href="/$language$/$translate("NAV_ABOUT")$">$translate("NAV_ABOUT")$</a>+        <a href="/$language$/$translate("NAV_ARCHIVE")$">$translate("NAV_ARCHIVE")$</a>+        <a href="/fr">FR</a>+        <a href="/en">EN</a>+    </nav>+</header>
+ data/templates/main.html view
@@ -0,0 +1,4 @@+<main>+  <h1>$title$</h1>+  $body$+</main>
+ data/templates/post-list.html view
@@ -0,0 +1,30 @@+<ul>+    $for(posts)$+        <li>+            <header>+            <a href="$url$">$title$</a> +            $if(date)$+            $translate("posted on")$ $date$+            $endif$++            $if(tags)$+            $translate("about")$ $tags$+            $endif$++            $if(category)$+            $translate("in")$ $category$+            $endif$+            </header>++            $if(teaser)$+            <main>+            $teaser$+            </main>++            <footer>+            <a href="$url$">$translate("Read more")$</a>+            </footer>+            $endif$+        </li>+    $endfor$+</ul>
+ data/templates/post.html view
@@ -0,0 +1,19 @@+<article>+    <header>+        $translate("Posted on")$ $date$+        $if(author)$+            $translate("by")$ $author$+        $endif$++        $if(tags)$+        $translate("about")$ $tags$+        $endif$++        $if(category)$+        $translate("in")$ $category$+        $endif$+    </header>+    <main>+        $body$+    </main>+</article>
+ data/templates/sitemap.xml view
@@ -0,0 +1,57 @@+<?xml version="1.0" encoding="UTF-8"?>+<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">+    $for(index)$+        <url>+            <loc>$translate("FEED_ROOT")$$url$</loc>+            <priority>1.0</priority>+        </url>+    $endfor$+    $for(pages)$+        <url>+            <loc>$translate("FEED_ROOT")$$url$</loc>+            <priority>.9</priority>+        </url>+    $endfor$+    $for(posts)$+        <url>+            <loc>$translate("FEED_ROOT")$$url$</loc>+            <priority>.8</priority>+        </url>+    $endfor$+    $for(categories)$+        <url>+            <loc>$translate("FEED_ROOT")$$url$</loc>+            <priority>.7</priority>+        </url>+    $endfor$+    $for(tags)$+        <url>+            <loc>$translate("FEED_ROOT")$$url$</loc>+            <priority>.6</priority>+        </url>+    $endfor$+    $for(archives)$+        <url>+            <loc>$translate("FEED_ROOT")$$url$</loc>+            <priority>.5</priority>+        </url>+    $endfor$+    $for(categoriesAllLanguages)$+        <url>+            <loc>$translate("FEED_ROOT")$$url$</loc>+            <priority>.4</priority>+        </url>+    $endfor$+    $for(tagsAllLanguages)$+        <url>+            <loc>$translate("FEED_ROOT")$$url$</loc>+            <priority>.3</priority>+        </url>+    $endfor$+    $for(archivesAllLanguages)$+        <url>+            <loc>$translate("FEED_ROOT")$$url$</loc>+            <priority>.2</priority>+        </url>+    $endfor$+</urlset>
+ data/templates/switch.html view
@@ -0,0 +1,7 @@+<aside>+  $switch$+</aside>++<section>+  $body$+</section>
+ data/templates/tag.html view
@@ -0,0 +1,21 @@+<main>+    <h1>+      $if(single)$+        $translate("POSTS_IN_LANGUAGE_TAGGED", title)$+      $else$+        $translate("POSTS_IN_EVERY_LANGUAGES_TAGGED", title)$+      $endif$+    </h1>+    <aside>+        <a href="$switch$">+            $if(single)$+                $translate("POSTS_IN_EVERY_LANGUAGES")$+            $else$+                $translate("POSTS_IN_LANGUAGE_ONLY")$+            $endif$+        </a>+    </aside>+    <section>+        $partial("templates/post-list.html")$+    </section>+</main>
+ data/templates/translation.yml view
@@ -0,0 +1,14 @@+---+#+# Translations in this file act as default.+# The can be overridden in language specific translations.+#+# /!\ This file must exist /!\+#++translation:+  DEFAULT_LANGUAGE  : en+  FEED_AUTHOR_EMAIL : your.email@add.ress+  FEED_AUTHOR_NAME  : Your NAME+  FEED_ROOT         : Your site's url+  FEED_TITLE        : Your site's name
+ haki18nll/Main.hs view
@@ -0,0 +1,313 @@+--------------------------------------------------------------------------------+{-# LANGUAGE OverloadedStrings #-}++import Hakyll++import Hakyll.Contrib.I18n+    ( Language+    , categoryField'+    , feedConfiguration+    , tagsField'+    , translate+    , translationCompiler+    , translationContext+    )++import Data.List (intersperse)+import System.FilePath ((</>), splitExtension, splitFileName, takeDirectory)+import Text.Pandoc (Format (..), Pandoc)+import Text.Pandoc.Filter.IncludeCode (includeCode)+import Text.Pandoc.Walk (walkM)++import qualified Data.HashMap.Strict as SM (union)+import qualified GHC.IO.Encoding as E++includeCodePandocCompiler :: Compiler (Item String)+includeCodePandocCompiler =+  pandocCompilerWithTransformM+    defaultHakyllReaderOptions+    defaultHakyllWriterOptions+    (unsafeCompiler . (walkM (includeCode (Just (Format "html5")))))++main :: IO ()+main = do+    E.setLocaleEncoding E.utf8+    hakyll $ do+        match "assets/**/*" $ do+            route idRoute+            compile copyFileCompiler++        match "css/*" $ do+            route idRoute+            compile compressCssCompiler++        match "*/translation.yml" $+            compile translationCompiler++        match ("snippets/*" .||. "*/snippets/*") $+            compile getResourceBody++        match ("templates/*" .&&. complement "templates/translation.yml") $+            compile templateBodyCompiler++        create ["index.html"] $ do+            route idRoute+            compile $ do+                defaultTranslation <- loadBody "templates/translation.yml"+                makeItem $ Redirect $ translate defaultTranslation "DEFAULT_LANGUAGE"++        create ["sitemap.xml"] $ do+            route idRoute+            compile $ do+                archives               <- loadAll $ hasVersion "archive"+                archivesAllLanguages   <- loadAll $ hasVersion "archiveAllLanguages"+                categories             <- loadAll $ ("*/categories/*" .&&. hasNoVersion)+                categoriesAllLanguages <- loadAll $ ("*/categories/*" .&&. hasVersion "categoryAllLanguages")+                index                  <- loadAll $ hasVersion "index"+                pages                  <- loadAll $ hasVersion "page"+                posts                  <- loadAll "*/posts/*/*"+                tags                   <- loadAll $ ("*/tags/*" .&&. hasNoVersion)+                tagsAllLanguages       <- loadAll $ ("*/tags/*" .&&. hasVersion "tagAllLanguages")++                let context =+                        listField "archives"               generalContext (return archives)               <>+                        listField "archivesAllLanguages"   generalContext (return archivesAllLanguages)   <>+                        listField "categories"             generalContext (return categories)             <>+                        listField "categoriesAllLanguages" generalContext (return categoriesAllLanguages) <>+                        listField "index"                  generalContext (return index)                  <>+                        listField "pages"                  generalContext (return pages)                  <>+                        listField "posts"                  generalContext (return posts)                  <>+                        listField "tags"                   generalContext (return tags)                   <>+                        listField "tagsAllLanguages"       generalContext (return tagsAllLanguages)++                makeItem ""+                    >>= loadAndApplyTemplate "templates/sitemap.xml" context+                    >>= relativizeUrls++        sequence_ $ [archives, categories, feeds, index, pages, posts, tags] <*> ["en", "fr"]++archives :: Language -> Rules ()+archives language = sequence_ $ [archives', archives''] <*> pure language where+    archives' :: Language -> Rules ()+    archives' language = do+        categories <- buildCategories (fromGlob $ language </> "posts/*/*") (fromCapture $ fromGlob $ language </> "categories/*.html")+        tags       <- buildTags       (fromGlob $ language </> "posts/*/*") (fromCapture $ fromGlob $ language </> "tags/*.html")++        create [fromFilePath $ language </> "archive.html"] $ version "archive" $ do+            route indexRoute+            compile $ do+                posts <- recentFirst =<< (loadAll $ fromGlob $ language </> "posts/*/*")++                let context =+                        boolField "single" (const True)                                <>+                        constField "switch" ("/archive" </> language)                  <>+                        listField "posts" (postContext tags categories) (return posts) <>+                        generalContext++                makeItem ""+                    >>= loadAndApplyTemplate "templates/archive.html" context+                    >>= loadAndApplyTemplate "templates/default.html" context+                    >>= relativizeUrls++    archives'' :: Language -> Rules ()+    archives'' language = do+        categories <- buildCategories "*/posts/*/*" (fromCapture $ fromGlob $ language </> "categories/*.html")+        tags       <- buildTags       "*/posts/*/*" (fromCapture $ fromGlob $ language </> "tags/*.html")++        create [fromFilePath $ language </> "archive.html"] $ version "archiveAllLanguages" $ do+            route $ gsubRoute (language </> "archive") (const $ "archive" </> language) `composeRoutes` indexRoute+            compile $ do+                posts <- recentFirst =<< loadAll ("*/posts/*/*")++                let context =+                        boolField "single" (const False)                               <>+                        constField "switch" ("/" ++ language </> "archive")            <>+                        listField "posts" (postContext tags categories) (return posts) <>+                        generalContext++                makeItem ""+                    >>= loadAndApplyTemplate "templates/archive.html" context+                    >>= loadAndApplyTemplate "templates/default.html" context+                    >>= relativizeUrls++categories :: Language -> Rules ()+categories language = sequence_ $ [categories', categories''] <*> pure language where+    categories' :: Language -> Rules ()+    categories' language = do+        categories <- buildCategories (fromGlob $ language </> "posts/*/*") (fromCapture $ fromGlob $ language </> "categories/*.html")+        tags       <- buildTags       (fromGlob $ language </> "posts/*/*") (fromCapture $ fromGlob $ language </> "tags/*.html")++        tagsRules categories $ \category pattern -> do+            route indexRoute+            compile $ do+                posts <- recentFirst =<< loadAll pattern++                let context =+                        boolField "single" (const True)                                <>+                        constField "switch" ("/categories" </> language </> category)  <>+                        listField "posts" (postContext tags categories) (return posts) <>+                        generalContext++                makeItem ""+                    >>= loadAndApplyTemplate "templates/category.html" context+                    >>= loadAndApplyTemplate "templates/default.html"  context+                    >>= relativizeUrls++    categories'' :: Language -> Rules ()+    categories'' language = do+        categories <- buildCategories "*/posts/*/*" (fromCapture $ fromGlob $ language </> "categories/*.html")+        tags       <- buildTags "*/posts/*/*"       (fromCapture $ fromGlob $ language </> "tags/*.html")++        version "categoryAllLanguages" $ tagsRules categories $ \category pattern -> do+            route $ gsubRoute (language </> "categories") (const $ "categories" </> language) `composeRoutes` indexRoute+            compile $ do+                posts <- recentFirst =<< loadAll pattern++                let context =+                        boolField "single" (const False)                                    <>+                        constField "switch" ("/" ++ language </> "categories" </> category) <>+                        listField "posts" (postContext tags categories) (return posts)      <>+                        generalContext++                makeItem ""+                    >>= loadAndApplyTemplate "templates/category.html" context+                    >>= loadAndApplyTemplate "templates/default.html"  context+                    >>= relativizeUrls++feeds :: Language -> Rules ()+feeds language = sequence_ $ [atom, rss] <*> pure language where+    atom :: Language -> Rules ()+    atom language = create [fromFilePath $ language </> "atom.xml"] $ do+        route idRoute+        compile $ do+            posts <- fmap (take 10) . recentFirst =<< (loadAll $ fromGlob $ language </> "posts/*/*")++            languageTranslation <- loadBody $ fromFilePath $ language </> "translation.yml"+            defaultTranslation  <- loadBody "templates/translation.yml"++            let translation = SM.union languageTranslation defaultTranslation+                context = listField "posts" generalContext (return posts) <> generalContext++            renderAtom (feedConfiguration translation) generalContext posts++    rss :: Language -> Rules ()+    rss language = create [fromFilePath $ language </> "rss.xml"] $ do+        route idRoute+        compile $ do+            posts <- fmap (take 10) . recentFirst =<< (loadAll $ fromGlob $ language </> "posts/*/*")++            languageTranslation <- loadBody $ fromFilePath $ language </> "translation.yml"+            defaultTranslation  <- loadBody "templates/translation.yml"++            let translation = SM.union languageTranslation defaultTranslation+                context = listField "posts" generalContext (return posts) <> generalContext++            renderRss (feedConfiguration translation) generalContext posts++index :: Language -> Rules ()+index language = do+    categories <- buildCategories (fromGlob $ language </> "posts/*/*") (fromCapture $ fromGlob $ language </> "categories/*.html")+    tags       <- buildTags       (fromGlob $ language </> "posts/*/*") (fromCapture $ fromGlob $ language </> "tags/*.html")++    match (fromGlob $ language </> "index.*") $ version "index" $ do+        route $ setExtension "html"+        compile $ do+            posts <- fmap (take 10) . recentFirst =<< (loadAll $ fromGlob $ language </> "posts/*/*")+            let context = listField "posts" (postContext tags categories) (return posts) <> generalContext+            pandocCompiler+                >>= applyAsTemplate                               context+                >>= loadAndApplyTemplate "templates/main.html"    context+                >>= loadAndApplyTemplate "templates/default.html" context+                >>= relativizeUrls++pages :: Language -> Rules ()+pages language = match ((fromGlob $ language </> "*.*") .&&. (complement . fromGlob $ language </> "index.*") .&&. (complement . fromGlob $ language </> "translation.yml")) $ version "page" $ do+    route $ indexRoute+    compile $+        pandocCompiler+            >>= applyAsTemplate                               generalContext+            >>= loadAndApplyTemplate "templates/main.html"    generalContext+            >>= loadAndApplyTemplate "templates/default.html" generalContext+            >>= relativizeUrls++posts :: Language -> Rules ()+posts language = do+    categories <- buildCategories (fromGlob $ language </> "posts/*/*") (fromCapture $ fromGlob $ language </> "categories/*.html")+    tags       <- buildTags       (fromGlob $ language </> "posts/*/*") (fromCapture $ fromGlob $ language </> "tags/*.html")++    match (fromGlob $ language </> "posts/*/*") $ do+        route indexRoute+        compile $ do+            let context = postContext tags categories++            pandocCompiler+                >>= saveSnapshot "teaser"+                >>= loadAndApplyTemplate "templates/post.html"    context+                >>= loadAndApplyTemplate "templates/main.html"    context+                >>= loadAndApplyTemplate "templates/default.html" context+                >>= relativizeUrls++tags :: Language -> Rules ()+tags language = sequence_ $ [tags', tags''] <*> pure language where+    tags' :: Language -> Rules ()+    tags' language = do+        categories <- buildCategories (fromGlob $ language </> "posts/*/*") (fromCapture $ fromGlob $ language </> "categories/*.html")+        tags       <- buildTags       (fromGlob $ language </> "posts/*/*") (fromCapture $ fromGlob $ language </> "tags/*.html")++        tagsRules tags $ \tag pattern -> do+            route indexRoute+            compile $ do+                posts <- recentFirst =<< loadAll pattern++                let context =+                        boolField "single" (const True)                                <>+                        constField "switch" ("/tags" </> language </> tag)             <>+                        listField "posts" (postContext tags categories) (return posts) <>+                        generalContext++                makeItem ""+                    >>= loadAndApplyTemplate "templates/tag.html"     context+                    >>= loadAndApplyTemplate "templates/default.html" context+                    >>= relativizeUrls++    tags'' :: Language -> Rules ()+    tags'' language = do+        categories <- buildCategories (fromGlob $ language </> "posts/*/*") (fromCapture $ fromGlob $ language </> "categories/*.html")+        tags       <- buildTags       (fromGlob $ language </> "posts/*/*") (fromCapture $ fromGlob $ language </> "tags/*.html")++        version "tagAllLanguages" $ tagsRules tags $ \tag pattern -> do+            route $ gsubRoute (language </> "tags") (const $ "tags" </> language) `composeRoutes` indexRoute+            compile $ do+                posts <- recentFirst =<< loadAll pattern++                let context =+                        boolField "single" (const False)                               <>+                        constField "switch" ("/" ++ language </> "tags" </> tag)       <>+                        listField "posts" (postContext tags categories) (return posts) <>+                        generalContext++                makeItem ""+                    >>= loadAndApplyTemplate "templates/tag.html"     context+                    >>= loadAndApplyTemplate "templates/default.html" context+                    >>= relativizeUrls++indexRoute :: Routes+indexRoute = customRoute $ (\(p, _) -> p </> "index.html") . splitExtension . toFilePath++dropIndexHtml :: Context a+dropIndexHtml = mapContext transform (urlField "url")+    where+        transform :: FilePath -> FilePath+        transform url = case splitFileName url of+            (p, "index.html") -> takeDirectory p+            _                 -> url++generalContext :: Context String+generalContext = dropIndexHtml <> translationContext <> defaultContext++postContext :: Tags -> Tags -> Context String+postContext tags categories =+    Hakyll.Contrib.I18n.categoryField' "category" categories <>+    Hakyll.Contrib.I18n.tagsField' "tags" tags               <>+    teaserField "teaser" "teaser"                            <>+    generalContext
+ hakyll-contrib-i18n.cabal view
@@ -0,0 +1,92 @@+cabal-version:      >=1.10+name:               hakyll-contrib-i18n+version:            0.1.0.0+license:            OtherLicense+license-file:       LICENSE+copyright:+    Copyright © 2020 Pablo COVES <pablo.coves@protonmail.com>+    This work is free. You can redistribute it and/or modify it under the+    terms of the Do What The Fuck You Want To Public License, Version 2,+    as published by Sam Hocevar. See http://www.wtfpl.net/ for more details.++maintainer:         pablo.coves@protonmail.com+author:             Pablo COVES+bug-reports:        https://gitlab.com/pcoves/hakyll-contrib-i18n/-/issues+synopsis:           A Hakyll library for internationalization.+description:+    A companion library for Hakyll that helps with internationalization.+    This library defines a custom compiler for translations stored in Yaml files.+    Once loaded, one can implicitly use them to translate strings in the template files.++category:           Web, Hakyll, I18n+build-type:         Simple+data-files:+    data/assets/images/haskell-logo.png+    data/css/default.css+    data/css/syntax.css+    data/en/about.rst+    data/en/index.md+    data/en/posts/category01/article01.md+    data/en/posts/category01/article02.md+    data/en/posts/category01/article03.md+    data/en/posts/category02/article04.md+    data/en/posts/category02/article05.md+    data/en/translation.yml+    data/fr/a_propos.md+    data/fr/index.md+    data/fr/posts/category01/article01.md+    data/fr/posts/category01/article02.md+    data/fr/posts/category02/article03.md+    data/fr/posts/category02/article04.md+    data/fr/posts/category03/article05.md+    data/fr/translation.yml+    data/templates/archive.html+    data/templates/category.html+    data/templates/contact.html+    data/templates/default.html+    data/templates/footer.html+    data/templates/header.html+    data/templates/main.html+    data/templates/post.html+    data/templates/post-list.html+    data/templates/sitemap.xml+    data/templates/switch.html+    data/templates/tag.html+    data/templates/translation.yml++extra-source-files: CHANGELOG.md++source-repository head+    type:     git+    location: https://gitlab.com/pcoves/hakyll-contrib-i18n++library+    exposed-modules:  Hakyll.Contrib.I18n+    hs-source-dirs:   src+    default-language: Haskell2010+    build-depends:+        base ==4.*,+        binary-instances >=1.0.1 && <1.1,+        bytestring >=0.10.10.1 && <0.11,+        filepath >=1.4.2.1 && <1.5,+        hakyll >=4.13.4.0 && <4.14,+        text >=1.2.4.0 && <1.3,+        time >=1.9.3 && <1.10,+        time-locale-compat >=0.1.1.5 && <0.2,+        unordered-containers >=0.2.10.0 && <0.3,+        yaml >=0.11.5.0 && <0.12++executable haki18nll+    main-is:          Main.hs+    hs-source-dirs:   haki18nll+    default-language: Haskell2010+    ghc-options:      -threaded+    build-depends:+        base ==4.*,+        hakyll ==4.13.*,+        hakyll-contrib-i18n -any,+        filepath >=1.4.2.1 && <1.5,+        pandoc >=2.9.2.1 && <2.10,+        pandoc-types ==1.20.*,+        pandoc-include-code >=1.5.0.0 && <1.6,+        unordered-containers >=0.2.10.0 && <0.3
+ src/Hakyll/Contrib/I18n.hs view
@@ -0,0 +1,170 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE FlexibleInstances #-}++module Hakyll.Contrib.I18n+    ( Hakyll.Contrib.I18n.categoryField+    , Hakyll.Contrib.I18n.categoryField'+    , Hakyll.Contrib.I18n.dateField+    , Hakyll.Contrib.I18n.tagsField+    , Hakyll.Contrib.I18n.tagsField'+    , Language+    , feedConfiguration+    , languageField+    , translate+    , translationCompiler+    , translationContext+    , translationField+    ) where++import Hakyll++import Control.Applicative+import Control.Monad (forM)+import Data.Binary.Instances.UnorderedContainers+import Data.ByteString (ByteString, writeFile)+import Data.ByteString.Lazy (toStrict)+import Data.List (intersperse)+import Data.Maybe (catMaybes)+import Data.Time.Format (formatTime)+import Data.Time.Locale.Compat (defaultTimeLocale)+import Data.Yaml ((.:), ParseException, Object, encode, parseEither, decodeEither', prettyPrintParseException)+import System.FilePath ((</>), joinPath, splitDirectories, splitFileName, takeDirectory)++import qualified Data.HashMap.Strict as SM (HashMap, lookupDefault, union)+import qualified Data.Text as T (pack)++type Language = String+type Translation = SM.HashMap String String++instance Writable Translation where+    write p = Data.ByteString.writeFile p . encode . itemBody++-- | Parse a `ByteString` into a `Translation` HashMap.+-- | Fails if there is no `translation` key.+parse :: ByteString -> Translation+parse = either error id . parse' . decodeEither'+    where+        parse' :: Either ParseException Object -> Either String Translation+        parse' = either (Left . prettyPrintParseException) (parseEither (.: T.pack "translation"))++-- | Compiles a `Translation` from a `yaml` file.+translationCompiler :: Compiler (Item Translation)+translationCompiler = cached "TranslationCompiler" $+    fmap (parse . toStrict) <$> getResourceLBS++languageFromFilePath :: FilePath -> Language+languageFromFilePath = head . splitDirectories++languageFromIdentifier :: Identifier -> Language+languageFromIdentifier = languageFromFilePath . toFilePath++languageFromItem :: Item a -> Language+languageFromItem = languageFromIdentifier . itemIdentifier++-- | Search for a word's translation in a `Translation`.+-- | If there is none, return the word unchanged.+translate :: Translation -> String -> String+translate translation word = SM.lookupDefault word word translation++-- | Hakyll's `dateField` but uses a format base on the `item`'s language.+dateField :: String -> Context a+dateField key = field key dateField'+    where+        dateField' :: Item a -> Compiler String+        dateField' item = do+            languageTranslation <- loadBody $ fromFilePath $ languageFromItem item </> "translation.yml"+            defaultTranslation  <- loadBody "templates/translation.yml"++            let translation = SM.union languageTranslation defaultTranslation+                dateFormat = translate translation "DATE_FORMAT"++            time <- getItemUTC defaultTimeLocale $ itemIdentifier item+            return $ formatTime defaultTimeLocale dateFormat time++-- | `Field` containing the `Item`'s language.+languageField :: String -> Context a+languageField key = field key (return . languageFromItem)++toUrl :: FilePath -> String+toUrl = Hakyll.toUrl . transform+    where+        transform :: FilePath -> FilePath+        transform url = case splitFileName url of+            (p, "index.html") -> takeDirectory p+            _                 -> url++renderLink :: (FilePath -> String) -> Translation -> String -> (Maybe FilePath) -> Maybe String+renderLink _ _ _ Nothing                             = Nothing+renderLink sanitizer translation tag (Just filePath) = Just $ "<a href=\"" ++ (sanitizer filePath) ++ "\">" ++ translate translation tag ++ "</a>"++tagsFieldWith+    :: (Identifier -> Compiler [String])+    -> (Translation -> String -> (Maybe FilePath) -> Maybe String)+    -> ([String] -> String)+    -> String+    -> Tags+    -> Context a+tagsFieldWith getter renderer join key tags = field key tagsFieldWith'+    where+        tagsFieldWith' :: Item a -> Compiler String+        tagsFieldWith' item = do+            languageTranslation <- loadBody $ fromFilePath $ languageFromItem item </> "translation.yml"+            defaultTranslation  <- loadBody "templates/translation.yml"+            let translation = SM.union languageTranslation defaultTranslation++            tags' <- getter $ itemIdentifier item+            links <- forM tags' $ \tag -> do+                route' <- getRoute $ tagsMakeId tags tag+                return $ renderer translation tag route'++            return $ join $ catMaybes links++-- | Hakyll's `tagsField` but with translation applied to the tag name.+tagsField :: String -> Tags -> Context a+tagsField = Hakyll.Contrib.I18n.tagsFieldWith getTags (renderLink Hakyll.toUrl) (mconcat . intersperse ", ")++-- | Hakyll's `categoryField` but with translation applied to the tag name.+categoryField :: String -> Tags -> Context a+categoryField = Hakyll.Contrib.I18n.tagsFieldWith getCategory (renderLink Hakyll.toUrl) (mconcat . intersperse ", ")++-- | Hakyll's `tagsField` but with translation applied to the tag name.+-- | It also remove any trailing `/index.html` in the route.+tagsField' :: String -> Tags -> Context a+tagsField' = Hakyll.Contrib.I18n.tagsFieldWith getTags (renderLink Hakyll.Contrib.I18n.toUrl) (mconcat . intersperse ", ")++-- | Hakyll's `categoryField` but with translation applied to the tag name.+-- | It also remove any trailing `/index.html` in the route.+categoryField' :: String -> Tags -> Context a+categoryField' = Hakyll.Contrib.I18n.tagsFieldWith getCategory (renderLink Hakyll.Contrib.I18n.toUrl) (mconcat . intersperse ", ")++-- | A function one can use to translate `String`s and `Field`s in the `Template`s base on the `Item`'s language.+translationField :: String -> Context a+translationField key = functionField key translationField'+    where+        translationField' :: [String] -> Item a -> Compiler String+        translationField' words item = do+            languageTranslation <- loadBody $ fromFilePath $ languageFromItem item </> "translation.yml"+            defaultTranslation  <- loadBody "templates/translation.yml"++            let translation = SM.union languageTranslation defaultTranslation+                translations = map (translate translation) words++            return $ (mconcat . intersperse " ") translations++-- | Helper `Context` exposing all the modules `Field`s in the same place.+translationContext :: Context a+translationContext+    = Hakyll.Contrib.I18n.dateField "date"+    <> languageField "language"+    <> translationField "translate"++-- | `FeedConfiguration` but with translated fields.+feedConfiguration :: Translation -> FeedConfiguration+feedConfiguration translation =+    FeedConfiguration+        { feedTitle       = translate translation "FEED_TITLE"+        , feedDescription = translate translation "FEED_DESCRIPTION"+        , feedAuthorName  = translate translation "FEED_AUTHOR_NAME"+        , feedAuthorEmail = translate translation "FEED_AUTHOR_EMAIL"+        , feedRoot        = translate translation "FEED_ROOT"+        }