tangled
alpha
login
or
join now
ericwood.org
/
photos-site
1
fork
atom
A little app to serve my photography from my personal website
1
fork
atom
overview
issues
pulls
pipelines
render markdown
ericwood.org
3 months ago
8c710e98
fb046272
+118
-5
5 changed files
expand all
collapse all
unified
split
Cargo.lock
Cargo.toml
src
app_error.rs
routes
blog
show.rs
templates
blog
show.jinja
+103
Cargo.lock
···
1111
1111
checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154"
1112
1112
1113
1113
[[package]]
1114
1114
+
name = "markdown"
1115
1115
+
version = "1.0.0"
1116
1116
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1117
1117
+
checksum = "a5cab8f2cadc416a82d2e783a1946388b31654d391d1c7d92cc1f03e295b1deb"
1118
1118
+
dependencies = [
1119
1119
+
"unicode-id",
1120
1120
+
]
1121
1121
+
1122
1122
+
[[package]]
1123
1123
+
name = "markdown-frontmatter"
1124
1124
+
version = "0.4.0"
1125
1125
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1126
1126
+
checksum = "7430fd66a1ba512543425144850284f8c821bc1e3e35cd6c13684823815d707a"
1127
1127
+
dependencies = [
1128
1128
+
"serde",
1129
1129
+
"serde_json",
1130
1130
+
"serde_yaml",
1131
1131
+
"thiserror 2.0.17",
1132
1132
+
"toml",
1133
1133
+
]
1134
1134
+
1135
1135
+
[[package]]
1114
1136
name = "matchers"
1115
1137
version = "0.2.0"
1116
1138
source = "registry+https://github.com/rust-lang/crates.io-index"
···
1440
1462
"chrono",
1441
1463
"dotenvy",
1442
1464
"init-tracing-opentelemetry",
1465
1465
+
"markdown",
1466
1466
+
"markdown-frontmatter",
1443
1467
"minijinja",
1444
1468
"minijinja-autoreload",
1445
1469
"serde",
···
2011
2035
]
2012
2036
2013
2037
[[package]]
2038
2038
+
name = "serde_spanned"
2039
2039
+
version = "1.0.3"
2040
2040
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2041
2041
+
checksum = "e24345aa0fe688594e73770a5f6d1b216508b4f93484c0026d521acd30134392"
2042
2042
+
dependencies = [
2043
2043
+
"serde_core",
2044
2044
+
]
2045
2045
+
2046
2046
+
[[package]]
2014
2047
name = "serde_urlencoded"
2015
2048
version = "0.7.1"
2016
2049
source = "registry+https://github.com/rust-lang/crates.io-index"
···
2065
2098
dependencies = [
2066
2099
"paste",
2067
2100
"regex",
2101
2101
+
]
2102
2102
+
2103
2103
+
[[package]]
2104
2104
+
name = "serde_yaml"
2105
2105
+
version = "0.9.34+deprecated"
2106
2106
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2107
2107
+
checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47"
2108
2108
+
dependencies = [
2109
2109
+
"indexmap",
2110
2110
+
"itoa",
2111
2111
+
"ryu",
2112
2112
+
"serde",
2113
2113
+
"unsafe-libyaml",
2068
2114
]
2069
2115
2070
2116
[[package]]
···
2541
2587
]
2542
2588
2543
2589
[[package]]
2590
2590
+
name = "toml"
2591
2591
+
version = "0.9.8"
2592
2592
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2593
2593
+
checksum = "f0dc8b1fb61449e27716ec0e1bdf0f6b8f3e8f6b05391e8497b8b6d7804ea6d8"
2594
2594
+
dependencies = [
2595
2595
+
"indexmap",
2596
2596
+
"serde_core",
2597
2597
+
"serde_spanned",
2598
2598
+
"toml_datetime",
2599
2599
+
"toml_parser",
2600
2600
+
"toml_writer",
2601
2601
+
"winnow",
2602
2602
+
]
2603
2603
+
2604
2604
+
[[package]]
2605
2605
+
name = "toml_datetime"
2606
2606
+
version = "0.7.3"
2607
2607
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2608
2608
+
checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533"
2609
2609
+
dependencies = [
2610
2610
+
"serde_core",
2611
2611
+
]
2612
2612
+
2613
2613
+
[[package]]
2614
2614
+
name = "toml_parser"
2615
2615
+
version = "1.0.4"
2616
2616
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2617
2617
+
checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e"
2618
2618
+
dependencies = [
2619
2619
+
"winnow",
2620
2620
+
]
2621
2621
+
2622
2622
+
[[package]]
2623
2623
+
name = "toml_writer"
2624
2624
+
version = "1.0.4"
2625
2625
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2626
2626
+
checksum = "df8b2b54733674ad286d16267dcfc7a71ed5c776e4ac7aa3c3e2561f7c637bf2"
2627
2627
+
2628
2628
+
[[package]]
2544
2629
name = "tonic"
2545
2630
version = "0.14.2"
2546
2631
source = "registry+https://github.com/rust-lang/crates.io-index"
···
2766
2851
checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5"
2767
2852
2768
2853
[[package]]
2854
2854
+
name = "unicode-id"
2855
2855
+
version = "0.3.6"
2856
2856
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2857
2857
+
checksum = "70ba288e709927c043cbe476718d37be306be53fb1fafecd0dbe36d072be2580"
2858
2858
+
2859
2859
+
[[package]]
2769
2860
name = "unicode-ident"
2770
2861
version = "1.0.19"
2771
2862
source = "registry+https://github.com/rust-lang/crates.io-index"
···
2791
2882
version = "1.12.0"
2792
2883
source = "registry+https://github.com/rust-lang/crates.io-index"
2793
2884
checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
2885
2885
+
2886
2886
+
[[package]]
2887
2887
+
name = "unsafe-libyaml"
2888
2888
+
version = "0.2.11"
2889
2889
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2890
2890
+
checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861"
2794
2891
2795
2892
[[package]]
2796
2893
name = "untrusted"
···
3280
3377
version = "0.53.1"
3281
3378
source = "registry+https://github.com/rust-lang/crates.io-index"
3282
3379
checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650"
3380
3380
+
3381
3381
+
[[package]]
3382
3382
+
name = "winnow"
3383
3383
+
version = "0.7.14"
3384
3384
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3385
3385
+
checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829"
3283
3386
3284
3387
[[package]]
3285
3388
name = "wit-bindgen"
+2
Cargo.toml
···
4
4
edition = "2024"
5
5
6
6
[dependencies]
7
7
+
markdown = "1.0.0"
7
8
anyhow = "1.0.100"
8
9
axum = { version = "0.8.6", features = ["macros"] }
9
10
axum-extra = { version = "0.12.1", features = ["query"] }
···
15
16
"tracing_subscriber_ext",
16
17
"metrics",
17
18
] }
19
19
+
markdown-frontmatter = "0.4.0"
18
20
minijinja = { version = "2.12.0", features = ["loader"] }
19
21
minijinja-autoreload = "2.12.0"
20
22
serde = "1.0.228"
+6
-1
src/app_error.rs
···
16
16
17
17
#[error("internal server error")]
18
18
Anyhow(#[from] anyhow::Error),
19
19
+
20
20
+
#[error("internal server error")]
21
21
+
IoError(#[from] std::io::Error),
19
22
}
20
23
21
24
impl AppError {
···
23
26
match self {
24
27
Self::NotFound => StatusCode::NOT_FOUND,
25
28
Self::ValidationError(_) => StatusCode::BAD_REQUEST,
26
26
-
Self::DbError(_) | Self::Anyhow(_) => StatusCode::INTERNAL_SERVER_ERROR,
29
29
+
Self::DbError(_) | Self::Anyhow(_) | Self::IoError(_) => {
30
30
+
StatusCode::INTERNAL_SERVER_ERROR
31
31
+
}
27
32
}
28
33
}
29
34
}
+6
-3
src/routes/blog/show.rs
···
1
1
-
use crate::{AppState, Response, templates::render};
1
1
+
use crate::{AppState, Response, app_error::AppError, templates::render};
2
2
use axum::{
3
3
extract::{Path, State},
4
4
response::Html,
5
5
};
6
6
use minijinja::context;
7
7
-
use std::sync::Arc;
7
7
+
use std::{fs::read_to_string, sync::Arc};
8
8
9
9
pub async fn show(Path(slug): Path<String>, State(state): State<Arc<AppState>>) -> Response {
10
10
+
let path = state.blog_slugs.get(&slug).ok_or(AppError::NotFound)?;
11
11
+
let md = read_to_string(path)?;
12
12
+
let body = markdown::to_html(&md);
10
13
let rendered = render(
11
14
&state.reloader,
12
15
"blog/show",
13
16
context! {
14
14
-
slug
17
17
+
body
15
18
},
16
19
)?;
17
20
+1
-1
templates/blog/show.jinja
···
3
3
{% block title %}Blog{% endblock %}
4
4
5
5
{% block body %}
6
6
-
{{ slug }}
6
6
+
{{ body }}
7
7
{% endblock %}