nek0 5 years ago
commit
b5e34273bf
  1. 5
      ChangeLog.md
  2. 2
      Setup.hs
  3. 28
      chaoszone.cabal
  4. 36
      newpost.sh
  5. 12
      site/about.md
  6. 8
      site/contact.md
  7. 142
      site/css/default.css
  8. 6
      site/css/font.css
  9. 56
      site/css/hover.scss
  10. 58
      site/css/math.scss
  11. 183
      site/css/menu.scss
  12. BIN
      site/fonts/Xolonium-Regular.otf
  13. BIN
      site/images/Chaoszone.png
  14. 35
      site/images/Chaoszone.svg
  15. BIN
      site/images/haskell-logo.png
  16. 17
      site/index.md
  17. BIN
      site/personae/neil.kra
  18. BIN
      site/personae/neil.kra~
  19. 13
      site/posts/2017-11-09-Hello-World!.md
  20. 154
      src/Main.hs
  21. 2
      templates/archive.html
  22. 40
      templates/default.html
  23. 7
      templates/post-list.html
  24. 17
      templates/post.html

5
ChangeLog.md

@ -0,0 +1,5 @@
# Revision history for chaoszone
## 0.0.0.0 -- YYYY-mm-dd
* First version. Released on an unsuspecting world.

2
Setup.hs

@ -0,0 +1,2 @@
import Distribution.Simple
main = defaultMain

28
chaoszone.cabal

@ -0,0 +1,28 @@
-- Initial chaoszone.cabal generated by cabal init. For further
-- documentation, see http://haskell.org/cabal/users-guide/
name: chaoszone
version: 0.0.0.0
-- synopsis:
-- description:
homepage: https://chaoszone.cz
license: PublicDomain
author: nek0
maintainer: nek0@chelnok.de
category: Web
build-type: Simple
extra-source-files: ChangeLog.md
cabal-version: >=1.10
executable chaoszone
main-is: Main.hs
-- other-modules:
other-extensions: OverloadedStrings
build-depends: base >=4.10 && <4.11
, time >=1.7
, filepath >=1.4
, hakyll >=4.9.8.0
, HTTP
, aeson
hs-source-dirs: src
default-language: Haskell2010

36
newpost.sh

@ -0,0 +1,36 @@
#! /bin/bash
date=$(date --rfc-3339=date)
title=
author=
function input {
echo "Enter post title:"
read title
echo "Enter author name:"
read author
}
function confirmation {
echo "Is the following correct?"
echo "title: $title"
echo "author: $author"
echo "y/n"
}
function main {
local conf="n"
while [ "$conf" != "y" ]
do
input
confirmation
read conf
done
postname="./site/posts/$date-${title// /-}.md"
echo -e "---\ntitle: ${title}\nauthor: ${author}\ndescription: \n---" >> $postname
vim $postname
}
main
unset date title author

12
site/about.md

@ -0,0 +1,12 @@
---
title: About
---
ChaosZone is the project to setting up an collaborative Assembly at the 34th
Chaos Communication Congress.
ChaosZone wants to becaome a place - a platform - to unite hackspaces around
C3D2, the Erfa of the Chaos Computer Club from Dresden in the former GDR.
We are focused on hacking (software, hardware and other stuff). We are
providing a friendly environment for learning from each other.

8
site/contact.md

@ -0,0 +1,8 @@
---
title: Contact
---
If you wish to contact the people behind the planned assembly, you may write to
<mail@c3d2.de>.
To contact the administrator of this site, write to <nek0@chaoszone.cz>.

142
site/css/default.css

