Commit 23f04635 authored by Joris's avatar Joris

Setup personal page with Hakyll

parent 0fe906ae
dist-newstyle
public/resumes
.ghc.environment.*
.stack-work/
_cache/
output/
public/
image: alpine:latest
pages:
stage: deploy
script:
- echo 'Nothing to do...'
artifacts:
paths:
- public
only:
- deploy
......@@ -4,5 +4,5 @@ startup_window: app
windows:
- console:
- clear
- app:
- make clean watch
- main:
- make install watch
......@@ -4,17 +4,21 @@ start:
@nix-shell --command "tmuxinator local"
stop:
@nix-shell --command "tmux kill-session -t personalPage"
@tmux kill-session -t personalPage
clean:
@cabal new-clean > /dev/null
@stack exec personalPage clean > /dev/null 2>&1 || true
@stack clean > /dev/null
watch:
@nodemon --watch src/ application.conf ./data.yaml resume/ --ext hs,conf,yaml,cls --exec 'clear && make build-and-launch-server --silent'
build-and-launch-server:
@(pkill personalPage || true) && (cabal new-run || true)
install:
@stack setup
.PHONY: build
build:
@cabal new-build || true
@stack build
@stack exec personalPage build
watch:
@nodemon --watch src -e hs --exec 'make watch-command --silent'
watch-command:
@(killall personalPage || :) && sleep 1 && stack build && stack exec personalPage clean && stack exec personalPage watch
Name: PersonalPage
Version: 1.0
Synopsis: My personal page
Homepage: guyonvarch.me
License: GPL-3
Author: Joris Guyonvarch
Category: Web
Build-type: Simple
Cabal-version: >= 1.8
Executable personalPage
Hs-source-dirs: src
Main-is: Main.hs
Ghc-options: -Wall -Werror
Build-depends:
base
, text
, aeson
, yaml
, blaze-html
, blaze-markup
, clay
, bytestring
, HaTeX
, process
, mtl
, transformers
, temporary
, scotty
, wai-middleware-static
, time
, config-manager
, lens
, directory
, filepath
Other-modules:
Conf
, Daemon
, Daemon.Frequency
, Date
, Design.Color
, Design.Global
, Design.Header
, Design.Media
, Design.NotFound
, Design.Projects
, Design.Resume
, Design.Size
, Model
, Model.Company
, Model.Date
, Model.Degree
, Model.Header
, Model.Identity
, Model.Job
, Model.Project
, Model.School
, Model.SkillType
, Model.Translated
, Model.Translation.Key
, Model.Translation.Language
, Model.Translation.Message
, PDF
, Resume
, Utils.String
, View.Git
, View.Header
, View.Icon
, View.Interval
, View.LaTeX.Resume
, View.NotFound
, View.Page
, View.Project
, View.Resume
# Personal Page
Generate a website presenting resume and project from data given by a yaml
file.
Live [here](https://guyonvarch.gitlab.io/personalPage).
[![build status](https://gitlab.com/guyonvarch/personalPage/badges/deploy/build.svg)](https://gitlab.com/guyonvarch/personalPage/commits/master)
## Required dependency
- `pdflatex`
## Getting started
## Gettings started
Install nix:
Install nix and follow the instructions:
``` bash
```bash
curl https://nixos.org/nix/install | sh
```
Then, launch the environment with:
Then, start the environment with:
``` bash
```bash
make start
```
......@@ -27,16 +28,14 @@ Later, stop the environment with:
make stop
```
## Build
## Deploy on gitlab pages
``` sh
make build
```bash
./deploy
```
## Configuration
## Improvements
```
port = 3000
git = "https://gitlab.com/"
generateResumes = Daily # Hourly / Daily
```
- prettify urls
- i18n ?
- blog ?
port = 3000
git = "https://gitlab.com/"
generateResumes = Daily
importMaybe "local.conf"
<svg id="logo_art" data-name="logo art" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 586 559"><defs><style>.cls-1{fill:#fc6d26;}.cls-2{fill:#e24329;}.cls-3{fill:#fca326;}</style></defs><title>gitlab-icon-rgb</title><g id="g44"><path id="path46" class="cls-1" d="M461.17,301.83l-18.91-58.12L404.84,128.43a6.47,6.47,0,0,0-12.27,0L355.15,243.64H230.82L193.4,128.43a6.46,6.46,0,0,0-12.26,0L143.78,243.64l-18.91,58.19a12.88,12.88,0,0,0,4.66,14.39L293,435,456.44,316.22a12.9,12.9,0,0,0,4.73-14.39"/></g><g id="g48"><path id="path50" class="cls-2" d="M293,434.91h0l62.16-191.28H230.87L293,434.91Z"/></g><g id="g56"><path id="path58" class="cls-1" d="M293,434.91,230.82,243.63h-87L293,434.91Z"/></g><g id="g64"><path id="path66" class="cls-3" d="M143.75,243.69h0l-18.91,58.12a12.88,12.88,0,0,0,4.66,14.39L293,435,143.75,243.69Z"/></g><g id="g72"><path id="path74" class="cls-2" d="M143.78,243.69h87.11L193.4,128.49a6.47,6.47,0,0,0-12.27,0l-37.35,115.2Z"/></g><g id="g76"><path id="path78" class="cls-1" d="M293,434.91l62.16-191.28H442.3L293,434.91Z"/></g><g id="g80"><path id="path82" class="cls-3" d="M442.24,243.69h0l18.91,58.12a12.85,12.85,0,0,1-4.66,14.39L293,434.91l149.2-191.22Z"/></g><g id="g84"><path id="path86" class="cls-2" d="M442.28,243.69h-87.1l37.42-115.2a6.46,6.46,0,0,1,12.26,0l37.42,115.2Z"/></g></svg>
\ No newline at end of file
#!/bin/sh
nix-shell --command "make clean build"
{-# LANGUAGE OverloadedStrings #-}
module Body
( style
) where
import Clay hiding (style)
import Prelude hiding ((**))
import qualified Color
import qualified Link
import qualified Media
import qualified Size
style :: Css
style = do
".Body__Container" ** p ? do
lineHeight (px 28)
".Body__Container" ** ul ? do
paddingLeft (px 0)
Media.desktop $ margin (px 20) (px 0) (px 20) (px 30)
Media.tablet $ margin (px 15) (px 0) (px 15) (px 20)
Media.mobile $ marginBottom Size.listItemSep
".Body__Container" ** li ? do
Size.lineHeight
before & do
content (stringContent "•")
color Color.red
display inlineBlock
marginRight (px 10)
Link.style (".Body__Container" ** a)
module Design.Color where
module Color where
import qualified Clay.Color as C
......
{-# LANGUAGE OverloadedStrings #-}
module Header
( style
) where
import Data.Monoid ((<>))
import Clay hiding (style)
import Clay.Display (displayTable)
import qualified Color as Color
import qualified Media as Media
style :: Css
style = do
".Header__Container" ? do
backgroundColor Color.red
color Color.white
fontSize (px 28)
display flex
".Header__Link" ? do
display flex
justifyContent center
alignItems center
flexGrow 1
flexBasis (px 0)
height (em 3)
lineHeight (em 3)
textDecoration none
padding (px 0) (px 0) (px 0) (px 0)
textAlign (alignSide sideCenter)
color Color.white
textTransform capitalize
transition "background-color" (ms 500) ease (sec 0)
Media.tablet $ fontSize (em 0.8)
Media.mobile $ fontSize (em 0.6)
(".Header__Link" # hover <> ".Header__Link" # focus <> ".Header__LinkCurrent") ? do
backgroundColor Color.red
borderBottomStyle solid
borderBottomColor (Color.red +. 40)
Media.mobile $ borderBottomWidth (px 6)
Media.tablet $ borderBottomWidth (px 8)
Media.desktop $ borderBottomWidth (px 10)
".Header__Icon" ? do
display flex
height (px 40)
marginRight (px 20)
Media.mobile $ display none
{-# LANGUAGE OverloadedStrings #-}
module IconLink
( style
) where
import Clay hiding (style)
import qualified Link
import qualified Media
style :: Css
style = do
Link.style ".IconLink__Link"
".IconLink__Link" ? do
display inlineFlex
alignItems center
marginBottom (px 15)
Media.desktop $ fontSize (px 18)
Media.tablet $ fontSize (px 16)
Media.mobile $ fontSize (px 14)
".IconLink__Icon" ? do
marginRight (px 12)
Media.desktop $ height (px 20)
Media.tablet $ height (px 16)
Media.mobile $ height (px 14)
{-# LANGUAGE OverloadedStrings #-}
module Link
( style
) where
import Clay hiding (style)
import Clay.Selector (Fix, SelectorF (SelectorF))
import qualified Color
style :: (Fix SelectorF) -> Css
style selector = do
selector ? do
textDecoration none
color Color.link
transition "color" (sec 0.3) easeOut (sec 0)
focus & outline solid (px 0) Color.white
(selector # hover) <> (selector # focus) ? do
textDecoration underline
color Color.blue
module Design.Media
module Media
( mobile
, mobileTablet
, tablet
......@@ -6,10 +6,10 @@ module Design.Media
, desktop
) where
import Clay hiding (query)
import Clay hiding (query)
import qualified Clay
import Clay.Stylesheet (Feature)
import qualified Clay.Media as Media
import qualified Clay.Media as Media
import Clay.Stylesheet (Feature)
mobile :: Css -> Css
mobile = query [Media.maxWidth mobileTabletLimit]
......
{-# LANGUAGE OverloadedStrings #-}
module Project
( style
) where
import Clay hiding (style)
style :: Css
style = do
".Project__Body" ? do
marginTop (px 20)
{-# LANGUAGE OverloadedStrings #-}
module Resume
( style
) where
import Clay hiding (style)
import qualified Color
import qualified Media
import qualified Size
style :: Css
style = do
".Resume__NameAndPrint" ? do
display flex
justifyContent spaceBetween
".Resume__Print" ? do
color Color.red
transition "all" (ms 100) ease (sec 0)
hover & transform (scale 1.2 1.2)
marginLeft (px 10)
Media.desktop $ do
lineHeight (px 50)
height (px 50)
fontSize (px 40)
Media.tablet $ do
lineHeight (px 40)
height (px 40)
fontSize (px 30)
Media.mobile $ do
lineHeight (px 30)
height (px 30)
fontSize (px 20)
".Resume__GitLabLink" ? do
Media.desktop $ marginLeft (px 30)
Media.tablet $ marginLeft (px 20)
".Resume__Container" ? do
Media.desktop $ do
marginBottom (px 40)
marginLeft (px 30)
Media.tablet $ do
marginBottom (px 40)
marginLeft (px 20)
Media.mobile $
marginBottom (px 25)
".Resume__Name" <> ".Resume__Location" <> ".Resume__Description" ? do
Size.lineHeight
".Resume__Name" ? do
backgroundColor Color.orange
color Color.white
padding (px 0) (px 10) (px 0) (px 10)
sym borderRadius (px 2)
Media.desktop $ do
display inlineBlock
marginBottom (px 10)
Media.mobileTablet $
marginBottom (px 10)
".Resume__Time" ? do
fontStyle italic
marginBottom (px 10)
Media.desktop $ do
display inlineBlock
marginLeft (px 15)
Media.mobile $
fontSize (pct 90)
".Resume__Location" ? do
color Color.green
Size.tabletMarginBottom
Media.mobile $ do
fontSize (pct 90)
marginBottom (px 10)
{-# LANGUAGE OverloadedStrings #-}
module Section
( style
) where
import Clay hiding (style)
import qualified Color
import qualified Media
style :: Css
style = do
".Section__Container" ? do
position relative
margin (pct 0) (pct 10) (pct 0) (pct 10)
".Section__Title" ? do
color Color.red
fontFamily [] [monospace]
fontWeight bold
Media.desktop $ do
lineHeight (px 50)
fontSize (px 30)
marginBottom (px 40)
marginTop (px 55)
Media.tablet $ do
lineHeight (px 40)
fontSize (px 27)
marginBottom (px 35)
marginTop (px 45)
Media.mobile $ do
lineHeight (px 30)
fontSize (px 22)
marginBottom (px 20)
marginTop (px 35)
".Section__Entries" ? do
paddingLeft (px 0)
module Design.Size
( indentation
, lineHeight
module Size
( lineHeight
, listItemSep
, tabletMarginBottom
) where
import Clay hiding (lineHeight)
import Clay hiding (lineHeight)
import qualified Clay
import qualified Design.Media as Media
indentation :: Css
indentation = do
Media.tablet $ marginLeft (px 10)
Media.desktop $ marginLeft (px 20)
import qualified Media
lineHeight :: Css
lineHeight = do
Media.mobile $ Clay.lineHeight (px 30)
Media.tablet $ Clay.lineHeight (px 35)
Media.desktop $ Clay.lineHeight (px 40)
Media.tablet $ Clay.lineHeight (px 35)
Media.mobile $ Clay.lineHeight (px 30)
listItemSep :: Size LengthUnit
listItemSep = px 8
listItemSep =
px 8
tabletMarginBottom :: Css
tabletMarginBottom = Media.tablet $ marginBottom (px 15)
tabletMarginBottom =
Media.tablet $ marginBottom (px 15)
{-# LANGUAGE OverloadedStrings #-}
module Skills
( style
) where
import Clay hiding (style)
import qualified Clay.Flexbox as CF
style :: Css
style = do
".Skills__List" ? do
display flex
flexWrap CF.wrap
sym2 margin (px 5) (px 0)
paddingLeft (px 0)
".Skills__Item" ? do
lineHeight normal
borderBottom solid (px 2) lightgray
margin (px 10) (px 15) (px 5) (px 0)
{-# LANGUAGE OverloadedStrings #-}
import Clay
import qualified Data.Text.Lazy.IO as T
import qualified Body
import qualified Color
import qualified Header
import qualified IconLink
import qualified Media
import qualified Project
import qualified Resume
import qualified Section
import qualified Skills
main :: IO ()
main = T.putStrLn . renderWith compact [] $ do
appearKeyframes
body ? do
overflowX hidden
color Color.black
margin (px 0) (px 0) (px 40) (px 0)
Media.mobile $ fontSize (px 16)
Media.tabletDesktop $ fontSize (px 18)
".Main__Container" ? do
animationName "appear"
animationDuration (sec 0.2)
animationTimingFunction easeIn
animationIterationCount (iterationCount 1.0)
svg ? do
width inherit
height inherit
ul ? do
listStyleType none
paddingLeft (px 0)
Body.style
Header.style
IconLink.style
Project.style
Resume.style
Section.style
Skills.style
appearKeyframes :: Css
appearKeyframes = keyframes
"appear"
[ (0, do
"transform" -: "translateX(10px)"
opacity 0
)
, (100, "transform" -: "translateX(0px)")
]
---
test: bazzz
---
# Expérience
## Développeur
5 ans et 2 mois, depuis 2014
Zengularity, Paris
Architecture web pour les systèmes d’information.
- Catalogue de formations pour les bénéficiaires du RSA en Seine-Saint-Denis.
- Déclaration de sinistres pour Saretec.
- Affranchissement à l’unité et automatique d’étiquettes Colissimo pour La Poste.
- Espace adhérent de la Mutuelle Nationale Territoriale (MNT).
- Analyse d’échantillons alimentaires et visualisation des résultats pour Adisseo.
- Scala
- Scala.js
- Elm
- Akka
- Play!
- MongoDB
- PostgreSQL
- ElasticSearch
## Chercheur stagiaire
5 mois, 2013
IRISA, Rennes
Mise à l’échelle d’une recherche à facettes, à base de requêtes guidées et
expressives, dans le web sémantique.
- Semantic Web
- Scala
- Java
- LaTeX
- GWT
- Jena
## Ingénieur de recherche stagiaire
3 mois, 2012
Mission Critical IT, Bruxelles
Recherche et édition guidées de données du web sémantique.
- Semantic Web
- Mercury
\section{Experience}
$for(experience)$
$body$
$endfor$
\section{Études}
$for(education)$
$body$
$endfor$