206 lines
9.8 KiB
HTML
206 lines
9.8 KiB
HTML
{% extends 'base.html' %}
|
|
|
|
{% block title %}
|
|
{{ page.title }} | Garage blog
|
|
{% endblock %}
|
|
|
|
{% block content %}
|
|
<section id="blogpost-section" class="section">
|
|
<div class="mx-auto max-w-7xl">
|
|
<div class="grid grid-cols-5 gap-x-12">
|
|
<div class="{% if page.extra.toc %}col-span-4{% else %}col-span-full{% endif %}">
|
|
<article class="box my-12">
|
|
<div class="flex flex-col bg-gray-50">
|
|
<div class="flex flex-col border-l-4 border-garage-orange py-2 pl-4 relative">
|
|
<h1 class="title leading-10 text-3xl text-garage-orange font-semibold">
|
|
{{ page.title }}
|
|
</h1>
|
|
{% if page.description %}
|
|
<p class="subtitle my-2 text-gray-600 italic text-sm">{{ page.description }}</p>
|
|
{% endif %}
|
|
<a id="back-to-blog-posts" class="absolute top-0 -left-12" href="/blog/"
|
|
title="Back to blog posts">
|
|
<div class="w-10 overflow-hidden inline-block group">
|
|
<div
|
|
class="h-16 bg-garage-gray group-hover:bg-garage-orange transform -rotate-45 origin-top-right">
|
|
</div>
|
|
</div>
|
|
</a>
|
|
</div>
|
|
<div
|
|
class="w-full text-garage-gray text-sm grid grid-cols-1 md:grid-cols-2 bg-gradient-to-r from-gray-100 to-transparent p-3 border-l-4 border-gray-300">
|
|
<div class="flex items-center justify-start md:justify-start">
|
|
{{ macros::page_publish_metadata(page=page) }}
|
|
</div>
|
|
<div class="flex items-center justify-start md:justify-end">
|
|
{{ macros::page_content_metadata(page=page) }}
|
|
</div>
|
|
<div>
|
|
{% if page.taxonomies.categories %}
|
|
{{ macros::render_categories(categories=page.taxonomies.categories) }}
|
|
{% endif %}
|
|
</div>
|
|
<div>
|
|
{% if page.taxonomies.tags %}
|
|
{{ macros::render_tags(tags=page.taxonomies.tags) }}
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="page-content max-w-4xl text-justify mt-12 px-5 md:px-12">
|
|
{{ page.content | safe }}
|
|
</div>
|
|
</article>
|
|
</div>
|
|
{% if page.extra.toc %}
|
|
<div
|
|
class="col-span-1 my-12 is-hidden-mobile bg-gradient-to-b from-yellow-100 to-transparent rounded shadow-inner">
|
|
<aside class="menu" style="position:sticky;top:0">
|
|
<p class="bg-yellow-200 uppercase text-xs font-light p-1 text-center text-gray-600">Contents</p>
|
|
<ul class="menu-list p-2 text-gray-800">
|
|
{% for h1 in page.toc %}
|
|
<li class="flex flex-col h-full">
|
|
<a id="link-{{h1.id}}"
|
|
class="toc text-sm text-gray-600 bg-transparent hover:text-orange-600 font-semibold {% if loop.first %}is-active{% endif %}"
|
|
href="{{ h1.permalink | safe }}">
|
|
{{ h1.title }}
|
|
</a>
|
|
{% if h1.children %}
|
|
<ul>
|
|
{% for h2 in h1.children %}
|
|
<li class="hover:text-orange-600 border-l border-orange-400">
|
|
<a id="link-{{h2.id}}" class="toc pl-2 text-xs" href="{{ h2.permalink | safe }}">
|
|
{{ h2.title }}
|
|
</a>
|
|
</li>
|
|
{% endfor %}
|
|
</ul>
|
|
{% endif %}
|
|
</li>
|
|
{% endfor %}
|
|
</ul>
|
|
</aside>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</section>
|
|
{% endblock %}
|
|
|
|
{% block pagination %}
|
|
{% if page.earlier or page.later or page.lighter or page.heavier %}
|
|
<section class="w-full">
|
|
<div class="container py-20">
|
|
<div class="mx-auto max-w-4xl">
|
|
<div class="column is-8">
|
|
<nav class="flex space-x-8 items-center justify-center">
|
|
{% if page.later %}
|
|
<div>
|
|
<a class="flex items-center space-x-1 hover:text-garage-orange font-semibold text-gray-800"
|
|
href="{{ page.later.permalink }}">
|
|
<span class="icon mr-2">
|
|
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"
|
|
xmlns="http://www.w3.org/2000/svg">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M7 16l-4-4m0 0l4-4m-4 4h18"></path>
|
|
</svg>
|
|
</span>
|
|
<span>{{ page.later.title }}</span>
|
|
</a>
|
|
</div>
|
|
{% endif %} {% if page.earlier %}
|
|
<div>
|
|
<a class="flex items-center space-x-1 hover:text-garage-orange font-semibold text-gray-800"
|
|
href="{{ page.earlier.permalink }}">
|
|
{{ page.earlier.title }}<span class="icon ml-2">
|
|
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"
|
|
xmlns="http://www.w3.org/2000/svg">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M17 8l4 4m0 0l-4 4m4-4H3"></path>
|
|
</svg>
|
|
</span>
|
|
</a>
|
|
</div>
|
|
{% endif %} {% if page.heavier %}
|
|
<div>
|
|
<a class="flex items-center space-x-1 hover:text-garage-orange font-semibold text-gray-800"
|
|
href="{{ page.heavier.permalink }}">
|
|
<span class="icon mr-2">
|
|
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"
|
|
xmlns="http://www.w3.org/2000/svg">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M7 16l-4-4m0 0l4-4m-4 4h18"></path>
|
|
</svg>
|
|
</span>
|
|
<span>{{ page.heavier.title }}</span>
|
|
</a>
|
|
</div>
|
|
{% endif %} {% if page.lighter %}
|
|
<div>
|
|
<a class="flex items-center space-x-1 hover:text-garage-orange font-semibold text-gray-800"
|
|
href="{{ page.lighter.permalink }}">
|
|
{{ page.lighter.title }}<span class="icon ml-2">
|
|
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"
|
|
xmlns="http://www.w3.org/2000/svg">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M17 8l4 4m0 0l-4 4m4-4H3"></path>
|
|
</svg>
|
|
</span>
|
|
</a>
|
|
</div>
|
|
{% endif %}
|
|
</nav>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
{% endif %}
|
|
{% endblock %}
|
|
|
|
{% block custom_js %}
|
|
{% if page.extra.toc %}
|
|
<script type="text/javascript">
|
|
const menuBarHeight = document.querySelector("nav.navbar").clientHeight;
|
|
const tocItems = document.querySelectorAll(".toc");
|
|
const navSections = new Array(tocItems.length);
|
|
|
|
tocItems.forEach((el, i) => {
|
|
let id = el.getAttribute("id").substring(5);
|
|
navSections[i] = document.getElementById(id);
|
|
})
|
|
|
|
function isVisible(tocIndex) {
|
|
const current = navSections[tocIndex];
|
|
const next = tocIndex < tocItems.length - 1 ? navSections[tocIndex + 1]
|
|
: document.querySelectorAll("section.section").item(1);
|
|
|
|
const c = current.getBoundingClientRect();
|
|
const n = next.getBoundingClientRect();
|
|
const h = (window.innerHeight || document.documentElement.clientHeight);
|
|
|
|
return (c.top <= h) && (n.top - menuBarHeight >= 0);
|
|
}
|
|
|
|
function activateIfVisible() {
|
|
for (b = true, i = 0; i < tocItems.length; i++) {
|
|
if (b && isVisible(i)) {
|
|
tocItems[i].classList.add('is-active');
|
|
b = false;
|
|
} else
|
|
tocItems[i].classList.remove('is-active');
|
|
}
|
|
}
|
|
|
|
var isTicking = null;
|
|
window.addEventListener('scroll', () => {
|
|
if (!isTicking) {
|
|
window.requestAnimationFrame(() => {
|
|
activateIfVisible();
|
|
isTicking = false;
|
|
});
|
|
isTicking = true;
|
|
}
|
|
}, false);
|
|
</script>
|
|
{% endif %}
|
|
{% endblock %}
|