@ -0,0 +1,142 @@
body {
color: white;
background-color: black;
background-image: linear-gradient(to bottom, rgba(0,0,0,0.9) 0%,rgba(0,0,0,0.9) 100%), url(/images/Chaoszone.svg);
background-size: contain;
background-attachment:fixed;
background-repeat:no-repeat;
background-position: center;
font-family: 'Xolonium';
font-size: 16px;
font-weight: normal;
font-style: normal;
margin: 0 50px 0;
display: flex;
min-height: 100vh;
flex-direction: column;
}
header {
border-bottom: 2px solid white;
margin-bottom: 30px;
padding: 12px 0px 12px 0px;
}
a {
color: #ccc000;
text-decoration: none;
}
a:hover {
color: #34c300;
text-decoration: underline
}
div#logo a {
color: white;
/*float: left;*/
font-size: 18px;
font-weight: bold;
text-decoration: none;
}
nav {
position: relative;
float: left;
}
nav ul{
text-align: left;
list-style: none;
display: inline-block;
margin: 0;
}
nav li a {
color: white;
font-size: 18px;
font-weight: bold;
margin-left: 12px;
text-decoration: none;
text-transform: uppercase;
}
article {
margin-left: 200px;
}
footer {
border-top: solid 2px white;
color: #555;
font-size: 12px;
margin-top: 30px;
padding: 12px 0px 12px 0px;
text-align: right;
}
h1 {
font-size: 24px;
}
h2 {
font-size: 20px;
}
div.info {
color: #555;
font-size: 14px;
font-style: italic;
}
.pagination {
display: inline-block;
width: 100%
}
.wrapper {
flex: 1;
}
.left, .right {
display: inline-block;
fill: curentColor;
}
.left {
float: left;
margin-left: 10%;
}
.right {
float: right;
margin-right: 10%;
}
.left svg, .right svg {
margin-bottom: -3px;
margin-left: 0.8ex;
margin-right: 0.8ex;
}
#yacs {
width: 100%
}
.page img {
width: 100%
}
.authors_comments {
border: 1px solid white;
border-radius: 5px;
padding: 0 1em 0;
background-color: #454545;
box-shadow: 5px 5px 5px #ffffff;
margin: 2em 0 2em;
}
@media screen and (max-width: 600px){
article {
margin: 120px 0 0 0;
}
}

6
site/css/font.css

@ -0,0 +1,6 @@
@font-face {
font-family: 'Xolonium'
src: url('/fonts/Xolononiu-Regular.otf') format('opentype');
font-weight: normal;
font-style: normal;
}

56
site/css/hover.scss

@ -0,0 +1,56 @@
.tooltip-toggle {
cursor: pointer;
//position: relative;
//Tooltip text container
&::before {
position: absolute;
top: -30px;
//left: -80px;
background-color: #00ff00;
border-radius: 5px;
color: #fff;
content: attr(aria-label); //This pulls in the text from the element with the tooltip
padding: 1ex;
text-transform: none;
font-weight: bold;
transition: all 0.5s ease;
width: 160px;
line-height: 16px;
}
//Tooltip arrow
//&::after {
// position: absolute;
// top: -12px;
// left: 9px;
// border-left: 5px solid transparent;
// border-right: 5px solid transparent;
// border-top: 5px solid #2B222A;
// content: " ";
// font-size: 0;
// line-height: 0;
// margin-left: -5px;
// width: 0;
//}
//Setting up the transition
&::before,
&::after {
color: #efefef;
font-family: monospace;
font-size: 16px;
opacity: 0;
pointer-events: none;
text-align: center;
}
//Triggering the transition
&:focus::before,
&:focus::after,
&:hover::before,
&:hover::after {
opacity: 1;
transition: all 0.75s ease;
}
}

58
site/css/math.scss

@ -0,0 +1,58 @@
@function fact($number) {
$value: 1;
@if $number > 0 {
@for $i from 1 through $number {
$value: $value * $i;
}
}
@return $value;
}
@function pow($number, $exp) {
$value: 1;
@if $exp > 0 {
@for $i from 1 through $exp {
$value: $value * $number;
}
}
@else if $exp < 0 {
@for $i from 1 through -$exp {
$value: $value / $number;
}
}
@return $value;
}
@function pi() {
@return 3.14159265359;
}
@function rad($angle) {
$unit: unit($angle);
$unitless: $angle / ($angle * 0 + 1);
// If the angle has 'deg' as unit, convert to radians.
@if $unit == deg {
$unitless: $unitless / 180 * pi();
}
@return $unitless;
}
@function sin($angle) {
$sin: 0;
$angle: rad($angle);
// Iterate a bunch of times.
@for $i from 0 through 10 {
$sin: $sin + pow(-1, $i) * pow($angle, (2 * $i + 1)) / fact(2 * $i + 1);
}
@return $sin;
}
@function cos($angle) {
$cos: 0;
$angle: rad($angle);
// Iterate a bunch of times.
@for $i from 0 through 10 {
$cos: $cos + pow(-1, $i) * pow($angle, 2 * $i) / fact(2 * $i);
}
@return $cos;
}

183
site/css/menu.scss

