You've already forked authentication-service
mirror of
https://github.com/matrix-org/matrix-authentication-service.git
synced 2025-08-09 04:22:45 +03:00
templates: fix the _ function not working in macros
This commit is contained in:
@@ -15,8 +15,9 @@
|
|||||||
use axum::{
|
use axum::{
|
||||||
http::StatusCode,
|
http::StatusCode,
|
||||||
response::{IntoResponse, Response},
|
response::{IntoResponse, Response},
|
||||||
Extension,
|
Extension, TypedHeader,
|
||||||
};
|
};
|
||||||
|
use headers::ContentType;
|
||||||
use mas_templates::ErrorContext;
|
use mas_templates::ErrorContext;
|
||||||
|
|
||||||
use crate::sentry::SentryEventID;
|
use crate::sentry::SentryEventID;
|
||||||
@@ -60,10 +61,11 @@ impl<E: std::fmt::Debug + std::fmt::Display> From<E> for FancyError {
|
|||||||
|
|
||||||
impl IntoResponse for FancyError {
|
impl IntoResponse for FancyError {
|
||||||
fn into_response(self) -> Response {
|
fn into_response(self) -> Response {
|
||||||
let error = format!("{:?}", self.context);
|
let error = format!("{}", self.context);
|
||||||
let event_id = sentry::capture_message(&error, sentry::Level::Error);
|
let event_id = sentry::capture_message(&error, sentry::Level::Error);
|
||||||
(
|
(
|
||||||
StatusCode::INTERNAL_SERVER_ERROR,
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
TypedHeader(ContentType::text()),
|
||||||
SentryEventID::from(event_id),
|
SentryEventID::from(event_id),
|
||||||
Extension(self.context),
|
Extension(self.context),
|
||||||
error,
|
error,
|
||||||
|
@@ -14,6 +14,8 @@
|
|||||||
|
|
||||||
//! Contexts used in templates
|
//! Contexts used in templates
|
||||||
|
|
||||||
|
use std::fmt::Formatter;
|
||||||
|
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use http::{Method, Uri, Version};
|
use http::{Method, Uri, Version};
|
||||||
use mas_data_model::{
|
use mas_data_model::{
|
||||||
@@ -984,6 +986,23 @@ pub struct ErrorContext {
|
|||||||
details: Option<String>,
|
details: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for ErrorContext {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
if let Some(code) = &self.code {
|
||||||
|
writeln!(f, "code: {code}")?;
|
||||||
|
}
|
||||||
|
if let Some(description) = &self.description {
|
||||||
|
writeln!(f, "{description}")?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(details) = &self.details {
|
||||||
|
writeln!(f, "details: {details}")?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl TemplateContext for ErrorContext {
|
impl TemplateContext for ErrorContext {
|
||||||
fn sample(_now: chrono::DateTime<Utc>, _rng: &mut impl Rng) -> Vec<Self>
|
fn sample(_now: chrono::DateTime<Utc>, _rng: &mut impl Rng) -> Vec<Self>
|
||||||
where
|
where
|
||||||
|
@@ -56,7 +56,10 @@ pub fn register(
|
|||||||
vite_manifest,
|
vite_manifest,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
env.add_global("_", Value::from_object(Translate { translator }));
|
env.add_global(
|
||||||
|
"translator",
|
||||||
|
Value::from_object(TranslatorFunc { translator }),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tester_empty(seq: &dyn SeqObject) -> bool {
|
fn tester_empty(seq: &dyn SeqObject) -> bool {
|
||||||
@@ -189,52 +192,73 @@ fn function_add_params_to_url(
|
|||||||
Ok(uri.to_string())
|
Ok(uri.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Translate {
|
struct TranslatorFunc {
|
||||||
translator: Arc<Translator>,
|
translator: Arc<Translator>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Debug for Translate {
|
impl std::fmt::Debug for TranslatorFunc {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
f.debug_struct("Translate")
|
f.debug_struct("TranslatorFunc")
|
||||||
.field("translations", &"..")
|
.field("translator", &"..")
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Display for Translate {
|
impl std::fmt::Display for TranslatorFunc {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.write_str("translator")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Object for TranslatorFunc {
|
||||||
|
fn call(&self, _state: &State, args: &[Value]) -> Result<Value, Error> {
|
||||||
|
let (lang,): (&str,) = from_args(args)?;
|
||||||
|
|
||||||
|
let lang: DataLocale = lang.parse().map_err(|e| {
|
||||||
|
Error::new(ErrorKind::InvalidOperation, "Invalid language").with_source(e)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Ok(Value::from_object(TranslateFunc {
|
||||||
|
lang,
|
||||||
|
translator: Arc::clone(&self.translator),
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TranslateFunc {
|
||||||
|
translator: Arc<Translator>,
|
||||||
|
lang: DataLocale,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Debug for TranslateFunc {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.debug_struct("Translate")
|
||||||
|
.field("translator", &"..")
|
||||||
|
.field("lang", &self.lang)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for TranslateFunc {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
f.write_str("translate")
|
f.write_str("translate")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Object for Translate {
|
impl Object for TranslateFunc {
|
||||||
fn call(&self, state: &State, args: &[Value]) -> Result<Value, Error> {
|
fn call(&self, state: &State, args: &[Value]) -> Result<Value, Error> {
|
||||||
let lang = state.lookup("lang").ok_or(minijinja::Error::new(
|
|
||||||
ErrorKind::UndefinedError,
|
|
||||||
"`lang` is not set",
|
|
||||||
))?;
|
|
||||||
|
|
||||||
let lang = lang.as_str().ok_or(minijinja::Error::new(
|
|
||||||
ErrorKind::InvalidOperation,
|
|
||||||
"`lang` is not a string",
|
|
||||||
))?;
|
|
||||||
|
|
||||||
let lang: DataLocale = lang.parse().map_err(|e| {
|
|
||||||
Error::new(ErrorKind::InvalidOperation, "Could not parse `lang`").with_source(e)
|
|
||||||
})?;
|
|
||||||
|
|
||||||
let (key, kwargs): (&str, Kwargs) = from_args(args)?;
|
let (key, kwargs): (&str, Kwargs) = from_args(args)?;
|
||||||
|
|
||||||
let (message, _locale) = if let Some(count) = kwargs.get("count")? {
|
let (message, _locale) = if let Some(count) = kwargs.get("count")? {
|
||||||
self.translator
|
self.translator
|
||||||
.plural_with_fallback(lang, key, count)
|
.plural_with_fallback(self.lang.clone(), key, count)
|
||||||
.ok_or(Error::new(
|
.ok_or(Error::new(
|
||||||
ErrorKind::InvalidOperation,
|
ErrorKind::InvalidOperation,
|
||||||
"Missing translation",
|
"Missing translation",
|
||||||
))?
|
))?
|
||||||
} else {
|
} else {
|
||||||
self.translator
|
self.translator
|
||||||
.message_with_fallback(lang, key)
|
.message_with_fallback(self.lang.clone(), key)
|
||||||
.ok_or(Error::new(
|
.ok_or(Error::new(
|
||||||
ErrorKind::InvalidOperation,
|
ErrorKind::InvalidOperation,
|
||||||
"Missing translation",
|
"Missing translation",
|
||||||
|
@@ -15,6 +15,7 @@ limitations under the License.
|
|||||||
#}
|
#}
|
||||||
|
|
||||||
{# Must be kept in sync with frontend/index.html #}
|
{# Must be kept in sync with frontend/index.html #}
|
||||||
|
{% set _ = translator(lang) %}
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
@@ -14,6 +14,8 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
#}
|
#}
|
||||||
|
|
||||||
|
{% set _ = translator(lang) %}
|
||||||
|
|
||||||
{% import "components/button.html" as button %}
|
{% import "components/button.html" as button %}
|
||||||
{% import "components/field.html" as field %}
|
{% import "components/field.html" as field %}
|
||||||
{% import "components/back_to_client.html" as back_to_client %}
|
{% import "components/back_to_client.html" as back_to_client %}
|
||||||
|
Reference in New Issue
Block a user