Initial commit
This commit is contained in:
commit
b8e56c87b4
29 changed files with 4131 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/target
|
1898
Cargo.lock
generated
Normal file
1898
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
23
Cargo.toml
Normal file
23
Cargo.toml
Normal file
|
@ -0,0 +1,23 @@
|
|||
[package]
|
||||
name = "rusty_duck"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[profile.release]
|
||||
opt-level = 'z' # Optimize for size.
|
||||
lto = true # Enable Link Time Optimisation
|
||||
codegen-units = 1 # Reduced to increase optimisations.
|
||||
panic = 'abort' # Abort on panic
|
||||
strip = "symbols" # Strip symbols from binary
|
||||
|
||||
[dependencies]
|
||||
askama = { version = "0.12.1", features = ["with-axum"] }
|
||||
askama_axum = "0.4.0"
|
||||
axum = "0.7.5"
|
||||
comrak = "0.27.0"
|
||||
markdown-parser = "0.1.2"
|
||||
rand = "0.8.5"
|
||||
serde = { version = "1.0.209", features = ["derive"] }
|
||||
serde_yaml = "0.9.34"
|
||||
tokio = { version = "1.39.3", features = ["macros", "rt-multi-thread"] }
|
||||
tower-http = { version = "0.5.2", features = ["fs"] }
|
13
assets/duck.asc
Normal file
13
assets/duck.asc
Normal file
|
@ -0,0 +1,13 @@
|
|||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
mDMEZMNBMhYJKwYBBAHaRw8BAQdAmPlgCTcSG+IWCXqaE5muoTUnU5phhTx0r7Rb
|
||||
/+KkBn20IFRlY2hubyBEdWNrIDxkdWNrQHRlY2hub2R1Y2subWU+iJkEExYKAEEW
|
||||
IQSNINxoxA6qXTt7s4AEGKzIL/qdBAUCZMNBMgIbAwUJA8JnAAULCQgHAgIiAgYV
|
||||
CgkICwIEFgIDAQIeBwIXgAAKCRAEGKzIL/qdBMi6APwNf+l6lEAe43VqFdX2JQBG
|
||||
Ix0zhcpFIsbj8uuGJigEFgD9GuMFECAIdnjeYKJCAl5HgOgmR8TK+rY5bMeVa93v
|
||||
wAS4OARkw0EyEgorBgEEAZdVAQUBAQdAl4PNh37rKOOd0bb47BhcaWMPhgBvWuz4
|
||||
uUbXpZOilyQDAQgHiH4EGBYKACYWIQSNINxoxA6qXTt7s4AEGKzIL/qdBAUCZMNB
|
||||
MgIbDAUJA8JnAAAKCRAEGKzIL/qdBP6iAQCJkWOreY5Kwz1JDwu0mICt3MobMJsX
|
||||
IT+H2MdjE5uyDQD/TBgZjHRp6xILvSSzS8H5e0ClBkKNqUhJMVZ+hPdx/wU=
|
||||
=dSiL
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
BIN
assets/favicon.png
Normal file
BIN
assets/favicon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.9 KiB |
BIN
assets/gnu-linux.gif
Normal file
BIN
assets/gnu-linux.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 550 B |
1614
assets/img/led_hoop/pcb.svg
Normal file
1614
assets/img/led_hoop/pcb.svg
Normal file
File diff suppressed because it is too large
Load diff
After Width: | Height: | Size: 476 KiB |
BIN
assets/img/led_hoop/schematic.png
Normal file
BIN
assets/img/led_hoop/schematic.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 100 KiB |
BIN
assets/mastodon_button_2.gif
Normal file
BIN
assets/mastodon_button_2.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
28
assets/old_style.css
Normal file
28
assets/old_style.css
Normal file
|
@ -0,0 +1,28 @@
|
|||
:root {
|
||||
font-size:1rem;
|
||||
--rhythm: 1.5rem;
|
||||
--line-length: 60vw;
|
||||
}
|
||||
|
||||
header {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
.\<h1\>,
|
||||
.\<h2\>,
|
||||
.\<h3\>,
|
||||
.\<h4\>,
|
||||
.\<h5\>,
|
||||
.\<h6\> {
|
||||
margin-block-start:var(--gap);
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 1.2em;
|
||||
}
|
5
assets/robots.txt
Normal file
5
assets/robots.txt
Normal file
|
@ -0,0 +1,5 @@
|
|||
User-agent: *
|
||||
Disallow: /
|
||||
|
||||
User-agent: ChatGPT-User
|
||||
Disallow: /
|
122
assets/style.css
Normal file
122
assets/style.css
Normal file
|
@ -0,0 +1,122 @@
|
|||
html {
|
||||
overflow-y: scroll;
|
||||
}
|
||||
body {
|
||||
background-color: #fff;
|
||||
color: #000;
|
||||
font-family: sans-serif;
|
||||
margin: 0;
|
||||
padding: 1ex;
|
||||
}
|
||||
/* HTML5 semantic tags: some (older) browsers display this inline by default */
|
||||
article, figcaption, figure, header, main, nav {
|
||||
display: block;
|
||||
}
|
||||
/* center images */
|
||||
img {
|
||||
margin: 0 auto;
|
||||
}
|
||||
table, img {
|
||||
border: 0;
|
||||
}
|
||||
hr {
|
||||
border: 0;
|
||||
border-bottom: 3px solid #aaa;
|
||||
height: 3px;
|
||||
}
|
||||
h1 {
|
||||
font-size: 140%;
|
||||
}
|
||||
h2 {
|
||||
font-size: 120%;
|
||||
}
|
||||
h3 {
|
||||
font-size: 120%;
|
||||
}
|
||||
h1,
|
||||
h1 a,
|
||||
h1 a:visited,
|
||||
h2,
|
||||
h2 a,
|
||||
h2 a:visited,
|
||||
h3,
|
||||
h3 a,
|
||||
h3 a:visited,
|
||||
h1 a:hover,
|
||||
h2 a:hover,
|
||||
h3 a:hover {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
table tr td {
|
||||
padding: 2px 10px 2px 0px;
|
||||
}
|
||||
pre {
|
||||
margin: 0;
|
||||
}
|
||||
pre code {
|
||||
display: block;
|
||||
border: 3px solid #aaa;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
code {
|
||||
background-color: #eee;
|
||||
border: 1px solid #aaa;
|
||||
font-family: monospace;
|
||||
overflow-x: auto;
|
||||
padding: 1px;
|
||||
word-wrap: normal;
|
||||
}
|
||||
#menu td {
|
||||
padding: 1ex 0;
|
||||
}
|
||||
#main {
|
||||
border-top: 3px solid #aaa;
|
||||
}
|
||||
#menuwrap,
|
||||
#menu,
|
||||
#main {
|
||||
margin: 0px auto;
|
||||
max-width: 100ex;
|
||||
}
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
.logo {
|
||||
display: flex;
|
||||
}
|
||||
img.logo {
|
||||
width: 7em;
|
||||
}
|
||||
.footer {
|
||||
margin-top: 4em;
|
||||
}
|
||||
.footer a img {
|
||||
float: left;
|
||||
margin-bottom: 3em;
|
||||
}
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body {
|
||||
background-color: #121210;
|
||||
color: #bdbdbd;
|
||||
}
|
||||
pre code, code {
|
||||
background-color: #333;
|
||||
border-color: #444;
|
||||
}
|
||||
hr {
|
||||
border-color: #444;
|
||||
}
|
||||
a {
|
||||
color: #56c8ff;
|
||||
}
|
||||
#main {
|
||||
border-top: 3px solid #444;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
BIN
assets/technoduck.png
Normal file
BIN
assets/technoduck.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 130 KiB |
14
posts/000-genesis.md
Normal file
14
posts/000-genesis.md
Normal file
|
@ -0,0 +1,14 @@
|
|||
---
|
||||
title: Full website Update
|
||||
date: 2023-01-12
|
||||
---
|
||||
## New Website
|
||||
|
||||
### Saait
|
||||
|
||||
I got a little bit tired of the old site, so changed it to something more ~websit-y~
|
||||
|
||||
Now its made using [Saait](https://git.codemadness.org/saait/) and what a treat it is.
|
||||
|
||||
More Updates coming.
|
||||
|
11
posts/001-bash_blogger.md
Normal file
11
posts/001-bash_blogger.md
Normal file
|
@ -0,0 +1,11 @@
|
|||
---
|
||||
title: Creating posts with bash and git from terminal
|
||||
date: 2023-01-13
|
||||
---
|
||||
Since updating this website with Saait, I have decided to create a tool to streamline page creation from the terminal.
|
||||
|
||||
Inspired by [bash_blog](https://github.com/j0m/bash_blog) and [bashblog](https://github.com/cfenollosa/bashblog) especially bash was chosen.
|
||||
|
||||
It is goofy, not as practical as I would think, but neat nevertheless.
|
||||
|
||||
Source at my [git](https://git.technoduck.me) repo.
|
32
posts/002-services.md
Normal file
32
posts/002-services.md
Normal file
|
@ -0,0 +1,32 @@
|
|||
---
|
||||
title: List of Services running on the server
|
||||
date: 2023-01-13
|
||||
---
|
||||
|
||||
### This blog
|
||||
|
||||
Self explanatory. This is my [website](/), my little corner of the internet.
|
||||
|
||||
### Email
|
||||
|
||||
Self hosted email server using Dovecot + Posfix.
|
||||
|
||||
### Git
|
||||
|
||||
[forgejo](https://git.technoduck.me) instance for my personal projects.
|
||||
|
||||
### Etebase
|
||||
|
||||
An [Etebase](https://etebase.technoduck.me) instance for syncing my tasks, to-do's and contacts between devices.
|
||||
|
||||
### Grocy
|
||||
|
||||
[Grocy](https://grocy.technoduck.me) instance for keeping track of food and grocery lists ( and literally anything else in your house including batteris in devices? ) it's really cool give it a check.
|
||||
|
||||
### Wiki
|
||||
|
||||
A [wikimedia](https://wiki.cold-metal.technoduck.me) instance running for a friend for categorizing all the lore of the world that is being created for a soft fiction story.
|
||||
|
||||
### WIP
|
||||
|
||||
Work in progress of a [website](https://wip.technoduck.me) I am making for a photographer/photography business.
|
41
posts/003-led_hoop.md
Normal file
41
posts/003-led_hoop.md
Normal file
|
@ -0,0 +1,41 @@
|
|||
---
|
||||
title: PCB LED hoop earring project
|
||||
date: 2024-01-02
|
||||
---
|
||||
## LED Hoops
|
||||
|
||||
### What?
|
||||
|
||||
First, a blog post by [mitxela](https://mitxela.com) came upon my eyes, and piqued my interest.
|
||||
|
||||
Inspired by the [industrial piercing](https://mitxela.com/projects/scaffold) and the electronics that went into it, I though if other pieces of jewelry can be made with electronics (they can, it was specifically a question if my measly hands could craft them).
|
||||
|
||||
Since for the first time, I didn't want to experiment with absolute microscopic sizes, I decided that a 4 cm hoop was an adequate project to attempt.
|
||||
|
||||
![schematic_kicad_image](img/led_hoop/schematic.png =800x)
|
||||
|
||||
An Attiny 24/44/84A can be used, I went with a -M variant, since it is slightly larger then the -MM variant, by a whole mm, which I assume will be easier to solder.
|
||||
|
||||
Placing them all in a nice hoop looking pcb, we obtain this:
|
||||
|
||||
![pcb_kicad_image](/assets/img/led_hoop/pcb.svg)
|
||||
|
||||
The test version comes with ISP pins for debugging and programming the chip when it's already installed.
|
||||
|
||||
0603 LED's were chosen for the same reason, they are small enough to be not that noticeable, but large enough to be not an incredible pain to work with.
|
||||
|
||||
### Why??
|
||||
|
||||
It looked and sounded fun, my only previous projects related to PCB production before this was edition a split [Sweep](https://github.com/davidphilipbarr/Sweep) keyboard.
|
||||
|
||||
And so I did.
|
||||
|
||||
### Cool. What now?
|
||||
|
||||
You can take your chance and go to [the git repository](https://git.technoduck.me/technoduck/led_hoop) for the project, `git pull`, and try your own luck.
|
||||
|
||||
|
||||
|
||||
|
||||
Batteries not included.
|
||||
|
16
posts/004-pantheon.md
Normal file
16
posts/004-pantheon.md
Normal file
|
@ -0,0 +1,16 @@
|
|||
---
|
||||
title: Pantheon
|
||||
date: 2024-03-03
|
||||
---
|
||||
# WATCH PANTHEON
|
||||
|
||||
## I DO NOT CARE WHAT DAY IT IS
|
||||
|
||||
### HERE'S YOUR PLAN
|
||||
|
||||
1. Wake up.
|
||||
2. Open whatever device you watch things on.
|
||||
3. Obtain, legally or illegaly, by any means necessary, 2 (two) seasons of Pantheon, created by Craig Silverstein based on short stories by Ken Liu.
|
||||
4. Binge the 2 sesons in a single night (it is feasable I checked)
|
||||
|
||||
Thank you for coming to my Ted Talk.
|
36
posts/005-regenesis.md
Normal file
36
posts/005-regenesis.md
Normal file
|
@ -0,0 +1,36 @@
|
|||
---
|
||||
title: Full website Re-Update
|
||||
date: 2024-08-29
|
||||
---
|
||||
## New Website?
|
||||
|
||||
### Rust
|
||||
|
||||
The time has come and another re-write is upon us.
|
||||
|
||||
This time inspied by [this article](https://blog.transrights.art/blogs/2024_Screw-Frameworks-New-Site-2),
|
||||
[theprimeagen](https://www.youtube.com/watch?v=rcZSOLAI1lM), and everpresent desire to rewrite everything in Rust,
|
||||
the new website is a complete rewrite using rust and adjacent techniques.
|
||||
|
||||
Using only
|
||||
```
|
||||
[dependencies]
|
||||
askama = { version = "0.12.1", features = ["with-axum"] }
|
||||
askama_axum = "0.4.0"
|
||||
axum = "0.7.5"
|
||||
comrak = "0.27.0"
|
||||
markdown-parser = "0.1.2"
|
||||
rand = "0.8.5"
|
||||
serde = { version = "1.0.209", features = ["derive"] }
|
||||
serde_yaml = "0.9.34"
|
||||
tokio = { version = "1.39.3", features = ["macros", "rt-multi-thread"] }
|
||||
tower-http = { version = "0.5.2", features = ["fs"] }
|
||||
```
|
||||
|
||||
as dependancies in the end we get a clean~ish, 2.8MB executable.
|
||||
|
||||
All markdown compilation gets done every time page is loaded, which is sub-optimal,
|
||||
But reading time for all posts is non-significant compared to other loading times.
|
||||
|
||||
And voila, there is the new post.
|
||||
|
40
src/blog_entries.rs
Normal file
40
src/blog_entries.rs
Normal file
|
@ -0,0 +1,40 @@
|
|||
use std::{fs::read_dir, path::Path};
|
||||
|
||||
use markdown_parser::*;
|
||||
|
||||
use crate::structs::{BlogInfo, IndexPostEntry};
|
||||
|
||||
pub fn get_blog_entry_markdown(path:&String) -> Result<Markdown,Error> {
|
||||
let location = format!("posts/{path}.md").to_string();
|
||||
read_file(Path::new(&location))
|
||||
}
|
||||
|
||||
pub fn get_all_markdowns() -> Vec<IndexPostEntry> {
|
||||
let mut post_vec:Vec<IndexPostEntry> = Vec::new();
|
||||
let mr_dir_iter = match read_dir("posts/") {
|
||||
Ok(iter) => iter,
|
||||
Err(err) => panic!("could ls files, err {err}")
|
||||
};
|
||||
|
||||
for entry in mr_dir_iter {
|
||||
if let Ok(entry) = entry {
|
||||
|
||||
let filename = entry.file_name().into_string().unwrap().split(".").collect::<Vec<_>>()[0].to_string();
|
||||
|
||||
|
||||
let front_matter_string = get_blog_entry_markdown(&filename).unwrap();
|
||||
|
||||
let front_matter:BlogInfo = serde_yaml::from_str(&front_matter_string.front_matter()).unwrap();
|
||||
|
||||
post_vec.push(IndexPostEntry{
|
||||
title: front_matter.title,
|
||||
date: front_matter.date,
|
||||
path: format!("/blog/{filename}"),
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
post_vec.sort_by_key(|e| e.path.clone() );
|
||||
post_vec.reverse();
|
||||
post_vec
|
||||
}
|
36
src/handlers.rs
Normal file
36
src/handlers.rs
Normal file
|
@ -0,0 +1,36 @@
|
|||
use axum::{extract::Path,response::Html};
|
||||
use crate::structs::*;
|
||||
use crate::rand_quote::get_quote;
|
||||
use crate::blog_entries::{get_all_markdowns, get_blog_entry_markdown};
|
||||
|
||||
pub async fn index() -> Html<String> {
|
||||
let all_entries = get_all_markdowns();
|
||||
let quote = get_quote();
|
||||
let new_page = IndexTemplate { random_quote: quote, index_post_entries:&all_entries};
|
||||
Html(new_page.to_string())
|
||||
}
|
||||
|
||||
pub async fn about() -> Html<String> {
|
||||
|
||||
let about_content = comrak::markdown_to_html("about", &comrak::Options::default());
|
||||
let page_content = AboutTemplate{about_content: &about_content};
|
||||
Html(page_content.to_string())
|
||||
}
|
||||
|
||||
|
||||
pub async fn blog(Path(blog_path):Path<String>) -> Html<String> {
|
||||
|
||||
match get_blog_entry_markdown(&blog_path){
|
||||
Ok(markdown) => Html(
|
||||
BlogTemplate{
|
||||
blog_content: &comrak::markdown_to_html(markdown.content(), &comrak::Options::default()),
|
||||
front_matter:&serde_yaml::from_str(markdown.front_matter()).unwrap()}.to_string()
|
||||
),
|
||||
Err(..) => not_found().await,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pub async fn not_found() -> Html<String> {
|
||||
Html(NotFoundTemplate{}.to_string())
|
||||
}
|
27
src/main.rs
Normal file
27
src/main.rs
Normal file
|
@ -0,0 +1,27 @@
|
|||
use axum::{routing::get, Router};
|
||||
use tower_http::services::{ServeDir, ServeFile};
|
||||
|
||||
|
||||
mod handlers;
|
||||
mod structs;
|
||||
pub mod blog_entries;
|
||||
pub mod rand_quote;
|
||||
|
||||
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
|
||||
let app: axum::Router = Router::new()
|
||||
.route("/", get(handlers::index))
|
||||
.route("/about", get(handlers::about))
|
||||
.route("/blog",get(handlers::index))
|
||||
.route("/blog/:blog_path",get(handlers::blog))
|
||||
.route_service("/robots.txt", ServeFile::new("assets/robots.txt"))
|
||||
.fallback(get(handlers::not_found))
|
||||
.nest_service("/assets", ServeDir::new("assets"));
|
||||
|
||||
|
||||
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000").await.unwrap();
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
}
|
19
src/rand_quote.rs
Normal file
19
src/rand_quote.rs
Normal file
|
@ -0,0 +1,19 @@
|
|||
use rand::Rng;
|
||||
|
||||
pub fn get_quote() -> &'static str {
|
||||
let vs = vec![
|
||||
"Silliness and tomfooler are afoot, and who am I to stop it.",
|
||||
"Low entropy self replicating phenomenon that generates a binding force called compassion.",
|
||||
"I was born in the late Holocene and I've seen some shit.",
|
||||
"If there's a deal meant for you, any wild place on earth will do.",
|
||||
"Live long and prosper.",
|
||||
"Prometheus they say brought gods fire down to man and we've caught it tamed it trained it since our history began.",
|
||||
"Oh, so, wenn PETER PARKER eine Reizüberflutung hat, dann sind es \"Spidey-Sinne\", aber wenn ich es tue, ICH HABE AUTISM.",
|
||||
"Guess we are doing Rust now",
|
||||
];
|
||||
let mut rng = rand::thread_rng();
|
||||
match vs.get(rng.gen_range(0..vs.len())) {
|
||||
Some(quote) => quote,
|
||||
None => "You have caught me off guard.",
|
||||
}
|
||||
}
|
40
src/structs.rs
Normal file
40
src/structs.rs
Normal file
|
@ -0,0 +1,40 @@
|
|||
use askama::Template;
|
||||
use serde::{Serialize,Deserialize};
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path="index.html")]
|
||||
pub struct IndexTemplate<'a> {
|
||||
pub random_quote: &'a str,
|
||||
pub index_post_entries: &'a Vec<IndexPostEntry>
|
||||
}
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path="about.html")]
|
||||
pub struct AboutTemplate<'a> {
|
||||
pub about_content: &'a String,
|
||||
}
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path="404.html")]
|
||||
pub struct NotFoundTemplate {
|
||||
}
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path="blog_entry.html")]
|
||||
pub struct BlogTemplate<'a> {
|
||||
pub front_matter: &'a BlogInfo,
|
||||
pub blog_content: &'a String,
|
||||
}
|
||||
|
||||
#[derive(Debug,Serialize,Deserialize)]
|
||||
pub struct BlogInfo {
|
||||
pub title: String,
|
||||
pub date: String,
|
||||
}
|
||||
|
||||
#[derive(Debug,Serialize,Deserialize,PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct IndexPostEntry {
|
||||
pub title: String,
|
||||
pub date: String,
|
||||
pub path: String,
|
||||
}
|
7
templates/404.html
Normal file
7
templates/404.html
Normal file
|
@ -0,0 +1,7 @@
|
|||
{% extends "layout.html" %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<p>Sadly this page doesnt seem to exist</p>
|
||||
|
||||
{% endblock %}
|
15
templates/about.html
Normal file
15
templates/about.html
Normal file
|
@ -0,0 +1,15 @@
|
|||
{% extends "layout.html" %}
|
||||
|
||||
{% block title %}
|
||||
About -
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<h2> yepper yapper yapper</h2>
|
||||
|
||||
<p> this is an about page </p>
|
||||
|
||||
{{ about_content|safe }}
|
||||
|
||||
{% endblock %}
|
15
templates/blog_entry.html
Normal file
15
templates/blog_entry.html
Normal file
|
@ -0,0 +1,15 @@
|
|||
{% extends "layout.html" %}
|
||||
|
||||
{% block title %}
|
||||
{{front_matter.title}} -
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<h1> {{front_matter.title}} </h1>
|
||||
|
||||
|
||||
{{ blog_content|safe }}
|
||||
|
||||
|
||||
{% endblock %}
|
24
templates/index.html
Normal file
24
templates/index.html
Normal file
|
@ -0,0 +1,24 @@
|
|||
{% extends "layout.html" %}
|
||||
|
||||
{% block quote %}
|
||||
{{ random_quote }}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1 style="margin-top:0.5em"> Posts </h1>
|
||||
|
||||
<div class="table">
|
||||
{% for entry in index_post_entries %}
|
||||
|
||||
<div>
|
||||
<time> {{ entry.date }} </time>
|
||||
<a href="{{ entry.path }}"> {{ entry.title }}</a>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
{% endblock %}
|
54
templates/layout.html
Normal file
54
templates/layout.html
Normal file
|
@ -0,0 +1,54 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>{% block title %}{% endblock %} Technoduck</title>
|
||||
<link rel="stylesheet" href="/assets/style.css">
|
||||
<link rel="stylesheet" href="https://unpkg.com/missing.css@1.1.2">
|
||||
<link rel="stylesheet" href="/assets/old_style.css">
|
||||
<link rel="icon" href="/assets/favicon.png" type="image/png" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<main>
|
||||
<header>
|
||||
<a href="/">
|
||||
<img style="display: flex; width: 7em;" align="left" alt="technoduck" src="/assets/technoduck.png">
|
||||
</a>
|
||||
<div class="table">
|
||||
<div class="float:left">
|
||||
<a href="/">Blog</a> |
|
||||
<a href="https://git.technoduck.me" title="Git repository with some of my projects">Git</a> |
|
||||
<a href="https://cv.technoduck.me">Files</a> |
|
||||
<a href="https://wip.technoduck.me">[WIP]</a> |
|
||||
</div>
|
||||
|
||||
<div class="float:right">
|
||||
<a href="/about">About</a> |
|
||||
<a href="assets/duck.asc">PGP</a> |
|
||||
<a href="mailto:duck@technoduck.me">Mail</a>
|
||||
</div>
|
||||
</div>
|
||||
<p>
|
||||
{% block quote %}{% endblock %}
|
||||
</p>
|
||||
|
||||
</header>
|
||||
{% block content%}{% endblock %}
|
||||
|
||||
<footer>
|
||||
<h4>
|
||||
Copyleft (c) 2022-2024 technoduck
|
||||
</h4>
|
||||
<a href="https://yesterweb.org/no-to-web3/" target="_blank">
|
||||
<img alt="a button that says 'keep the web free, say no to web3', linking to a page about web3" src="https://auzziejay.com/images/noweb32.gif">
|
||||
</a>
|
||||
<a href="https://voidlinux.org" target="_blank">
|
||||
<img alt="A button indicating this site was made with Gnu+Linux, linking to Voidlinux website" src="/assets/gnu-linux.gif">
|
||||
</a>
|
||||
<a href="https://joinfediverse.wiki/Main_Page/Fancy" target="_blank">
|
||||
<img alt="Button with Mastodon on it, linking to joinfediverse wiki" src="/assets/mastodon_button_2.gif">
|
||||
</a>
|
||||
</footer>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in a new issue