Switch to Hugo.
|
@ -1,3 +1,6 @@
|
|||
[submodule "dist"]
|
||||
path = dist
|
||||
url = ./dist
|
||||
[submodule "themes/smol"]
|
||||
path = themes/smol
|
||||
url = https://github.com/colorchestra/smol.git
|
||||
|
|
33
README.md
|
@ -1,33 +0,0 @@
|
|||
# elm-pages-starter
|
||||
|
||||
[![Deploy to Netlify](https://www.netlify.com/img/deploy/button.svg)](https://app.netlify.com/start/deploy?repository=https://github.com/dillonkearns/elm-pages-starter)
|
||||
|
||||
This is an example repo to get you up and running with `elm-pages`.
|
||||
|
||||
The entrypoint file is `index.js`. That file imports `src/Main.elm`. The `content` folder is turned into your static pages. The rest is mostly determined by logic in the Elm code! Learn more with the resources below.
|
||||
|
||||
## Setup Instructions
|
||||
Click "Use this template" on this Github page to fork the repo.
|
||||
|
||||
Or git clone it:
|
||||
|
||||
```
|
||||
git clone git@github.com:dillonkearns/elm-pages-starter.git
|
||||
```
|
||||
|
||||
Then install and run the dev server
|
||||
|
||||
```
|
||||
cd elm-pages-starter
|
||||
npm install
|
||||
npm start # starts a local dev server using `elm-pages develop`
|
||||
```
|
||||
|
||||
From there you can tweak the `content` folder or change the `src/Main.elm` file.
|
||||
|
||||
|
||||
## Learn more about `elm-pages`
|
||||
|
||||
- Documentation site: https://elm-pages.com
|
||||
- [Elm Package docs](https://package.elm-lang.org/packages/dillonkearns/elm-pages/latest/)
|
||||
- [`elm-pages` blog](https://elm-pages.com/blog)
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
title: "{{ replace .Name "-" " " | title }}"
|
||||
date: {{ .Date }}
|
||||
draft: true
|
||||
---
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
baseURL = "http://ericonr.github.io/"
|
||||
languageCode = "en-us"
|
||||
title = "Érico's place"
|
||||
theme = "smol"
|
||||
publishdir = "dist"
|
||||
|
||||
# Header
|
||||
[menu]
|
||||
[[menu.main]]
|
||||
identifier = "posts"
|
||||
name = "Posts"
|
||||
url = "/posts/"
|
||||
weight = 1
|
||||
|
||||
[[menu.main]]
|
||||
identifier = "projects"
|
||||
name = "Projects"
|
||||
url = "/projects/"
|
||||
weight = 2
|
||||
|
||||
[[menu.main]]
|
||||
identifier = "about"
|
||||
name = "About"
|
||||
url = "/about"
|
||||
weight = 3
|
||||
|
||||
# Footer
|
||||
[[menu.footer]]
|
||||
name = "Github"
|
||||
url = "https://github.com/ericonr"
|
||||
weight = 1
|
||||
|
||||
[[menu.footer]]
|
||||
name = "Twitter"
|
||||
url = "https://twitter.com/JumpingUnicorn3"
|
||||
weight = 2
|
|
@ -1,13 +1,16 @@
|
|||
---
|
||||
title: Érico's
|
||||
type: page
|
||||
title: "About"
|
||||
date: 2020-06-03T02:37:50-03:00
|
||||
draft: false
|
||||
---
|
||||
|
||||
{{< figure src="/erico.jpg" >}}
|
||||
|
||||
## Hello!
|
||||
|
||||
This is a personal blog, for projects and thoughts. We'll see how it goes.
|
||||
|
||||
Click [here](blog)!
|
||||
Click [here](/posts)!
|
||||
|
||||
---
|
||||
|
||||
|
@ -15,23 +18,20 @@ Click [here](blog)!
|
|||
|
||||
Esse é um blog pessoal, para projetos e pensamentos. Vamos ver o que que sai.
|
||||
|
||||
Clique [aqui](blog)!
|
||||
Clique [aqui](/posts)!
|
||||
|
||||
---
|
||||
|
||||
For an initial introduction, take a look at my [first blog post](blog/hello-world).
|
||||
For an initial introduction, take a look at my [first blog post](/posts/hello-world).
|
||||
|
||||
**Name**: Érico Nogueira Rolim
|
||||
|
||||
**E-mail**: *classified*
|
||||
|
||||
**Twitter**: [@JumpingUnicorn3](https://twitter.com/JumpingUnicorn3) - I should
|
||||
probably use this more often
|
||||
|
||||
**IRC**: "ericonr" or "ericonr\_" on Freenode, depending on how cooperative my
|
||||
internet connection has been
|
||||
|
||||
**Mastodon**: I should probably create one
|
||||
**Mastodon**: I should probably sign up
|
||||
|
||||
**Occupation**: Embedded systems engineer
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
{
|
||||
"type": "blog",
|
||||
"author": "Érico Nogueira",
|
||||
"title": "A Draft Blog Post",
|
||||
"description": "I'm not quite ready to share this post with the world",
|
||||
"image": "images/article-covers/mountains.jpg",
|
||||
"draft": true,
|
||||
"published": "2019-09-21",
|
||||
}
|
||||
---
|
||||
|
||||
This blog post is a draft! Check out `Index.elm` to see how it's being skipped in the `/blog/` listing page.
|
|
@ -1,67 +0,0 @@
|
|||
---
|
||||
{
|
||||
"type": "blog",
|
||||
"author": "Érico Nogueira",
|
||||
"title": "Hello world - and blinking LEDs! 🚀",
|
||||
"description": "Here's my first blog post",
|
||||
"image": "images/article-covers/hello.jpg",
|
||||
"published": "2020-05-04",
|
||||
}
|
||||
---
|
||||
|
||||
Welcome to my blog! It was built with `elm-pages` as a learning exercise.
|
||||
Usually I am more of an embedded systems engineer and systems programmer. I
|
||||
like using C, a bit of C++ and Python, and I am learning Rust and Go - now Elm
|
||||
too. I love FOSS software, and am part of the Void Linux organization, more
|
||||
specifically the documentation team.
|
||||
|
||||
---
|
||||
|
||||
## Olá mundo - e LEDs piscantes
|
||||
|
||||
Bem-vindes ao meu blog! Ele foi construído com `elm-pages`, como um exercício
|
||||
de aprendizado. Normalmente eu sou um engenheiro de sistemas embarcados e
|
||||
programador de sistemas. Eu gosto de usar C, um pouco de C++ e Python, e estou
|
||||
aprendendo Rust e Go - agora Elm também. Eu amo software livre, e sou parte da
|
||||
organização Void Linux, no time de documentação.
|
||||
|
||||
---
|
||||
|
||||
All this to say that I can write code like:
|
||||
|
||||
```cpp
|
||||
#include <stdio.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
printf("Hello World!\n");
|
||||
}
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```python
|
||||
print('Hello world!')
|
||||
```
|
||||
|
||||
but I can also write code like
|
||||
|
||||
```cpp
|
||||
#include <hal.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
while (1) {
|
||||
gpio_reg ~= 0x0001;
|
||||
delay_ms(200);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
and that I want to learn to write code like this:
|
||||
|
||||
```elm
|
||||
plus : number -> number -> number
|
||||
plus m n =
|
||||
m + n
|
||||
```
|
|
@ -1,4 +0,0 @@
|
|||
---
|
||||
title: Érico's blog
|
||||
type: blog-index
|
||||
---
|
|
@ -0,0 +1,43 @@
|
|||
---
|
||||
title: "Hello World"
|
||||
date: 2020-06-03T02:16:09-03:00
|
||||
draft: false
|
||||
---
|
||||
|
||||
Welcome to my blog! It is built with `hugo` for practical purposes. I like using
|
||||
C with a dash of C++ and Python, and I am learning Rust and Go too. I love FOSS
|
||||
software, and am part of the Void Linux organization, more specifically the
|
||||
documentation team.
|
||||
|
||||
---
|
||||
|
||||
All this to say that I can write code like:
|
||||
|
||||
```cpp
|
||||
#include <stdio.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
printf("Hello World!\n");
|
||||
}
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```python
|
||||
print('Hello world!')
|
||||
```
|
||||
|
||||
but I can also write code like
|
||||
|
||||
```cpp
|
||||
#include <hal.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
while (1) {
|
||||
gpio_reg ~= 0x0001;
|
||||
delay_ms(200);
|
||||
}
|
||||
}
|
||||
```
|
|
@ -1,22 +0,0 @@
|
|||
---
|
||||
title: Érico's projects
|
||||
type: page
|
||||
---
|
||||
|
||||
## Individual projects
|
||||
|
||||
- [AppPauser](https://github.com/ericonr/AppPauser): Go project on Linux for
|
||||
sending SIGSTP and SIGCON signals to a monitored application.
|
||||
- [aluno\_exatas](https://github.com/ericonr/aluno_exatas): tools for
|
||||
simplifying data processing after lab procedures, in Python.
|
||||
- [generate-sb-efi](https://github.com/ericonr/generate-sb-efi): Python utility
|
||||
for dealing with UEFI bundles.
|
||||
|
||||
## Contributions
|
||||
|
||||
- [Void Linux](https://github.com/void-linux): I am part of the organization,
|
||||
and have contributed packaging and documentation.
|
||||
- [ly](https://github.com/cylgom/ly): TUI display manager. I contributed
|
||||
the Portuguese translation and a small feature.
|
||||
- [BMSpy](https://github.com/ericonr/BMSpy): Block-Model Simulator for Python.
|
||||
I contributed mainly documentation, as well as some utility functions.
|
|
@ -0,0 +1,25 @@
|
|||
---
|
||||
title: "Projects"
|
||||
date: 2020-06-03T02:19:40-03:00
|
||||
draft: false
|
||||
---
|
||||
|
||||
## Individual projects
|
||||
|
||||
- [AppPauser](https://github.com/ericonr/AppPauser): Go project on Linux for
|
||||
sending SIGSTP and SIGCON signals to a monitored application.
|
||||
- [AppPauserRunit](https://github.com/ericonr/AppPauserRunit): Re-implementation
|
||||
of AppPauser, but using runit + shell instead. Much tidier.
|
||||
- [aluno\_exatas](https://github.com/ericonr/aluno_exatas): tools for
|
||||
simplifying data processing after lab procedures, in Python.
|
||||
- [generate-sb-efi](https://github.com/ericonr/generate-sb-efi): Python utility
|
||||
for dealing with UEFI bundles.
|
||||
|
||||
## Contributions
|
||||
|
||||
- [Void Linux](https://github.com/void-linux): I am part of the organization,
|
||||
and have contributed packaging and documentation.
|
||||
- [ly](https://github.com/cylgom/ly): TUI display manager. I contributed the
|
||||
Portuguese translation and a small feature.
|
||||
- [BMSpy](https://github.com/ericonr/BMSpy): Block-Model Simulator for Python. I
|
||||
contributed mainly documentation, as well as some utility functions.
|
2
dist
|
@ -1 +1 @@
|
|||
Subproject commit 3f173b7e9a11262bc7cadf7aba3b039c308d0fc3
|
||||
Subproject commit 1eba7f6a30a16ee80414dd160b36a9e205f3c580
|
59
elm.json
|
@ -1,59 +0,0 @@
|
|||
{
|
||||
"type": "application",
|
||||
"source-directories": [
|
||||
"src",
|
||||
"gen"
|
||||
],
|
||||
"elm-version": "0.19.1",
|
||||
"dependencies": {
|
||||
"direct": {
|
||||
"avh4/elm-color": "1.0.0",
|
||||
"dillonkearns/elm-pages": "4.0.1",
|
||||
"dillonkearns/elm-rss": "1.0.0",
|
||||
"dillonkearns/elm-sitemap": "1.0.0",
|
||||
"elm/browser": "1.0.2",
|
||||
"elm/core": "1.0.5",
|
||||
"elm/html": "1.0.0",
|
||||
"elm/http": "2.0.0",
|
||||
"elm/json": "1.1.3",
|
||||
"elm/parser": "1.1.0",
|
||||
"elm/svg": "1.0.1",
|
||||
"elm/time": "1.0.0",
|
||||
"elm/url": "1.0.0",
|
||||
"elm-community/list-extra": "8.2.3",
|
||||
"elm-community/result-extra": "2.4.0",
|
||||
"elm-community/string-extra": "4.0.1",
|
||||
"elm-explorations/markdown": "1.0.0",
|
||||
"justinmimbs/date": "3.2.0",
|
||||
"lukewestby/elm-string-interpolate": "1.0.4",
|
||||
"mdgriffith/elm-markup": "3.0.1",
|
||||
"mdgriffith/elm-ui": "1.1.5",
|
||||
"noahzgordon/elm-color-extra": "1.0.2",
|
||||
"rtfeldman/elm-hex": "1.0.0"
|
||||
},
|
||||
"indirect": {
|
||||
"billstclair/elm-xml-eeue56": "1.0.1",
|
||||
"dmy/elm-imf-date-time": "1.0.1",
|
||||
"elm/bytes": "1.0.8",
|
||||
"elm/file": "1.0.5",
|
||||
"elm/random": "1.0.0",
|
||||
"elm/regex": "1.0.0",
|
||||
"elm/virtual-dom": "1.0.2",
|
||||
"elm-community/dict-extra": "2.4.0",
|
||||
"fredcy/elm-parseint": "2.0.1",
|
||||
"justinmimbs/time-extra": "1.1.0",
|
||||
"lazamar/dict-parser": "1.0.2",
|
||||
"mgold/elm-nonempty-list": "4.1.0",
|
||||
"miniBill/elm-codec": "1.2.0",
|
||||
"ryannhg/date-format": "2.3.0",
|
||||
"tripokey/elm-fuzzy": "5.2.1",
|
||||
"zwilias/json-decode-exploration": "6.0.0"
|
||||
}
|
||||
},
|
||||
"test-dependencies": {
|
||||
"direct": {
|
||||
"elm-explorations/test": "1.2.2"
|
||||
},
|
||||
"indirect": {}
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 307 KiB |
Before Width: | Height: | Size: 293 KiB |
|
@ -1,39 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 323.141 322.95" enable-background="new 0 0 323.141 322.95" xml:space="preserve">
|
||||
<g>
|
||||
<polygon
|
||||
fill="#F0AD00"
|
||||
points="161.649,152.782 231.514,82.916 91.783,82.916"/>
|
||||
|
||||
<polygon
|
||||
fill="#7FD13B"
|
||||
points="8.867,0 79.241,70.375 232.213,70.375 161.838,0"/>
|
||||
|
||||
<rect
|
||||
fill="#7FD13B"
|
||||
x="192.99"
|
||||
y="107.392"
|
||||
transform="matrix(0.7071 0.7071 -0.7071 0.7071 186.4727 -127.2386)"
|
||||
width="107.676"
|
||||
height="108.167"/>
|
||||
|
||||
<polygon
|
||||
fill="#60B5CC"
|
||||
points="323.298,143.724 323.298,0 179.573,0"/>
|
||||
|
||||
<polygon
|
||||
fill="#5A6378"
|
||||
points="152.781,161.649 0,8.868 0,314.432"/>
|
||||
|
||||
<polygon
|
||||
fill="#F0AD00"
|
||||
points="255.522,246.655 323.298,314.432 323.298,178.879"/>
|
||||
|
||||
<polygon
|
||||
fill="#60B5CC"
|
||||
points="161.649,170.517 8.869,323.298 314.43,323.298"/>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 1.1 KiB |
|
@ -1 +0,0 @@
|
|||
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>GitHub icon</title><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg>
|
Before Width: | Height: | Size: 827 B |
Before Width: | Height: | Size: 976 B |
|
@ -1,2 +0,0 @@
|
|||
<svg version="1.1" viewBox="251.0485 144.52063 56.114286 74.5" width="50px" height="74.5"><defs><linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%"><stop offset="10%" style="stop-color:rgba(1.96%,45.88%,90.2%,1);stop-opacity:1"></stop><stop offset="100%" style="stop-color:rgba(0%,94.9%,37.65%,1);stop-opacity:1"></stop></linearGradient></defs><metadata></metadata><g id="Canvas_11" stroke="none" fill="url(#grad1)" stroke-opacity="1" fill-opacity="1" stroke-dasharray="none"><g id="Canvas_11: Layer 1"><g id="Group_38"><g id="Graphic_32"><path d="M 252.5485 146.02063 L 252.5485 217.52063 L 305.66277 217.52063 L 305.66277 161.68254 L 290.00087 146.02063 Z" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="3"></path></g><g id="Line_34"><line x1="266.07286" y1="182.8279" x2="290.75465" y2="183.00997" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"></line></g><g id="Line_35"><line x1="266.07286" y1="191.84156" x2="290.75465" y2="192.02363" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"></line></g><g id="Line_36"><line x1="266.07286" y1="200.85522" x2="290.75465" y2="201.0373" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"></line></g><g id="Line_37"><line x1="266.07286" y1="164.80058" x2="278.3874" y2="164.94049" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"></line></g></g></g></g></svg>
|
||||
|
Before Width: | Height: | Size: 1.4 KiB |
22
index.js
|
@ -1,22 +0,0 @@
|
|||
import hljs from "highlight.js/lib/highlight";
|
||||
import "highlight.js/styles/github.css";
|
||||
import elm from 'highlight.js/lib/languages/elm';
|
||||
import cpp from 'highlight.js/lib/languages/cpp';
|
||||
import python from 'highlight.js/lib/languages/python';
|
||||
// we're just importing the syntaxes we want from hljs
|
||||
// in order to reduce our JS bundle size
|
||||
// see https://bjacobel.com/2016/12/04/highlight-bundle-size/
|
||||
hljs.registerLanguage('elm', elm);
|
||||
hljs.registerLanguage('cpp', cpp);
|
||||
hljs.registerLanguage('python', python);
|
||||
|
||||
|
||||
import "./style.css";
|
||||
// @ts-ignore
|
||||
window.hljs = hljs;
|
||||
const { Elm } = require("./src/Main.elm");
|
||||
const pagesInit = require("elm-pages");
|
||||
|
||||
pagesInit({
|
||||
mainElmModule: Elm.Main
|
||||
});
|
|
@ -1,3 +0,0 @@
|
|||
[build]
|
||||
publish = "./dist/"
|
||||
command = "export ELM_HOME=\"$NETLIFY_CACHE_DIR/elm\" && npm run build"
|
22
package.json
|
@ -1,22 +0,0 @@
|
|||
{
|
||||
"name": "ericonr-blog",
|
||||
"version": "1.0.0",
|
||||
"description": "Érico Nogueira's blog",
|
||||
"scripts": {
|
||||
"start": "elm-pages develop",
|
||||
"serve": "npm run build && http-server ./dist -a localhost -p 3000 -c-1",
|
||||
"build": "elm-pages build"
|
||||
},
|
||||
"author": "Érico Nogueira",
|
||||
"license": "BSD-3",
|
||||
"dependencies": {
|
||||
"elm-pages": "1.3.0",
|
||||
"highlight.js": "^9.15.10",
|
||||
"node-sass": "^4.12.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"elm": "latest-0.19.1",
|
||||
"elm-format": "^0.8.2",
|
||||
"http-server": "^0.11.1"
|
||||
}
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
module Data.Author exposing (Author, all, decoder, view)
|
||||
|
||||
import Element exposing (Element)
|
||||
import Html.Attributes as Attr
|
||||
import Json.Decode as Decode exposing (Decoder)
|
||||
import List.Extra
|
||||
import Pages
|
||||
import Pages.ImagePath as ImagePath exposing (ImagePath)
|
||||
|
||||
|
||||
type alias Author =
|
||||
{ name : String
|
||||
, avatar : ImagePath Pages.PathKey
|
||||
, bio : String
|
||||
}
|
||||
|
||||
|
||||
all : List Author
|
||||
all =
|
||||
[ { name = "Érico Nogueira"
|
||||
, avatar = Pages.images.author.erico
|
||||
, bio = "Embedded systems engineer, systems programmer and documentation appreciator."
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
decoder : Decoder Author
|
||||
decoder =
|
||||
Decode.string
|
||||
|> Decode.andThen
|
||||
(\lookupName ->
|
||||
case List.Extra.find (\currentAuthor -> currentAuthor.name == lookupName) all of
|
||||
Just author ->
|
||||
Decode.succeed author
|
||||
|
||||
Nothing ->
|
||||
Decode.fail ("Couldn't find author with name " ++ lookupName ++ ". Options are " ++ String.join ", " (List.map .name all))
|
||||
)
|
||||
|
||||
|
||||
view : List (Element.Attribute msg) -> Author -> Element msg
|
||||
view attributes author =
|
||||
Element.image
|
||||
(Element.width (Element.px 70)
|
||||
:: Element.htmlAttribute (Attr.class "avatar")
|
||||
:: attributes
|
||||
)
|
||||
{ src = ImagePath.toString author.avatar, description = author.name }
|
|
@ -1,91 +0,0 @@
|
|||
module DocumentSvg exposing (view)
|
||||
|
||||
import Color
|
||||
import Element exposing (Element)
|
||||
import Svg exposing (..)
|
||||
import Svg.Attributes exposing (..)
|
||||
|
||||
|
||||
strokeColor =
|
||||
-- "url(#grad1)"
|
||||
"black"
|
||||
|
||||
|
||||
pageTextColor =
|
||||
"white"
|
||||
|
||||
|
||||
fillColor =
|
||||
"url(#grad1)"
|
||||
|
||||
|
||||
|
||||
-- "none"
|
||||
|
||||
|
||||
fillGradient =
|
||||
gradient
|
||||
(Color.rgb255 214 2 112)
|
||||
(Color.rgb255 0 56 168)
|
||||
|
||||
|
||||
|
||||
-- (Color.rgb255 252 0 255)
|
||||
-- (Color.rgb255 0 219 222)
|
||||
-- (Color.rgb255 255 93 194)
|
||||
-- (Color.rgb255 255 150 250)
|
||||
|
||||
|
||||
gradient color1 color2 =
|
||||
linearGradient [ id "grad1", x1 "0%", y1 "0%", x2 "100%", y2 "0%" ]
|
||||
[ stop
|
||||
[ offset "10%"
|
||||
, Svg.Attributes.style ("stop-color:" ++ Color.toCssString color1 ++ ";stop-opacity:1")
|
||||
]
|
||||
[]
|
||||
, stop [ offset "100%", Svg.Attributes.style ("stop-color:" ++ Color.toCssString color2 ++ ";stop-opacity:1") ] []
|
||||
]
|
||||
|
||||
|
||||
view : Element msg
|
||||
view =
|
||||
svg
|
||||
[ version "1.1"
|
||||
, viewBox "251.0485 144.52063 56.114286 74.5"
|
||||
, width "56.114286"
|
||||
, height "74.5"
|
||||
, Svg.Attributes.width "30px"
|
||||
]
|
||||
[ defs []
|
||||
[ fillGradient ]
|
||||
, metadata [] []
|
||||
, g
|
||||
[ id "Canvas_11"
|
||||
, stroke "none"
|
||||
, fill fillColor
|
||||
, strokeOpacity "1"
|
||||
, fillOpacity "1"
|
||||
, strokeDasharray "none"
|
||||
]
|
||||
[ g [ id "Canvas_11: Layer 1" ]
|
||||
[ g [ id "Group_38" ]
|
||||
[ g [ id "Graphic_32" ]
|
||||
[ Svg.path
|
||||
[ d "M 252.5485 146.02063 L 252.5485 217.52063 L 305.66277 217.52063 L 305.66277 161.68254 L 290.00087 146.02063 Z"
|
||||
, stroke strokeColor
|
||||
, strokeLinecap "round"
|
||||
, strokeLinejoin "round"
|
||||
, strokeWidth "3"
|
||||
]
|
||||
[]
|
||||
]
|
||||
, g [ id "Line_34" ] [ line [ x1 "266.07286", y1 "182.8279", x2 "290.75465", y2 "183.00997", stroke pageTextColor, strokeLinecap "round", strokeLinejoin "round", strokeWidth "2" ] [] ]
|
||||
, g [ id "Line_35" ] [ line [ x1 "266.07286", y1 "191.84156", x2 "290.75465", y2 "192.02363", stroke pageTextColor, strokeLinecap "round", strokeLinejoin "round", strokeWidth "2" ] [] ]
|
||||
, g [ id "Line_36" ] [ line [ x1 "266.07286", y1 "200.85522", x2 "290.75465", y2 "201.0373", stroke pageTextColor, strokeLinecap "round", strokeLinejoin "round", strokeWidth "2" ] [] ]
|
||||
, g [ id "Line_37" ] [ line [ x1 "266.07286", y1 "164.80058", x2 "278.3874", y2 "164.94049", stroke pageTextColor, strokeLinecap "round", strokeLinejoin "round", strokeWidth "2" ] [] ]
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
|> Element.html
|
||||
|> Element.el []
|
76
src/Feed.elm
|
@ -1,76 +0,0 @@
|
|||
module Feed exposing (fileToGenerate)
|
||||
|
||||
import Metadata exposing (Metadata(..))
|
||||
import Pages
|
||||
import Pages.PagePath as PagePath exposing (PagePath)
|
||||
import Rss
|
||||
|
||||
|
||||
fileToGenerate :
|
||||
{ siteTagline : String
|
||||
, siteUrl : String
|
||||
}
|
||||
->
|
||||
List
|
||||
{ path : PagePath Pages.PathKey
|
||||
, frontmatter : Metadata
|
||||
, body : String
|
||||
}
|
||||
->
|
||||
{ path : List String
|
||||
, content : String
|
||||
}
|
||||
fileToGenerate config siteMetadata =
|
||||
{ path = [ "blog", "feed.xml" ]
|
||||
, content = generate config siteMetadata
|
||||
}
|
||||
|
||||
|
||||
generate :
|
||||
{ siteTagline : String
|
||||
, siteUrl : String
|
||||
}
|
||||
->
|
||||
List
|
||||
{ path : PagePath Pages.PathKey
|
||||
, frontmatter : Metadata
|
||||
, body : String
|
||||
}
|
||||
-> String
|
||||
generate { siteTagline, siteUrl } siteMetadata =
|
||||
Rss.generate
|
||||
{ title = "elm-pages Blog"
|
||||
, description = siteTagline
|
||||
, url = "https://elm-pages.com/blog"
|
||||
, lastBuildTime = Pages.builtAt
|
||||
, generator = Just "elm-pages"
|
||||
, items = siteMetadata |> List.filterMap metadataToRssItem
|
||||
, siteUrl = siteUrl
|
||||
}
|
||||
|
||||
|
||||
metadataToRssItem :
|
||||
{ path : PagePath Pages.PathKey
|
||||
, frontmatter : Metadata
|
||||
, body : String
|
||||
}
|
||||
-> Maybe Rss.Item
|
||||
metadataToRssItem page =
|
||||
case page.frontmatter of
|
||||
Article article ->
|
||||
if article.draft then
|
||||
Nothing
|
||||
|
||||
else
|
||||
Just
|
||||
{ title = article.title
|
||||
, description = article.description
|
||||
, url = PagePath.toString page.path
|
||||
, categories = []
|
||||
, author = article.author.name
|
||||
, pubDate = Rss.Date article.published
|
||||
, content = Nothing
|
||||
}
|
||||
|
||||
_ ->
|
||||
Nothing
|
134
src/Index.elm
|
@ -1,134 +0,0 @@
|
|||
module Index exposing (view)
|
||||
|
||||
import Data.Author
|
||||
import Date
|
||||
import Element exposing (Element)
|
||||
import Element.Border
|
||||
import Element.Font
|
||||
import Metadata exposing (Metadata)
|
||||
import Pages
|
||||
import Pages.PagePath as PagePath exposing (PagePath)
|
||||
import Pages.Platform exposing (Page)
|
||||
|
||||
|
||||
type alias PostEntry =
|
||||
( PagePath Pages.PathKey, Metadata.ArticleMetadata )
|
||||
|
||||
|
||||
view :
|
||||
List ( PagePath Pages.PathKey, Metadata )
|
||||
-> Element msg
|
||||
view posts =
|
||||
Element.column [ Element.spacing 20 ]
|
||||
(posts
|
||||
|> List.filterMap
|
||||
(\( path, metadata ) ->
|
||||
case metadata of
|
||||
Metadata.Page meta ->
|
||||
Nothing
|
||||
|
||||
Metadata.Author _ ->
|
||||
Nothing
|
||||
|
||||
Metadata.Article meta ->
|
||||
if meta.draft then
|
||||
Nothing
|
||||
|
||||
else
|
||||
Just ( path, meta )
|
||||
|
||||
Metadata.BlogIndex ->
|
||||
Nothing
|
||||
)
|
||||
|> List.sortWith postPublishDateDescending
|
||||
|> List.map postSummary
|
||||
)
|
||||
|
||||
|
||||
postPublishDateAscending : PostEntry -> PostEntry -> Order
|
||||
postPublishDateAscending ( _, metadata1 ) ( _, metadata2 ) =
|
||||
Date.compare metadata1.published metadata2.published
|
||||
|
||||
|
||||
postPublishDateDescending : PostEntry -> PostEntry -> Order
|
||||
postPublishDateDescending ( _, metadata1 ) ( _, metadata2 ) =
|
||||
Date.compare metadata2.published metadata1.published
|
||||
|
||||
|
||||
postSummary : PostEntry -> Element msg
|
||||
postSummary ( postPath, post ) =
|
||||
articleIndex post
|
||||
|> linkToPost postPath
|
||||
|
||||
|
||||
linkToPost : PagePath Pages.PathKey -> Element msg -> Element msg
|
||||
linkToPost postPath content =
|
||||
Element.link [ Element.width Element.fill ]
|
||||
{ url = PagePath.toString postPath, label = content }
|
||||
|
||||
|
||||
title : String -> Element msg
|
||||
title text =
|
||||
[ Element.text text ]
|
||||
|> Element.paragraph
|
||||
[ Element.Font.size 36
|
||||
, Element.Font.center
|
||||
, Element.Font.family [ Element.Font.typeface "Raleway" ]
|
||||
, Element.Font.semiBold
|
||||
, Element.padding 16
|
||||
]
|
||||
|
||||
|
||||
articleIndex : Metadata.ArticleMetadata -> Element msg
|
||||
articleIndex metadata =
|
||||
Element.el
|
||||
[ Element.centerX
|
||||
, Element.width (Element.maximum 800 Element.fill)
|
||||
, Element.padding 40
|
||||
, Element.spacing 10
|
||||
, Element.Border.width 1
|
||||
, Element.Border.color (Element.rgba255 0 0 0 0.1)
|
||||
, Element.mouseOver
|
||||
[ Element.Border.color (Element.rgba255 0 0 0 1)
|
||||
]
|
||||
]
|
||||
(postPreview metadata)
|
||||
|
||||
|
||||
readMoreLink =
|
||||
Element.text "Continue reading >>"
|
||||
|> Element.el
|
||||
[ Element.centerX
|
||||
, Element.Font.size 18
|
||||
, Element.alpha 0.6
|
||||
, Element.mouseOver [ Element.alpha 1 ]
|
||||
, Element.Font.underline
|
||||
, Element.Font.center
|
||||
]
|
||||
|
||||
|
||||
postPreview : Metadata.ArticleMetadata -> Element msg
|
||||
postPreview post =
|
||||
Element.textColumn
|
||||
[ Element.centerX
|
||||
, Element.width Element.fill
|
||||
, Element.spacing 30
|
||||
, Element.Font.size 18
|
||||
]
|
||||
[ title post.title
|
||||
, Element.row [ Element.spacing 10, Element.centerX ]
|
||||
[ Data.Author.view [ Element.width (Element.px 40) ] post.author
|
||||
, Element.text post.author.name
|
||||
, Element.text "•"
|
||||
, Element.text (post.published |> Date.format "MMMM ddd, yyyy")
|
||||
]
|
||||
, post.description
|
||||
|> Element.text
|
||||
|> List.singleton
|
||||
|> Element.paragraph
|
||||
[ Element.Font.size 22
|
||||
, Element.Font.center
|
||||
, Element.Font.family [ Element.Font.typeface "Raleway" ]
|
||||
]
|
||||
, readMoreLink
|
||||
]
|
130
src/Layout.elm
|
@ -1,130 +0,0 @@
|
|||
module Layout exposing (..)
|
||||
|
||||
import DocumentSvg
|
||||
import Element exposing (Element)
|
||||
import Element.Background
|
||||
import Element.Border
|
||||
import Element.Font as Font
|
||||
import Element.Region
|
||||
import Html exposing (Html)
|
||||
import Metadata exposing (Metadata)
|
||||
import Pages
|
||||
import Pages.Directory as Directory exposing (Directory)
|
||||
import Pages.ImagePath as ImagePath
|
||||
import Pages.PagePath as PagePath exposing (PagePath)
|
||||
import Palette
|
||||
|
||||
|
||||
|
||||
--view :
|
||||
-- { path : PagePath Pages.PathKey
|
||||
-- , frontmatter : Metadata
|
||||
-- }
|
||||
|
||||
|
||||
view :
|
||||
{ title : String, body : List (Element msg) }
|
||||
->
|
||||
{ path : PagePath Pages.PathKey
|
||||
, frontmatter : Metadata
|
||||
}
|
||||
-> { title : String, body : Html msg }
|
||||
view document page =
|
||||
{ title = document.title
|
||||
, body =
|
||||
Element.column
|
||||
[ Element.width Element.fill ]
|
||||
[ header page.path
|
||||
, Element.column
|
||||
[ Element.padding 30
|
||||
, Element.spacing 40
|
||||
, Element.Region.mainContent
|
||||
, Element.width (Element.fill |> Element.maximum 800)
|
||||
, Element.centerX
|
||||
]
|
||||
document.body
|
||||
]
|
||||
|> Element.layout
|
||||
[ Element.width Element.fill
|
||||
, Font.size 20
|
||||
, Font.family [ Font.typeface "Roboto" ]
|
||||
, Font.color (Element.rgba255 0 0 0 0.8)
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
header : PagePath Pages.PathKey -> Element msg
|
||||
header currentPath =
|
||||
Element.column [ Element.width Element.fill ]
|
||||
[ Element.el
|
||||
[ Element.height (Element.px 4)
|
||||
, Element.width Element.fill
|
||||
, Element.Background.gradient
|
||||
{ angle = 0.2
|
||||
, steps =
|
||||
[ Element.rgb255 0 242 96
|
||||
, Element.rgb255 5 117 230
|
||||
]
|
||||
}
|
||||
]
|
||||
Element.none
|
||||
, Element.row
|
||||
[ Element.paddingXY 25 4
|
||||
, Element.spaceEvenly
|
||||
, Element.width Element.fill
|
||||
, Element.Region.navigation
|
||||
, Element.Border.widthEach { bottom = 1, left = 0, right = 0, top = 0 }
|
||||
, Element.Border.color (Element.rgba255 40 80 40 0.4)
|
||||
]
|
||||
[ Element.link []
|
||||
{ url = "/"
|
||||
, label =
|
||||
Element.row [ Font.size 30, Element.spacing 16 ]
|
||||
[ DocumentSvg.view
|
||||
, Element.text "Érico's bihorn"
|
||||
]
|
||||
}
|
||||
, Element.row [ Element.spacing 15 ]
|
||||
[ githubRepoLink
|
||||
, highlightableLink currentPath Pages.pages.blog.directory "Blog"
|
||||
, highlightableLink currentPath Pages.pages.project.directory "Projects"
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
highlightableLink :
|
||||
PagePath Pages.PathKey
|
||||
-> Directory Pages.PathKey Directory.WithIndex
|
||||
-> String
|
||||
-> Element msg
|
||||
highlightableLink currentPath linkDirectory displayName =
|
||||
let
|
||||
isHighlighted =
|
||||
currentPath |> Directory.includes linkDirectory
|
||||
in
|
||||
Element.link
|
||||
(if isHighlighted then
|
||||
[ Font.underline
|
||||
, Font.color Palette.color.primary
|
||||
]
|
||||
|
||||
else
|
||||
[]
|
||||
)
|
||||
{ url = linkDirectory |> Directory.indexPath |> PagePath.toString
|
||||
, label = Element.text displayName
|
||||
}
|
||||
|
||||
|
||||
githubRepoLink : Element msg
|
||||
githubRepoLink =
|
||||
Element.newTabLink []
|
||||
{ url = "https://github.com/ericonr/ericonr"
|
||||
, label =
|
||||
Element.image
|
||||
[ Element.width (Element.px 22)
|
||||
, Font.color Palette.color.primary
|
||||
]
|
||||
{ src = ImagePath.toString Pages.images.github, description = "Github repo" }
|
||||
}
|
414
src/Main.elm
|
@ -1,414 +0,0 @@
|
|||
module Main exposing (main)
|
||||
|
||||
import Color
|
||||
import Data.Author as Author
|
||||
import Date
|
||||
import DocumentSvg
|
||||
import Element exposing (Element)
|
||||
import Element.Background
|
||||
import Element.Border
|
||||
import Element.Font as Font
|
||||
import Element.Region
|
||||
import Feed
|
||||
import Head
|
||||
import Head.Seo as Seo
|
||||
import Html exposing (Html)
|
||||
import Html.Attributes as Attr
|
||||
import Index
|
||||
import Json.Decode
|
||||
import Layout
|
||||
import Markdown
|
||||
import Metadata exposing (Metadata)
|
||||
import MySitemap
|
||||
import Page.Article
|
||||
import Pages exposing (images, pages)
|
||||
import Pages.Directory as Directory exposing (Directory)
|
||||
import Pages.Document
|
||||
import Pages.ImagePath as ImagePath exposing (ImagePath)
|
||||
import Pages.Manifest as Manifest
|
||||
import Pages.Manifest.Category
|
||||
import Pages.PagePath as PagePath exposing (PagePath)
|
||||
import Pages.Platform exposing (Page)
|
||||
import Pages.StaticHttp as StaticHttp
|
||||
import Palette
|
||||
|
||||
|
||||
manifest : Manifest.Config Pages.PathKey
|
||||
manifest =
|
||||
{ backgroundColor = Just Color.white
|
||||
, categories = [ Pages.Manifest.Category.education ]
|
||||
, displayMode = Manifest.Standalone
|
||||
, orientation = Manifest.Portrait
|
||||
, description = "elm-pages-starter - A statically typed site generator."
|
||||
, iarcRatingId = Nothing
|
||||
, name = "elm-pages-starter"
|
||||
, themeColor = Just Color.white
|
||||
, startUrl = pages.index
|
||||
, shortName = Just "elm-pages-starter"
|
||||
, sourceIcon = images.iconPng
|
||||
}
|
||||
|
||||
|
||||
type alias Rendered =
|
||||
Element Msg
|
||||
|
||||
|
||||
|
||||
-- the intellij-elm plugin doesn't support type aliases for Programs so we need to use this line
|
||||
-- main : Platform.Program Pages.Platform.Flags (Pages.Platform.Model Model Msg Metadata Rendered) (Pages.Platform.Msg Msg Metadata Rendered)
|
||||
|
||||
|
||||
main : Pages.Platform.Program Model Msg Metadata Rendered
|
||||
main =
|
||||
Pages.Platform.application
|
||||
{ init = \_ -> init
|
||||
, view = view
|
||||
, update = update
|
||||
, subscriptions = subscriptions
|
||||
, documents = [ markdownDocument ]
|
||||
, manifest = manifest
|
||||
, canonicalSiteUrl = canonicalSiteUrl
|
||||
, onPageChange = \_ -> ()
|
||||
, generateFiles = generateFiles
|
||||
, internals = Pages.internals
|
||||
}
|
||||
|
||||
|
||||
generateFiles :
|
||||
List
|
||||
{ path : PagePath Pages.PathKey
|
||||
, frontmatter : Metadata
|
||||
, body : String
|
||||
}
|
||||
->
|
||||
List
|
||||
(Result String
|
||||
{ path : List String
|
||||
, content : String
|
||||
}
|
||||
)
|
||||
generateFiles siteMetadata =
|
||||
[ Feed.fileToGenerate { siteTagline = siteTagline, siteUrl = canonicalSiteUrl } siteMetadata |> Ok
|
||||
, MySitemap.build { siteUrl = canonicalSiteUrl } siteMetadata |> Ok
|
||||
]
|
||||
|
||||
|
||||
markdownDocument : ( String, Pages.Document.DocumentHandler Metadata Rendered )
|
||||
markdownDocument =
|
||||
Pages.Document.parser
|
||||
{ extension = "md"
|
||||
, metadata = Metadata.decoder
|
||||
, body =
|
||||
\markdownBody ->
|
||||
Html.div [] [ Markdown.toHtml [] markdownBody ]
|
||||
|> Element.html
|
||||
|> List.singleton
|
||||
|> Element.paragraph [ Element.width Element.fill ]
|
||||
|> Ok
|
||||
}
|
||||
|
||||
|
||||
type alias Model =
|
||||
{}
|
||||
|
||||
|
||||
init : ( Model, Cmd Msg )
|
||||
init =
|
||||
( Model, Cmd.none )
|
||||
|
||||
|
||||
type alias Msg =
|
||||
()
|
||||
|
||||
|
||||
update : Msg -> Model -> ( Model, Cmd Msg )
|
||||
update msg model =
|
||||
case msg of
|
||||
() ->
|
||||
( model, Cmd.none )
|
||||
|
||||
|
||||
subscriptions : Model -> Sub Msg
|
||||
subscriptions _ =
|
||||
Sub.none
|
||||
|
||||
|
||||
view :
|
||||
List ( PagePath Pages.PathKey, Metadata )
|
||||
->
|
||||
{ path : PagePath Pages.PathKey
|
||||
, frontmatter : Metadata
|
||||
}
|
||||
->
|
||||
StaticHttp.Request
|
||||
{ view : Model -> Rendered -> { title : String, body : Html Msg }
|
||||
, head : List (Head.Tag Pages.PathKey)
|
||||
}
|
||||
view siteMetadata page =
|
||||
StaticHttp.succeed
|
||||
{ view =
|
||||
\model viewForPage ->
|
||||
Layout.view (pageView model siteMetadata page viewForPage) page
|
||||
, head = head page.frontmatter
|
||||
}
|
||||
|
||||
|
||||
pageView :
|
||||
Model
|
||||
-> List ( PagePath Pages.PathKey, Metadata )
|
||||
-> { path : PagePath Pages.PathKey, frontmatter : Metadata }
|
||||
-> Rendered
|
||||
-> { title : String, body : List (Element Msg) }
|
||||
pageView model siteMetadata page viewForPage =
|
||||
case page.frontmatter of
|
||||
Metadata.Page metadata ->
|
||||
{ title = metadata.title
|
||||
, body =
|
||||
[ viewForPage
|
||||
]
|
||||
|
||||
-- |> Element.textColumn
|
||||
-- [ Element.width Element.fill
|
||||
-- ]
|
||||
}
|
||||
|
||||
Metadata.Article metadata ->
|
||||
Page.Article.view metadata viewForPage
|
||||
|
||||
Metadata.Author author ->
|
||||
{ title = author.name
|
||||
, body =
|
||||
[ Palette.blogHeading author.name
|
||||
, Author.view [] author
|
||||
, Element.paragraph [ Element.centerX, Font.center ] [ viewForPage ]
|
||||
]
|
||||
}
|
||||
|
||||
Metadata.BlogIndex ->
|
||||
{ title = "Érico's blog"
|
||||
, body =
|
||||
[ Element.column [ Element.padding 20, Element.centerX ] [ Index.view siteMetadata ]
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
articleImageView : ImagePath Pages.PathKey -> Element msg
|
||||
articleImageView articleImage =
|
||||
Element.image [ Element.width Element.fill ]
|
||||
{ src = ImagePath.toString articleImage
|
||||
, description = "Article cover photo"
|
||||
}
|
||||
|
||||
|
||||
header : PagePath Pages.PathKey -> Element msg
|
||||
header currentPath =
|
||||
Element.column [ Element.width Element.fill ]
|
||||
[ Element.el
|
||||
[ Element.height (Element.px 4)
|
||||
, Element.width Element.fill
|
||||
, Element.Background.gradient
|
||||
{ angle = 0.2
|
||||
, steps =
|
||||
[ Element.rgb255 0 242 96
|
||||
, Element.rgb255 5 117 230
|
||||
]
|
||||
}
|
||||
]
|
||||
Element.none
|
||||
, Element.row
|
||||
[ Element.paddingXY 25 4
|
||||
, Element.spaceEvenly
|
||||
, Element.width Element.fill
|
||||
, Element.Region.navigation
|
||||
, Element.Border.widthEach { bottom = 1, left = 0, right = 0, top = 0 }
|
||||
, Element.Border.color (Element.rgba255 40 80 40 0.4)
|
||||
]
|
||||
[ Element.link []
|
||||
{ url = "/"
|
||||
, label =
|
||||
Element.row [ Font.size 30, Element.spacing 16 ]
|
||||
[ DocumentSvg.view
|
||||
, Element.text "elm-pages-starter"
|
||||
]
|
||||
}
|
||||
, Element.row [ Element.spacing 15 ]
|
||||
[ elmDocsLink
|
||||
, githubRepoLink
|
||||
, highlightableLink currentPath pages.blog.directory "Blog"
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
highlightableLink :
|
||||
PagePath Pages.PathKey
|
||||
-> Directory Pages.PathKey Directory.WithIndex
|
||||
-> String
|
||||
-> Element msg
|
||||
highlightableLink currentPath linkDirectory displayName =
|
||||
let
|
||||
isHighlighted =
|
||||
currentPath |> Directory.includes linkDirectory
|
||||
in
|
||||
Element.link
|
||||
(if isHighlighted then
|
||||
[ Font.underline
|
||||
, Font.color Palette.color.primary
|
||||
]
|
||||
|
||||
else
|
||||
[]
|
||||
)
|
||||
{ url = linkDirectory |> Directory.indexPath |> PagePath.toString
|
||||
, label = Element.text displayName
|
||||
}
|
||||
|
||||
|
||||
commonHeadTags : List (Head.Tag Pages.PathKey)
|
||||
commonHeadTags =
|
||||
[ Head.rssLink "/blog/feed.xml"
|
||||
, Head.sitemapLink "/sitemap.xml"
|
||||
]
|
||||
|
||||
|
||||
{-| <https://developer.twitter.com/en/docs/tweets/optimize-with-cards/overview/abouts-cards>
|
||||
<https://htmlhead.dev>
|
||||
<https://html.spec.whatwg.org/multipage/semantics.html#standard-metadata-names>
|
||||
<https://ogp.me/>
|
||||
-}
|
||||
head : Metadata -> List (Head.Tag Pages.PathKey)
|
||||
head metadata =
|
||||
commonHeadTags
|
||||
++ (case metadata of
|
||||
Metadata.Page meta ->
|
||||
Seo.summaryLarge
|
||||
{ canonicalUrlOverride = Nothing
|
||||
, siteName = "elm-pages-starter"
|
||||
, image =
|
||||
{ url = images.iconPng
|
||||
, alt = "elm-pages logo"
|
||||
, dimensions = Nothing
|
||||
, mimeType = Nothing
|
||||
}
|
||||
, description = siteTagline
|
||||
, locale = Nothing
|
||||
, title = meta.title
|
||||
}
|
||||
|> Seo.website
|
||||
|
||||
Metadata.Article meta ->
|
||||
Seo.summaryLarge
|
||||
{ canonicalUrlOverride = Nothing
|
||||
, siteName = "elm-pages starter"
|
||||
, image =
|
||||
{ url = meta.image
|
||||
, alt = meta.description
|
||||
, dimensions = Nothing
|
||||
, mimeType = Nothing
|
||||
}
|
||||
, description = meta.description
|
||||
, locale = Nothing
|
||||
, title = meta.title
|
||||
}
|
||||
|> Seo.article
|
||||
{ tags = []
|
||||
, section = Nothing
|
||||
, publishedTime = Just (Date.toIsoString meta.published)
|
||||
, modifiedTime = Nothing
|
||||
, expirationTime = Nothing
|
||||
}
|
||||
|
||||
Metadata.Author meta ->
|
||||
let
|
||||
( firstName, lastName ) =
|
||||
case meta.name |> String.split " " of
|
||||
[ first, last ] ->
|
||||
( first, last )
|
||||
|
||||
[ first, middle, last ] ->
|
||||
( first ++ " " ++ middle, last )
|
||||
|
||||
[] ->
|
||||
( "", "" )
|
||||
|
||||
_ ->
|
||||
( meta.name, "" )
|
||||
in
|
||||
Seo.summary
|
||||
{ canonicalUrlOverride = Nothing
|
||||
, siteName = "elm-pages-starter"
|
||||
, image =
|
||||
{ url = meta.avatar
|
||||
, alt = meta.name ++ "'s elm-pages articles."
|
||||
, dimensions = Nothing
|
||||
, mimeType = Nothing
|
||||
}
|
||||
, description = meta.bio
|
||||
, locale = Nothing
|
||||
, title = meta.name ++ "'s elm-pages articles."
|
||||
}
|
||||
|> Seo.profile
|
||||
{ firstName = firstName
|
||||
, lastName = lastName
|
||||
, username = Nothing
|
||||
}
|
||||
|
||||
Metadata.BlogIndex ->
|
||||
Seo.summaryLarge
|
||||
{ canonicalUrlOverride = Nothing
|
||||
, siteName = "elm-pages"
|
||||
, image =
|
||||
{ url = images.iconPng
|
||||
, alt = "elm-pages logo"
|
||||
, dimensions = Nothing
|
||||
, mimeType = Nothing
|
||||
}
|
||||
, description = siteTagline
|
||||
, locale = Nothing
|
||||
, title = "elm-pages blog"
|
||||
}
|
||||
|> Seo.website
|
||||
)
|
||||
|
||||
|
||||
canonicalSiteUrl : String
|
||||
canonicalSiteUrl =
|
||||
"https://elm-pages-starter.netlify.com"
|
||||
|
||||
|
||||
siteTagline : String
|
||||
siteTagline =
|
||||
"Starter blog for elm-pages"
|
||||
|
||||
|
||||
publishedDateView metadata =
|
||||
Element.text
|
||||
(metadata.published
|
||||
|> Date.format "MMMM ddd, yyyy"
|
||||
)
|
||||
|
||||
|
||||
githubRepoLink : Element msg
|
||||
githubRepoLink =
|
||||
Element.newTabLink []
|
||||
{ url = "https://github.com/dillonkearns/elm-pages"
|
||||
, label =
|
||||
Element.image
|
||||
[ Element.width (Element.px 22)
|
||||
, Font.color Palette.color.primary
|
||||
]
|
||||
{ src = ImagePath.toString Pages.images.github, description = "Github repo" }
|
||||
}
|
||||
|
||||
|
||||
elmDocsLink : Element msg
|
||||
elmDocsLink =
|
||||
Element.newTabLink []
|
||||
{ url = "https://package.elm-lang.org/packages/dillonkearns/elm-pages/latest/"
|
||||
, label =
|
||||
Element.image
|
||||
[ Element.width (Element.px 22)
|
||||
, Font.color Palette.color.primary
|
||||
]
|
||||
{ src = ImagePath.toString Pages.images.elmLogo, description = "Elm Package Docs" }
|
||||
}
|
104
src/Metadata.elm
|
@ -1,104 +0,0 @@
|
|||
module Metadata exposing (ArticleMetadata, Metadata(..), PageMetadata, decoder)
|
||||
|
||||
import Data.Author
|
||||
import Date exposing (Date)
|
||||
import Dict exposing (Dict)
|
||||
import Element exposing (Element)
|
||||
import Json.Decode as Decode exposing (Decoder)
|
||||
import List.Extra
|
||||
import Pages
|
||||
import Pages.ImagePath as ImagePath exposing (ImagePath)
|
||||
|
||||
|
||||
type Metadata
|
||||
= Page PageMetadata
|
||||
| Article ArticleMetadata
|
||||
| Author Data.Author.Author
|
||||
| BlogIndex
|
||||
|
||||
|
||||
type alias ArticleMetadata =
|
||||
{ title : String
|
||||
, description : String
|
||||
, published : Date
|
||||
, author : Data.Author.Author
|
||||
, image : ImagePath Pages.PathKey
|
||||
, draft : Bool
|
||||
}
|
||||
|
||||
|
||||
type alias PageMetadata =
|
||||
{ title : String }
|
||||
|
||||
|
||||
decoder =
|
||||
Decode.field "type" Decode.string
|
||||
|> Decode.andThen
|
||||
(\pageType ->
|
||||
case pageType of
|
||||
"page" ->
|
||||
Decode.field "title" Decode.string
|
||||
|> Decode.map (\title -> Page { title = title })
|
||||
|
||||
"blog-index" ->
|
||||
Decode.succeed BlogIndex
|
||||
|
||||
"author" ->
|
||||
Decode.map3 Data.Author.Author
|
||||
(Decode.field "name" Decode.string)
|
||||
(Decode.field "avatar" imageDecoder)
|
||||
(Decode.field "bio" Decode.string)
|
||||
|> Decode.map Author
|
||||
|
||||
"blog" ->
|
||||
Decode.map6 ArticleMetadata
|
||||
(Decode.field "title" Decode.string)
|
||||
(Decode.field "description" Decode.string)
|
||||
(Decode.field "published"
|
||||
(Decode.string
|
||||
|> Decode.andThen
|
||||
(\isoString ->
|
||||
case Date.fromIsoString isoString of
|
||||
Ok date ->
|
||||
Decode.succeed date
|
||||
|
||||
Err error ->
|
||||
Decode.fail error
|
||||
)
|
||||
)
|
||||
)
|
||||
(Decode.field "author" Data.Author.decoder)
|
||||
(Decode.field "image" imageDecoder)
|
||||
(Decode.field "draft" Decode.bool
|
||||
|> Decode.maybe
|
||||
|> Decode.map (Maybe.withDefault False)
|
||||
)
|
||||
|> Decode.map Article
|
||||
|
||||
_ ->
|
||||
Decode.fail <| "Unexpected page type " ++ pageType
|
||||
)
|
||||
|
||||
|
||||
imageDecoder : Decoder (ImagePath Pages.PathKey)
|
||||
imageDecoder =
|
||||
Decode.string
|
||||
|> Decode.andThen
|
||||
(\imageAssetPath ->
|
||||
case findMatchingImage imageAssetPath of
|
||||
Nothing ->
|
||||
Decode.fail "Couldn't find image."
|
||||
|
||||
Just imagePath ->
|
||||
Decode.succeed imagePath
|
||||
)
|
||||
|
||||
|
||||
findMatchingImage : String -> Maybe (ImagePath Pages.PathKey)
|
||||
findMatchingImage imageAssetPath =
|
||||
Pages.allImages
|
||||
|> List.Extra.find
|
||||
(\image ->
|
||||
ImagePath.toString image
|
||||
== imageAssetPath
|
||||
)
|
|
@ -1,41 +0,0 @@
|
|||
module MySitemap exposing (..)
|
||||
|
||||
import Metadata exposing (Metadata(..))
|
||||
import Pages
|
||||
import Pages.PagePath as PagePath exposing (PagePath)
|
||||
import Sitemap
|
||||
|
||||
|
||||
build :
|
||||
{ siteUrl : String
|
||||
}
|
||||
->
|
||||
List
|
||||
{ path : PagePath Pages.PathKey
|
||||
, frontmatter : Metadata
|
||||
, body : String
|
||||
}
|
||||
->
|
||||
{ path : List String
|
||||
, content : String
|
||||
}
|
||||
build config siteMetadata =
|
||||
{ path = [ "sitemap.xml" ]
|
||||
, content =
|
||||
Sitemap.build config
|
||||
(siteMetadata
|
||||
|> List.filter
|
||||
(\page ->
|
||||
case page.frontmatter of
|
||||
Article articleData ->
|
||||
not articleData.draft
|
||||
|
||||
_ ->
|
||||
True
|
||||
)
|
||||
|> List.map
|
||||
(\page ->
|
||||
{ path = PagePath.toString page.path, lastMod = Nothing }
|
||||
)
|
||||
)
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
module Page.Article exposing (..)
|
||||
|
||||
import Data.Author as Author
|
||||
import Date
|
||||
import Element exposing (Element)
|
||||
import Element.Font as Font
|
||||
import Pages
|
||||
import Pages.ImagePath as ImagePath exposing (ImagePath)
|
||||
import Palette
|
||||
|
||||
|
||||
view metadata viewForPage =
|
||||
{ title = metadata.title
|
||||
, body =
|
||||
Element.column [ Element.spacing 10 ]
|
||||
[ Element.row [ Element.spacing 10 ]
|
||||
[ Author.view [] metadata.author
|
||||
, Element.column [ Element.spacing 10, Element.width Element.fill ]
|
||||
[ Element.paragraph [ Font.bold, Font.size 24 ]
|
||||
[ Element.text metadata.author.name
|
||||
]
|
||||
, Element.paragraph [ Font.size 16 ]
|
||||
[ Element.text metadata.author.bio ]
|
||||
]
|
||||
]
|
||||
]
|
||||
:: (publishedDateView metadata |> Element.el [ Font.size 16, Font.color (Element.rgba255 0 0 0 0.6) ])
|
||||
:: Palette.blogHeading metadata.title
|
||||
:: articleImageView metadata.image
|
||||
:: [ viewForPage ]
|
||||
}
|
||||
|
||||
|
||||
publishedDateView metadata =
|
||||
Element.text
|
||||
(metadata.published
|
||||
|> Date.format "MMMM ddd, yyyy"
|
||||
)
|
||||
|
||||
|
||||
articleImageView : ImagePath Pages.PathKey -> Element msg
|
||||
articleImageView articleImage =
|
||||
Element.image [ Element.width Element.fill ]
|
||||
{ src = ImagePath.toString articleImage
|
||||
, description = "Article cover photo"
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
module Palette exposing (blogHeading, color, heading)
|
||||
|
||||
import Element exposing (Element)
|
||||
import Element.Font as Font
|
||||
import Element.Region
|
||||
|
||||
|
||||
color =
|
||||
{ primary = Element.rgb255 5 117 230
|
||||
, secondary = Element.rgb255 0 242 96
|
||||
}
|
||||
|
||||
|
||||
heading : Int -> List (Element msg) -> Element msg
|
||||
heading level content =
|
||||
Element.paragraph
|
||||
([ Font.bold
|
||||
, Font.family [ Font.typeface "Raleway" ]
|
||||
, Element.Region.heading level
|
||||
]
|
||||
++ (case level of
|
||||
1 ->
|
||||
[ Font.size 36 ]
|
||||
|
||||
2 ->
|
||||
[ Font.size 24 ]
|
||||
|
||||
_ ->
|
||||
[ Font.size 20 ]
|
||||
)
|
||||
)
|
||||
content
|
||||
|
||||
|
||||
blogHeading : String -> Element msg
|
||||
blogHeading title =
|
||||
Element.paragraph
|
||||
[ Font.bold
|
||||
, Font.family [ Font.typeface "Raleway" ]
|
||||
, Element.Region.heading 1
|
||||
, Font.size 36
|
||||
, Font.center
|
||||
]
|
||||
[ Element.text title ]
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
|
@ -1,5 +0,0 @@
|
|||
@import url("https://fonts.googleapis.com/css?family=Montserrat:400,700|Roboto&display=swap");
|
||||
|
||||
.avatar img {
|
||||
border-radius: 50%;
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Vimux
|
||||
|
||||
Copyright (c) 2020 colorchestra
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -0,0 +1,82 @@
|
|||
# smol
|
||||
|
||||
A minimal, monospaced blogging theme for Hugo that respects your privacy and is easy on your bandwidth.
|
||||
|
||||
A real-life example can be found at https://morph.sh.
|
||||
|
||||
smol is based on [Blank](https://github.com/Vimux/Blank) created by [Vimux](https://github.com/Vimux).
|
||||
|
||||
|
||||
![Screenshot](/images/tn.png)
|
||||
|
||||
## Features
|
||||
|
||||
- No JavaScript
|
||||
- No Google spyware or tracking of any kind
|
||||
- No other external dependencies, embedded fonts or comment sections
|
||||
- Dark mode support (depending on your OS's setting)
|
||||
|
||||
## Installation
|
||||
|
||||
In your Hugo site `themes` directory, run:
|
||||
|
||||
```
|
||||
git clone https://github.com/colorchestra/smol
|
||||
```
|
||||
|
||||
Next, open `config.toml` in the base of the Hugo site and ensure the theme option is set to `smol`.
|
||||
|
||||
```
|
||||
theme = "smol"
|
||||
```
|
||||
|
||||
Lastly, add the following lines to your `config.toml` to make use of all the menu entries in the header and footer sections if you need them.
|
||||
|
||||
```
|
||||
# Header
|
||||
[menu]
|
||||
[[menu.main]]
|
||||
identifier = "posts"
|
||||
name = "Posts"
|
||||
url = "/posts/"
|
||||
weight = 1
|
||||
|
||||
[[menu.main]]
|
||||
identifier = "categories"
|
||||
name = "Categories"
|
||||
url = "/categories/"
|
||||
weight = 2
|
||||
|
||||
[[menu.main]]
|
||||
identifier = "tags"
|
||||
name = "Tags"
|
||||
url = "/tags/"
|
||||
weight = 3
|
||||
|
||||
# Footer
|
||||
[[menu.footer]]
|
||||
name = "Github"
|
||||
url = "https://github.com/example
|
||||
weight = 1
|
||||
|
||||
[[menu.footer]]
|
||||
name = "Mastodon"
|
||||
url = "https://example.com/@user
|
||||
weight = 2
|
||||
|
||||
[[menu.footer]]
|
||||
name = "Imprint"
|
||||
url = "/imprint"
|
||||
weight = 3
|
||||
|
||||
```
|
||||
|
||||
For more information read the official [quick start guide](https://gohugo.io/getting-started/quick-start/) of Hugo.
|
||||
|
||||
## Contributing
|
||||
|
||||
Have you found a bug or got an idea for a new feature? Feel free to use the [issue tracker](https://github.com/colorchestra/smol/issues) to let me know. Or make directly a [pull request](https://github.com/colorchestra/smol/pulls).
|
||||
|
||||
## License
|
||||
|
||||
This theme is released under the [MIT license](https://github.com/colorchestra/smol/blob/master/LICENSE).
|
|
@ -0,0 +1,4 @@
|
|||
+++
|
||||
title = "{{ replace .Name "-" " " | title }}"
|
||||
date = {{ .Date }}
|
||||
+++
|
After Width: | Height: | Size: 73 KiB |
After Width: | Height: | Size: 80 KiB |
|
@ -0,0 +1,21 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="{{ .Site.LanguageCode | default "en-us" }}">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<style type=text/css>body{font-family:monospace;}</style>
|
||||
<title>{{ .Title }}</title>
|
||||
{{ with .Site.Params.description }}<meta name="description" content="{{ . }}">{{ end }}
|
||||
{{ with .Site.Params.author }}<meta name="author" content="{{ . }}">{{ end }}
|
||||
<link rel="stylesheet" href="{{ "css/style.css" | relURL }}">
|
||||
{{ with .OutputFormats.Get "RSS" -}}
|
||||
{{ printf `<link rel="%s" type="%s" href="%s" title="%s">` .Rel .MediaType.Type .RelPermalink $.Site.Title | safeHTML }}
|
||||
{{- end }}
|
||||
</head>
|
||||
<body>
|
||||
{{ partial "header" . }}
|
||||
{{ block "main" . }}{{ end }}
|
||||
{{ partial "footer" . }}
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,26 @@
|
|||
{{ define "main" }}
|
||||
<main>
|
||||
{{ $listtitle := .Title }}
|
||||
{{ if or .Title .Content }}
|
||||
<div>
|
||||
{{ with .Title }}<h1>{{ . }}</h1>{{ end }}
|
||||
{{ with .Content }}<div>{{ . }}</div>{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
||||
|
||||
<ul>
|
||||
{{ range .Paginator.Pages }}
|
||||
<li>
|
||||
<div class="post-title">
|
||||
{{ if eq $listtitle "Posts" }}
|
||||
{{ .Date.Format "2006-01-02" }} <a href="{{ .RelPermalink }}">{{.Title }}</a>
|
||||
{{ else }}
|
||||
<a href="{{ .RelPermalink }}">{{.Title }}</a>
|
||||
{{ end }}
|
||||
</div>
|
||||
</li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
{{ partial "pagination.html" . }}
|
||||
</main>
|
||||
{{ end }}
|
|
@ -0,0 +1,16 @@
|
|||
{{ define "main" }}
|
||||
<main>
|
||||
<article>
|
||||
<h1>{{ .Title }}</h1>
|
||||
<b><time>{{ .Date.Format "02.01.2006 15:04" }}</time></b>
|
||||
{{ range .Params.tags }}
|
||||
<a href="{{ "/tags/" | relLangURL }}{{ . | urlize }}">{{ . }}</a>
|
||||
{{ end }}
|
||||
|
||||
<div>
|
||||
{{ .Content }}
|
||||
</div>
|
||||
</article>
|
||||
</main>
|
||||
{{ partial "sidebar.html" . }}
|
||||
{{ end }}
|
|
@ -0,0 +1,13 @@
|
|||
<article>
|
||||
<h1><a href="{{ .Permalink }}">{{ .Title }}</a></h1>
|
||||
<b><time>{{ .Date.Format "02.01.2006 15:04" }}</time></b>
|
||||
{{ range .Params.tags }}
|
||||
<a href="{{ "/tags/" | relLangURL }}{{ . | urlize }}">{{ . }}</a>
|
||||
{{ end }}
|
||||
<div>
|
||||
{{ .Summary }}
|
||||
{{ if .Truncated }}
|
||||
<a href="{{ .Permalink }}">Read more...</a>
|
||||
{{ end }}
|
||||
</div>
|
||||
</article>
|
|
@ -0,0 +1,9 @@
|
|||
{{ define "main" }}
|
||||
<main>
|
||||
{{ $paginator := .Paginate (where .Site.RegularPages "Type" "in" .Site.Params.mainSections) }}
|
||||
{{ range $paginator.Pages }}
|
||||
{{ .Render "summary" }}
|
||||
{{ end }}
|
||||
{{ partial "pagination.html" . }}
|
||||
</main>
|
||||
{{ end }}
|
|
@ -0,0 +1,7 @@
|
|||
<footer>
|
||||
<p>© {{ now.Year }} <a href="{{ .Site.BaseURL }}"><b>{{ .Site.Title }}</b></a>.
|
||||
{{- range .Site.Menus.footer }}
|
||||
<a href="{{ .URL }}"><b>{{ .Name }}</b></a>.
|
||||
{{- end }}
|
||||
</p>
|
||||
</footer>
|
|
@ -0,0 +1,16 @@
|
|||
<header>
|
||||
{{ strings.Repeat ( .Site.Title | len | add 6 ) "=" }}<br>
|
||||
== <a href="{{ .Site.BaseURL }}">{{ .Site.Title }}</a> ==<br>
|
||||
{{ strings.Repeat ( .Site.Title | len | add 6 ) "=" }}
|
||||
<div style="float: right;">{{ .Site.Params.subtitle }}</div><br>
|
||||
<p>
|
||||
<nav>
|
||||
<a href="/"><b>Start</b></a>.
|
||||
{{ with .Site.Menus.main }}
|
||||
{{ range . }}
|
||||
<a href="{{ .URL | relURL }}"><b>{{ .Name }}</b></a>.
|
||||
{{ end }}
|
||||
</nav>
|
||||
</p>
|
||||
{{ end }}
|
||||
</header>
|
|
@ -0,0 +1,9 @@
|
|||
<div>
|
||||
{{ if .Paginator.HasPrev }}
|
||||
<a href="{{ .Paginator.Prev.URL }}">Previous Page</a>
|
||||
{{ end }}
|
||||
{{ .Paginator.PageNumber }} of {{ .Paginator.TotalPages }}
|
||||
{{ if .Paginator.HasNext }}
|
||||
<a href="{{ .Paginator.Next.URL }}">Next Page</a>
|
||||
{{ end }}
|
||||
</div>
|
|
@ -0,0 +1,14 @@
|
|||
<aside>
|
||||
<div>
|
||||
<div>
|
||||
<h3>LATEST POSTS</h3>
|
||||
</div>
|
||||
<div>
|
||||
<ul>
|
||||
{{ range first 5 (where .Site.RegularPages "Type" "in" .Site.Params.mainSections) }}
|
||||
<li><a href="{{ .RelPermalink }}">{{ .Title }}</a></li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
|
@ -0,0 +1,6 @@
|
|||
html {overflow-y: scroll}
|
||||
body{max-width:800px;margin:40px auto;padding:0 10px;font:14px/1.5 monospace;color:#444}h1,h2,h3{line-height:1.2}@media (prefers-color-scheme: dark){body{color:white;background:#444}a:link{color:#5bf}a:visited{color:#ccf}}
|
||||
code{color: #FFFFFF; background:#000000; padding:2px}
|
||||
pre{color: #FFFFFF; background:#000000; padding:24px; white-space: pre-wrap}
|
||||
article{padding:20px 0}
|
||||
.center {display: block;margin-left: auto;margin-right: auto;width: 100%;}
|
|
@ -0,0 +1,17 @@
|
|||
name = "smol"
|
||||
license = "MIT"
|
||||
licenselink = "https://github.com/colorchestra/smol/blob/master/LICENSE.md"
|
||||
description = "Minimal Hugo theme using a Monospace font and without any tracking or external dependencies."
|
||||
homepage = "https://github.com/colorchestra/smol"
|
||||
tags = ["blog", "minimal", "monospace", "dark mode", "simple", "clean", "light", "responsive", "fast", "no-js", "no-tracking", "privacy"]
|
||||
features = ["blog", "privacy", "responsive", "fast"]
|
||||
min_version = "0.20"
|
||||
|
||||
[author]
|
||||
name = "morph"
|
||||
homepage = "morph.sh"
|
||||
|
||||
[original]
|
||||
author = "Vimux"
|
||||
homepage = "https://github.com/Vimux"
|
||||
repo = "https://github.com/colorchestra/blank"
|