mirror of
https://git.joinplu.me/Plume/Plume.git
synced 2024-11-22 19:41:03 +00:00
Replace the input! macro with an Input builder (#646)
* Replace the input! macro with an Input builder * Use a BTreeMap instead of an HashMap Followinf @fdb-hiroshima's advice * Rename Input::to_html to Input::html To make clippy happy * Wrap error messages in red paragraphs
This commit is contained in:
parent
935d331e97
commit
8ab690001d
14 changed files with 297 additions and 146 deletions
|
@ -5,7 +5,7 @@ use rocket::http::{Method, Status};
|
||||||
use rocket::request::Request;
|
use rocket::request::Request;
|
||||||
use rocket::response::{self, content::Html as HtmlCt, Responder, Response};
|
use rocket::response::{self, content::Html as HtmlCt, Responder, Response};
|
||||||
use rocket_i18n::Catalog;
|
use rocket_i18n::Catalog;
|
||||||
use std::collections::hash_map::DefaultHasher;
|
use std::collections::{btree_map::BTreeMap, hash_map::DefaultHasher};
|
||||||
use std::hash::Hasher;
|
use std::hash::Hasher;
|
||||||
use templates::Html;
|
use templates::Html;
|
||||||
|
|
||||||
|
@ -231,11 +231,108 @@ macro_rules! icon {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! input {
|
/// A builder type to generate `<input>` tags in a type-safe way.
|
||||||
($catalog:expr, $name:tt ($kind:tt), $label:expr, $optional:expr, $details:expr, $form:expr, $err:expr, $props:expr) => {{
|
///
|
||||||
use std::borrow::Cow;
|
/// # Example
|
||||||
use validator::ValidationErrorsKind;
|
///
|
||||||
let cat = $catalog;
|
/// This example uses all options, but you don't have to specify everything.
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # let current_email = "foo@bar.baz";
|
||||||
|
/// # let catalog = gettext::Catalog::parse("").unwrap();
|
||||||
|
/// Input::new("mail", "Your email address")
|
||||||
|
/// .input_type("email")
|
||||||
|
/// .default(current_email)
|
||||||
|
/// .optional()
|
||||||
|
/// .details("We won't use it for advertising.")
|
||||||
|
/// .set_prop("class", "email-input")
|
||||||
|
/// .to_html(catalog);
|
||||||
|
/// ```
|
||||||
|
pub struct Input {
|
||||||
|
/// The name of the input (`name` and `id` in HTML).
|
||||||
|
name: String,
|
||||||
|
/// The description of this field.
|
||||||
|
label: String,
|
||||||
|
/// The `type` of the input (`text`, `email`, `password`, etc).
|
||||||
|
input_type: String,
|
||||||
|
/// The default value for this input field.
|
||||||
|
default: Option<String>,
|
||||||
|
/// `true` if this field is not required (will add a little badge next to the label).
|
||||||
|
optional: bool,
|
||||||
|
/// A small message to display next to the label.
|
||||||
|
details: Option<String>,
|
||||||
|
/// Additional HTML properties.
|
||||||
|
props: BTreeMap<String, String>,
|
||||||
|
/// The error message to show next to this field.
|
||||||
|
error: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Input {
|
||||||
|
/// Creates a new input with a given name.
|
||||||
|
pub fn new(name: impl ToString, label: impl ToString) -> Input {
|
||||||
|
Input {
|
||||||
|
name: name.to_string(),
|
||||||
|
label: label.to_string(),
|
||||||
|
input_type: "text".into(),
|
||||||
|
default: None,
|
||||||
|
optional: false,
|
||||||
|
details: None,
|
||||||
|
props: BTreeMap::new(),
|
||||||
|
error: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the `type` of this input.
|
||||||
|
pub fn input_type(mut self, t: impl ToString) -> Input {
|
||||||
|
self.input_type = t.to_string();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Marks this field as optional.
|
||||||
|
pub fn optional(mut self) -> Input {
|
||||||
|
self.optional = true;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Fills the input with a default value (useful for edition form, to show the current values).
|
||||||
|
pub fn default(mut self, val: impl ToString) -> Input {
|
||||||
|
self.default = Some(val.to_string());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Adds additional information next to the label.
|
||||||
|
pub fn details(mut self, text: impl ToString) -> Input {
|
||||||
|
self.details = Some(text.to_string());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Defines an additional HTML property.
|
||||||
|
///
|
||||||
|
/// This method can be called multiple times for the same input.
|
||||||
|
pub fn set_prop(mut self, key: impl ToString, val: impl ToString) -> Input {
|
||||||
|
self.props.insert(key.to_string(), val.to_string());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Shows an error message
|
||||||
|
pub fn error(mut self, errs: &validator::ValidationErrors) -> Input {
|
||||||
|
if let Some(field_errs) = errs.clone().field_errors().get(self.name.as_str()) {
|
||||||
|
self.error = Some(
|
||||||
|
field_errs[0]
|
||||||
|
.message
|
||||||
|
.clone()
|
||||||
|
.unwrap_or_default()
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the HTML markup for this field.
|
||||||
|
pub fn html(mut self, cat: &Catalog) -> Html<String> {
|
||||||
|
if !self.optional {
|
||||||
|
self = self.set_prop("required", true);
|
||||||
|
}
|
||||||
|
|
||||||
Html(format!(
|
Html(format!(
|
||||||
r#"
|
r#"
|
||||||
|
@ -247,98 +344,30 @@ macro_rules! input {
|
||||||
{error}
|
{error}
|
||||||
<input type="{kind}" id="{name}" name="{name}" value="{val}" {props} dir="auto"/>
|
<input type="{kind}" id="{name}" name="{name}" value="{val}" {props} dir="auto"/>
|
||||||
"#,
|
"#,
|
||||||
name = stringify!($name),
|
name = self.name,
|
||||||
label = i18n!(cat, $label),
|
label = self.label,
|
||||||
kind = stringify!($kind),
|
kind = self.input_type,
|
||||||
optional = if $optional {
|
optional = if self.optional {
|
||||||
format!("<small>{}</small>", i18n!(cat, "Optional"))
|
format!("<small>{}</small>", i18n!(cat, "Optional"))
|
||||||
} else {
|
} else {
|
||||||
String::new()
|
String::new()
|
||||||
},
|
},
|
||||||
details = if $details.len() > 0 {
|
details = self
|
||||||
format!("<small>{}</small>", i18n!(cat, $details))
|
.details
|
||||||
} else {
|
.map(|d| format!("<small>{}</small>", d))
|
||||||
String::new()
|
.unwrap_or_default(),
|
||||||
},
|
error = self
|
||||||
error = if let Some(ValidationErrorsKind::Field(errs)) =
|
.error
|
||||||
$err.errors().get(stringify!($name))
|
.map(|e| format!(r#"<p class="error" dir="auto">{}</p>"#, e))
|
||||||
{
|
.unwrap_or_default(),
|
||||||
format!(
|
val = escape(&self.default.unwrap_or_default()),
|
||||||
r#"<p class="error" dir="auto">{}</p>"#,
|
props = self
|
||||||
errs[0]
|
.props
|
||||||
.message
|
.into_iter()
|
||||||
.clone()
|
.fold(String::new(), |mut res, (key, val)| {
|
||||||
.unwrap_or(Cow::from("Unknown error"))
|
res.push_str(&format!("{}=\"{}\" ", key, val));
|
||||||
)
|
res
|
||||||
} else {
|
})
|
||||||
String::new()
|
|
||||||
},
|
|
||||||
val = escape(&$form.$name),
|
|
||||||
props = $props
|
|
||||||
))
|
))
|
||||||
}};
|
}
|
||||||
($catalog:expr, $name:tt (optional $kind:tt), $label:expr, $details:expr, $form:expr, $err:expr, $props:expr) => {
|
|
||||||
input!(
|
|
||||||
$catalog,
|
|
||||||
$name($kind),
|
|
||||||
$label,
|
|
||||||
true,
|
|
||||||
$details,
|
|
||||||
$form,
|
|
||||||
$err,
|
|
||||||
$props
|
|
||||||
)
|
|
||||||
};
|
|
||||||
($catalog:expr, $name:tt (optional $kind:tt), $label:expr, $form:expr, $err:expr, $props:expr) => {
|
|
||||||
input!(
|
|
||||||
$catalog,
|
|
||||||
$name($kind),
|
|
||||||
$label,
|
|
||||||
true,
|
|
||||||
"",
|
|
||||||
$form,
|
|
||||||
$err,
|
|
||||||
$props
|
|
||||||
)
|
|
||||||
};
|
|
||||||
($catalog:expr, $name:tt ($kind:tt), $label:expr, $details:expr, $form:expr, $err:expr, $props:expr) => {
|
|
||||||
input!(
|
|
||||||
$catalog,
|
|
||||||
$name($kind),
|
|
||||||
$label,
|
|
||||||
false,
|
|
||||||
$details,
|
|
||||||
$form,
|
|
||||||
$err,
|
|
||||||
$props
|
|
||||||
)
|
|
||||||
};
|
|
||||||
($catalog:expr, $name:tt ($kind:tt), $label:expr, $form:expr, $err:expr, $props:expr) => {
|
|
||||||
input!(
|
|
||||||
$catalog,
|
|
||||||
$name($kind),
|
|
||||||
$label,
|
|
||||||
false,
|
|
||||||
"",
|
|
||||||
$form,
|
|
||||||
$err,
|
|
||||||
$props
|
|
||||||
)
|
|
||||||
};
|
|
||||||
($catalog:expr, $name:tt ($kind:tt), $label:expr, $form:expr, $err:expr) => {
|
|
||||||
input!($catalog, $name($kind), $label, false, "", $form, $err, "")
|
|
||||||
};
|
|
||||||
($catalog:expr, $name:tt ($kind:tt), $label:expr, $props:expr) => {{
|
|
||||||
let cat = $catalog;
|
|
||||||
Html(format!(
|
|
||||||
r#"
|
|
||||||
<label for="{name}" dir="auto">{label}</label>
|
|
||||||
<input type="{kind}" id="{name}" name="{name}" {props} dir="auto"/>
|
|
||||||
"#,
|
|
||||||
name = stringify!($name),
|
|
||||||
label = i18n!(cat, $label),
|
|
||||||
kind = stringify!($kind),
|
|
||||||
props = $props
|
|
||||||
))
|
|
||||||
}};
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,11 @@
|
||||||
<!-- Rocket hack to use various HTTP methods -->
|
<!-- Rocket hack to use various HTTP methods -->
|
||||||
<input type=hidden name="_method" value="put">
|
<input type=hidden name="_method" value="put">
|
||||||
|
|
||||||
@input!(ctx.1, title (text), "Title", form, errors.clone(), "minlenght=\"1\"")
|
@(Input::new("title", i18n!(ctx.1, "Title"))
|
||||||
|
.default(&form.title)
|
||||||
|
.error(&errors)
|
||||||
|
.set_prop("minlenght", 1)
|
||||||
|
.html(ctx.1))
|
||||||
|
|
||||||
<label for="summary">@i18n!(ctx.1, "Description")<small>@i18n!(ctx.1, "Markdown syntax is supported")</small></label>
|
<label for="summary">@i18n!(ctx.1, "Description")<small>@i18n!(ctx.1, "Markdown syntax is supported")</small></label>
|
||||||
<textarea id="summary" name="summary" rows="20">@form.summary</textarea>
|
<textarea id="summary" name="summary" rows="20">@form.summary</textarea>
|
||||||
|
|
|
@ -9,7 +9,11 @@
|
||||||
@:base(ctx, i18n!(ctx.1, "New Blog"), {}, {}, {
|
@:base(ctx, i18n!(ctx.1, "New Blog"), {}, {}, {
|
||||||
<h1 dir="auto">@i18n!(ctx.1, "Create a blog")</h1>
|
<h1 dir="auto">@i18n!(ctx.1, "Create a blog")</h1>
|
||||||
<form method="post" action="@uri!(blogs::create)">
|
<form method="post" action="@uri!(blogs::create)">
|
||||||
@input!(ctx.1, title (text), "Title", form, errors, "required minlength=\"1\"")
|
@(Input::new("title", i18n!(ctx.1, "Title"))
|
||||||
|
.default(&form.title)
|
||||||
|
.error(&errors)
|
||||||
|
.set_prop("minlength", 1)
|
||||||
|
.html(ctx.1))
|
||||||
<input type="submit" value="@i18n!(ctx.1, "Create blog")" dir="auto"/>
|
<input type="submit" value="@i18n!(ctx.1, "Create blog")" dir="auto"/>
|
||||||
</form>
|
</form>
|
||||||
})
|
})
|
||||||
|
|
|
@ -17,7 +17,11 @@
|
||||||
])
|
])
|
||||||
|
|
||||||
<form method="post" action="@uri!(instance::update_settings)">
|
<form method="post" action="@uri!(instance::update_settings)">
|
||||||
@input!(ctx.1, name (text), "Name", form, errors.clone(), "props")
|
@(Input::new("name", i18n!(ctx.1, "Name"))
|
||||||
|
.default(&form.name)
|
||||||
|
.error(&errors)
|
||||||
|
.set_prop("minlength", 1)
|
||||||
|
.html(ctx.1))
|
||||||
|
|
||||||
<label for="open_registrations">
|
<label for="open_registrations">
|
||||||
<input type="checkbox" name="open_registrations" id="open_registrations" @if instance.open_registrations { checked }>
|
<input type="checkbox" name="open_registrations" id="open_registrations" @if instance.open_registrations { checked }>
|
||||||
|
@ -30,7 +34,11 @@
|
||||||
<label for="long_description">@i18n!(ctx.1, "Long description")<small>@i18n!(ctx.1, "Markdown syntax is supported")</small></label>
|
<label for="long_description">@i18n!(ctx.1, "Long description")<small>@i18n!(ctx.1, "Markdown syntax is supported")</small></label>
|
||||||
<textarea id="long_description" name="long_description">@Html(form.long_description)</textarea>
|
<textarea id="long_description" name="long_description">@Html(form.long_description)</textarea>
|
||||||
|
|
||||||
@input!(ctx.1, default_license (text), "Default article license", form, errors, "minlenght=\"1\"")
|
@(Input::new("default_license", i18n!(ctx.1, "Default article license"))
|
||||||
|
.default(&form.default_license)
|
||||||
|
.error(&errors)
|
||||||
|
.set_prop("minlength", 1)
|
||||||
|
.html(ctx.1))
|
||||||
|
|
||||||
<input type="submit" value="@i18n!(ctx.1, "Save these settings")"/>
|
<input type="submit" value="@i18n!(ctx.1, "Save these settings")"/>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -7,22 +7,19 @@
|
||||||
@:base(ctx, i18n!(ctx.1, "Media upload"), {}, {}, {
|
@:base(ctx, i18n!(ctx.1, "Media upload"), {}, {}, {
|
||||||
<h1>@i18n!(ctx.1, "Media upload")</h1>
|
<h1>@i18n!(ctx.1, "Media upload")</h1>
|
||||||
<form method="post" enctype="multipart/form-data" action="@uri!(medias::upload)">
|
<form method="post" enctype="multipart/form-data" action="@uri!(medias::upload)">
|
||||||
<label for="alt">
|
@(Input::new("alt", i18n!(ctx.1, "Description"))
|
||||||
@i18n!(ctx.1, "Description")
|
.details(i18n!(ctx.1, "Useful for visually impaired people, as well as licensing information"))
|
||||||
<small>@i18n!(ctx.1, "Useful for visually impaired people, as well as licensing information")</small>
|
.set_prop("minlenght", 1)
|
||||||
</label>
|
.html(ctx.1))
|
||||||
<input type="text" id="alt" name="alt" required minlenght="1"/>
|
|
||||||
|
|
||||||
<label for="cw">
|
@(Input::new("cw", i18n!(ctx.1, "Content warning"))
|
||||||
@i18n!(ctx.1, "Content warning")
|
.details(i18n!(ctx.1, "Leave it empty, if none is needed"))
|
||||||
<small>@i18n!(ctx.1, "Leave it empty, if none is needed")</small>
|
.optional()
|
||||||
</label>
|
.html(ctx.1))
|
||||||
<input type="txt" id="cw" name="cw"/>
|
|
||||||
|
|
||||||
<label for="file">
|
@(Input::new("file", i18n!(ctx.1, "File"))
|
||||||
@i18n!(ctx.1, "File")
|
.input_type("file")
|
||||||
</label>
|
.html(ctx.1))
|
||||||
<input type="file" id="file" name="file" required/>
|
|
||||||
|
|
||||||
<input type="submit" value="@i18n!(ctx.1, "Send")"/>
|
<input type="submit" value="@i18n!(ctx.1, "Send")"/>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -144,7 +144,11 @@
|
||||||
|
|
||||||
@if ctx.2.is_some() {
|
@if ctx.2.is_some() {
|
||||||
<form method="post" action="@uri!(comments::create: blog_name = &blog.fqn, slug = &article.slug)">
|
<form method="post" action="@uri!(comments::create: blog_name = &blog.fqn, slug = &article.slug)">
|
||||||
@input!(ctx.1, warning (optional text), "Content warning", comment_form, comment_errors, "")
|
@(Input::new("warning", i18n!(ctx.1, "Content warning"))
|
||||||
|
.default(&comment_form.warning)
|
||||||
|
.error(&comment_errors)
|
||||||
|
.optional()
|
||||||
|
.html(ctx.1))
|
||||||
|
|
||||||
<label for="plume-editor">@i18n!(ctx.1, "Your comment")</label>
|
<label for="plume-editor">@i18n!(ctx.1, "Your comment")</label>
|
||||||
@if let Some(ref prev) = previous_comment {
|
@if let Some(ref prev) = previous_comment {
|
||||||
|
|
|
@ -25,8 +25,15 @@
|
||||||
} else {
|
} else {
|
||||||
<form id="plume-fallback-editor" class="new-post" method="post" action="@uri!(posts::new: blog = blog.actor_id)" content-size="@content_len">
|
<form id="plume-fallback-editor" class="new-post" method="post" action="@uri!(posts::new: blog = blog.actor_id)" content-size="@content_len">
|
||||||
}
|
}
|
||||||
@input!(ctx.1, title (text), "Title", form, errors.clone(), "required")
|
@(Input::new("title", i18n!(ctx.1, "Title"))
|
||||||
@input!(ctx.1, subtitle (optional text), "Subtitle", form, errors.clone(), "")
|
.default(&form.title)
|
||||||
|
.error(&errors)
|
||||||
|
.html(ctx.1))
|
||||||
|
@(Input::new("subtitle", i18n!(ctx.1, "Subtitle"))
|
||||||
|
.default(&form.subtitle)
|
||||||
|
.error(&errors)
|
||||||
|
.optional()
|
||||||
|
.html(ctx.1))
|
||||||
|
|
||||||
@if let Some(ValidationErrorsKind::Field(errs)) = errors.clone().errors().get("content") {
|
@if let Some(ValidationErrorsKind::Field(errs)) = errors.clone().errors().get("content") {
|
||||||
@format!(r#"<p class="error">{}</p>"#, errs[0].message.clone().unwrap_or_else(|| Cow::from("Unknown error")))
|
@format!(r#"<p class="error">{}</p>"#, errs[0].message.clone().unwrap_or_else(|| Cow::from("Unknown error")))
|
||||||
|
@ -40,9 +47,17 @@
|
||||||
<a href="@uri!(medias::new)">@i18n!(ctx.1, "Upload media")</a>
|
<a href="@uri!(medias::new)">@i18n!(ctx.1, "Upload media")</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@input!(ctx.1, tags (optional text), "Tags, separated by commas", form, errors.clone(), "")
|
@(Input::new("tags", i18n!(ctx.1, "Tags, separated by commas"))
|
||||||
|
.default(&form.tags)
|
||||||
@input!(ctx.1, license (optional text), "License", "Leave it empty to reserve all rights", form, errors, "")
|
.error(&errors)
|
||||||
|
.optional()
|
||||||
|
.html(ctx.1))
|
||||||
|
@(Input::new("license", i18n!(ctx.1, "License"))
|
||||||
|
.default(&form.license)
|
||||||
|
.error(&errors)
|
||||||
|
.optional()
|
||||||
|
.details("Leave it empty to reserve all rights")
|
||||||
|
.html(ctx.1))
|
||||||
|
|
||||||
@:image_select(ctx, "cover", i18n!(ctx.1, "Illustration"), true, medias, form.cover)
|
@:image_select(ctx, "cover", i18n!(ctx.1, "Illustration"), true, medias, form.cover)
|
||||||
|
|
||||||
|
|
|
@ -16,15 +16,28 @@
|
||||||
<form method="post" action="/login">
|
<form method="post" action="/login">
|
||||||
<h2>@i18n!(ctx.1, "I'm from this instance")</h2>
|
<h2>@i18n!(ctx.1, "I'm from this instance")</h2>
|
||||||
<p>@login_msg</p>
|
<p>@login_msg</p>
|
||||||
@input!(ctx.1, email_or_name (text), "Username, or email", login_form, login_errs.clone(), "minlenght=\"1\"")
|
@(Input::new("email_or_name", i18n!(ctx.1, "Username, or email"))
|
||||||
@input!(ctx.1, password (password), "Password", login_form, login_errs, "minlenght=\"1\"")
|
.default(&login_form.email_or_name)
|
||||||
|
.error(&login_errs)
|
||||||
|
.set_prop("minlenght", 1)
|
||||||
|
.html(ctx.1))
|
||||||
|
@(Input::new("password", i18n!(ctx.1, "Password"))
|
||||||
|
.default(login_form.password)
|
||||||
|
.error(&login_errs)
|
||||||
|
.set_prop("minlength", 1)
|
||||||
|
.html(ctx.1))
|
||||||
<input type="submit" value="@i18n!(ctx.1, "Log in")" />
|
<input type="submit" value="@i18n!(ctx.1, "Log in")" />
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<form method="post">
|
<form method="post">
|
||||||
<h2>@i18n!(ctx.1, "I'm from another instance")</h2>
|
<h2>@i18n!(ctx.1, "I'm from another instance")</h2>
|
||||||
<p>@remote_msg</p>
|
<p>@remote_msg</p>
|
||||||
@input!(ctx.1, remote (text), "Username", "Example: user@plu.me", remote_form, remote_errs.clone(), "minlenght=\"1\"")
|
@(Input::new("remote", i18n!(ctx.1, "Username"))
|
||||||
|
.details("Example: user@plu.me")
|
||||||
|
.default(&remote_form.remote)
|
||||||
|
.error(&remote_errs)
|
||||||
|
.set_prop("minlenght", 1)
|
||||||
|
.html(ctx.1))
|
||||||
<input type="submit" value="@i18n!(ctx.1, "Continue to your instance")"/>
|
<input type="submit" value="@i18n!(ctx.1, "Continue to your instance")"/>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -6,21 +6,48 @@
|
||||||
@:base(ctx, i18n!(ctx.1, "Search"), {}, {}, {
|
@:base(ctx, i18n!(ctx.1, "Search"), {}, {}, {
|
||||||
<h1>@i18n!(ctx.1, "Search")</h1>
|
<h1>@i18n!(ctx.1, "Search")</h1>
|
||||||
<form method="get" id="form">
|
<form method="get" id="form">
|
||||||
<input id="q" name="q" placeholder="@i18n!(ctx.1, "Your query")" type="search" style="-webkit-appearance: none;">
|
@(Input::new("q", "Your query")
|
||||||
|
.input_type("search")
|
||||||
|
.set_prop("style", "-webkit-appearance: none;")
|
||||||
|
.html(ctx.1))
|
||||||
<details>
|
<details>
|
||||||
<summary>@i18n!(ctx.1, "Advanced search")</summary>
|
<summary>@i18n!(ctx.1, "Advanced search")</summary>
|
||||||
@input!(ctx.1, title (text), "Article title matching these words", &format!("placeholder=\"{}\"", i18n!(ctx.1, "Title")))
|
|
||||||
@input!(ctx.1, subtitle (text), "Subtitle matching these words", &format!("placeholder=\"{}\"", i18n!(ctx.1, "Subtitle - byline")))
|
|
||||||
@input!(ctx.1, content (text), "Content matching these words", &format!("placeholder=\"{}\"", i18n!(ctx.1, "Body content")))
|
|
||||||
@input!(ctx.1, after (date), "From this date", &format!("max={}", now))
|
|
||||||
@input!(ctx.1, before (date), "To this date", &format!("max={}", now))
|
|
||||||
|
|
||||||
@input!(ctx.1, tag (text), "Containing these tags", &format!("placeholder=\"{}\"", i18n!(ctx.1, "Tags")))
|
@(Input::new("title", i18n!(ctx.1, "Article title matching these words"))
|
||||||
@input!(ctx.1, instance (text), "Posted on one of these instances", &format!("placeholder=\"{}\"", i18n!(ctx.1, "Instance domain")))
|
.set_prop("placeholder", i18n!(ctx.1, "Title"))
|
||||||
@input!(ctx.1, author (text), "Posted by one of these authors", &format!("placeholder=\"{}\"", i18n!(ctx.1, "Author(s)")))
|
.html(ctx.1))
|
||||||
@input!(ctx.1, blog (text), "Posted on one of these blogs", &format!("placeholder=\"{}\"", i18n!(ctx.1, "Blog title")))
|
@(Input::new("subtitle", i18n!(ctx.1, "Subtitle matching these words"))
|
||||||
@input!(ctx.1, lang (text), "Written in this language", &format!("placeholder=\"{}\"", i18n!(ctx.1, "Language")))
|
.set_prop("placeholder", i18n!(ctx.1, "Subtitle"))
|
||||||
@input!(ctx.1, license (text), "Published under this license", &format!("placeholder=\"{}\"", i18n!(ctx.1, "Article license")))
|
.html(ctx.1))
|
||||||
|
@(Input::new("content", i18n!(ctx.1, "Content macthing these words"))
|
||||||
|
.set_prop("placeholder", i18n!(ctx.1, "Body content"))
|
||||||
|
.html(ctx.1))
|
||||||
|
@(Input::new("after", i18n!(ctx.1, "From this date"))
|
||||||
|
.input_type("date")
|
||||||
|
.set_prop("max", now)
|
||||||
|
.html(ctx.1))
|
||||||
|
@(Input::new("before", i18n!(ctx.1, ""))
|
||||||
|
.input_type("date")
|
||||||
|
.set_prop("max", now)
|
||||||
|
.html(ctx.1))
|
||||||
|
@(Input::new("tag", i18n!(ctx.1, "Containing these tags"))
|
||||||
|
.set_prop("placeholder", i18n!(ctx.1, "Tags"))
|
||||||
|
.html(ctx.1))
|
||||||
|
@(Input::new("instance", i18n!(ctx.1, "Posted on one of these instances"))
|
||||||
|
.set_prop("placeholder", i18n!(ctx.1, "Instance domain"))
|
||||||
|
.html(ctx.1))
|
||||||
|
@(Input::new("author", i18n!(ctx.1, "Posted by one of these authors"))
|
||||||
|
.set_prop("placeholder", i18n!(ctx.1, "Author(s)"))
|
||||||
|
.html(ctx.1))
|
||||||
|
@(Input::new("blog", i18n!(ctx.1, "Posted on one of these blogs"))
|
||||||
|
.set_prop("placeholder", i18n!(ctx.1, "Blog title"))
|
||||||
|
.html(ctx.1))
|
||||||
|
@(Input::new("lang", i18n!(ctx.1, "Written in this language"))
|
||||||
|
.set_prop("placeholder", i18n!(ctx.1, "Language"))
|
||||||
|
.html(ctx.1))
|
||||||
|
@(Input::new("license", i18n!(ctx.1, "Published under this license"))
|
||||||
|
.set_prop("placeholder", i18n!(ctx.1, "Article license"))
|
||||||
|
.html(ctx.1))
|
||||||
</details>
|
</details>
|
||||||
<input type="submit" value="@i18n!(ctx.1, "Search")"/>
|
<input type="submit" value="@i18n!(ctx.1, "Search")"/>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -12,8 +12,17 @@
|
||||||
<p>@message</p>
|
<p>@message</p>
|
||||||
}
|
}
|
||||||
<form method="post" action="@uri!(session::create)">
|
<form method="post" action="@uri!(session::create)">
|
||||||
@input!(ctx.1, email_or_name (text), "Username, or email", form, errors.clone(), "minlenght=\"1\"")
|
@(Input::new("email_or_name", i18n!(ctx.1, "Username, or email"))
|
||||||
@input!(ctx.1, password (password), "Password", form, errors, "minlenght=\"1\"")
|
.default(&form.email_or_name)
|
||||||
|
.error(&errors)
|
||||||
|
.set_prop("minlenght", 1)
|
||||||
|
.html(ctx.1))
|
||||||
|
@(Input::new("password", i18n!(ctx.1, "Password"))
|
||||||
|
.default(&form.password)
|
||||||
|
.error(&errors)
|
||||||
|
.set_prop("minlenght", 8)
|
||||||
|
.input_type("password")
|
||||||
|
.html(ctx.1))
|
||||||
<input type="submit" value="@i18n!(ctx.1, "Log in")" />
|
<input type="submit" value="@i18n!(ctx.1, "Log in")" />
|
||||||
</form>
|
</form>
|
||||||
<a href="@uri!(session::password_reset_request_form)">Forgot your password?</a>
|
<a href="@uri!(session::password_reset_request_form)">Forgot your password?</a>
|
||||||
|
|
|
@ -9,8 +9,18 @@
|
||||||
<h1>@i18n!(ctx.1, "Reset your password")</h1>
|
<h1>@i18n!(ctx.1, "Reset your password")</h1>
|
||||||
|
|
||||||
<form method="POST">
|
<form method="POST">
|
||||||
@input!(ctx.1, password (password), "New password", form, errors.clone(), "minlenght=\"8\"")
|
@(Input::new("password", i18n!(ctx.1, "New password"))
|
||||||
@input!(ctx.1, password_confirmation (password), "Confirmation", form, errors.clone(), "minlenght=\"8\"")
|
.default(&form.password)
|
||||||
|
.error(&errors)
|
||||||
|
.set_prop("minlenght", 8)
|
||||||
|
.input_type("password")
|
||||||
|
.html(ctx.1))
|
||||||
|
@(Input::new("password_confirmation", i18n!(ctx.1, "Confirmation"))
|
||||||
|
.default(&form.password_confirmation)
|
||||||
|
.error(&errors)
|
||||||
|
.set_prop("minlenght", 8)
|
||||||
|
.input_type("password")
|
||||||
|
.html(ctx.1))
|
||||||
<input type="submit" value="@i18n!(ctx.1, "Update password")" />
|
<input type="submit" value="@i18n!(ctx.1, "Update password")" />
|
||||||
</form>
|
</form>
|
||||||
})
|
})
|
||||||
|
|
|
@ -9,7 +9,12 @@
|
||||||
<h1>@i18n!(ctx.1, "Reset your password")</h1>
|
<h1>@i18n!(ctx.1, "Reset your password")</h1>
|
||||||
|
|
||||||
<form method="POST">
|
<form method="POST">
|
||||||
@input!(ctx.1, email (email), "E-mail", form, errors.clone(), "minlenght=\"1\"")
|
@(Input::new("email", i18n!(ctx.1, "Email"))
|
||||||
|
.default(&form.email)
|
||||||
|
.error(&errors)
|
||||||
|
.set_prop("minlenght", 1)
|
||||||
|
.input_type("email")
|
||||||
|
.html(ctx.1))
|
||||||
<input type="submit" value="@i18n!(ctx.1, "Send password reset link")" />
|
<input type="submit" value="@i18n!(ctx.1, "Send password reset link")" />
|
||||||
</form>
|
</form>
|
||||||
})
|
})
|
||||||
|
|
|
@ -18,8 +18,15 @@
|
||||||
<!-- Rocket hack to use various HTTP methods -->
|
<!-- Rocket hack to use various HTTP methods -->
|
||||||
<input type=hidden name="_method" value="put">
|
<input type=hidden name="_method" value="put">
|
||||||
|
|
||||||
@input!(ctx.1, display_name (text), "Display name", form, errors.clone())
|
@(Input::new("display_name", i18n!(ctx.1, ""))
|
||||||
@input!(ctx.1, email (text), "Email", form, errors.clone())
|
.default(&form.display_name)
|
||||||
|
.error(&errors)
|
||||||
|
.html(ctx.1))
|
||||||
|
@(Input::new("email", i18n!(ctx.1, ""))
|
||||||
|
.default(&form.email)
|
||||||
|
.error(&errors)
|
||||||
|
.input_type("email")
|
||||||
|
.html(ctx.1))
|
||||||
<label for="summary">@i18n!(ctx.1, "Summary")</label>
|
<label for="summary">@i18n!(ctx.1, "Summary")</label>
|
||||||
<textarea id="summary" name="summary">@form.summary</textarea>
|
<textarea id="summary" name="summary">@form.summary</textarea>
|
||||||
|
|
||||||
|
|
|
@ -11,13 +11,32 @@
|
||||||
@if enabled {
|
@if enabled {
|
||||||
<h1>@i18n!(ctx.1, "Create an account")</h1>
|
<h1>@i18n!(ctx.1, "Create an account")</h1>
|
||||||
<form method="post" action="@uri!(user::create)">
|
<form method="post" action="@uri!(user::create)">
|
||||||
@input!(ctx.1, username (text), "Username", form, errors.clone(), "minlenght=\"1\"")
|
|
||||||
@input!(ctx.1, email (text), "Email", form, errors.clone())
|
|
||||||
@input!(ctx.1, password (password), "Password", form, errors.clone(), "minlenght=\"8\"")
|
|
||||||
@if let Some(ValidationErrorsKind::Field(errs)) = errors.clone().errors().get("__all__") {
|
@if let Some(ValidationErrorsKind::Field(errs)) = errors.clone().errors().get("__all__") {
|
||||||
<p class="error">@errs[0].message.as_ref().unwrap_or(&Cow::from("Unknown error"))</p>
|
<p class="error">@errs[0].message.as_ref().unwrap_or(&Cow::from("Unknown error"))</p>
|
||||||
}
|
}
|
||||||
@input!(ctx.1, password_confirmation (password), "Password confirmation", form, errors, "minlenght=\"8\"")
|
|
||||||
|
@(Input::new("username", i18n!(ctx.1, ""))
|
||||||
|
.default(&form.username)
|
||||||
|
.error(&errors)
|
||||||
|
.set_prop("minlength", 1)
|
||||||
|
.html(ctx.1))
|
||||||
|
@(Input::new("email", i18n!(ctx.1, ""))
|
||||||
|
.default(&form.email)
|
||||||
|
.error(&errors)
|
||||||
|
.set_prop("minlength", 1)
|
||||||
|
.html(ctx.1))
|
||||||
|
@(Input::new("password", i18n!(ctx.1, ""))
|
||||||
|
.default(&form.password)
|
||||||
|
.error(&errors)
|
||||||
|
.set_prop("minlength", 8)
|
||||||
|
.input_type("password")
|
||||||
|
.html(ctx.1))
|
||||||
|
@(Input::new("password_confirmation", i18n!(ctx.1, ""))
|
||||||
|
.default(&form.password_confirmation)
|
||||||
|
.error(&errors)
|
||||||
|
.set_prop("minlength", 8)
|
||||||
|
.input_type("password")
|
||||||
|
.html(ctx.1))
|
||||||
|
|
||||||
<input type="submit" value="@i18n!(ctx.1, "Create your account")" />
|
<input type="submit" value="@i18n!(ctx.1, "Create your account")" />
|
||||||
</form>
|
</form>
|
||||||
|
|
Loading…
Reference in a new issue