Display errors on invalid forms
It will probably need a bit of styling…
This commit is contained in:
parent
153400959c
commit
5f3afe900f
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -999,6 +999,8 @@ dependencies = [
|
|||||||
"rocket_csrf 0.1.0 (git+https://github.com/fdb-hiroshima/rocket_csrf?rev=80687a64a8b9d44e4983e63cca6d707498e92fc7)",
|
"rocket_csrf 0.1.0 (git+https://github.com/fdb-hiroshima/rocket_csrf?rev=80687a64a8b9d44e4983e63cca6d707498e92fc7)",
|
||||||
"rocket_i18n 0.1.1 (git+https://github.com/BaptisteGelez/rocket_i18n?rev=5b4225d5bed5769482dc926a7e6d6b79f1217be6)",
|
"rocket_i18n 0.1.1 (git+https://github.com/BaptisteGelez/rocket_i18n?rev=5b4225d5bed5769482dc926a7e6d6b79f1217be6)",
|
||||||
"rpassword 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rpassword 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"serde 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"serde_derive 1.0.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_json 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_json 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"validator 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"validator 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"validator_derive 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"validator_derive 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -10,6 +10,8 @@ failure = "0.1"
|
|||||||
gettext-rs = "0.4"
|
gettext-rs = "0.4"
|
||||||
heck = "0.3.0"
|
heck = "0.3.0"
|
||||||
rpassword = "2.0"
|
rpassword = "2.0"
|
||||||
|
serde = "1.0"
|
||||||
|
serde_derive = "1.0"
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
validator = "0.7"
|
validator = "0.7"
|
||||||
validator_derive = "0.7"
|
validator_derive = "0.7"
|
||||||
|
@ -15,6 +15,9 @@ extern crate rocket_contrib;
|
|||||||
extern crate rocket_csrf;
|
extern crate rocket_csrf;
|
||||||
extern crate rocket_i18n;
|
extern crate rocket_i18n;
|
||||||
extern crate rpassword;
|
extern crate rpassword;
|
||||||
|
extern crate serde;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate serde_derive;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate serde_json;
|
extern crate serde_json;
|
||||||
extern crate validator;
|
extern crate validator;
|
||||||
|
@ -41,7 +41,9 @@ fn activity_details(name: String, conn: DbConn) -> ActivityStream<CustomGroup> {
|
|||||||
#[get("/blogs/new")]
|
#[get("/blogs/new")]
|
||||||
fn new(user: User) -> Template {
|
fn new(user: User) -> Template {
|
||||||
Template::render("blogs/new", json!({
|
Template::render("blogs/new", json!({
|
||||||
"account": user
|
"account": user,
|
||||||
|
"errors": null,
|
||||||
|
"form": null
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,7 +52,7 @@ fn new_auth() -> Flash<Redirect>{
|
|||||||
utils::requires_login("You need to be logged in order to create a new blog", uri!(new))
|
utils::requires_login("You need to be logged in order to create a new blog", uri!(new))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromForm, Validate)]
|
#[derive(FromForm, Validate, Serialize)]
|
||||||
struct NewBlogForm {
|
struct NewBlogForm {
|
||||||
#[validate(custom = "valid_slug")]
|
#[validate(custom = "valid_slug")]
|
||||||
pub title: String
|
pub title: String
|
||||||
@ -98,7 +100,8 @@ fn create(conn: DbConn, data: LenientForm<NewBlogForm>, user: User) -> Result<Re
|
|||||||
} else {
|
} else {
|
||||||
Err(Template::render("blogs/new", json!({
|
Err(Template::render("blogs/new", json!({
|
||||||
"account": user,
|
"account": user,
|
||||||
"errors": errors.inner()
|
"errors": errors.inner(),
|
||||||
|
"form": form
|
||||||
})))
|
})))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,12 +77,14 @@ fn new(blog: String, user: User, conn: DbConn) -> Template {
|
|||||||
}))
|
}))
|
||||||
} else {
|
} else {
|
||||||
Template::render("posts/new", json!({
|
Template::render("posts/new", json!({
|
||||||
"account": user
|
"account": user,
|
||||||
|
"errors": null,
|
||||||
|
"form": null
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromForm, Validate)]
|
#[derive(FromForm, Validate, Serialize)]
|
||||||
struct NewPostForm {
|
struct NewPostForm {
|
||||||
#[validate(custom = "valid_slug")]
|
#[validate(custom = "valid_slug")]
|
||||||
pub title: String,
|
pub title: String,
|
||||||
@ -113,7 +115,7 @@ fn create(blog_name: String, data: LenientForm<NewPostForm>, user: User, conn: D
|
|||||||
Err(e) => e
|
Err(e) => e
|
||||||
};
|
};
|
||||||
if let Err(e) = slug_taken_err {
|
if let Err(e) = slug_taken_err {
|
||||||
errors.add("title", e)
|
errors.add("title", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if errors.is_empty() {
|
if errors.is_empty() {
|
||||||
@ -150,7 +152,8 @@ fn create(blog_name: String, data: LenientForm<NewPostForm>, user: User, conn: D
|
|||||||
} else {
|
} else {
|
||||||
Err(Template::render("posts/new", json!({
|
Err(Template::render("posts/new", json!({
|
||||||
"account": user,
|
"account": user,
|
||||||
"errors": errors.inner()
|
"errors": errors.inner(),
|
||||||
|
"form": form
|
||||||
})))
|
})))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,9 @@ use plume_models::{
|
|||||||
#[get("/login")]
|
#[get("/login")]
|
||||||
fn new(user: Option<User>) -> Template {
|
fn new(user: Option<User>) -> Template {
|
||||||
Template::render("session/login", json!({
|
Template::render("session/login", json!({
|
||||||
"account": user
|
"account": user,
|
||||||
|
"errors": null,
|
||||||
|
"form": null
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27,7 +29,9 @@ struct Message {
|
|||||||
fn new_message(user: Option<User>, message: Message) -> Template {
|
fn new_message(user: Option<User>, message: Message) -> Template {
|
||||||
Template::render("session/login", json!({
|
Template::render("session/login", json!({
|
||||||
"account": user,
|
"account": user,
|
||||||
"message": message.m
|
"message": message.m,
|
||||||
|
"errors": null,
|
||||||
|
"form": null
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,7 +70,8 @@ fn create(conn: DbConn, data: LenientForm<LoginForm>, flash: Option<FlashMessage
|
|||||||
} else {
|
} else {
|
||||||
Err(Template::render("session/login", json!({
|
Err(Template::render("session/login", json!({
|
||||||
"account": user,
|
"account": user,
|
||||||
"errors": errors.inner()
|
"errors": errors.inner(),
|
||||||
|
"form": form
|
||||||
})))
|
})))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -121,7 +121,9 @@ fn activity_details(name: String, conn: DbConn) -> ActivityStream<CustomPerson>
|
|||||||
#[get("/users/new")]
|
#[get("/users/new")]
|
||||||
fn new(user: Option<User>) -> Template {
|
fn new(user: Option<User>) -> Template {
|
||||||
Template::render("users/new", json!({
|
Template::render("users/new", json!({
|
||||||
"account": user
|
"account": user,
|
||||||
|
"errors": null,
|
||||||
|
"form": null
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,16 +160,16 @@ fn update(_name: String, conn: DbConn, user: User, data: LenientForm<UpdateUserF
|
|||||||
Redirect::to(uri!(me))
|
Redirect::to(uri!(me))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromForm, Validate)]
|
#[derive(FromForm, Serialize, Validate)]
|
||||||
#[validate(schema(function = "passwords_match", skip_on_field_errors = "false"))]
|
#[validate(schema(function = "passwords_match", skip_on_field_errors = "false"))]
|
||||||
struct NewUserForm {
|
struct NewUserForm {
|
||||||
#[validate(length(min = "1"))]
|
#[validate(length(min = "1", message = "Username can't be empty"))]
|
||||||
username: String,
|
username: String,
|
||||||
#[validate(email)]
|
#[validate(email(message = "Invalid email"))]
|
||||||
email: String,
|
email: String,
|
||||||
#[validate(length(min = "8"))]
|
#[validate(length(min = "8", message = "Password should be at least 8 characters long"))]
|
||||||
password: String,
|
password: String,
|
||||||
#[validate(length(min = "8"))]
|
#[validate(length(min = "8", message = "Password should be at least 8 characters long"))]
|
||||||
password_confirmation: String
|
password_confirmation: String
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,7 +198,8 @@ fn create(conn: DbConn, data: LenientForm<NewUserForm>) -> Result<Redirect, Temp
|
|||||||
Redirect::to(uri!(super::session::new))
|
Redirect::to(uri!(super::session::new))
|
||||||
})
|
})
|
||||||
.map_err(|e| Template::render("users/new", json!({
|
.map_err(|e| Template::render("users/new", json!({
|
||||||
"errors": e.inner()
|
"errors": e.inner(),
|
||||||
|
"form": form
|
||||||
})))
|
})))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
{% extends "base" %}
|
{% extends "base" %}
|
||||||
|
{% import "macros" as macros %}
|
||||||
|
|
||||||
{% block title %}
|
{% block title %}
|
||||||
{{ "New blog" | _ }}
|
{{ "New blog" | _ }}
|
||||||
@ -7,8 +8,8 @@
|
|||||||
{% block content %}
|
{% block content %}
|
||||||
<h1>{{ "Create a blog" | _ }}</h1>
|
<h1>{{ "Create a blog" | _ }}</h1>
|
||||||
<form method="post">
|
<form method="post">
|
||||||
<label for="title">{{ "Title" | _ }}</label>
|
{{ macros::input(name="title", label="Title", errors=errors, form=form) }}
|
||||||
<input type="text" id="title" name="title" />
|
|
||||||
<input type="submit" value="{{ "Create blog" | _ }}"/>
|
<input type="submit" value="{{ "Create blog" | _ }}"/>
|
||||||
</form>
|
</form>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
@ -21,3 +21,12 @@
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
{% endmacro post_card %}
|
{% endmacro post_card %}
|
||||||
|
{% macro input(name, label, errors, form, type="text") %}
|
||||||
|
<label for="{{ name }}">{{ label | _ }}</label>
|
||||||
|
{% if errors is defined and errors[name] %}
|
||||||
|
{% for err in errors[name] %}
|
||||||
|
<p class="error">{{ err.message | _ }}</p>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
<input type="{{ type }}" id="{{ name }}" name="{{ name }}" value="{{ form[name] | default(value="") }}"/>
|
||||||
|
{% endmacro input %}
|
||||||
|
@ -7,11 +7,18 @@
|
|||||||
{% block content %}
|
{% block content %}
|
||||||
<h1>{{ "Create a post" | _ }}</h1>
|
<h1>{{ "Create a post" | _ }}</h1>
|
||||||
<form class="new-post" method="post">
|
<form class="new-post" method="post">
|
||||||
<input type="text" class="title" name="title" placeholder="{{ "Title" | _ }}">
|
{{ macros::input(name="title", label="Title", errors=errors, form=form) }}
|
||||||
<textarea name="content" placeholder="{{ "Content" | _ }}"></textarea>
|
|
||||||
|
|
||||||
<label for="license">{{ "License" | _ }}</label>
|
<label for="{{ name }}">{{ label | _ }}</label>
|
||||||
<input type="text" id="licence" name="license" />
|
{% if errors is defined and errors.content %}
|
||||||
|
{% for err in errors.content %}
|
||||||
|
<p class="error">{{ err.message | _ }}</p>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<textarea name="content" placeholder="{{ "Content" | _ }}" value="{{ form.content | default(value="") }}"></textarea>
|
||||||
|
|
||||||
|
{{ macros::input(name="license", label="License", errors=errors, form=form) }}
|
||||||
|
|
||||||
<input type="submit" value="{{ "Publish" | _ }}" />
|
<input type="submit" value="{{ "Publish" | _ }}" />
|
||||||
</form>
|
</form>
|
||||||
|
@ -10,11 +10,8 @@
|
|||||||
<p>{{ message }}</p>
|
<p>{{ message }}</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<form method="post">
|
<form method="post">
|
||||||
<label for="email_or_name">{{ "Username or email" | _ }}</label>
|
{{ macros::input(name="email_or_name", label="Username or email", errors=errors, form=form) }}
|
||||||
<input type="text" id="email_or_name" name="email_or_name" />
|
{{ macros::input(name="password", label="Password", errors=errors, form=form, type="password") }}
|
||||||
|
|
||||||
<label for="password">{{ "Password" | _ }}</label>
|
|
||||||
<input type="password" id="password" name="password" />
|
|
||||||
|
|
||||||
<input type="submit" value="{{ "Login" | _ }}" />
|
<input type="submit" value="{{ "Login" | _ }}" />
|
||||||
</form>
|
</form>
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
{% extends "base" %}
|
{% extends "base" %}
|
||||||
|
{% import "macros" as macros %}
|
||||||
|
|
||||||
{% block title %}
|
{% block title %}
|
||||||
{{ "New Account" | _ }}
|
{{ "New Account" | _ }}
|
||||||
@ -7,17 +8,10 @@
|
|||||||
{% block content %}
|
{% block content %}
|
||||||
<h1>{{ "Create an account" | _ }}</h1>
|
<h1>{{ "Create an account" | _ }}</h1>
|
||||||
<form method="post">
|
<form method="post">
|
||||||
<label for="username">{{ "Username" | _ }}</label>
|
{{ macros::input(name="username", label="Username", errors=errors, form=form) }}
|
||||||
<input type="text" id="username" name="username" />
|
{{ macros::input(name="email", label="Email", errors=errors, form=form, type="email") }}
|
||||||
|
{{ macros::input(name="password", label="Password", errors=errors, form=form, type="password") }}
|
||||||
<label for="email">{{ "Email" | _ }}</label>
|
{{ macros::input(name="password_confirmation", label="Password confirmation", errors=errors, form=form, type="password") }}
|
||||||
<input type="email" id="email" name="email" />
|
|
||||||
|
|
||||||
<label for="password">{{ "Password" | _ }}</label>
|
|
||||||
<input type="password" id="password" name="password" />
|
|
||||||
|
|
||||||
<label for="password_confirmation">{{ "Password confirmation" | _ }}</label>
|
|
||||||
<input type="password" id="password_confirmation" name="password_confirmation" />
|
|
||||||
|
|
||||||
<input type="submit" value="{{ "Create account" | _ }}" />
|
<input type="submit" value="{{ "Create account" | _ }}" />
|
||||||
</form>
|
</form>
|
||||||
|
Loading…
Reference in New Issue
Block a user