worked on html templates
1
.gitignore
vendored
|
@ -1 +1,2 @@
|
|||
/target
|
||||
.env
|
||||
|
|
6
Cargo.lock
generated
|
@ -389,6 +389,7 @@ dependencies = [
|
|||
"gray_matter",
|
||||
"notify",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"syntect",
|
||||
"tokio",
|
||||
"tower 0.5.1",
|
||||
|
@ -1438,11 +1439,12 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.111"
|
||||
version = "1.0.132"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4"
|
||||
checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"memchr",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
|
|
@ -14,6 +14,7 @@ comrak = "0.29.0"
|
|||
gray_matter = "0.2.8"
|
||||
notify = "6.1.1"
|
||||
serde = { version = "1.0.213", features = ["derive"] }
|
||||
serde_json = "1.0.132"
|
||||
syntect = "5.2.0"
|
||||
tokio = { version = "1.41.0", features = ["full"] }
|
||||
tower = "0.5.1"
|
||||
|
|
133
src/main.rs
|
@ -14,6 +14,7 @@ use comrak::{markdown_to_html_with_plugins, Options, Plugins};
|
|||
use gray_matter::engine::YAML;
|
||||
use gray_matter::Matter;
|
||||
use notify::{RecursiveMode, Watcher};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tower::ServiceBuilder;
|
||||
use tower_http::services::ServeDir;
|
||||
use tower_http::trace::TraceLayer;
|
||||
|
@ -36,12 +37,11 @@ pub struct Post {
|
|||
body: String,
|
||||
}
|
||||
|
||||
/*#[derive(Template)]
|
||||
#[template(path = "includes/head.html", escape = "none")]
|
||||
struct HeadTemplate {
|
||||
styles: String,
|
||||
meta: Meta,
|
||||
}*/
|
||||
#[derive(Clone, Deserialize, Serialize)]
|
||||
pub struct Button {
|
||||
path: String,
|
||||
location: String,
|
||||
}
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "base.html", escape = "none")]
|
||||
|
@ -53,7 +53,9 @@ struct BaseTemplate {
|
|||
#[derive(Template)]
|
||||
#[template(path = "index.html", escape = "none")]
|
||||
struct IndexTemplate {
|
||||
_parent: BaseTemplate,
|
||||
styles: String,
|
||||
meta: Meta,
|
||||
}
|
||||
|
||||
#[derive(Template)]
|
||||
|
@ -62,6 +64,15 @@ struct HomelabTemplate {
|
|||
styles: String,
|
||||
}
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "buttons.html", escape = "none")]
|
||||
struct ButtonsTemplate {
|
||||
_parent: BaseTemplate,
|
||||
styles: String,
|
||||
meta: Meta,
|
||||
buttons: Vec<Button>,
|
||||
}
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "blog_list.html", escape = "none")]
|
||||
struct BlogListTemplate {
|
||||
|
@ -171,6 +182,76 @@ async fn blog(State(state): State<Arc<RwLock<AppState>>>) -> Result<impl IntoRes
|
|||
return Ok(HtmlTemplate(template));
|
||||
}
|
||||
|
||||
async fn buttons(
|
||||
State(state): State<Arc<RwLock<AppState>>>,
|
||||
) -> Result<impl IntoResponse, StatusCode> {
|
||||
let mut styles: String = state
|
||||
.read()
|
||||
.unwrap()
|
||||
.styles
|
||||
.get("nord.css")
|
||||
.unwrap()
|
||||
.clone();
|
||||
styles.push_str(
|
||||
state
|
||||
.read()
|
||||
.unwrap()
|
||||
.styles
|
||||
.get("colors.css")
|
||||
.unwrap()
|
||||
.as_str(),
|
||||
);
|
||||
styles.push_str(
|
||||
state
|
||||
.read()
|
||||
.unwrap()
|
||||
.styles
|
||||
.get("core.css")
|
||||
.unwrap()
|
||||
.as_str(),
|
||||
);
|
||||
styles.push_str(
|
||||
state
|
||||
.read()
|
||||
.unwrap()
|
||||
.styles
|
||||
.get("components.css")
|
||||
.unwrap()
|
||||
.as_str(),
|
||||
);
|
||||
styles.push_str(
|
||||
state
|
||||
.read()
|
||||
.unwrap()
|
||||
.styles
|
||||
.get("font.css")
|
||||
.unwrap()
|
||||
.as_str(),
|
||||
);
|
||||
let json_data: Result<Vec<Button>, _> = serde_json::from_str(
|
||||
std::fs::read_to_string("./static/img/88x31/index.json")
|
||||
.unwrap()
|
||||
.as_str(),
|
||||
);
|
||||
let meta = Meta {
|
||||
title: "CBAX dot DEV Blog".into(),
|
||||
author: "Chad Baxter".into(),
|
||||
description: "An interesting place of techobabble. See my internet friends' 88x31s".into(),
|
||||
img_path: "".into(),
|
||||
canonical_url: "buttons".into(),
|
||||
};
|
||||
let template = ButtonsTemplate {
|
||||
_parent: BaseTemplate {
|
||||
styles: styles.clone(),
|
||||
meta: meta.clone(),
|
||||
},
|
||||
styles,
|
||||
meta,
|
||||
buttons: json_data.unwrap_or(vec![]),
|
||||
};
|
||||
return Ok(HtmlTemplate(template));
|
||||
}
|
||||
|
||||
async fn blog_post(
|
||||
State(state): State<Arc<RwLock<AppState>>>,
|
||||
Path(post_slug): Path<String>,
|
||||
|
@ -280,6 +361,15 @@ async fn homelab(
|
|||
.unwrap()
|
||||
.as_str(),
|
||||
);
|
||||
styles.push_str(
|
||||
state
|
||||
.read()
|
||||
.unwrap()
|
||||
.styles
|
||||
.get("styles.css")
|
||||
.unwrap()
|
||||
.as_str(),
|
||||
);
|
||||
let template = HomelabTemplate { styles };
|
||||
return Ok(HtmlTemplate(template));
|
||||
}
|
||||
|
@ -330,7 +420,21 @@ async fn index(
|
|||
.unwrap()
|
||||
.as_str(),
|
||||
);
|
||||
let template = IndexTemplate { styles };
|
||||
let meta = Meta {
|
||||
title: "CBAX dot DEV Blog".into(),
|
||||
author: "Chad Baxter".into(),
|
||||
description: "An interesting place of techobabble.".into(),
|
||||
img_path: "".into(),
|
||||
canonical_url: "blog".into(),
|
||||
};
|
||||
let template = IndexTemplate {
|
||||
_parent: BaseTemplate {
|
||||
styles: styles.clone(),
|
||||
meta: meta.clone(),
|
||||
},
|
||||
styles,
|
||||
meta,
|
||||
};
|
||||
return Ok(HtmlTemplate(template));
|
||||
}
|
||||
|
||||
|
@ -351,20 +455,6 @@ async fn main() {
|
|||
posts: HashMap::new(),
|
||||
styles: HashMap::new(),
|
||||
}));
|
||||
state.write().unwrap().posts.insert(
|
||||
"test_slug".into(),
|
||||
Post {
|
||||
meta: Meta {
|
||||
title: "Test Post".into(),
|
||||
author: "Chad Baxter".into(),
|
||||
description: "This is a test post".into(),
|
||||
img_path: "/res/cbax.gif".into(),
|
||||
canonical_url: "//cbax.dev/blog/test_slug".into(),
|
||||
},
|
||||
cover_img_path: "/res/covers/test.png".into(),
|
||||
body: "this is a test post!".into(),
|
||||
},
|
||||
);
|
||||
let builder = SyntectAdapterBuilder::new()
|
||||
.theme_set(syntect::highlighting::ThemeSet::from(&LazyThemeSet::from(
|
||||
extra(),
|
||||
|
@ -522,6 +612,7 @@ async fn main() {
|
|||
.route("/homelab", get(homelab))
|
||||
.route("/blog", get(blog))
|
||||
.route("/blog/:post_slug", get(blog_post))
|
||||
.route("/buttons", get(buttons))
|
||||
.with_state(state.clone())
|
||||
.fallback_service(serve_dir())
|
||||
.layer(axum_server_timing::ServerTimingLayer::new("Axum"))
|
||||
|
|
|
@ -129,6 +129,12 @@
|
|||
color: var(--text-color);
|
||||
cursor: pointer;
|
||||
transition-duration: 0.5s;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.button-stealth {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.button:hover {
|
||||
|
@ -136,9 +142,12 @@
|
|||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hover-button {
|
||||
margin: 0.25rem 0.5rem 0.5rem 0.25rem;
|
||||
}
|
||||
|
||||
.hover-button:hover {
|
||||
margin: 0.5rem 1rem 1rem 0.5rem;
|
||||
box-shadow: 0.5rem 0.5rem 0rem rgba(var(--highlight-color-rgb), 0.3);
|
||||
box-shadow: 0.25rem 0.25rem 0rem rgba(var(--highlight-color-rgb), 0.3);
|
||||
}
|
||||
|
||||
.button:active {
|
||||
|
@ -156,13 +165,22 @@
|
|||
border: 0;
|
||||
}
|
||||
|
||||
.badge {
|
||||
position: relative;
|
||||
top: -7px;
|
||||
right: 7px;
|
||||
padding: 2px 2px;
|
||||
border-radius: 25%;
|
||||
background: var(--nord12);
|
||||
color: var(--bg-color);
|
||||
}
|
||||
|
||||
/* -------- Box components -------- */
|
||||
|
||||
|
||||
.box {
|
||||
margin: 0.5rem;
|
||||
padding: 1rem;
|
||||
padding: 0.5rem;
|
||||
border: 1px solid var(--highlight-color);
|
||||
}
|
||||
|
||||
|
@ -249,3 +267,31 @@
|
|||
.fancy:hover::before {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* -------- Nav components -------- */
|
||||
|
||||
.nav-title {
|
||||
font-size: large;
|
||||
font-style: oblique;
|
||||
font-weight: 950;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* -------- 88x31 --------*/
|
||||
|
||||
.eex31-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
align-content: flex-start;
|
||||
padding-left: 0.5rem;
|
||||
padding-right: 0.5rem;
|
||||
width: 50vw;
|
||||
}
|
||||
|
||||
.eex31 {
|
||||
width: 88;
|
||||
height: 31;
|
||||
margin: 0.5rem;
|
||||
}
|
||||
|
|
|
@ -93,15 +93,35 @@ code {
|
|||
article {
|
||||
background-color: var(--article-color);
|
||||
width: 90vw;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
nav {
|
||||
width: 70vw;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-content: center;
|
||||
}
|
||||
|
||||
footer {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
display: flex;
|
||||
position: sticky;
|
||||
top: 100vh;
|
||||
width: 90vw;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
align-content: center;
|
||||
}
|
||||
fieldset {
|
||||
border-color: var(--bg-color);
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
nav, footer {
|
||||
width: 100vw;
|
||||
legend {
|
||||
font-weight: 700;
|
||||
font-size: large;
|
||||
}
|
||||
|
||||
/* ---------------- Highlighting ---------------- */
|
||||
|
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 878 B After Width: | Height: | Size: 878 B |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 367 B After Width: | Height: | Size: 367 B |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
BIN
static/img/88x31/dontfeedai.gif
Normal file
After Width: | Height: | Size: 934 B |
BIN
static/img/88x31/eightyeightthirtyone.png
Normal file
After Width: | Height: | Size: 646 B |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 441 B After Width: | Height: | Size: 441 B |
70
static/img/88x31/index.json
Normal file
|
@ -0,0 +1,70 @@
|
|||
[
|
||||
{
|
||||
"path": "/res/img/88x31/abc.gif",
|
||||
"location": "https://www.mozilla.org/en-US/firefox/"
|
||||
},
|
||||
{
|
||||
"path": "/res/img/88x31/adryd.png",
|
||||
"location": "https://adryd.com/"
|
||||
},
|
||||
{
|
||||
"path": "/res/img/88x31/cbax.gif",
|
||||
"location": "https://cbax.dev/"
|
||||
},
|
||||
{
|
||||
"path": "/res/img/88x31/dam.gif",
|
||||
"location": "https://damcraft.de/"
|
||||
},
|
||||
{
|
||||
"path": "/res/img/88x31/eva.gif",
|
||||
"location": "https://kibty.town/"
|
||||
},
|
||||
{
|
||||
"path": "/res/img/88x31/honbra.png",
|
||||
"location": "https://honbra.com/"
|
||||
},
|
||||
{
|
||||
"path": "/res/img/88x31/kofi.gif",
|
||||
"location": "https://ko-fi.com/mrcbax"
|
||||
},
|
||||
{
|
||||
"path": "/res/img/88x31/mat.png",
|
||||
"location": "https://matdoes.dev/"
|
||||
},
|
||||
{
|
||||
"path": "/res/img/88x31/neovim.gif",
|
||||
"location": "https://neovim.io/"
|
||||
},
|
||||
{
|
||||
"path": "/res/img/88x31/notnite.gif",
|
||||
"location": "https://notnite.com/"
|
||||
},
|
||||
{
|
||||
"path": "/res/img/88x31/powered_by_alpine.gif",
|
||||
"location": "https://alpinelinux.org/"
|
||||
},
|
||||
{
|
||||
"path": "/res/img/88x31/shwecky.png",
|
||||
"location": "https://shrecked.dev/"
|
||||
},
|
||||
{
|
||||
"path": "/res/img/88x31/ssi.gif",
|
||||
"location": "https://ssi.fyi/"
|
||||
},
|
||||
{
|
||||
"path": "/res/img/88x31/ublockorigin.png",
|
||||
"location": "https://ublockorigin.com/"
|
||||
},
|
||||
{
|
||||
"path": "/res/img/88x31/dontfeedai.gif",
|
||||
"location": "https://github.com/mrcbax/TeapotFortune"
|
||||
},
|
||||
{
|
||||
"path": "/res/img/88x31/eightyeightthirtyone.png",
|
||||
"location": "https://eightyeightthirty.one/"
|
||||
},
|
||||
{
|
||||
"path": "/res/img/88x31/preserve.gif",
|
||||
"location": "https://archive.org/"
|
||||
}
|
||||
]
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 695 B After Width: | Height: | Size: 695 B |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 350 B After Width: | Height: | Size: 350 B |
BIN
static/img/88x31/preserve.gif
Normal file
After Width: | Height: | Size: 2 KiB |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 92 KiB After Width: | Height: | Size: 92 KiB |
Before Width: | Height: | Size: 5 KiB After Width: | Height: | Size: 5 KiB |
|
@ -2,8 +2,10 @@
|
|||
{% block content %}
|
||||
<article class="box box-pop">
|
||||
{% for (slug, post) in posts %}
|
||||
{% if loop.first %}<div class="new_callout">NEW!</div>{% endif %}
|
||||
<a class="fancy" href="/blog/{{ slug }}"><h2>{{ post.title }}</h2></a>
|
||||
{% if loop.first %}
|
||||
<span class="badge">NEW</span>
|
||||
{% endif %}
|
||||
<p>{{ post.description }}</p>
|
||||
{% endfor %}
|
||||
</article>
|
||||
|
|
8
templates/buttons.html
Normal file
|
@ -0,0 +1,8 @@
|
|||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
<article class="box box-pop eex31-container">
|
||||
{% for button in buttons %}
|
||||
<a href="{{ button.location }}"><img class="eex31" src="{{ button.path }}"></img></a>
|
||||
{% endfor %}
|
||||
</article>
|
||||
{% endblock %}
|
|
@ -1,3 +1,4 @@
|
|||
<footer>
|
||||
<p>Copyright 2024 cbax</p>
|
||||
<p>©2024 cbax</p>
|
||||
<a class="fancy" href="/buttons">BUTTONS!</a>
|
||||
</footer>
|
||||
|
|
|
@ -1,69 +1,15 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>CBAX dot DEV</title>
|
||||
<style>
|
||||
{{styles}}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="main">
|
||||
<div id="card">
|
||||
<span>
|
||||
<h1>cbax ❲. ❳ dev</h1>
|
||||
</span>
|
||||
<br>
|
||||
<hl></hl>
|
||||
<br>
|
||||
<fieldset>
|
||||
<legend>Contacts & Links</legend>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Email</td>
|
||||
<td>me (at) cbax dot dev</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>GitHub</td>
|
||||
<td><a href="//github.com/mrcbax" class="fancy">mrcbax</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Blog</td>
|
||||
<td><a href="//computeco.de" class="fancy">ComputeCode</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>About</legend>
|
||||
<ul>
|
||||
<li>42U homelab owner <a class="fancy" href="/homelab">See Details</a></li>
|
||||
<li>Amateur radio operator</li>
|
||||
<li>AS202239 - 44net member</li>
|
||||
<li>Retro-tech enthusiast</li>
|
||||
</ul>
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
<footer>
|
||||
<a href="//cbax.dev"><img src="/res/img/cbax.gif"/></a>
|
||||
<a href="//ssi.fyi"><img src="/res/img/ssi.gif"/></a>
|
||||
<a href="//adryd.com"><img src="/res/img/adryd.png"/></a>
|
||||
<a href="//matdoes.dev"><img src="/res/img/mat.png"/></a>
|
||||
<a href="//shrecked.dev"><img src="/res/img/shwecky.png"/></a>
|
||||
<a href="//honbra.com"><img src="/res/img/honbra.png"/></a>
|
||||
<a href="//notnite.com"><img src="/res/img/notnite.gif"/></a>
|
||||
<a href="//damcraft.de"><img src="/res/img/dam.gif"/></a>
|
||||
<a href="//kibty.town"><img src="/res/img/eva.gif"/></a>
|
||||
<a href="//alpinelinux.org"><img src="/res/img/powered_by_alpine.gif"/></a>
|
||||
<a href="//neovim.io"><img src="/res/img/neovim.gif"/></a>
|
||||
<a href="//ublockorigin.com"><img src="/res/img/ublockorigin.png"/></a>
|
||||
<a href="//www.mozilla.org/en-US/firefox/new"><img src="/res/img/abc.gif"/></a>
|
||||
<a href="//ko-fi.com/mrcbax"><img src="/res/img/kofi.gif"/></a>
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
<article class="box box-pop">
|
||||
<p>This site is currently under construction, you can find the source code <a href="https://git.cbax.dev/cbax/cbax_dev">here</a></p>
|
||||
<fieldset>
|
||||
<legend>About Me</legend>
|
||||
<ul>
|
||||
<li>42U homelab owner <a class="fancy" href="/homelab">See Details</a></li>
|
||||
<li>Amateur radio operator</li>
|
||||
<li>AS202239 - 44net member</li>
|
||||
<li>Retro-tech enthusiast</li>
|
||||
</ul>
|
||||
</fieldset>
|
||||
</article>
|
||||
{% endblock %}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
<nav>
|
||||
<a class="fancy" href="/">Home</a>
|
||||
<nav class="box box-stealth">
|
||||
<a class="button hover-button button-stealth" href="/">Home</button>
|
||||
<a class="button hover-button button-stealth nav-title" href="/">CBAX.DEV</a>
|
||||
<a class="button hover-button button-stealth" href="/blog">Blog</a>
|
||||
</nav>
|
||||
|
|