initial
This commit is contained in:
3
theme/.metadata.toml
Normal file
3
theme/.metadata.toml
Normal file
@@ -0,0 +1,3 @@
|
||||
repo = "github:NTBBloodbath/norgowind"
|
||||
version = "0.6.0"
|
||||
pin = false
|
||||
21
theme/LICENSE
Normal file
21
theme/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2025 NTBBloodbath <bloodbathalchemist@protonmail.com>
|
||||
|
||||
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.
|
||||
143
theme/README.md
Normal file
143
theme/README.md
Normal file
@@ -0,0 +1,143 @@
|
||||
# Norgowind
|
||||
|
||||
[](./LICENSE)
|
||||

|
||||
|
||||
A modern, responsive theme for the [Norgolith SSG](https://github.com/NTBBloodbath/norgolith), built with TailwindCSS. Norgowind provides a clean, customizable look for your Norgolith-powered site, with extra features and easy configuration.
|
||||
|
||||
---
|
||||
|
||||
## Features
|
||||
- Beautiful, responsive minimal design powered by TailwindCSS
|
||||
- Ready-to-use templates for posts, categories, home, and more
|
||||
- Customizable navigation and footer links
|
||||
- Built-in icons support thanks to tabler icons library
|
||||
- Mermaid.js support for diagrams and charts
|
||||
- Additional blockquote styles (tip, note, important, warning, error)
|
||||
- Truncation options for post cards
|
||||
|
||||
## Demo
|
||||
See Norgowind in action:
|
||||
- [amartin.beer](https://amartin.beer)
|
||||
- [Official Norgolith documentation](https://norgolith.amartin.beer)
|
||||
|
||||
### Showcase
|
||||
|
||||
<details>
|
||||
<summary>Home page</summary>
|
||||
|
||||
<img width="1904" height="1212" alt="image" src="https://github.com/user-attachments/assets/c66ac751-cb0a-4cd5-bc8c-bf10b6414997" />
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Post view</summary>
|
||||
|
||||
<img width="1904" height="1064" alt="image" src="https://github.com/user-attachments/assets/77a47b5c-b9d3-409e-a022-5493f049b968" />
|
||||
|
||||
</details>
|
||||
|
||||
## Requirements
|
||||
- [Norgolith](https://github.com/NTBBloodbath/norgolith) (latest commit on `master` branch required)
|
||||
- [TailwindCSS CLI](https://tailwindcss.com/docs/installation) (for development or custom styling)
|
||||
|
||||
## Installation
|
||||
```bash
|
||||
lith theme pull github:NTBBloodbath/norgowind
|
||||
```
|
||||
|
||||
> [!IMPORTANT]
|
||||
>
|
||||
> Norgowind requires the latest Norgolith commit in the master branch in order to work.
|
||||
|
||||
## Usage
|
||||
After installing, configure your site as described below. If you plan to modify the CSS, see the [Tailwind Reloading](#tailwind-reloading) section.
|
||||
|
||||
### Configuration
|
||||
Add the following fields to your `norgolith.toml`:
|
||||
|
||||
```toml
|
||||
[extra]
|
||||
license = "GPLv2" # Optional
|
||||
favicon_path = "/assets/norgolith.svg" # Fallback to default favicon
|
||||
footer_author_link = "https://github.com/NTBBloodbath" # Optional
|
||||
enable_mermaid = true # Enable Mermaid.js for diagrams
|
||||
|
||||
[extra.nav]
|
||||
# Link_name = "url"
|
||||
# blog = "/posts"
|
||||
# GitHub = "https://github.com/NTBBloodbath/norgolith"
|
||||
|
||||
[extra.footer]
|
||||
# Link_name = "url"
|
||||
# GitHub = "https://github.com/NTBBloodbath/norgolith"
|
||||
```
|
||||
|
||||
### Templates
|
||||
Norgowind provides these templates:
|
||||
```
|
||||
templates
|
||||
├── partials
|
||||
│ ├── footer.html <- Footer content
|
||||
│ └── nav.html <- Header navbar
|
||||
├── base.html <- Main template (extends others)
|
||||
├── categories.html <- Categories list
|
||||
├── category.html <- Category posts list
|
||||
├── default.html <- Default template for all content
|
||||
├── home.html <- Homepage
|
||||
├── post.html <- Blog post
|
||||
└── posts.html <- Posts list
|
||||
```
|
||||
|
||||
To use a template, set the `layout` metadata in your content files. For example, in a blog post:
|
||||
```norg
|
||||
layout: post
|
||||
```
|
||||
|
||||
> [!TIP]
|
||||
>
|
||||
> Norgolith expects your blog posts in the `content/posts` directory.
|
||||
|
||||
### MermaidJS Support
|
||||
Norgowind comes with opt-in support for MermaidJS flowcharts. You can use mermaid charts through embedded HTML in your norg content if you set the `enable_mermaid` option to `true` in the `extra` table of your configuration file:
|
||||
```org
|
||||
@embed html
|
||||
<pre class="mermaid">
|
||||
flowchart LR
|
||||
A[HTML Fragment] --> B[Tera Engine]
|
||||
C[Validated Metadata] --> B
|
||||
D[Site Config] --> B
|
||||
E[Post Collection] --> B
|
||||
B --> F[Layout Template]
|
||||
F --> G[Final HTML]
|
||||
</pre>
|
||||
@end
|
||||
```
|
||||
|
||||
### Additional Styling
|
||||
Norgowind adds extra blockquote classes (use with `+html.class` tags):
|
||||
- `tip` (green)
|
||||
- `note` (blue)
|
||||
- `important` (violet)
|
||||
- `warning` (yellow)
|
||||
- `error` (red)
|
||||
|
||||

|
||||
|
||||
### Additional Metadata Fields
|
||||
- `truncate`: Set the truncate character length for recent post cards.
|
||||
- `truncate_char`: Set the truncate character (default is ellipsis). Leave empty to disable.
|
||||
|
||||
### Tailwind Reloading
|
||||
By default, Tailwind's configuration in Norgowind watches content files and templates. Each new class added to content using a `+html.class` tag will be included in the styling file.
|
||||
|
||||
For site development, install the TailwindCSS CLI and run:
|
||||
```sh
|
||||
tailwindcss -i theme/assets/css/tailwind.css -o theme/assets/css/styles.min.css --minify --watch
|
||||
```
|
||||
|
||||
## Contributing
|
||||
Contributions, issues, and feature requests are welcome! Feel free to open an issue or pull request.
|
||||
|
||||
## License
|
||||
Norgowind is licensed under the MIT License.
|
||||
1
theme/assets/css/prism-sweetie.min.css
vendored
Normal file
1
theme/assets/css/prism-sweetie.min.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
pre[class*=language-]{--padding-y:var(--am-prism-padding-y, 1rem);--padding-x:var(--am-prism-padding-x, 1rem);padding:var(--padding-y) var(--padding-x);overflow:auto;font-size:var(--am-prism-font-size,.85em);border-radius:var(--am-prism-border-radius,.4em)}pre>code[class*=language-]{padding:initial;font-size:1em;font-weight:400;font-family:var(--am-prism-font-family,ui-monospace),monospace;line-height:var(--am-prism-line-height,1.5);background-color:initial}code[class*=language-],pre[class*=language-]{text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}pre[class*=language-] .line-numbers-rows{box-sizing:content-box;margin:calc(var(--padding-y) * -1) 0;padding:var(--padding-y) 0}.line-numbers.line-numbers .line-numbers-rows{border-right-width:var(--am-prism-border-width,1px);border-right-color:var(--am-prism-border-color)}.line-numbers .line-numbers-rows>span:before{color:var(--am-prism-line-numbers-color)}div.code-toolbar>.toolbar{top:.3rem!important;right:.3rem!important}div.code-toolbar>.toolbar>.toolbar-item>button.copy-to-clipboard-button{display:inline-flex;padding:0 .75em;font-size:var(--am-prism-font-size,.8em);font-family:var(--am-prism-font-family,ui-monospace),monospace;font-weight:600!important;line-height:2.25em;color:var(--am-prism-copy-color);background-color:var(--am-prism-copy-bg);border-radius:calc(var(--am-prism-border-radius, .4em) - .1em);cursor:pointer;box-shadow:none;opacity:1;transition:opacity .2s}div.code-toolbar>.toolbar>.toolbar-item>button.copy-to-clipboard-button:hover{opacity:.8}div.code-toolbar>.toolbar>.toolbar-item>button.copy-to-clipboard-button:focus{opacity:1}code[class*=language-],pre[class*=language-]{color:#202023}pre[class*=language-]{background:#bbbbce}:not(pre)>code[class*=language-]{padding:.1em .3em;border-radius:.3em;color:#202023;background:#bbbbce}pre[data-line]{position:relative}pre[class*=language-]>code[class*=language-]{position:relative;z-index:1}.line-highlight{position:absolute;left:0;right:0;padding:inherit 0;margin-top:1em;background:#fff8c5;box-shadow:inset 5px 0 0 #eed888;z-index:0;pointer-events:none;line-height:inherit;white-space:pre}.namespace{opacity:.7}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#8989a9}.token.operator,.token.punctuation{color:#0c5090}.token.boolean,.token.constant,.token.deleted,.token.number,.token.property,.token.class-name,.token.symbol,.token.tag{color:#ae580e}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#287f0d}.language-css .token.string,.style .token.string,.token.entity,.token.url{color:#287f0d}.token.atrule,.token.attr-value,.token.keyword{color:#0c5090}.token.function{color:#a00c79}.token.macro,.token.important,.token.regex,.token.variable{color:#9437ff}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}:root{--am-prism-line-numbers-color:#18181a77;--am-prism-border-color:#18181a22;--am-prism-copy-color:#202023aa;--am-prism-copy-bg:#78789d22}html[class*="-dark"],html[class*="dark-"],.dark{& code[class*=language-],& pre[class*=language-]{color:#d3d7de}& pre[class*=language-]{background:#303040}& :not(pre)>code[class*=language-]{padding:.1em .3em;border-radius:.3em;color:#bdbdbd;background:#303040}& pre[data-line]{position:relative}& pre[class*=language-]>code[class*=language-]{position:relative;z-index:1}& .line-highlight{position:absolute;left:0;right:0;padding:inherit 0;margin-top:1em;background:#2f2a1e;box-shadow:inset 5px 0 0 #674c16;z-index:0;pointer-events:none;line-height:inherit;white-space:pre}& .namespace{opacity:.7}& .token.cdata,& .token.comment,& .token.doctype,& .token.prolog{color:#798399}& .token.punctuation,& .token.operator,& .token.variable{color:#73a3f3}& .token.boolean,& .token.constant,& .token.deleted,& .token.number,& .token.property,& .token.symbol,& .token.class-name,& .token.tag{color:#e7a06a}& .token.attr-name,& .token.builtin,& .token.char,& .token.inserted,& .token.selector,& .token.string{color:#89c252}& .language-css .token.string,& .style .token.string,& .token.entity,& .token.url{color:#89c252;background:#161b22}& .token.atrule,& .token.keyword{color:#73a3f3}& .token.attr-value,& .token.function{color:#d087e8}& .token.macro,& .token.important,& .token.regex{color:#b094e2}& .token.bold,& .token.important{font-weight:700}& .token.italic{font-style:italic}& .token.entity{cursor:help}&{--am-prism-line-numbers-color:#bdbdbd55;--am-prism-border-color:#bdbdbd22;--am-prism-copy-color:#d3d7de;--am-prism-copy-bg:#707b8722}}
|
||||
1372
theme/assets/css/styles.min.css
vendored
Normal file
1372
theme/assets/css/styles.min.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
343
theme/assets/css/tailwind.css
Normal file
343
theme/assets/css/tailwind.css
Normal file
@@ -0,0 +1,343 @@
|
||||
@import url("https://fonts.googleapis.com/css2?family=Fira+Mono:wght@400;500;700&display=swap");
|
||||
@import url("https://unpkg.com/@catppuccin/palette/css/catppuccin.css");
|
||||
@import "tailwindcss";
|
||||
/* User content */
|
||||
@source "../../../content";
|
||||
/* User templates */
|
||||
@source "../../../templates";
|
||||
/* Theme templates */
|
||||
@source "../../templates";
|
||||
|
||||
/* Use dark class for dark theme */
|
||||
@custom-variant dark (&:where(.dark, .dark *));
|
||||
|
||||
@layer base {
|
||||
/* Buttons use pointer cursor */
|
||||
button:not(:disabled),
|
||||
[role="button"]:not(:disabled) {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Fix some code rendering bugs with PrismJS
|
||||
* See https://github.com/PrismJS/prism/issues/2443
|
||||
*/
|
||||
@layer utilities {
|
||||
.table {
|
||||
display: initial;
|
||||
}
|
||||
}
|
||||
|
||||
/* Colorscheme, using sweetie palette */
|
||||
:root {
|
||||
--base: var(--ctp-latte-base);
|
||||
--base-alt: var(--ctp-latte-mantle);
|
||||
--surface: var(--ctp-latte-surface0);
|
||||
--text: var(--ctp-latte-text);
|
||||
--text-alt: var(--ctp-latte-subtext1);
|
||||
--grey: var(--ctp-latte-overlay1);
|
||||
--dark-grey: var(--ctp-latte-overlay0);
|
||||
--magenta: var(--ctp-latte-mauve);
|
||||
--red: var(--ctp-latte-red);
|
||||
--orange: var(--ctp-latte-peach);
|
||||
--yellow: var(--ctp-latte-yellow);
|
||||
--green: var(--ctp-latte-green);
|
||||
--teal: var(--ctp-latte-teal);
|
||||
--cyan: var(--ctp-latte-sky);
|
||||
--blue: var(--ctp-latte-blue);
|
||||
--violet: var(--ctp-latte-lavender);
|
||||
}
|
||||
:root.dark {
|
||||
--base: var(--ctp-mocha-base);
|
||||
--base-alt: var(--ctp-mocha-mantle);
|
||||
--surface: var(--ctp-mocha-surface0);
|
||||
--text: var(--ctp-mocha-text);
|
||||
--text-alt: var(--ctp-mocha-subtext1);
|
||||
--grey: var(--ctp-mocha-overlay1);
|
||||
--dark-grey: var(--ctp-mocha-overlay0);
|
||||
--magenta: var(--ctp-mocha-mauve);
|
||||
--red: var(--ctp-mocha-red);
|
||||
--orange: var(--ctp-mocha-peach);
|
||||
--yellow: var(--ctp-mocha-yellow);
|
||||
--green: var(--ctp-mocha-green);
|
||||
--teal: var(--ctp-mocha-teal);
|
||||
--cyan: var(--ctp-mocha-sky);
|
||||
--blue: var(--ctp-mocha-blue);
|
||||
--violet: var(--ctp-mocha-lavender);
|
||||
}
|
||||
|
||||
@theme static {
|
||||
--font-sans:
|
||||
"Fira Mono", ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji",
|
||||
"Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||
--font-mono:
|
||||
"Fira Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas,
|
||||
"Liberation Mono", "Courier New", monospace;
|
||||
|
||||
--color-base: var(--base);
|
||||
--color-base-alt: var(--base-alt);
|
||||
--color-surface: var(--surface);
|
||||
--color-text: var(--text);
|
||||
--color-text-alt: var(--text-alt);
|
||||
--color-grey: var(--grey);
|
||||
--color-dark-grey: var(--dark-grey);
|
||||
--color-red: var(--red);
|
||||
--color-orange: var(--orange);
|
||||
--color-green: var(--green);
|
||||
--color-teal: var(--teal);
|
||||
--color-yellow: var(--yellow);
|
||||
--color-blue: var(--blue);
|
||||
--color-magenta: var(--magenta);
|
||||
--color-violet: var(--violet);
|
||||
--color-cyan: var(--cyan);
|
||||
}
|
||||
|
||||
/* Overall design */
|
||||
html {
|
||||
scrollbar-color: var(--blue) var(--surface);
|
||||
@apply scroll-smooth tabular-nums font-sans;
|
||||
}
|
||||
|
||||
body {
|
||||
@apply bg-base text-text antialiased font-medium;
|
||||
}
|
||||
|
||||
main a {
|
||||
@apply underline hover:text-blue;
|
||||
}
|
||||
|
||||
a.icon {
|
||||
@apply no-underline;
|
||||
}
|
||||
|
||||
a {
|
||||
@apply transition-colors duration-200 ease-in-out;
|
||||
}
|
||||
|
||||
hr {
|
||||
/* brightness-120 = #39394b */
|
||||
@apply text-base-alt dark:brightness-120;
|
||||
}
|
||||
|
||||
header,
|
||||
footer {
|
||||
@apply bg-surface text-text-alt;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
@apply font-bold;
|
||||
}
|
||||
|
||||
h1 {
|
||||
@apply text-3xl;
|
||||
}
|
||||
|
||||
h2 {
|
||||
@apply text-2xl;
|
||||
counter-increment: h2;
|
||||
counter-reset: h3;
|
||||
}
|
||||
|
||||
h3 {
|
||||
@apply text-xl;
|
||||
counter-increment: h3;
|
||||
counter-reset: h4;
|
||||
}
|
||||
|
||||
h4 {
|
||||
@apply text-lg;
|
||||
counter-increment: h4;
|
||||
}
|
||||
|
||||
h5 {
|
||||
counter-increment: h5;
|
||||
}
|
||||
|
||||
h6 {
|
||||
@apply font-semibold;
|
||||
counter-increment: h6;
|
||||
}
|
||||
|
||||
p {
|
||||
@apply leading-relaxed py-2;
|
||||
}
|
||||
|
||||
strong {
|
||||
@apply font-semibold;
|
||||
}
|
||||
|
||||
ul {
|
||||
@apply list-disc;
|
||||
}
|
||||
|
||||
ol {
|
||||
@apply list-decimal;
|
||||
}
|
||||
|
||||
ul,
|
||||
ol {
|
||||
@apply leading-relaxed;
|
||||
}
|
||||
|
||||
nav ul,
|
||||
nav ol {
|
||||
@apply mx-2 space-y-0 list-none;
|
||||
}
|
||||
|
||||
main ul {
|
||||
@apply pl-4;
|
||||
}
|
||||
|
||||
/* Margins */
|
||||
main h2,
|
||||
article h2,
|
||||
section h2 {
|
||||
@apply mt-10;
|
||||
}
|
||||
main h3,
|
||||
article h3,
|
||||
section h3 {
|
||||
@apply mt-8;
|
||||
}
|
||||
main h4,
|
||||
article h4,
|
||||
section h4 {
|
||||
@apply mt-6;
|
||||
}
|
||||
main h5,
|
||||
article h5,
|
||||
section h5 {
|
||||
@apply mt-4;
|
||||
}
|
||||
main h6,
|
||||
article h6,
|
||||
section h6 {
|
||||
@apply mt-2;
|
||||
}
|
||||
|
||||
/* Visual flair */
|
||||
main div#content h2:not(:first-child) {
|
||||
@apply border-t border-t-base-alt dark:border-t-[#39394b] pt-5;
|
||||
}
|
||||
main div#content h3:not(:first-child) {
|
||||
@apply border-t border-t-base-alt dark:border-t-[#39394b] pt-4;
|
||||
}
|
||||
main div#content h4:not(:first-child) {
|
||||
@apply border-t border-t-base-alt dark:border-t-[#39394b] pt-3;
|
||||
}
|
||||
main div#content h5:not(:first-child) {
|
||||
@apply border-t border-t-base-alt dark:border-t-[#39394b] pt-2;
|
||||
}
|
||||
main div#content h6:not(:first-child) {
|
||||
@apply border-t border-t-base-alt dark:border-t-[#39394b] pt-1;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
@apply p-4 my-4 border-s-4 rounded-r-sm border-base-alt bg-surface dark:border-surface dark:bg-base-alt;
|
||||
}
|
||||
|
||||
blockquote.tip {
|
||||
@apply border-green bg-green/30;
|
||||
}
|
||||
blockquote.note {
|
||||
@apply border-blue bg-blue/30;
|
||||
}
|
||||
blockquote.important {
|
||||
@apply border-violet bg-violet/30;
|
||||
}
|
||||
blockquote.warning {
|
||||
@apply border-yellow bg-yellow/30;
|
||||
}
|
||||
blockquote.error {
|
||||
@apply border-red bg-red/30;
|
||||
}
|
||||
|
||||
blockquote > p {
|
||||
@apply leading-relaxed;
|
||||
}
|
||||
|
||||
/* Inline verbatim `` */
|
||||
code:not([class*="language-"]) {
|
||||
@apply px-1 py-px font-mono text-sm rounded-md bg-base-alt dark:bg-surface dark:brightness-80;
|
||||
}
|
||||
|
||||
/* Table of Contents */
|
||||
nav.toc {
|
||||
@apply h-3/4 pt-4 pb-4 font-mono bg-surface border-2 border-base-alt rounded-md;
|
||||
}
|
||||
|
||||
nav.toc ol {
|
||||
@apply pl-4 list-decimal list-inside;
|
||||
}
|
||||
|
||||
nav.toc ul {
|
||||
@apply pl-4 list-disc list-inside;
|
||||
}
|
||||
|
||||
nav.toc ol li,
|
||||
nav.toc ul li {
|
||||
@apply mt-0 pb-0;
|
||||
}
|
||||
|
||||
nav.toc ol li a,
|
||||
nav.toc ul li a {
|
||||
@apply no-underline hover:text-blue;
|
||||
}
|
||||
|
||||
nav.toc ol li::marker,
|
||||
nav.toc ul li::marker {
|
||||
@apply hover:text-blue;
|
||||
}
|
||||
|
||||
nav.toc ol li ol,
|
||||
nav.toc ul li ul {
|
||||
@apply pb-2;
|
||||
}
|
||||
|
||||
/* PrismJS specific css */
|
||||
pre[class*="language-"],
|
||||
code[class*="language-"] {
|
||||
font-variant-ligatures: common-ligatures !important;
|
||||
@apply bg-surface! dark:bg-base-alt font-mono! text-shadow-none!;
|
||||
}
|
||||
|
||||
/* PrismJS line-numbers plugin */
|
||||
pre[class*="language-"].line-numbers {
|
||||
counter-reset: linenumber;
|
||||
@apply relative pl-13;
|
||||
}
|
||||
|
||||
pre[class*="language-"].line-numbers > code {
|
||||
white-space: inherit;
|
||||
@apply relative;
|
||||
}
|
||||
|
||||
.line-numbers .line-numbers-rows {
|
||||
@apply absolute flex flex-col top-[-1.5px] -left-12 w-10 pointer-events-none select-none border-r! border-r-grey!;
|
||||
}
|
||||
|
||||
.line-numbers-rows > span {
|
||||
counter-increment: linenumber;
|
||||
@apply block leading-[1.5];
|
||||
}
|
||||
|
||||
.line-numbers-rows > span:before {
|
||||
content: counter(linenumber);
|
||||
@apply text-grey! text-right pr-2 block;
|
||||
}
|
||||
|
||||
/* Center MermaidJS charts and diagrams */
|
||||
pre.mermaid {
|
||||
@apply flex justify-center;
|
||||
}
|
||||
|
||||
/* Automatic dark theme for MermaidJS */
|
||||
.dark .mermaid {
|
||||
filter: invert(0.9) hue-rotate(180deg);
|
||||
}
|
||||
147
theme/templates/base.html
Normal file
147
theme/templates/base.html
Normal file
@@ -0,0 +1,147 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ config.language }}">
|
||||
<head>
|
||||
{% block head %}
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="generator" content="Norgolith" />
|
||||
|
||||
{# Dynamic meta tags #}
|
||||
{% if metadata.description and not metadata.description == "nil" %}
|
||||
<meta name="description" content="{{ metadata.description }}" />
|
||||
{% endif %}
|
||||
{% if metadata.authors %}
|
||||
<meta name="author" content="{{ metadata.authors | join(sep=", ") }}" />
|
||||
{% endif %}
|
||||
{% if metadata.categories %}
|
||||
<meta name="keywords" content="{{ metadata.categories | join(sep=", ") }}" />
|
||||
{% endif %}
|
||||
|
||||
{# SEO Meta Tags #}
|
||||
{% block seo_tags %}{% endblock seo_tags %}
|
||||
|
||||
{# Syntax highlighter #}
|
||||
{% if config.highlighter is defined and config.highlighter.enable %}
|
||||
{# If highlighter is enabled but the engine is not defined then fallback to prismjs #}
|
||||
{% if config.highlighter.engine is not string or config.highlighter.engine == "prism" %}
|
||||
{# PrismJS #}
|
||||
{# Themes from automadcms:
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://unpkg.com/automad-prism-themes@0.3.1/dist/prism-catppuccin-frappe.light-dark.css"
|
||||
/>
|
||||
#}
|
||||
<link rel="stylesheet" href="/assets/css/prism-sweetie.min.css" />
|
||||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/prism.min.js"></script>
|
||||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/autoloader/prism-autoloader.min.js"></script>
|
||||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/line-numbers/prism-line-numbers.min.js"></script>
|
||||
{% elif config.highlighter.engine is defined
|
||||
and config.highlighter.engine == "hljs" %}
|
||||
{# Highlight.js #}
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/atom-one-dark.min.css">
|
||||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
|
||||
<script>hljs.highlightAll();</script> #}
|
||||
{# Enable this one instead if you want all the `<code>` tags to be highlighted
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", (event) => {
|
||||
document.querySelectorAll("code").forEach((block) => {
|
||||
hljs.highlightBlock(block);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
#}
|
||||
{% elif config.highlighter.engine is string
|
||||
and config.highlighter.engine not in ["prism", "hljs"] %}
|
||||
<script>
|
||||
window.alert("Warning: highlighter is enabled in the site configuration but its engine is not 'prism' nor 'hljs'");
|
||||
</script>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{# AlpineJS #}
|
||||
<script defer src="https://cdn.jsdelivr.net/npm/@alpinejs/collapse@3.x.x/dist/cdn.min.js"></script>
|
||||
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
|
||||
<script>
|
||||
document.addEventListener("alpine:init", () => {
|
||||
Alpine.data("menu", () => ({
|
||||
currentPage: window.location.pathname,
|
||||
|
||||
openMobile: false,
|
||||
|
||||
toggleMobile() {
|
||||
this.openMobile = !this.openMobile;
|
||||
}
|
||||
}));
|
||||
|
||||
Alpine.data("toc", () => ({
|
||||
open: false,
|
||||
|
||||
toggle() {
|
||||
this.open = !this.open;
|
||||
document.querySelector("#toc-toggle-icon").classList.toggle("rotate-90");
|
||||
}
|
||||
}));
|
||||
|
||||
Alpine.data("theme", () => ({
|
||||
// Defaults to dark theme
|
||||
current: "dark",
|
||||
|
||||
init() {
|
||||
const storedTheme = localStorage.getItem("theme");
|
||||
if (storedTheme === "dark") {
|
||||
this.current = "dark";
|
||||
} else if (storedTheme === "light") {
|
||||
this.current = "light";
|
||||
} else if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
|
||||
this.current = "dark";
|
||||
}
|
||||
localStorage.setItem("theme", this.current);
|
||||
if (this.current === "dark") {
|
||||
document.documentElement.classList.add("dark");
|
||||
}
|
||||
},
|
||||
|
||||
toggle() {
|
||||
this.current = this.current === "dark" ? "light" : "dark";
|
||||
document.documentElement.classList.toggle("dark", this.current === "dark");
|
||||
localStorage.setItem("theme", this.current);
|
||||
}
|
||||
}));
|
||||
});
|
||||
</script>
|
||||
|
||||
{# MermaidJS #}
|
||||
{% if config.extra.enable_mermaid %}
|
||||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/mermaid/11.9.0/mermaid.min.js"></script>
|
||||
{% endif %}
|
||||
|
||||
{# Icons #}
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tabler-icons/3.28.1/tabler-icons.min.css">
|
||||
|
||||
{# Styling and favicon #}
|
||||
<link rel="stylesheet" href="/assets/css/styles.min.css" />
|
||||
{% if config.extra.favicon_path is defined and config.extra.favicon_path is string %}
|
||||
<link rel="icon" href={{ config.extra.favicon_path }} />
|
||||
{% else %}
|
||||
<link rel="icon" href="/assets/norgolith.svg" />
|
||||
{% endif %}
|
||||
|
||||
<title>{% block title %}{% endblock title %} - {{ config.title | title }}</title>
|
||||
{% endblock head %}
|
||||
</head>
|
||||
<body>
|
||||
<div class="transition-colors duration-150 ease-linear">
|
||||
<header class="relative shadow-sm">
|
||||
{% include "partials/nav.html" %}
|
||||
</header>
|
||||
|
||||
<main class="container mx-auto min-h-screen pt-8 px-4 md:px-0">
|
||||
{% block content %}{% endblock content %}
|
||||
</main>
|
||||
|
||||
<footer class="mt-8 py-4 px-6 w-full font-mono">
|
||||
{% include "partials/footer.html" %}
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
33
theme/templates/categories.html
Normal file
33
theme/templates/categories.html
Normal file
@@ -0,0 +1,33 @@
|
||||
{% extends "base.html" %}
|
||||
{% block seo_tags %}
|
||||
<meta property="og:title" content="Categories - {{ config.title | title }}" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:url" content="{{ config.rootUrl }}/categories" />
|
||||
<meta property="og:description" content="Posts categories" />
|
||||
<meta property="og:site_name" content="{{ config.title }}" />
|
||||
<meta property="og:locale" content="{{ config.language }}" />
|
||||
{# TODO: add support for og:image using metadata #}
|
||||
<link rel="canonical" href="{{ config.rootUrl }}/categories" />
|
||||
<meta name="robots" content="index, follow" />
|
||||
{% endblock seo_tags %}
|
||||
{% block title %}Categories{% endblock title %}
|
||||
{% block content %}
|
||||
<div>
|
||||
<h1>Categories</h1>
|
||||
<p class="text-sm text-text/70"><i>All the categories used in posts.</i></p>
|
||||
<ul class="mt-6 pt-6 border-t border-t-base-alt dark:border-t-[#39394b]">
|
||||
{% for category in categories | sort %}
|
||||
{%- set_global cat_posts = 0 -%}
|
||||
{% for post in posts %}
|
||||
{% if category in post.categories %}
|
||||
{%- set_global cat_posts = cat_posts + 1 -%}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<li>
|
||||
<a class="font-mono text-lg no-underline! hover:underline! hover:decoration-dashed" href="/categories/{{ category }}">{{ category }}</a>
|
||||
<span class="text-grey">({{ cat_posts }} post{{ cat_posts | pluralize }})</span>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endblock content %}
|
||||
31
theme/templates/category.html
Normal file
31
theme/templates/category.html
Normal file
@@ -0,0 +1,31 @@
|
||||
{% extends "base.html" %}
|
||||
{% block seo_tags %}
|
||||
<meta property="og:title" content="Category: {{ category }} - {{ config.title | title }}" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:url" content="{{ config.rootUrl }}/categories/{{ category }}" />
|
||||
<meta property="og:description" content="Posts on category {{ category }}" />
|
||||
<meta property="og:site_name" content="{{ config.title }}" />
|
||||
<meta property="og:locale" content="{{ config.language }}" />
|
||||
{# TODO: add support for og:image using metadata #}
|
||||
<link rel="canonical" href="{{ config.rootUrl }}/categories/{{ category }}" />
|
||||
<meta name="robots" content="index, follow" />
|
||||
{% endblock seo_tags %}
|
||||
{% block title %}Category: {{ category }}{% endblock title %}
|
||||
{% block content %}
|
||||
<div>
|
||||
<h1>Posts in {{ category }}</h1>
|
||||
<p class="text-sm text-text/70"><i>All the posts with the category "{{ category }}"</i></p>
|
||||
<ul class="mt-6 pt-6 border-t border-t-base-alt dark:border-t-[#39394b]">
|
||||
{% for post in posts | filter(attribute="draft", value=false) | sort(attribute="created") | reverse %}
|
||||
{% if category in post.categories %}
|
||||
<li>
|
||||
<div class="flex flex-col md:flex-row space-x-4">
|
||||
<a class="font-mono text-lg w-fit no-underline! hover:underline! hover:decoration-dashed" href="{{ post.permalink }}">{{ post.title }}</a>
|
||||
<time class="text-grey text-sm italic"> on <strong>{{ post.created | date(format="%B %e, %Y") }}</strong></time>
|
||||
</div>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endblock content %}
|
||||
17
theme/templates/default.html
Normal file
17
theme/templates/default.html
Normal file
@@ -0,0 +1,17 @@
|
||||
{% extends "base.html" %}
|
||||
{% block seo_tags %}
|
||||
<meta property="og:title" content="{{ metadata.title | title }} - {{ config.title | title }}" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:url" content="{{ metadata.permalink }}" />
|
||||
<meta property="og:description" content="{{ metadata.description }}" />
|
||||
<meta property="og:site_name" content="{{ config.title }}" />
|
||||
<meta property="og:locale" content="{{ config.language }}" />
|
||||
{# TODO: add support for og:image using metadata #}
|
||||
<link rel="canonical" href="{{ metadata.permalink }}" />
|
||||
<meta name="robots" content="index, follow" />
|
||||
{% endblock seo_tags %}
|
||||
|
||||
{% block title %}{{ metadata.title | title }}{% endblock title %}
|
||||
{% block content %}
|
||||
{{ content | safe }}
|
||||
{% endblock content %}
|
||||
45
theme/templates/home.html
Normal file
45
theme/templates/home.html
Normal file
@@ -0,0 +1,45 @@
|
||||
{% extends "base.html" %}
|
||||
{% block seo_tags %}
|
||||
<meta property="og:title" content="{{ config.title | title }}" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:url" content="{{ metadata.permalink }}" />
|
||||
<meta property="og:description" content="{{ metadata.description }}" />
|
||||
<meta property="og:site_name" content="{{ config.title }}" />
|
||||
<meta property="og:locale" content="{{ config.language }}" />
|
||||
{# TODO: add support for og:image using metadata #}
|
||||
<link rel="canonical" href="{{ config.rootUrl }}" />
|
||||
<meta name="robots" content="index, follow" />
|
||||
{% endblock seo_tags %}
|
||||
|
||||
{% block title %}{{ metadata.title | title }}{% endblock title %}
|
||||
{% block content %}
|
||||
{{ content | safe }}
|
||||
|
||||
{# Latest 5 non-draft blog posts, ordered automatically by date #}
|
||||
{% if posts | filter(attribute="draft", value=false) | length > 0 %}
|
||||
<section>
|
||||
<h2>Recent posts</h2>
|
||||
{% for post in posts | filter(attribute="draft", value=false) | sort(attribute="created") | reverse | slice(end=5) %}
|
||||
<div class="bg-surface p-4 mt-4 border-2 border-base-alt rounded-md shadow-lg">
|
||||
<div class="flex flex-col">
|
||||
<h3 class="mt-0! text-text-alt"><a class="no-underline! hover:underline! hover:decoration-dashed" href="{{ post.permalink }}">{{ post.title }}</a></h3>
|
||||
<time class="text-dark-grey dark:text-grey" datetime="{{ post.created }}">{{ post.created | date(format="%B %e, %Y") }}</time>
|
||||
<span class="text-sm text-grey italic">{{ post.description }}</span>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<p>
|
||||
{% if post.truncate_char and post.truncate_char is matching("^nil$") %}
|
||||
{% set truncate_char = "" %}
|
||||
{% else %}
|
||||
{% set truncate_char = "…" %}
|
||||
{% endif %}
|
||||
{{ post.raw | striptags | truncate(length=post.truncate | default(value=100), end=truncate_char) | safe }}
|
||||
</p>
|
||||
<a class="no-underline! text-dark-grey font-semibold" href="{{ post.permalink }}">Read more …</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</section>
|
||||
{% endif %}
|
||||
|
||||
{% endblock content %}
|
||||
30
theme/templates/partials/footer.html
Normal file
30
theme/templates/partials/footer.html
Normal file
@@ -0,0 +1,30 @@
|
||||
<div
|
||||
class="flex flex-col md:flex-row justify-between md:items-center font-medium text-xs md:text-sm text-text-alt space-y-4 md:space-y-0"
|
||||
>
|
||||
<span
|
||||
>Copyright © {{ now(format="%Y") }}
|
||||
{% if config.extra.footer_author_link %}
|
||||
<a
|
||||
href="{{ config.extra.footer_author_link }}"
|
||||
class="text-blue hover:underline">{{ config.author }}</a
|
||||
>.
|
||||
{% else %}
|
||||
{{ config.author }}.
|
||||
{% endif %}
|
||||
{% if config.extra.license %}
|
||||
<br class="md:hidden" /> Licensed under {{ config.extra.license }}.
|
||||
{% endif %}
|
||||
</span>
|
||||
<div class="flex flex-inline">
|
||||
{% for name, link in config.extra.footer %}
|
||||
<div class="mr-4 md:mr-6 lg:mr-8 last:mr-0">
|
||||
<a
|
||||
href="{{ link }}"
|
||||
class="hover:text-blue"
|
||||
>
|
||||
<span>{{ name | title }}</span>
|
||||
</a>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
72
theme/templates/partials/nav.html
Normal file
72
theme/templates/partials/nav.html
Normal file
@@ -0,0 +1,72 @@
|
||||
<nav x-data="menu" class="container mx-auto px-4 md:px-0 font-mono">
|
||||
<div class="flex items-center justify-between h-16">
|
||||
<!-- Logo and dark mode -->
|
||||
<div x-data="theme" class="flex items-center shrink-0 space-x-2">
|
||||
<a href="/" class="flex items-center space-x-2">
|
||||
<!-- <img src="{{ config.rootUrl }}/assets/norgolith.svg" alt="Norgolith Logo" class="h-8 w-8"> -->
|
||||
<span class="text-lg md:text-xl font-bold text-magenta">{{ config.title | title }}</span>
|
||||
</a>
|
||||
<button
|
||||
@click="toggle()"
|
||||
type="button"
|
||||
class="rounded-lg flex items-center"
|
||||
:aria-label="current === 'dark' ? 'Switch to light mode' : 'Switch to dark mode'"
|
||||
>
|
||||
<i
|
||||
:class="current === 'dark' ? 'ti-sun hover:text-yellow' : 'ti-moon hover:text-blue'"
|
||||
class="ti text-xl md:text-2xl text-grey transition-colors duration-200 ease-in-out"
|
||||
></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Desktop Menu -->
|
||||
<div class="hidden md:flex md:items-center md:space-x-8">
|
||||
{% for name, link in config.extra.nav %}
|
||||
<a
|
||||
:class="{ 'text-magenta!': currentPage.startsWith('{{ link }}') }"
|
||||
class="text-text-alt hover:text-blue px-3 py-2 rounded-md text-sm font-medium"
|
||||
href="{{ link }}"
|
||||
>{{ name | title }}</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<!-- Mobile Menu Button -->
|
||||
<div class="md:hidden">
|
||||
<button @click="toggleMobile" type="button" class="inline-flex items-center justify-center p-2 rounded-md text-dark-grey hover:text-text-alt focus:outline-none" aria-controls="mobile-menu" aria-expanded="false">
|
||||
<span class="sr-only">Open main menu</span>
|
||||
<!-- Hamburger Icon -->
|
||||
<svg x-show="!openMobile" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"/>
|
||||
</svg>
|
||||
<!-- Close Icon -->
|
||||
<svg x-show="openMobile" class="h-5 w-5 text-red" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Mobile Menu -->
|
||||
<div
|
||||
x-show="openMobile"
|
||||
x-transition:enter="transition ease-out duration-300"
|
||||
x-transition:enter-start="opacity-0"
|
||||
x-transition:enter-end="opacity-100"
|
||||
x-transition:leave="transition ease-in duration-300"
|
||||
x-transition:leave-start="opacity-100"
|
||||
x-transition:leave-end="opacity-0"
|
||||
@click.outside="openMobile = false"
|
||||
class="md:hidden"
|
||||
id="mobile-menu"
|
||||
>
|
||||
<div class="flex flex-row items-center justify-between pt-2 pb-4">
|
||||
{% for name, link in config.extra.nav %}
|
||||
<a
|
||||
:class="{ 'text-blue!': currentPage.startsWith('{{ link }}') }"
|
||||
class="text-text-alt hover:text-blue px-3 py-2 rounded-md text-sm font-medium"
|
||||
href="{{ link }}"
|
||||
>{{ name | title }}</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
77
theme/templates/post.html
Normal file
77
theme/templates/post.html
Normal file
@@ -0,0 +1,77 @@
|
||||
{% extends "base.html" %}
|
||||
{% block seo_tags %}
|
||||
<meta property="og:title" content="{{ metadata.title | title }} - {{ config.title | title }}" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:url" content="{{ metadata.permalink }}" />
|
||||
<meta property="og:description" content="{{ metadata.description }}" />
|
||||
<meta property="og:site_name" content="{{ config.title }}" />
|
||||
<meta property="og:locale" content="{{ config.language }}" />
|
||||
{# TODO: add support for og:image using metadata #}
|
||||
<link rel="canonical" href="{{ metadata.permalink }}" />
|
||||
<meta name="robots" content="index, follow" />
|
||||
{% endblock seo_tags %}
|
||||
|
||||
{% block title %}{{ metadata.title | title }}{% endblock title %}
|
||||
{% block content %}
|
||||
<div>
|
||||
<h1>{{ metadata.title }}</h1>
|
||||
</div>
|
||||
<div class="flex flex-col md:flex-row">
|
||||
<div class="flex flex-col md:flex-row flex-1 justify-between">
|
||||
<div class="flex flex-col space-y-2">
|
||||
{# Date, reading time #}
|
||||
{% set created = metadata.created | date(format="%B %e, %Y") %}
|
||||
{% set updated = metadata.updated | date(format="%B %e, %Y") %}
|
||||
<span class="text-grey text-sm tabular-nums text-opacity-70 dark:text-opacity-100 space-x-1">
|
||||
<time datetime="{{ metadata.created }}">{{ created }}</time>
|
||||
{% if created != updated %}
|
||||
(Last edit: <time datetime="{{ metadata.updated }}">{{ metadata.updated | date(format="%B %e, %Y") }}</time>)
|
||||
{% endif %}
|
||||
</span>
|
||||
</div>
|
||||
{% if metadata.categories | length > 0 %}
|
||||
<div class="flex flex-wrap items-center max-w-[50%]">
|
||||
<span class="font-semibold mr-px">Tags: </span>
|
||||
{% for category in metadata.categories %}
|
||||
<a
|
||||
class="w-fit bg-grey hover:bg-magenta text-base hover:text-base! no-underline! hover:no-underline! text-sm mr-2 last:mr-0 px-1 rounded-sm"
|
||||
href="/categories/{{ category }}"
|
||||
>
|
||||
{{ category | capitalize }}
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% if metadata.toc %}
|
||||
<div x-data="toc" class="mt-4">
|
||||
{% set toc_html = generate_toc(toc=metadata.toc, list_type="ol") %}
|
||||
<button @click="toggle()" type="button" class="inline-flex items-center">
|
||||
<span class="sr-only">Close Table of Contents</span>
|
||||
<h3 class="mt-0! mr-1">
|
||||
Table of Contents
|
||||
</h3>
|
||||
<span
|
||||
id="toc-toggle-icon"
|
||||
class="transition-all duration-300 ease-in-out text-2xl hover:text-blue ti ti-arrow-badge-right-filled"
|
||||
></span>
|
||||
</button>
|
||||
<nav
|
||||
x-transition:enter="transition ease-out duration-300"
|
||||
x-transition:enter-start="opacity-0"
|
||||
x-transition:enter-end="opacity-100"
|
||||
x-transition:leave="transition ease-in duration-300"
|
||||
x-transition:leave-start="opacity-100"
|
||||
x-transition:leave-end="opacity-0"
|
||||
x-show="open"
|
||||
class="toc"
|
||||
>
|
||||
{{ toc_html | safe }}
|
||||
</nav>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div id="content" class="mt-12 break-keep pt-10 border-t border-t-base-alt dark:border-t-[#39394b]">
|
||||
{{ content | safe }}
|
||||
</div>
|
||||
{% endblock content %}
|
||||
38
theme/templates/posts.html
Normal file
38
theme/templates/posts.html
Normal file
@@ -0,0 +1,38 @@
|
||||
{% extends "base.html" %}
|
||||
{% block seo_tags %}
|
||||
<meta property="og:title" content="{{ metadata.title | title }} - {{ config.title | title }}" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:url" content="{{ metadata.permalink }}" />
|
||||
<meta property="og:description" content="Posts on {{ config.title | title }}" />
|
||||
<meta property="og:site_name" content="{{ config.title }}" />
|
||||
<meta property="og:locale" content="{{ config.language }}" />
|
||||
<link rel="canonical" href="{{ metadata.permalink }}" />
|
||||
<meta name="robots" content="index, follow" />
|
||||
{% endblock seo_tags %}
|
||||
|
||||
{% block title %}{{ metadata.title | title }}{% endblock title %}
|
||||
{% block content %}
|
||||
<h1 class="text-center">Posts</h1>
|
||||
<div class="mt-6 pt-6 border-t border-t-base-alt dark:border-t-[#39394b] break-keep">
|
||||
{% for post in posts | filter(attribute="draft", value=false) | sort(attribute="created") | reverse %}
|
||||
<div class="bg-surface p-4 mt-4 border-2 border-base-alt rounded-xl shadow-lg">
|
||||
<div class="flex flex-col">
|
||||
<h3 class="mt-0! text-text-alt"><a class="no-underline! hover:underline! hover:decoration-dashed" href="{{ post.permalink }}">{{ post.title }}</a></h3>
|
||||
<time class="text-dark-grey dark:text-grey" datetime="{{ post.created }}">{{ post.created | date(format="%B %e, %Y") }}</time>
|
||||
<span class="text-sm text-grey italic">{{ post.description }}</span>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<p>
|
||||
{% if post.truncate_char is defined and post.truncate_char is matching("^nil$") %}
|
||||
{% set truncate_char = "" %}
|
||||
{% else %}
|
||||
{% set truncate_char = "…" %}
|
||||
{% endif %}
|
||||
{{ post.raw | striptags | truncate(length=post.truncate | default(value=300), end=truncate_char) | safe }}
|
||||
</p>
|
||||
<a class="no-underline! text-dark-grey font-semibold" href="{{ post.permalink }}">Read more …</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endblock content %}
|
||||
33
theme/templates/rss.xml
Normal file
33
theme/templates/rss.xml
Normal file
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>{{ config.title }}</title>
|
||||
<link>{{ config.rootUrl | escape_xml | safe }}</link>
|
||||
<description>{{ config.rss.description | default(value="Latest posts")}}</description>
|
||||
<generator>Norgolith</generator>
|
||||
<language>{{ config.language }}</language>
|
||||
<lastBuildDate>{{ now | date(format="%a, %d %b %Y %H:%M:%S %z") }}</lastBuildDate>
|
||||
<ttl>{{ config.rss.ttl | default(value=60) }}</ttl>
|
||||
<atom:link href="{{ config.rootUrl }}/rss.xml" rel="self" type="application/rss+xml" />
|
||||
|
||||
<image>
|
||||
<url>{{ config.rootUrl | escape_xml | safe }}{{ config.rss.image | default(value="/assets/favicon.svg") }}</url>
|
||||
<title>{{ config.title }}</title>
|
||||
<link>{{ config.rootUrl | escape_xml | safe }}</link>
|
||||
<width>144</width>
|
||||
<height>144</height>
|
||||
</image>
|
||||
|
||||
{% for post in posts | filter(attribute="draft", value=false) | sort(attribute="created") | reverse %}
|
||||
<item>
|
||||
<title>{{ post.title }}</title>
|
||||
<link>{{ post.permalink | escape_xml | safe }}</link>
|
||||
<guid>{{ post.permalink | escape_xml | safe }}</guid>
|
||||
<description>{{ post.description }}</description>
|
||||
<author>{{ post.authors | join(sep=", ") }}</author>
|
||||
<pubDate>{{ post.created | date(format="%a, %d %b %Y %H:%M:%S %z") }}</pubDate>
|
||||
{% if post.categories %}{% for category in post.categories %}<category>{{ category }}</category>{% endfor %}{% endif %}
|
||||
</item>
|
||||
{% endfor %}
|
||||
</channel>
|
||||
</rss>
|
||||
5
theme/theme.toml
Normal file
5
theme/theme.toml
Normal file
@@ -0,0 +1,5 @@
|
||||
name = "Norgowind"
|
||||
author = "NTBBloodbath"
|
||||
description = "Norgolith <3 TailwindCSS"
|
||||
version = "0.4.1"
|
||||
license = "MIT"
|
||||
Reference in New Issue
Block a user