Skip to content

Commit

Permalink
Replace tera with askama
Browse files Browse the repository at this point in the history
  • Loading branch information
GuillaumeGomez committed Jan 22, 2024
1 parent 4b3a59a commit d1db306
Show file tree
Hide file tree
Showing 50 changed files with 1,493 additions and 1,068 deletions.
1,168 changes: 768 additions & 400 deletions Cargo.lock

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ tempfile = "3.1.0"
fn-error-context = "0.2.0"

# Templating
tera = { version = "1.5.0", features = ["builtins"] }
# tera = { version = "1.5.0", features = ["builtins"] }
askama = { path = "/home/imperio/rust/askama/askama" } # { git = "https://github.com/djc/askama" }
walkdir = "2"

# Date and Time utilities
Expand Down
27 changes: 13 additions & 14 deletions src/utils/html.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use crate::web::page::TemplateData;
use crate::web::page::templates::{Head, Vendored, Body, Topbar};
use crate::web::rustdoc::RustdocPage;
use askama::Template;
use lol_html::element;
use lol_html::errors::RewritingError;
use tera::Context;

/// Rewrite a rustdoc page to have the docs.rs topbar
///
Expand All @@ -12,17 +13,15 @@ use tera::Context;
pub(crate) fn rewrite_lol(
html: &[u8],
max_allowed_memory_usage: usize,
ctx: Context,
templates: &TemplateData,
data: &RustdocPage,
) -> Result<Vec<u8>, RewritingError> {
use lol_html::html_content::{ContentType, Element};
use lol_html::{HtmlRewriter, MemorySettings, Settings};

let templates = &templates.templates;
let tera_head = templates.render("rustdoc/head.html", &ctx).unwrap();
let tera_vendored_css = templates.render("rustdoc/vendored.html", &ctx).unwrap();
let tera_body = templates.render("rustdoc/body.html", &ctx).unwrap();
let tera_rustdoc_topbar = templates.render("rustdoc/topbar.html", &ctx).unwrap();
let head_html = Head::new(data).render().unwrap();
let vendored_html = Vendored::new(data).render().unwrap();
let body_html = Body::new(data).render().unwrap();
let topbar_html = Topbar::new(data).render().unwrap();

// Before: <body> ... rustdoc content ... </body>
// After:
Expand All @@ -46,12 +45,12 @@ pub(crate) fn rewrite_lol(
rustdoc_body_class.set_attribute("tabindex", "-1")?;
// Change the `body` to a `div`
rustdoc_body_class.set_tag_name("div")?;
// Prepend the tera content
rustdoc_body_class.prepend(&tera_body, ContentType::Html);
// Prepend the askama content
rustdoc_body_class.prepend(&body_html, ContentType::Html);
// Wrap the transformed body and topbar into a <body> element
rustdoc_body_class.before(r#"<body class="rustdoc-page">"#, ContentType::Html);
// Insert the topbar outside of the rustdoc div
rustdoc_body_class.before(&tera_rustdoc_topbar, ContentType::Html);
rustdoc_body_class.before(&topbar_html, ContentType::Html);
// Finalize body with </body>
rustdoc_body_class.after("</body>", ContentType::Html);

Expand All @@ -62,7 +61,7 @@ pub(crate) fn rewrite_lol(
element_content_handlers: vec![
// Append `style.css` stylesheet after all head elements.
element!("head", |head: &mut Element| {
head.append(&tera_head, ContentType::Html);
head.append(&head_html, ContentType::Html);
Ok(())
}),
element!("body", body_handler),
Expand All @@ -81,7 +80,7 @@ pub(crate) fn rewrite_lol(
element!(
"link[rel='stylesheet'][href*='rustdoc-']",
|rustdoc_css: &mut Element| {
rustdoc_css.before(&tera_vendored_css, ContentType::Html);
rustdoc_css.before(&vendored_html, ContentType::Html);
Ok(())
}
),
Expand Down
9 changes: 6 additions & 3 deletions src/web/build_details.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::{
AsyncStorage, Config,
};
use anyhow::Context as _;
use askama::Template;
use axum::{
extract::{Extension, Path},
response::IntoResponse,
Expand All @@ -27,16 +28,17 @@ pub(crate) struct BuildDetails {
output: String,
}

#[derive(Template)]
#[template(path = "crate/build_details.html")]
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
struct BuildDetailsPage {
metadata: MetaData,
build_details: BuildDetails,
use_direct_platform_links: bool,
csp_nonce: String,
}

impl_axum_webpage! {
BuildDetailsPage = "crate/build_details.html",
}
impl_axum_webpage! { BuildDetailsPage }

pub(crate) async fn build_details_handler(
Path((name, version, id)): Path<(String, String, String)>,
Expand Down Expand Up @@ -85,6 +87,7 @@ pub(crate) async fn build_details_handler(
output,
},
use_direct_platform_links: true,
csp_nonce: String::new(),
}
.into_response())
}
Expand Down
9 changes: 6 additions & 3 deletions src/web/builds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use axum::{
use chrono::{DateTime, Utc};
use serde::Serialize;
use std::sync::Arc;
use askama::Template;

#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
pub(crate) struct Build {
Expand All @@ -25,18 +26,19 @@ pub(crate) struct Build {
build_time: DateTime<Utc>,
}

#[derive(Template)]
#[template(path = "crate/builds.html")]
#[derive(Debug, Clone, Serialize)]
struct BuildsPage {
metadata: MetaData,
builds: Vec<Build>,
limits: Limits,
canonical_url: CanonicalUrl,
use_direct_platform_links: bool,
csp_nonce: String,
}

impl_axum_webpage! {
BuildsPage = "crate/builds.html",
}
impl_axum_webpage! { BuildsPage }

pub(crate) async fn build_list_handler(
Path((name, req_version)): Path<(String, String)>,
Expand Down Expand Up @@ -65,6 +67,7 @@ pub(crate) async fn build_list_handler(
limits: Limits::for_crate(&config, &mut conn, &name).await?,
canonical_url: CanonicalUrl::from_path(format!("/crate/{name}/latest/builds")),
use_direct_platform_links: true,
csp_nonce: String::new(),
}
.into_response())
}
Expand Down
21 changes: 17 additions & 4 deletions src/web/crate_details.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use crate::{
AsyncStorage,
};
use anyhow::{anyhow, Context, Result};
use askama::Template;
use axum::{
extract::{Extension, Path},
response::{IntoResponse, Response as AxumResponse},
Expand Down Expand Up @@ -369,13 +370,17 @@ pub(crate) async fn releases_for_crate(
Ok(releases)
}


#[derive(Template)]
#[template(path = "crate/details.html")]
#[derive(Debug, Clone, PartialEq, Serialize)]
struct CrateDetailsPage {
details: CrateDetails,
csp_nonce: String,
}

impl_axum_webpage! {
CrateDetailsPage = "crate/details.html",
CrateDetailsPage,
cpu_intensive_rendering = true,
}

Expand Down Expand Up @@ -425,7 +430,7 @@ pub(crate) async fn crate_details_handler(
Err(e) => warn!("error fetching readme: {:?}", &e),
}

let mut res = CrateDetailsPage { details }.into_response();
let mut res = CrateDetailsPage { details, csp_nonce: String::new() }.into_response();
res.extensions_mut()
.insert::<CachePolicy>(if is_latest_url {
CachePolicy::ForeverInCdn
Expand All @@ -435,16 +440,19 @@ pub(crate) async fn crate_details_handler(
Ok(res.into_response())
}

#[derive(Template)]
#[template(path = "rustdoc/releases.html")]
#[derive(Debug, Clone, PartialEq, Serialize)]
struct ReleaseList {
releases: Vec<Release>,
crate_name: String,
inner_path: String,
target: String,
csp_nonce: String,
}

impl_axum_webpage! {
ReleaseList = "rustdoc/releases.html",
ReleaseList,
cache_policy = |_| CachePolicy::ForeverInCdn,
cpu_intensive_rendering = true,
}
Expand Down Expand Up @@ -520,6 +528,7 @@ pub(crate) async fn get_all_releases(
target: target.to_string(),
inner_path,
crate_name: params.name,
csp_nonce: String::new(),
};
Ok(res.into_response())
}
Expand All @@ -531,16 +540,19 @@ struct ShortMetadata {
doc_targets: Vec<String>,
}

#[derive(Template)]
#[template(path = "rustdoc/platforms.html")]
#[derive(Debug, Clone, PartialEq, Serialize)]
struct PlatformList {
metadata: ShortMetadata,
inner_path: String,
use_direct_platform_links: bool,
current_target: String,
csp_nonce: String,
}

impl_axum_webpage! {
PlatformList = "rustdoc/platforms.html",
PlatformList,
cache_policy = |_| CachePolicy::ForeverInCdn,
cpu_intensive_rendering = true,
}
Expand Down Expand Up @@ -671,6 +683,7 @@ pub(crate) async fn get_all_platforms_inner(
inner_path,
use_direct_platform_links: is_crate_root,
current_target,
csp_nonce: String::new()
};
Ok(res.into_response())
}
Expand Down
8 changes: 8 additions & 0 deletions src/web/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ impl IntoResponse for AxumNope {
title: "The requested resource does not exist",
message: "no such resource".into(),
status: StatusCode::NOT_FOUND,
csp_nonce: String::new(),
}
.into_response()
}
Expand All @@ -50,6 +51,7 @@ impl IntoResponse for AxumNope {
title: "The requested build does not exist",
message: "no such build".into(),
status: StatusCode::NOT_FOUND,
csp_nonce: String::new(),
}
.into_response(),

Expand All @@ -60,6 +62,7 @@ impl IntoResponse for AxumNope {
title: "The requested crate does not exist",
message: "no such crate".into(),
status: StatusCode::NOT_FOUND,
csp_nonce: String::new(),
}
.into_response()
}
Expand All @@ -68,6 +71,7 @@ impl IntoResponse for AxumNope {
title: "The requested owner does not exist",
message: "no such owner".into(),
status: StatusCode::NOT_FOUND,
csp_nonce: String::new(),
}
.into_response(),

Expand All @@ -78,6 +82,7 @@ impl IntoResponse for AxumNope {
title: "The requested version does not exist",
message: "no such version for this crate".into(),
status: StatusCode::NOT_FOUND,
csp_nonce: String::new(),
}
.into_response()
}
Expand All @@ -94,6 +99,7 @@ impl IntoResponse for AxumNope {
title: "Bad request",
message: "Bad request".into(),
status: StatusCode::BAD_REQUEST,
csp_nonce: String::new(),
}
.into_response(),
AxumNope::InternalServerError => {
Expand All @@ -102,6 +108,7 @@ impl IntoResponse for AxumNope {
title: "Internal server error",
message: "internal server error".into(),
status: StatusCode::INTERNAL_SERVER_ERROR,
csp_nonce: String::new(),
}
.into_response()
}
Expand All @@ -110,6 +117,7 @@ impl IntoResponse for AxumNope {
title: "Internal Server Error",
message: Cow::Owned(source.to_string()),
status: StatusCode::INTERNAL_SERVER_ERROR,
csp_nonce: String::new(),
};

crate::utils::report_error(&source);
Expand Down
7 changes: 6 additions & 1 deletion src/web/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,15 @@ use crate::{
};
use anyhow::anyhow;
use axum::{extract::Path, response::IntoResponse};
use askama::Template;
use serde::Serialize;
use sqlx::Row as _;
use std::collections::{HashMap, VecDeque};

const DEFAULT_NAME: &str = "default";

#[derive(Template)]
#[template(path = "crate/features.html")]
#[derive(Debug, Clone, Serialize)]
struct FeaturesPage {
metadata: MetaData,
Expand All @@ -23,10 +26,11 @@ struct FeaturesPage {
canonical_url: CanonicalUrl,
is_latest_url: bool,
use_direct_platform_links: bool,
csp_nonce: String,
}

impl_axum_webpage! {
FeaturesPage = "crate/features.html",
FeaturesPage,
cache_policy = |page| if page.is_latest_url {
CachePolicy::ForeverInCdn
} else {
Expand Down Expand Up @@ -84,6 +88,7 @@ pub(crate) async fn build_features_handler(
is_latest_url,
canonical_url: CanonicalUrl::from_path(format!("/crate/{}/latest/features", &name)),
use_direct_platform_links: true,
csp_nonce: String::new(),
}
.into_response())
}
Expand Down
2 changes: 1 addition & 1 deletion src/web/highlight.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ pub fn with_lang(lang: Option<&str>, code: &str) -> String {
} else {
log::error!("failed while highlighting code: {err:?}");
}
tera::escape_html(code)
crate::web::page::templates::filters::escape_html(code).map(|s| s.to_string()).unwrap_or_default()
}
}
}
Expand Down
8 changes: 6 additions & 2 deletions src/web/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pub mod page;
use crate::utils::get_correct_docsrs_style_file;
use crate::utils::report_error;
use anyhow::{anyhow, bail, Context as _, Result};
use askama::Template;
use axum_extra::middleware::option_layer;
use serde_json::Value;
use tracing::{info, instrument};
Expand All @@ -24,7 +25,7 @@ mod markdown;
pub(crate) mod metrics;
mod releases;
mod routes;
mod rustdoc;
pub(crate) mod rustdoc;
mod sitemap;
mod source;
mod statics;
Expand Down Expand Up @@ -558,6 +559,8 @@ impl MetaData {
}
}

#[derive(Template)]
#[template(path = "error.html")]
#[derive(Debug, Clone, PartialEq, Serialize)]
pub(crate) struct AxumErrorPage {
/// The title of the page
Expand All @@ -566,10 +569,11 @@ pub(crate) struct AxumErrorPage {
pub message: Cow<'static, str>,
#[serde(skip)]
pub status: StatusCode,
pub csp_nonce: String,
}

impl_axum_webpage! {
AxumErrorPage = "error.html",
AxumErrorPage,
status = |err| err.status,
}

Expand Down
Loading

0 comments on commit d1db306

Please sign in to comment.