This commit is contained in:
avitex 2020-04-12 03:22:25 +10:00
parent 09489ffa02
commit 446a5a1d0f
Signed by: avitex
GPG Key ID: 38C76CBF3749D62C
42 changed files with 642 additions and 284 deletions

3
.gitignore vendored
View File

@ -1,2 +1 @@
.idea/
public
public/

16
.travis.yml Normal file
View File

@ -0,0 +1,16 @@
language: minimal
before_script:
# Download and unzip the zola executable
- curl -s -L https://github.com/getzola/zola/releases/download/v0.10.1/zola-v0.10.1-x86_64-unknown-linux-gnu.tar.gz | sudo tar xvzf - -C /usr/local/bin
script:
- zola build
after_success: |
[ $TRAVIS_BRANCH = code ] &&
[ $TRAVIS_PULL_REQUEST = false ] &&
zola build &&
sudo pip install ghp-import &&
ghp-import -c 1bit.pw -n public -b master &&
git push -fq https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git master

View File

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2018 James Dyson
Copyright (c) 2018-2020 James Dyson
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -1,7 +1,10 @@
title = "1bit.pw"
base_url = "https://1bit.pw"
description = "Home of avitex"
compile_sass = true
title = "1-bit Password"
description = ""
highlight_code = true
build_search_index = true
taxonomies = [
{name = "blog/tags", rss = true},
@ -11,15 +14,11 @@ taxonomies = [
[extra]
author = "avitex"
[[extra.main_menu]]
name = "home"
url = "/"
[[extra.main_menu]]
name = "blog"
url = "/blog"
sub = [
{name = "lastest", url = "/blog"},
{name = "latest", url = "/blog"},
{name = "categories", url = "/blog/categories"},
{name = "tags", url = "/blog/tags"}
]
@ -27,6 +26,11 @@ sub = [
[[extra.main_menu]]
name = "projects"
url = "/projects"
sub = [
{name = "rust", url = "#rust"},
{name = "elixir", url = "#elixir"},
{name = "github", url = "https://github.com/avitex"}
]
[[extra.main_menu]]
name = "about"
@ -35,4 +39,4 @@ sub = [
{name = "overview", url = "/about"},
{name = "bio", url = "/about/bio"},
{name = "social", url = "/about/social"}
]
]

View File

@ -1,4 +1,7 @@
+++
insert_anchor_links = "right"
+++
My [projects](/projects), [thoughts](/blog), and [me](/about)
My [projects](/projects), [thoughts](/blog), and [me](/about)
![avitex](/brain-only.png)

View File

@ -1,14 +1,15 @@
+++
template = "about.html"
insert_anchor_links = "right"
+++
Hi! I'm James. I live in Australia, and the virtual realm is my dojo.
Hi! I'm James, a fellow earthling living in Australia.
## PGP
You can find my pgp public key [here](/id/pk.txt).
You can find my PGP public key [here](/id/pk.txt).
## Contacting me
## Contact
If you wish to contact me, email is easiest via `theavitex (at) gmail (dot) com`.
See my [social links](./about/social.md) for other methods to get in touch.
See my [social links](@/about/social.md) for other methods to get in touch.

View File

@ -26,7 +26,7 @@
## Forums
- [Rust](https://users.rust-lang.org/u/avitex) (_dormant)
- [Rust](https://users.rust-lang.org/u/avitex) (_dormant_)
- [Vue](https://forum.vuejs.org/u/avitex) (_dormant_)
- [Elixir](https://elixirforum.com/u/avitex) (_dormant_)
@ -34,8 +34,8 @@
- [Steam](https://steamcommunity.com/id/avitex)
- [Faceit](https://www.faceit.com/en/players/avitex)
- [ESEA](https://play.esea.net/users/680258) (dormant)
- [Cybergamer](https://www.cybergamer.com/profile/246296/avitex/) (dormant)
- [ESEA](https://play.esea.net/users/680258) (_dormant_)
- [Cybergamer](https://www.cybergamer.com/profile/246296/avitex/) (_dormant_)
## Other

View File

@ -1,4 +1,5 @@
+++
paginate_by = 10
insert_anchor_links = "right"
template = "blog.html"
+++

View File

@ -1,5 +1,27 @@
+++
template = "projects.html"
insert_anchor_links = "right"
+++
Nothing here... yet
Project repositories, along with their associated state.
PRs are always welcome, see my [about](@/about/_index.md) to contact me.
## Rust
- `arae` - [git](https://github.com/avitex/rust-arae) - `todo`, `v0.1`
- `dnscat2` - [git](https://github.com/avitex/rust-dnscat2) - `todo`, `v0.1`
- `public-ip` - [git](https://github.com/avitex/rust-public-ip) - `todo`, `v0.1`
- `mdbook-tera` - [git](https://github.com/avitex/mdbook-tera) - `v0.2`
- `xlff` [git](https://github.com/avitex/rust-xlff) - `todo`, `unpublished`
- `abuseipdb` - [git](https://github.com/avitex/rust-abuseipdb) - `todo`, `v0.2`
- `aliasable-deref-trait` - [git](https://github.com/avitex/rust-aliasable-deref-trait) - `todo`, `v0.2`
- `shared-box` - [git](https://github.com/avitex/rust-shared-box) - `todo`, `unpublished`
- `wamp-message` - [git](https://github.com/avitex/rust-wamp-message) - `dead`, `unpublished`
- `feast` - [git](https://github.com/avitex/feast) - `todo`, `experimental`, `v0.1`
- `battlelayer` - [git](https://github.com/avitex/battlelayer) - `todo`, `unpublished`
## Elixir
- `glicko` - [git](https://github.com/avitex/elixir-glicko) - `v0.6`
- `rcon` - [git](https://github.com/avitex/elixir-rcon) - `v0.3`
- `vultr` - [git](https://github.com/avitex/elixir-vultr) - `todo`, `v0.3`
- `gitlab` - [git](https://github.com/avitex/elixir-gitlab) - `todo`, `unpublished`
- `typed-struct-cast` - [git](https://github.com/avitex/typed-struct-cast) - `todo`, `unpublished`

View File

@ -1,31 +0,0 @@
.monk.dark {
color: #acc;
background-color: #20262e;
a {
color: #94b4cb;
}
code {
background-color: #161a20;
}
.menu a {
color: #42a542;
text-decoration-color: #205720;
&:hover {
text-decoration-color: #428a42;
}
&.active {
font-weight: 600;
color: #5ce95c;
text-decoration-color: #52a852;
}
}
hr {
border-bottom-color: #283339;
}
}

17
sass/_header.scss Normal file
View File

@ -0,0 +1,17 @@
.site-header {
padding: 2rem 0;
display: flex;
align-items: center;
.brand {
margin-right: 0.5rem;
opacity: 0.8;
&:hover {
opacity: 1;
}
}
nav {
flex: 1;
}
}

14
sass/_home.scss Normal file
View File

@ -0,0 +1,14 @@
.home-page {
width: 100%;
height: 100%;
min-width: 600px;
display: flex;
align-items: center;
justify-content: center;
.inner {
h1 {
margin: 0;
}
}
}

View File

@ -1,31 +0,0 @@
.monk.light {
color: #444;
background-color: #fff;
a {
color: #556;
}
code {
background-color: #eee;
}
.menu a {
color: #222;
text-decoration-color: #555;
&:hover {
text-decoration-color: #428a42;
}
&.active {
font-weight: 600;
color: #77f;
text-decoration-color: #99f;
}
}
hr {
border-bottom-color: #ddd;
}
}

View File

@ -1,9 +1,10 @@
html, body {
margin: 0;
height: 100%;
width: 100%;
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
* {
box-sizing: border-box;
}
html, body {
height: 100%;
width: 100%;
}

19
sass/_scrollbar.scss Normal file
View File

@ -0,0 +1,19 @@
@media screen and (min-width: 1200px) {
* {
scrollbar-width: thin;
scrollbar-color: $bg-color $border-color;
}
*::-webkit-scrollbar {
width: 16px;
}
*::-webkit-scrollbar-track {
background: $border-color;
}
*::-webkit-scrollbar-thumb {
background-color: $bg-color;
border: 3px solid $border-color;
}
}

13
sass/_search.scss Normal file
View File

@ -0,0 +1,13 @@
.search-container {
input {
padding: 0.5rem 0.75rem;
border: none;
font-family: $mono-font;
background-color: $fg-color;
border-radius: 4px;
}
.search-results {
display: none;
}
}

37
sass/_site-nav.scss Normal file
View File

@ -0,0 +1,37 @@
.site-nav {
ul {
padding: 0;
list-style: none;
text-transform: uppercase;
letter-spacing: 0.1rem;
font-weight: bold;
font-family: $heading-font;
font-size: 0.8rem;
}
li {
display: inline-block;
padding: 0 0.2rem;
color: $grey;
& > a.active {
color: $white;
}
}
a {
color: inherit;
border: none;
text-decoration: none;
}
.main-menu {
font-size: 0.75rem;
}
.sub-menu {
color: $grey;
font-size: 0.65rem;
}
}

View File

@ -1,76 +0,0 @@
.monk {
font-size: 14px;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
.container {
margin: 0 auto;
width: 100%;
max-width: 800px;
}
h1, h2, h3, h4, h5, h6 {
font-weight: 600;
}
.main {
padding-top: 5px;
padding-bottom: 5px;
padding-left: 5px;
padding-right: 5px;
}
.header {
padding-top: 10px;
padding-bottom: 10px;
}
.menu {
font-size: 0;
list-style: none;
margin: 0;
padding: 0;
}
.menu li {
display: inline;
margin-left: 5px;
margin-right: 5px;
}
.menu a {
text-decoration: underline dotted;
}
.main-menu span {
font-size: 16px;
}
.sub-menu {
margin-top: 2px;
opacity: 0.8;
}
.sub-menu span {
font-size: 14px;
}
code {
padding-left: 4px;
padding-right: 4px;
border-radius: 3px;
}
pre {
overflow: auto;
padding: 4px;
}
.muted {
opacity: 0.5;
}
hr {
border: 0;
border-bottom: 1px solid;
}

View File

@ -1,5 +1,147 @@
@import "reset";
@import "theme";
@import "dark";
@import "light";
$red: #ef5350;
$grey: #a1a1a1;
$white: #f1f1f1;
$bg-color: #111111;
$fg-color: #1d1d1d;
$border-color: #161616;
$mono-font: 'Source Code Pro', monospace;
$content-font: 'Charter', serif;
$heading-font: 'Space Grotesk', Helvetica, sans-serif;
@import './reset';
@import './scrollbar';
@import './header';
@import './search';
@import './site-nav';
@import './home';
* {
color: inherit;
line-height: 1.3;
text-decoration: inherit;
}
html {
color: $white;
background: $bg-color;
font-family: $content-font;
text-rendering: optimizeLegibility;
@media all and (min-width: 640px) {
font-size: 17px;
}
@media all and (min-width: 720px) {
font-size: 18px
}
@media all and (min-width: 1024px) {
font-size: 19px;
}
}
main {
font-size: 0.9rem;
a {
color: $red;
border-bottom: 1px solid $red;
}
}
h1, h2, h3 {
font-weight: bold;
font-family: $heading-font;
margin: 1.2rem 0 0.4rem 0;
& > a {
color: inherit;
border-bottom: none;
}
a.anchor {
display: none;
color: $red;
font-weight: bold;
text-decoration: none;
}
&:hover a.anchor {
display: inline;
}
}
h1 {
font-size: 2.5rem;
}
h2 {
font-size: 1.5rem;
}
h3 {
font-size: 1.25rem;
}
small {
font-size: 0.5em;
}
hr {
border: none;
height: 2px;
margin-bottom: 0.5rem;
margin-top: 0.5rem;
background-color: $border-color;
}
article {
header, footer .info {
font-size: 0.8em;
}
.icon {
color: $grey;
}
.readmore {
span {
font-size: 0.9em;
}
.icon {
color: $red;
}
}
}
p {
padding-top: 0.5rem;
padding-bottom: 0.5rem;
}
code {
font-family: $mono-font;
background-color: $fg-color;
padding: 2.5px 5px;
border-radius: 4px;
font-size: 0.75em;
}
.container {
width: 100%;
min-width: 600px;
max-width: 900px;
margin-left: auto;
margin-right: auto;
padding-bottom: 2rem;
}
.muted {
color: $grey;
}
.mono {
font-family: $mono-font;
}

BIN
static/brain-256px.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

BIN
static/brain-48px.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 760 B

After

Width:  |  Height:  |  Size: 2.7 KiB

1
static/fonts.min.css vendored Normal file

File diff suppressed because one or more lines are too long

View File

180
static/search.js Normal file
View File

@ -0,0 +1,180 @@
function debounce(func, wait) {
var timeout;
return function () {
var context = this;
var args = arguments;
clearTimeout(timeout);
timeout = setTimeout(function () {
timeout = null;
func.apply(context, args);
}, wait);
};
}
// Taken from mdbook
// The strategy is as follows:
// First, assign a value to each word in the document:
// Words that correspond to search terms (stemmer aware): 40
// Normal words: 2
// First word in a sentence: 8
// Then use a sliding window with a constant number of words and count the
// sum of the values of the words within the window. Then use the window that got the
// maximum sum. If there are multiple maximas, then get the last one.
// Enclose the terms in <b>.
function makeTeaser(body, terms) {
var TERM_WEIGHT = 40;
var NORMAL_WORD_WEIGHT = 2;
var FIRST_WORD_WEIGHT = 8;
var TEASER_MAX_WORDS = 30;
var stemmedTerms = terms.map(function (w) {
return elasticlunr.stemmer(w.toLowerCase());
});
var termFound = false;
var index = 0;
var weighted = []; // contains elements of ["word", weight, index_in_document]
// split in sentences, then words
var sentences = body.toLowerCase().split(". ");
for (var i in sentences) {
var words = sentences[i].split(" ");
var value = FIRST_WORD_WEIGHT;
for (var j in words) {
var word = words[j];
if (word.length > 0) {
for (var k in stemmedTerms) {
if (elasticlunr.stemmer(word).startsWith(stemmedTerms[k])) {
value = TERM_WEIGHT;
termFound = true;
}
}
weighted.push([word, value, index]);
value = NORMAL_WORD_WEIGHT;
}
index += word.length;
index += 1; // ' ' or '.' if last word in sentence
}
index += 1; // because we split at a two-char boundary '. '
}
if (weighted.length === 0) {
return body;
}
var windowWeights = [];
var windowSize = Math.min(weighted.length, TEASER_MAX_WORDS);
// We add a window with all the weights first
var curSum = 0;
for (var i = 0; i < windowSize; i++) {
curSum += weighted[i][1];
}
windowWeights.push(curSum);
for (var i = 0; i < weighted.length - windowSize; i++) {
curSum -= weighted[i][1];
curSum += weighted[i + windowSize][1];
windowWeights.push(curSum);
}
// If we didn't find the term, just pick the first window
var maxSumIndex = 0;
if (termFound) {
var maxFound = 0;
// backwards
for (var i = windowWeights.length - 1; i >= 0; i--) {
if (windowWeights[i] > maxFound) {
maxFound = windowWeights[i];
maxSumIndex = i;
}
}
}
var teaser = [];
var startIndex = weighted[maxSumIndex][2];
for (var i = maxSumIndex; i < maxSumIndex + windowSize; i++) {
var word = weighted[i];
if (startIndex < word[2]) {
// missing text from index to start of `word`
teaser.push(body.substring(startIndex, word[2]));
startIndex = word[2];
}
// add <em/> around search terms
if (word[1] === TERM_WEIGHT) {
teaser.push("<b>");
}
startIndex = word[2] + word[0].length;
teaser.push(body.substring(word[2], startIndex));
if (word[1] === TERM_WEIGHT) {
teaser.push("</b>");
}
}
teaser.push("…");
return teaser.join("");
}
function formatSearchResultItem(item, terms) {
return '<div class="search-results__item">'
+ `<a href="${item.ref}">${item.doc.title}</a>`
+ `<div>${makeTeaser(item.doc.body, terms)}</div>`
+ '</div>';
}
function initSearch() {
var $searchInput = document.getElementById("search");
var $searchResults = document.querySelector(".search-results");
var $searchResultsItems = document.querySelector(".search-results__items");
var MAX_ITEMS = 10;
var options = {
bool: "AND",
fields: {
title: {boost: 2},
body: {boost: 1},
}
};
var currentTerm = "";
var index = elasticlunr.Index.load(window.searchIndex);
$searchInput.addEventListener("keyup", debounce(function() {
var term = $searchInput.value.trim();
if (term === currentTerm || !index) {
return;
}
$searchResults.style.display = term === "" ? "none" : "block";
$searchResultsItems.innerHTML = "";
if (term === "") {
return;
}
var results = index.search(term, options);
if (results.length === 0) {
$searchResults.style.display = "none";
return;
}
currentTerm = term;
for (var i = 0; i < Math.min(results.length, MAX_ITEMS); i++) {
var item = document.createElement("li");
item.innerHTML = formatSearchResultItem(results[i], term.split(" "));
$searchResultsItems.appendChild(item);
}
}, 150));
}
if (document.readyState === "complete" ||
(document.readyState !== "loading" && !document.documentElement.doScroll)
) {
initSearch();
} else {
document.addEventListener("DOMContentLoaded", initSearch);
}

View File

@ -1 +1,3 @@
{% extends "index.html" %}
{% extends "content.html" %}
{% block title %}About - {{ config.title }}{% endblock %}

View File

@ -0,0 +1 @@
<a class="anchor" aria-label="Anchor link for: {{ id }}" href="#{{ id }}">#</a>

View File

@ -1,19 +1,22 @@
{% extends "index.html" %}
{% extends "content.html" %}
{% import "post_macros.html" as post_macros %}
{% block title %}Blog - {{ config.title }}{% endblock %}
{% block content %}
<main class="main">
{% for page in paginator.pages %}
{{ post_macros::page_in_list(page=page) }}
{% endfor %}
<nav>
<p>
{% if paginator.previous %}
<a href="{{ paginator.previous }}">&laquo; Previous</a> |
{% endif %}
<span>Page {{ paginator.current_index }} of {{ paginator.pagers | length }}</span>
{% if paginator.next %}
| <a href="{{ paginator.next }}">Next &raquo;</a>
{% endif %}
</p>
</nav>
</main>
{% endblock content %}
<main class="main">
{% for page in paginator.pages %}
{{ post_macros::page_in_list(page=page) }}
{% endfor %}
<hr />
<nav class="pagination muted">
{% if paginator.previous %}
<a href="{{ paginator.previous }}">&laquo; Previous</a> |
{% endif %}
<span>Page {{ paginator.current_index }} of {{ paginator.number_pagers }}</span>
{% if paginator.next %}
| <a href="{{ paginator.next }}">Next &raquo;</a>
{% endif %}
</nav>
</main>
{% endblock content %}

View File

@ -1,4 +1,4 @@
{% extends "index.html" %}
{% extends "content.html" %}
{% block content %}
<h1>Categories</h1>

View File

@ -1,4 +1,5 @@
{% extends "index.html" %}
{% extends "content.html" %}
{% import "post_macros.html" as post_macros %}
{% block content %}
<h1>Category: <code>{{ term.name }}</code> <small>(<a href="{{ get_taxonomy_url(kind="blog/categories", name=term.name) }}rss.xml">RSS</a>)</small></h1>

View File

@ -1,10 +1,11 @@
{% extends "index.html" %}
{% extends "content.html" %}
{% import "post_macros.html" as post_macros %}
{% block content %}
<article itemscope itemtype="http://schema.org/BlogPosting">
<header>
<h1 itemprop="headline">{{ page.title }}</h1>
<span class="muted">{{ post_macros::meta(page=page) }}</span>
<header class="article-header">
<span class="mono info">{{ post_macros::meta(page=page) }}</span>
<h1 itemprop="name headline">{{ page.title }}</h1>
</header>
<div itemprop="articleBody">
{{ page.content | safe }}
@ -12,7 +13,7 @@
{% block page_footer %}
<footer>
<hr>
<p>
<p class="info muted mono">
{% if config.extra.author %}
Published by {{ config.extra.author }}
{% endif %}

View File

@ -1,5 +1,4 @@
{% extends "index.html" %}
{% extends "content.html" %}
{% block content %}
<h1>Tags</h1>
{% if terms %}

View File

@ -1,4 +1,5 @@
{% extends "index.html" %}
{% extends "content.html" %}
{% import "post_macros.html" as post_macros %}
{% block content %}
<h1>Tag: <code>{{ term.name }}</code> <small>(<a href="{{ get_taxonomy_url(kind="blog/tags", name=term.name) }}rss.xml">RSS</a>)</small></h1>

15
templates/content.html Normal file
View File

@ -0,0 +1,15 @@
{% extends "root.html" %}
{% import "macros.html" as macros %}
{% block body %}
<div class="container">
<header class="site-header">
<a class="brand" href="{{ get_url(path="/") }}"><img alt="avitex logo" src="{{ get_url(path="brain-48px.png") }}" /></a>
{% include "partials/site-nav.html" %}
</header>
<main class="content {% block extra_content_class %}{% endblock extra_content_class %}">
{% block content %}
{{ section.content | safe }}
{% endblock content %}
</main>
</div>
{% endblock body %}

View File

@ -1,69 +1,12 @@
{% extends "root.html" %}
{% import "macros.html" as macros %}
{% import "post_macros.html" as post_macros %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1">
<link rel="icon" type="image/png" href="{{ get_url(path="/favicon.png", trailing_slash=false) }}">
<title>{% block title %}{{ config.title }}{% endblock title %}</title>
{% if config.generate_rss %}
<link rel="alternate" type="application/rss+xml" title="RSS" href="{{ get_url(path="rss.xml") }}">
{% endif %}
{% block css %}
<link rel="stylesheet" href="{{ get_url(path="/site.css", trailing_slash=false) }}">
{% endblock css %}
{% block extra_head %}
{% endblock extra_head %}
</head>
<body class="monk dark">
<div class="container">
{% block header %}
{% if config.extra.main_menu %}
<header class="header">
<nav itemscope itemtype="http://schema.org/SiteNavigationElement">
<ul class="menu main-menu">
{% for item in config.extra.main_menu %}
<li>
<a itemprop="url"
class="{% if macros::is_active_nav(url=macros::link(url=item.url), curr_url=current_url) == "true" %}active{% endif %}"
href="{{ macros::link(url=item.url) }}">
<span itemprop="name">{{ item.name }}</span>
</a>
</li>
{% endfor %}
</ul>
<ul class="menu sub-menu">
{% for item in config.extra.main_menu %}
{% if item.sub and current_url is starting_with(macros::link(url=item.url)) %}
{% for sub_item in item.sub %}
<li>
<a itemprop="url"
class="{% if macros::link(url=sub_item.url) == current_url %}active{% endif %}"
href="{{ macros::link(url=sub_item.url) }}">
<span itemprop="name">{{ sub_item.name }}</span>
</a>
</li>
{% endfor %}
{% endif %}
{% endfor %}
</ul>
</nav>
</header>
{% endif %}
{% endblock header %}
<hr />
{% block content %}
<main class="main">
{{ section.content | safe }}
</main>
{% endblock content %}
</div>
</body>
</html>
{% block title %}{{ config.description }} - {{ config.title }}{% endblock %}
{% block body %}
<main class="home-page">
<img src="/brain-256px.png" alt="avitex logo" />
<div class="inner">
<h1>avitex</h1>
{% include "partials/site-nav.html" %}
</div>
</main>
{% endblock body %}

View File

@ -12,4 +12,4 @@
{%- else -%}
{{ curr_url is starting_with(url) }}
{%- endif -%}
{% endmacro is_active_nav %}
{% endmacro is_active_nav %}

View File

@ -1,8 +1,6 @@
{% extends "index.html" %}
{% extends "content.html" %}
{% block title %}{{ page.title }} - {{ config.title }}{% endblock %}
{% block content %}
<main class="main">
{{ page.content | safe }}
</main>
{% endblock content %}
{{ page.content | safe }}
{% endblock content %}

View File

@ -0,0 +1,6 @@
<div class="search-container">
<input id="search" type="search" placeholder="🔎 Search">
<div class="search-results">
<div class="search-results__items"></div>
</div>
</div>

View File

@ -0,0 +1,28 @@
<nav class="site-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
<ul class="menu main-menu">
{% for item in config.extra.main_menu %}
<li>
<a itemprop="url"
class="{% if macros::is_active_nav(url=macros::link(url=item.url), curr_url=current_url) == "true" %}active{% endif %}"
href="{{ macros::link(url=item.url) }}">
<span itemprop="name">{{ item.name }}</span>
</a>
</li>
{% endfor %}
</ul>
<ul class="menu sub-menu">
{% for item in config.extra.main_menu %}
{% if item.sub and current_url is starting_with(macros::link(url=item.url)) %}
{% for sub_item in item.sub %}
<li>
<a itemprop="url"
class="{% if macros::link(url=sub_item.url) == current_url %}active{% endif %}"
href="{{ macros::link(url=sub_item.url) }}">
<span itemprop="name">{{ sub_item.name }}</span>
</a>
</li>
{% endfor %}
{% endif %}
{% endfor %}
</ul>
</nav>

View File

@ -1,18 +1,17 @@
{% macro meta(page) %}
<svg style="margin-bottom:-3px" class="i-clock" viewBox="0 0 32 32"
<svg style="margin-bottom: -3px" class="icon i-edit" viewBox="0 0 32 32"
width="16" height="16" fill="none" stroke="currentcolor"
stroke-linecap="round" stroke-linejoin="round" stroke-width="6.25%">
<path d="M30 7 L25 2 5 22 3 29 10 27 Z M21 6 L26 11 Z M5 22 L10 27 Z"/>
</svg>
<time datetime="{{ page.date | date(format="%F") }}" itemprop="datePublished">{{ page.date | date(format="%b %d, %Y") }}</time>
<svg style="margin-bottom:-3px" class="icon i-clock" viewBox="0 0 32 32"
width="16" height="16" fill="none" stroke="currentcolor"
stroke-linecap="round" stroke-linejoin="round" stroke-width="6.25%">
<circle cx="16" cy="16" r="14"/>
<path d="M16 8 L16 16 20 20"/>
</svg>
<span>{{ page.reading_time }} minute read</span>
<svg style="margin-bottom: -3px" class="i-edit" viewBox="0 0 32 32"
width="16" height="16" fill="none" stroke="currentcolor"
stroke-linecap="round" stroke-linejoin="round" stroke-width="6.25%">
<path d="M30 7 L25 2 5 22 3 29 10 27 Z M21 6 L26 11 Z M5 22 L10 27 Z"/>
</svg>
Published: {{ page.date | date(format="%F") }}
{% endmacro meta %}
{% macro page_in_list(page) %}
@ -21,12 +20,19 @@
<h2 itemprop="name">
<a href="{{ page.permalink }}">{{ page.title }}</a>
</h2>
<span class="muted">{{ self::meta(page=page) }}</span>
<span class="muted mono">{{ self::meta(page=page) }}</span>
</header>
{% if page.summary %}
<div itemprop="summary">
{{ page.summary | safe }}
<nav class="readmore"><a itemprop="url" href="{{ page.permalink }}">Read More&nbsp;&raquo;</a></nav>
<nav class="readmore">
<a itemprop="url" href="{{ page.permalink }}">
<span>Read More</span>
<svg class="icon i-caret-r" xmlns="http://www.w3.org/2000/svg" fill="currentcolor" viewBox="0 0 5.9 9" width="5.9" height="9">
<path d="M5.9 4.5L4.5 3.1 1.4 0 0 1.4l3.1 3.1-3.1 3L1.4 9l3.1-3.1z"></path>
</svg>
</a>
</nav>
</div>
{% endif %}
</article>

View File

@ -1 +1,3 @@
{% extends "index.html" %}
{% extends "content.html" %}
{% block title %}Projects - {{ config.title }}{% endblock %}

20
templates/root.html Normal file
View File

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="theme-color" content="#111111"/>
<meta name="author" content="{{ config.extra.author }}">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="{{ get_url(path="site.css") }}"/>
<link rel="stylesheet" href="{{ get_url(path="fonts.min.css") }}"/>
<link rel="icon" type="image/png" href="{{ get_url(path="favicon.png") }}">
<title>{% block title %}{{ config.title }}{% endblock title %}</title>
</head>
<body>
{% block body %}{% endblock body %}
<script type="text/javascript" src="{{ get_url(path="elasticlunr.min.js") }}"></script>
<script type="text/javascript" src="{{ get_url(path="search_index.en.js") }}"></script>
<script type="text/javascript" src="{{ get_url(path="search.js") }}"></script>
</body>
</html>