@ -0,0 +1,183 @@
@import "math";
// vars
$fg:#ff0000;
$bg:#00ff00;
// config
$menu-items: 5;
$open-distance: 110px;
$start-angle: (0 - pi()) / 2;
$opening-angle: pi() + 0;
.menu {
//@extend %goo;
$width:300px;
$height:300px;
//$width: 250px + (150px * abs(cos($start-angle)));
//$height: 250px + (150px * abs(sin($start-angle)));
position:fixed;
//left:50%;
display: inline-block;
margin-left:-$width/2;
padding-top:$height/2;
padding-left:$width/2;
padding-bottom:-$height/2;
width:$width;
height:$height;
box-sizing:border-box;
font-size:20px;
text-align:left;
}
%ball {
background: $bg;
border-radius: 50%;
width: 80px;
height: 80px;
margin-left: -40px;
margin-top: -40px;
position: absolute;
top: 50%;
color: white;
text-align:center;
line-height: 80px;
transform: translate3d(0,0,0);
transition:transform ease-out 200ms;
svg {
padding-top: 10px;
width: 60px;
height: 60px;
}
}
.menu-open {
display: none;
}
.menu-item {
@extend %ball;
}
.hamburger {
$width: 25px;
$height: 3px;
width: $width;
height: $height;
background: white;
display: block;
position: absolute;
top: 50%;
left: 50%;
margin-left: -$width/2;
margin-top: -$height/2;
transition: transform 200ms;
}
$hamburger-spacing:8px;
.hamburger-1 {
transform:translate3d(0,-$hamburger-spacing,0);
}
.hamburger-2 {
transform:translate3d(0,0,0);
}
.hamburger-3 {
transform:translate3d(0,$hamburger-spacing,0);
}
.menu-open:checked + .menu-open-button {
.hamburger-1 {
transform:translate3d(0,0,0) rotate(45deg);
}
.hamburger-2 {
transform:translate3d(0,0,0) scale(0.1,1);
}
.hamburger-3 {
transform:translate3d(0,0,0) rotate(-45deg);
}
}
.menu-item {
&:hover {
background:#acffac;
color:$fg;
}
@for $i from 1 through $menu-items {
&:nth-child(#{$i+2}) {
transition-duration:10ms+(60ms*($i));
}
}
}
.menu-open-button {
@extend %ball;
z-index:2;
//transition-timing-function:cubic-bezier(0.175, 0.885, 0.320, 1.275);
transition-timing-function:cubic-bezier(0.175, 0.885, 0.320, 1.0);
transition-duration:400ms;
transform:scale(1.1,1.1) translate3d(0,0,0);
cursor:pointer;
}
.menu-open-button:hover {
transform:scale(1.2,1.2) translate3d(0,0,0);
}
.menu-open:checked + .menu-open-button {
transition-timing-function:linear;
transition-duration:200ms;
transform:scale(0.8,0.8) translate3d(0,0,0);
}
.menu-open:checked ~ .menu-item {
transition-timing-function:cubic-bezier(0.935, 0.000, 0.340, 1.330);
@for $i from 1 through $menu-items {
$angle:((pi() - pi())/2)+((pi()/($menu-items - 1))*($i - 1) + $start-angle);
&:nth-child(#{$i+2}) {
transition-duration:80ms+(80ms*$i);
transform:translate3d(cos($angle)*$open-distance,sin($angle)*$open-distance,0);
}
}
}
@media screen and (max-width: 600px){
.menu {
position: relative;
padding-top: 0;
padding-bottom: 0;
height: 80px;
width: 100%;
}
%ball {
$dim: 1.4cm;
width: $dim;
height: $dim;
line-height: $dim;
svg {
$dim: 1.2cm;
padding-top: 0.1cm;
width: $dim;
height: $dim;
}
}
.menu-open:checked~.menu-item{
transition-timing-function:cubic-bezier(0.165, 0.840, 0.440, 1.000);
@for $i from 1 through $menu-items{
&:nth-child(#{$i+2}){
transition-duration:90ms+(100ms*$i);
transform:translate3d(1.4cm*$i,0,0);
}
}
}
}

BIN
site/fonts/Xolonium-Regular.otf

Binary file not shown.

BIN
site/images/Chaoszone.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

35
site/images/Chaoszone.svg

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 19 KiB

BIN
site/images/haskell-logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

17
site/index.md

