From 8220c5020be4da1ab89e4a1b5be1f3d271bfb273 Mon Sep 17 00:00:00 2001
From: Guillaume Gomez
Date: Tue, 23 Dec 2025 22:07:03 +0100
Subject: [PATCH] Update to new `askama` 0.15 version
---
Cargo.lock | 26 +++++++++++++++-------
Cargo.toml | 2 +-
src/web/highlight.rs | 2 +-
src/web/page/templates.rs | 28 ++++++++++++++----------
templates/core/about/builds.html | 2 +-
templates/core/home.html | 2 +-
templates/crate/build_details.html | 4 ++--
templates/crate/builds.html | 6 +++---
templates/crate/details.html | 8 +++----
templates/crate/features.html | 4 ++--
templates/crate/source.html | 8 +++----
templates/header/topbar_end.html | 30 +++++++++++++-------------
templates/macros.html | 8 +++----
templates/releases/activity.html | 2 +-
templates/releases/build_queue.html | 2 +-
templates/releases/feed.xml | 2 +-
templates/releases/releases.html | 6 +++---
templates/releases/search_results.html | 2 +-
templates/rustdoc/head.html | 24 ++++++++++-----------
templates/rustdoc/platforms.html | 4 ++--
templates/rustdoc/releases.html | 2 +-
templates/rustdoc/topbar.html | 6 +++---
22 files changed, 98 insertions(+), 82 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
index 56b66055c..b029d4e77 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -317,11 +317,11 @@ dependencies = [
[[package]]
name = "askama"
-version = "0.14.0"
+version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f75363874b771be265f4ffe307ca705ef6f3baa19011c149da8674a87f1b75c4"
+checksum = "21c01049339e624573a8027fe9392219f64d315a0ad24712b469611b3138f042"
dependencies = [
- "askama_derive",
+ "askama_macros",
"itoa 1.0.16",
"percent-encoding",
"serde",
@@ -330,9 +330,9 @@ dependencies = [
[[package]]
name = "askama_derive"
-version = "0.14.0"
+version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "129397200fe83088e8a68407a8e2b1f826cf0086b21ccdb866a722c8bcd3a94f"
+checksum = "e393a25182a000666df345c2bdaa9ab6b0c243974ec7d29e377d6feea651778d"
dependencies = [
"askama_parser",
"basic-toml",
@@ -345,15 +345,25 @@ dependencies = [
"syn 2.0.111",
]
+[[package]]
+name = "askama_macros"
+version = "0.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4e8bb77385d2954705452516f99511835be34b4c4a15a70800623b91406b1db9"
+dependencies = [
+ "askama_derive",
+]
+
[[package]]
name = "askama_parser"
-version = "0.14.0"
+version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d6ab5630b3d5eaf232620167977f95eb51f3432fc76852328774afbd242d4358"
+checksum = "fb6401aa356822013db13e8f756011cd5042e7e61d37456bb8b7ef26feb8ebca"
dependencies = [
- "memchr",
+ "rustc-hash",
"serde",
"serde_derive",
+ "unicode-ident",
"winnow",
]
diff --git a/Cargo.toml b/Cargo.toml
index d2c3c2736..28218a6d0 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -22,7 +22,7 @@ exclude = [
[workspace.dependencies]
anyhow = { version = "1.0.42", features = ["backtrace"]}
-askama = "0.14.0"
+askama = "0.15.0"
async-stream = "0.3.5"
axum-extra = { version = "0.12.0", features = ["typed-header", "routing", "middleware"] }
bincode = "~2" # bincode is unmaintained, and 3.0 is just a breaking notification
diff --git a/src/web/highlight.rs b/src/web/highlight.rs
index 0c6bb9a10..7900b6b81 100644
--- a/src/web/highlight.rs
+++ b/src/web/highlight.rs
@@ -82,7 +82,7 @@ pub fn with_lang(lang: Option<&str>, code: &str, default: Option<&str>) -> Strin
} else {
log::error!("failed while highlighting code: {err:?}");
}
- crate::web::page::templates::filters::escape_html(code, &())
+ crate::web::page::templates::filters::escape_html_inner(code)
.map(|s| s.to_string())
.unwrap_or_default()
}
diff --git a/src/web/page/templates.rs b/src/web/page/templates.rs
index 77593a8f7..729bfc485 100644
--- a/src/web/page/templates.rs
+++ b/src/web/page/templates.rs
@@ -94,9 +94,9 @@ pub mod filters {
use askama::filters::Safe;
use chrono::{DateTime, Utc};
use std::borrow::Cow;
+ use std::fmt::Display;
- // Copied from `tera`.
- pub fn escape_html<'a>(input: &'a str, _: &dyn Values) -> askama::Result> {
+ pub fn escape_html_inner(input: &str) -> askama::Result {
if !input.chars().any(|c| "&<>\"'/".contains(c)) {
return Ok(Cow::Borrowed(input));
}
@@ -118,7 +118,14 @@ pub mod filters {
}
// Copied from `tera`.
- pub fn escape_xml<'a>(input: &'a str, _: &dyn Values) -> askama::Result> {
+ #[askama::filter_fn]
+ pub fn escape_html(input: &str, _: &dyn Values) -> askama::Result {
+ escape_html_inner(input)
+ }
+
+ // Copied from `tera`.
+ #[askama::filter_fn]
+ pub fn escape_xml(input: &str, _: &dyn Values) -> askama::Result {
if !input.chars().any(|c| "&<>\"'".contains(c)) {
return Ok(Cow::Borrowed(input));
}
@@ -138,15 +145,18 @@ pub mod filters {
/// Prettily format a timestamp
// TODO: This can be replaced by chrono
+ #[askama::filter_fn]
pub fn timeformat(value: &DateTime, _: &dyn Values) -> askama::Result {
Ok(crate::web::duration_to_str(*value))
}
+ #[askama::filter_fn]
pub fn format_secs(mut value: f32, _: &dyn Values) -> askama::Result {
const TIMES: &[&str] = &["seconds", "minutes", "hours"];
let mut chosen_time = &TIMES[0];
+ let mut value = value;
for time in &TIMES[1..] {
if value / 60.0 >= 1.0 {
chosen_time = time;
@@ -167,6 +177,7 @@ pub mod filters {
/// Dedent a string by removing all leading whitespace
#[allow(clippy::unnecessary_wraps)]
+ #[askama::filter_fn]
pub fn dedent>>(
value: T,
_: &dyn Values,
@@ -204,6 +215,7 @@ pub mod filters {
Ok(unindented)
}
+ #[askama::filter_fn]
pub fn highlight(
code: impl std::fmt::Display,
_: &dyn Values,
@@ -214,6 +226,7 @@ pub mod filters {
Ok(Safe(format!("{highlighted_code} ")))
}
+ #[askama::filter_fn]
pub fn round(value: &f32, _: &dyn Values, precision: u32) -> askama::Result {
let multiplier = if precision == 0 {
1.0
@@ -223,14 +236,7 @@ pub mod filters {
Ok(((multiplier * *value).round() / multiplier).to_string())
}
- pub fn split_first<'a>(
- value: &'a str,
- _: &dyn Values,
- pat: &str,
- ) -> askama::Result> {
- Ok(value.split(pat).next())
- }
-
+ #[askama::filter_fn]
pub fn json_encode(
value: &T,
_: &dyn Values,
diff --git a/templates/core/about/builds.html b/templates/core/about/builds.html
index 543259ba3..0c483b1fb 100644
--- a/templates/core/about/builds.html
+++ b/templates/core/about/builds.html
@@ -104,7 +104,7 @@
- {% call macros::crate_limits(limits=limits) %}
+ {% call macros::crate_limits(limits=limits) %}{% endcall %}
If your build fails because it hit one of these limits, please
diff --git a/templates/core/home.html b/templates/core/home.html
index 3af8f54a9..5ddc6dae9 100644
--- a/templates/core/home.html
+++ b/templates/core/home.html
@@ -43,7 +43,7 @@
{{ crate::icons::IconCubes.render_solid(false, false, "") }} D
{%- for release in recent_releases -%}
{%- set release_params = release.rustdoc_params() -%}
- {% set release_url %}
+ {% decl release_url %}
{%- if release.rustdoc_status -%}
{%- set release_url = release_params.rustdoc_url() -%}
{%- else -%}
diff --git a/templates/crate/build_details.html b/templates/crate/build_details.html
index bfbc1caf8..581dd11d5 100644
--- a/templates/crate/build_details.html
+++ b/templates/crate/build_details.html
@@ -2,7 +2,7 @@
{%- import "header/package_navigation.html" as navigation -%}
{%- block title -%}
- {% call macros::doc_title(name=metadata.name, version=metadata.version) %}
+ {% call macros::doc_title(name=metadata.name, version=metadata.version) %}{% endcall %}
{%- endblock title -%}
{%- block body_classes -%}
@@ -14,7 +14,7 @@
{%- endblock topbar -%}
{%- block header -%}
- {% call navigation::package_navigation(metadata=metadata, active_tab="builds") %}
+ {% call navigation::package_navigation(metadata=metadata, active_tab="builds") %}{% endcall %}
{%- endblock header -%}
{%- block body -%}
diff --git a/templates/crate/builds.html b/templates/crate/builds.html
index f131c13c2..27647c079 100644
--- a/templates/crate/builds.html
+++ b/templates/crate/builds.html
@@ -2,7 +2,7 @@
{%- import "header/package_navigation.html" as navigation -%}
{%- block title -%}
- {% call macros::doc_title(name=metadata.name, version=metadata.version) %}
+ {% call macros::doc_title(name=metadata.name, version=metadata.version) %}{% endcall %}
{%- endblock title -%}
{%- block meta -%}
@@ -18,7 +18,7 @@
{%- endblock topbar -%}
{%- block header -%}
- {% call navigation::package_navigation(metadata=metadata, active_tab="builds") %}
+ {% call navigation::package_navigation(metadata=metadata, active_tab="builds") %}{% endcall %}
{%- endblock header -%}
{%- block body -%}
@@ -100,7 +100,7 @@ {{ metadata.name }}'s sandbox limits
resources. The limits for this crate are the following:
- {% call macros::crate_limits(limits=limits) %}
+ {% call macros::crate_limits(limits=limits) %}{% endcall %}
If a build fails because it hit one of those limits please
diff --git a/templates/crate/details.html b/templates/crate/details.html
index 1efbdf5e8..25e6f152c 100644
--- a/templates/crate/details.html
+++ b/templates/crate/details.html
@@ -2,7 +2,7 @@
{%- import "header/package_navigation.html" as navigation -%}
{%- block title -%}
- {% call macros::doc_title(name=name, version=version) %}
+ {% call macros::doc_title(name=name, version=version) %}{% endcall %}
{%- endblock title -%}
{%- block meta -%}
@@ -15,7 +15,7 @@
{%- block header -%}
{# Set the active tab to the `crate` tab #}
- {% call navigation::package_navigation(metadata=metadata, active_tab="crate") %}
+ {% call navigation::package_navigation(metadata=metadata, active_tab="crate") %}{% endcall %}
{%- endblock header -%}
{%- block body -%}
@@ -112,7 +112,7 @@
@@ -122,7 +122,7 @@
diff --git a/templates/crate/features.html b/templates/crate/features.html
index 8f0c8cc56..19f1334cf 100644
--- a/templates/crate/features.html
+++ b/templates/crate/features.html
@@ -2,7 +2,7 @@
{%- import "header/package_navigation.html" as navigation -%}
{%- block title -%}
- {% call macros::doc_title(name=metadata.name, version=metadata.version) %}
+ {% call macros::doc_title(name=metadata.name, version=metadata.version) %}{% endcall %}
{%- endblock title -%}
{%- block meta -%}
@@ -14,7 +14,7 @@
{%- endblock topbar -%}
{%- block header -%}
- {% call navigation::package_navigation(metadata=metadata, active_tab="features") %}
+ {% call navigation::package_navigation(metadata=metadata, active_tab="features") %}{% endcall %}
{%- endblock header -%}
{%- block body -%}
diff --git a/templates/crate/source.html b/templates/crate/source.html
index 3e1670bfe..70d59d0c0 100644
--- a/templates/crate/source.html
+++ b/templates/crate/source.html
@@ -2,7 +2,7 @@
{%- import "header/package_navigation.html" as navigation -%}
{%- block title -%}
- {% call macros::doc_title(name=metadata.name, version=metadata.version) %}
+ {% call macros::doc_title(name=metadata.name, version=metadata.version) %}{% endcall %}
{%- endblock title -%}
{%- block topbar -%}
@@ -11,7 +11,7 @@
{%- block header -%}
{# Set the active tab to the `source` tab #}
- {% call navigation::package_navigation(metadata=metadata, active_tab="source") %}
+ {% call navigation::package_navigation(metadata=metadata, active_tab="source") %}{% endcall %}
{%- endblock header -%}
{%- block body_classes -%}
@@ -84,7 +84,7 @@
#}
{# Text files or files which mime starts with `text` #}
- {%- elif file.mime == "text/plain" || file.mime|split_first("/") == Some("text") -%}
+ {%- elif file.mime == "text/plain" || file.mime.split('/').next() == Some("text") -%}
{{ crate::icons::IconFileLines.render_regular(false, false, "") }}
{# Binary files and any unrecognized types #}
@@ -113,7 +113,7 @@
{# If the file has content, then display it in a codeblock #}
{%- if let Some(file_content) = file_content -%}
- {% set file_name %}
+ {% decl file_name %}
{% if let Some(file) = file %}
{% set file_name = file.name.as_str() %}
{% else %}
diff --git a/templates/header/topbar_end.html b/templates/header/topbar_end.html
index 3dc5c1185..6be3a52b5 100644
--- a/templates/header/topbar_end.html
+++ b/templates/header/topbar_end.html
@@ -14,48 +14,48 @@
href="/about",
text="About docs.rs",
icon=crate::icons::IconCircleInfo,
- ) -%}
+ ) -%}{% endcall %}
{%- call macros::menu_link_with_icon_brand(
href="/about/badges",
text="Badges",
icon=crate::icons::IconFonticons,
- ) -%}
+ ) -%}{% endcall %}
{%- call macros::menu_link_with_icon_solid(
href="/about/builds",
text="Builds",
icon=crate::icons::IconGears,
- ) -%}
+ ) -%}{% endcall %}
{%- call macros::menu_link_with_icon_solid(
href="/about/metadata",
text="Metadata",
icon=crate::icons::IconTable,
- ) -%}
+ ) -%}{% endcall %}
{%- call macros::menu_link_with_icon_solid(
href="/about/redirections",
text="Shorthand URLs",
icon=crate::icons::IconRoad,
- ) -%}
+ ) -%}{% endcall %}
{%- call macros::menu_link_with_icon_solid(
href="/about/download",
text="Download",
icon=crate::icons::IconDownload,
- ) -%}
+ ) -%}{% endcall %}
{%- call macros::menu_link_with_icon_solid(
href="/about/rustdoc-json",
text="Rustdoc JSON",
icon=crate::icons::IconFileCode,
- ) -%}
+ ) -%}{% endcall %}
{%- call macros::menu_link_with_icon_solid(
href="/releases/queue",
text="Build queue",
icon=crate::icons::IconGears,
- ) -%}
+ ) -%}{% endcall %}
{%- call macros::menu_link_with_icon_solid(
href="https://foundation.rust-lang.org/policies/privacy-policy/#docs.rs",
text="Privacy policy",
icon=crate::icons::IconShieldHalved,
target="_blank",
- ) -%}
+ ) -%}{% endcall %}
@@ -68,36 +68,36 @@
href="https://www.rust-lang.org/",
text="Rust website",
target="_blank"
- ) %}
+ ) %}{% endcall %}
{% call macros::menu_link(
href="https://doc.rust-lang.org/book/",
text="The Book",
target="_blank"
- ) %}
+ ) %}{% endcall %}
{% call macros::menu_link(
href="https://doc.rust-lang.org/std/",
text="Standard Library API Reference",
target="_blank"
- ) %}
+ ) %}{% endcall %}
{% call macros::menu_link(
href="https://doc.rust-lang.org/rust-by-example/",
text="Rust by Example",
target="_blank"
- ) %}
+ ) %}{% endcall %}
{% call macros::menu_link(
href="https://doc.rust-lang.org/cargo/guide/",
text="The Cargo Guide",
target="_blank"
- ) %}
+ ) %}{% endcall %}
{% call macros::menu_link(
href="https://doc.rust-lang.org/nightly/clippy",
text="Clippy Documentation",
target="_blank"
- ) %}
+ ) %}{% endcall %}
diff --git a/templates/macros.html b/templates/macros.html
index 975f527d3..c6d3d10e3 100644
--- a/templates/macros.html
+++ b/templates/macros.html
@@ -96,7 +96,7 @@
{%- set release_params = params.clone().with_req_version(release.version.clone()) -%}
{# The url for the release, `/crate/:name/:version` #}
- {% set release_url %}
+ {% decl release_url %}
{% if use_target_redirect %}
{%- set release_url = release_params.target_redirect_url() -%}
{% else %} {# /crate #}
@@ -104,8 +104,8 @@
{% endif %}
{# The release's name and version, `:name-:version` #}
{%- set release_name = "{}-{}"|format(params.name(), release.version) -%}
- {%- set warning -%}
- {%- set title -%}
+ {%- decl warning -%}
+ {%- decl title -%}
{%- set yanked = release.yanked.unwrap_or_default() -%}
{%- if !release.is_library.unwrap_or_default() -%}
@@ -160,7 +160,7 @@
{%- for dep in dependencies -%}