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 Mar 11, 2024
1 parent a82561c commit 3754294
Show file tree
Hide file tree
Showing 51 changed files with 882 additions and 989 deletions.
312 changes: 73 additions & 239 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 @@ -101,7 +101,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::{Body, Head, Topbar, Vendored};
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, response::IntoResponse};
use chrono::{DateTime, Utc};
use futures_util::TryStreamExt;
Expand All @@ -26,18 +27,19 @@ 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,
all_log_filenames: Vec<String>,
current_filename: Option<String>,
csp_nonce: String,
}

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

#[derive(Clone, Deserialize, Debug)]
pub(crate) struct BuildDetailsParams {
Expand Down Expand Up @@ -115,6 +117,7 @@ pub(crate) async fn build_details_handler(
use_direct_platform_links: true,
all_log_filenames,
current_filename,
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 @@ -10,6 +10,7 @@ use crate::{
Config,
};
use anyhow::Result;
use askama::Template;
use axum::{
extract::Extension, http::header::ACCESS_CONTROL_ALLOW_ORIGIN, response::IntoResponse, Json,
};
Expand All @@ -27,18 +28,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, ReqVersion)>,
Expand All @@ -62,6 +64,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
25 changes: 21 additions & 4 deletions src/web/crate_details.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ use crate::{
encode_url_path,
error::{AxumNope, AxumResult},
extractors::{DbConnection, Path},
page::templates::filters,
MatchedRelease, ReqVersion,
},
AsyncStorage,
};
use anyhow::{anyhow, Context, Result};
use askama::Template;
use axum::{
extract::Extension,
response::{IntoResponse, Response as AxumResponse},
Expand Down Expand Up @@ -383,13 +385,16 @@ 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 @@ -429,7 +434,11 @@ 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 req_version.is_latest() {
CachePolicy::ForeverInCdn
Expand All @@ -439,16 +448,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 @@ -513,6 +525,7 @@ pub(crate) async fn get_all_releases(
target,
inner_path,
crate_name: params.name,
csp_nonce: String::new(),
};
Ok(res.into_response())
}
Expand All @@ -525,16 +538,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 @@ -635,6 +651,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
7 changes: 7 additions & 0 deletions src/web/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,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 @@ -49,6 +50,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 @@ -59,6 +61,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 @@ -67,6 +70,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 @@ -77,6 +81,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 @@ -93,13 +98,15 @@ impl IntoResponse for AxumNope {
title: "Bad request",
message: Cow::Owned(source.to_string()),
status: StatusCode::BAD_REQUEST,
csp_nonce: String::new(),
}
.into_response(),
AxumNope::InternalError(source) => {
let web_error = crate::web::AxumErrorPage {
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 @@ -10,12 +10,15 @@ use crate::{
},
};
use anyhow::anyhow;
use askama::Template;
use axum::response::IntoResponse;
use serde::Serialize;
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 @@ -24,10 +27,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 @@ -82,6 +86,7 @@ pub(crate) async fn build_features_handler(
is_latest_url: req_version.is_latest(),
canonical_url: CanonicalUrl::from_path(format!("/crate/{}/latest/features", &name)),
use_direct_platform_links: true,
csp_nonce: String::new(),
}
.into_response())
}
Expand Down
4 changes: 3 additions & 1 deletion src/web/highlight.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,9 @@ 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
Loading

0 comments on commit 3754294

Please sign in to comment.