@ -0,0 +1,17 @@
---
title: Home
---
## Welcome, Comrades!
Welcome to this blog!
We are ChaosZone, mostly hackers from eastern countries, but all creatures are
welcome. Meet us at our Assembly at 34C3.
The latest posts here are
$partial("templates/post-list.html")$
…and there are even more in the [archive](/archive.html).

BIN
site/personae/neil.kra

Binary file not shown.

BIN
site/personae/neil.kra~

Binary file not shown.

13
site/posts/2017-11-09-Hello-World!.md

@ -0,0 +1,13 @@
---
title: Hello World!
author: nek0
description: The ChaosZone introduces itself
---
Hi there!
We are the ChaosZone, an assembly of hackers from eastern countries at the 34th
Chaos Communication Congress in Leipzig.
We aim to provide a comfy coding space with lots of collaboration, information
and knowledge sharing.

154
src/Main.hs

@ -0,0 +1,154 @@
--------------------------------------------------------------------------------
{-# LANGUAGE OverloadedStrings #-}
import Data.Monoid ((<>))
import Hakyll
-- import Hakyll.Web.Sass
import Data.Time.Clock (UTCTime)
import Data.Time.Format (parseTimeM, defaultTimeLocale)
import Data.List
import Data.Maybe (fromMaybe)
import System.FilePath (takeFileName)
import Control.Monad (liftM)
import Network.HTTP.Base (urlEncode)
--------------------------------------------------------------------------------
baseUrl :: String
baseUrl = "https://chaoszone.cz"
main :: IO ()
main = hakyllWith config $ do
is <- sortIdentifiersByDate <$> getMatches "site/posts/*.md"
match "templates/*" $ compile templateBodyCompiler
match
( "site/images/*"
.||. "site/fonts/*"
.||. "site/humans.txt"
.||. "site/robots.txt"
) $ do
route myRoute
compile copyFileCompiler
match "site/css/*.css" $ do
route myRoute
compile compressCssCompiler
-- match "site/css/*.scss" $ do
-- route $ myRoute `composeRoutes` setExtension "css"
-- compile $ fmap compressCss <$> sassCompiler
match (fromList ["site/about.md", "site/contact.md"]) $ do
route $ myRoute `composeRoutes` setExtension "html"
compile $ do
-- firstUrl <- return . fromMaybe "" =<< getRoute (head is)
-- latestUrl <- return . fromMaybe "" =<< getRoute (last is)
pandocCompiler
>>= loadAndApplyTemplate "templates/default.html"
-- (menuCtx firstUrl latestUrl)
defaultContext
>>= relativizeUrls
match "site/index.md" $ do
route $ myRoute `composeRoutes` setExtension "html"
compile $ do
posts <- fmap (take 5) . recentFirst =<< loadAll "site/posts/*"
let indexCtx = listField "posts" postCtx (return posts) <>
constField "title" "Home" <>
defaultContext
getResourceBody
>>= applyAsTemplate indexCtx
>>= renderPandoc
>>= loadAndApplyTemplate "templates/default.html" defaultContext
>>= relativizeUrls
create ["archive.html"] $ do
route idRoute
compile $ do
-- firstUrl <- return . fromMaybe "" =<< getRoute (head is)
-- latestUrl <- return . fromMaybe "" =<< getRoute (last is)
posts <- recentFirst =<< loadAll "site/posts/*"
let archiveCtx =
listField "posts" postCtx (return posts) <>
constField "title" "Archives" <>
-- (menuCtx firstUrl latestUrl)
defaultContext
makeItem ""
>>= loadAndApplyTemplate "templates/archive.html" archiveCtx
>>= loadAndApplyTemplate "templates/default.html" archiveCtx
>>= relativizeUrls
pages <- buildPaginateWith
(liftM (paginateEvery 1) . sortRecentFirst)
"site/posts/*.md"
(\n -> is !! (n - 1))
paginateRules pages $ \num pat -> do
route $ myRoute `composeRoutes` setExtension "html"
compile $ do
-- firstUrl <- fmap ('/' :) . return . fromMaybe "" =<< getRoute (head is)
-- latestUrl <- fmap ('/' :) . return . fromMaybe "" =<< getRoute (last is)
ident <- getUnderlying
title <- getMetadataField' ident "title"
url <- return . fromMaybe "" =<< getRoute ident
compiled <- getResourceBody >>= renderPandoc
let pageCtx = paginateContext pages num
let flattrCtx = constField "enctitle" (urlEncode title) <>
constField "encurl" (urlEncode $ baseUrl ++ url)
let ctx = postCtx <> pageCtx <> flattrCtx
full <- loadAndApplyTemplate "templates/post.html" ctx compiled
_ <- saveSnapshot "content" compiled
loadAndApplyTemplate "templates/default.html"
defaultContext full
>>= relativizeUrls
-- create ["index.html"] $ do
-- route idRoute
-- compile $ do
-- post <- fmap head . recentFirst =<< (loadAll "site/posts/*" :: Compiler [Item String])
-- let indexCtx =
-- constField "date" "%B %e, %Y" <>
-- defaultContext
-- makeItem (itemBody post)
-- >>= relativizeUrls
--------------------------------------------------------------------------------
myRoute :: Routes
myRoute = gsubRoute "site/" (const "")
--------------------------------------------------------------------------------
postCtx :: Context String
postCtx =
dateField "date" "%B %e, %Y" <>
defaultContext
-- menuCtx :: String -> String -> Context String
-- menuCtx first latest =
-- constField "first" first <>
-- constField "latest" latest <>
-- defaultContext
--------------------------------------------------------------------------------
config :: Configuration
config = defaultConfiguration
{ deployCommand = "rsync --del --checksum -rave 'ssh -p 5555' _site/* nek0@chelnok.de:/home/nek0/www/chaoszone"
}
--------------------------------------------------------------------------------
sortIdentifiersByDate :: [Identifier] -> [Identifier]
sortIdentifiersByDate =
sortBy byDate
where
byDate id1 id2 =
let fn1 = takeFileName $ toFilePath id1
fn2 = takeFileName $ toFilePath id2
parseTime' fn = parseTimeM True defaultTimeLocale "%Y-%m-%d" $
intercalate "-" $ take 3 $ splitAll "-" fn
in compare
(parseTime' fn1 :: Maybe UTCTime)
(parseTime' fn2 :: Maybe UTCTime)

2
templates/archive.html

@ -0,0 +1,2 @@
Here you can find all my previous posts:
$partial("templates/post-list.html")$

40
templates/default.html

@ -0,0 +1,40 @@
<!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>ChaosZone</title>
<link rel="stylesheet" href="/css/default.css" />
<link rel="stylesheet" href="/css/hover.css" />
<link rel="icon" type="image/svg+xml" href="/images/Chaoszone.svg">
</head>
<body>
<div class="wrapper">
<header id="header">
<div id="logo">
<a href="/">ChaosZone</a>
</div>
</header>
<nav class="menu">
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about.html">About</a></li>
<li><a href="/contact.html">Contact</a></li>
<li><a href="/archive.html">Archive</a></li>
</ul>
</nav>
<article id="content">
<h1>$title$</h1>
$body$
</article>
</div>
<footer id="footer">
Site proudly generated by
<a href="http://jaspervdj.be/hakyll">Hakyll</a>
</footer>
</body>
</html>

7
templates/post-list.html

@ -0,0 +1,7 @@
<ul>
$for(posts)$
<li>
<a href="$url$">$title$</a> - $date$
</li>
$endfor$
</ul>

17
templates/post.html

@ -0,0 +1,17 @@
<div class="info">
Posted on $date$
$if(author)$
by $author$
$endif$
</div>
$body$
<div class="pagination">
$if(previousPageNum)$
<a class="left" href="$previousPageUrl$"><svg width="1em" height="1em" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1664 896v128q0 53-32.5 90.5t-84.5 37.5h-704l293 294q38 36 38 90t-38 90l-75 76q-37 37-90 37-52 0-91-37l-651-652q-37-37-37-90 0-52 37-91l651-650q38-38 91-38 52 0 90 38l75 74q38 38 38 91t-38 91l-293 293h704q52 0 84.5 37.5t32.5 90.5z" fill="#fff"/></svg>previous page</a>
$endif$
$if(nextPageNum)$
<a class="right" href="$nextPageUrl$">next page<svg width="1em" height="1em" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1600 960q0 54-37 91l-651 651q-39 37-91 37-51 0-90-37l-75-75q-38-38-38-91t38-91l293-293h-704q-52 0-84.5-37.5t-32.5-90.5v-128q0-53 32.5-90.5t84.5-37.5h704l-293-294q-38-36-38-90t38-90l75-75q38-38 90-38 53 0 91 38l651 651q37 35 37 90z" fill="#fff"/></svg></a>
$endif$
</div>
Loading…
Cancel
Save