From b008e11fb046d7356712db4aef31f9b7be4915d1 Mon Sep 17 00:00:00 2001
From: Bat
Date: Fri, 29 Jun 2018 14:22:43 +0200
Subject: [PATCH 001/103] Add validator
---
Cargo.lock | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++
Cargo.toml | 10 +++++----
src/main.rs | 3 +++
3 files changed, 67 insertions(+), 4 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
index f20bc426..3e41543e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -592,6 +592,11 @@ dependencies = [
"unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
+[[package]]
+name = "if_chain"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
[[package]]
name = "indexmap"
version = "1.0.1"
@@ -995,6 +1000,8 @@ dependencies = [
"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)",
"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_derive 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"webfinger 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1183,6 +1190,18 @@ dependencies = [
"utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
+[[package]]
+name = "regex"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex-syntax 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
[[package]]
name = "regex-syntax"
version = "0.5.5"
@@ -1191,6 +1210,14 @@ dependencies = [
"ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
+[[package]]
+name = "regex-syntax"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
[[package]]
name = "relay"
version = "0.1.1"
@@ -1926,6 +1953,32 @@ dependencies = [
"rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)",
]
+[[package]]
+name = "validator"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.0.1 (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)",
+ "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "validator_derive"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "if_chain 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.14.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "validator 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
[[package]]
name = "vcpkg"
version = "0.2.3"
@@ -2064,6 +2117,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum hyper 0.11.25 (registry+https://github.com/rust-lang/crates.io-index)" = "549dbb86397490ce69d908425b9beebc85bbaad25157d67479d4995bb56fdf9a"
"checksum hyper-tls 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a5aa51f6ae9842239b0fac14af5f22123b8432b4cc774a44ff059fcba0f675ca"
"checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d"
+"checksum if_chain 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "61bb90bdd39e3af69b0172dfc6130f6cd6332bf040fbb9bdd4401d37adbd48b8"
"checksum indexmap 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08173ba1e906efb6538785a8844dd496f5d34f0a2d88038e95195172fc667220"
"checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08"
"checksum isatty 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a118a53ba42790ef25c82bb481ecf36e2da892646cccd361e69a6bb881e19398"
@@ -2128,7 +2182,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "edecf0f94da5551fc9b492093e30b041a891657db7940ee221f9d2f66e82eef2"
"checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd"
"checksum regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "aec3f58d903a7d2a9dc2bf0e41a746f4530e0cab6b615494e058f67a3ef947fb"
+"checksum regex 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "13c93d55961981ba9226a213b385216f83ab43bd6ac53ab16b2eeb47e337cf4e"
"checksum regex-syntax 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "bd90079345f4a4c3409214734ae220fd773c6f2e8a543d07370c6c1c369cfbfb"
+"checksum regex-syntax 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05b06a75f5217880fc5e905952a42750bf44787e56a6c6d6852ed0992f5e1d54"
"checksum relay 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1576e382688d7e9deecea24417e350d3062d97e32e45d70b1cde65994ff1489a"
"checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5"
"checksum reqwest 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)" = "241faa9a8ca28a03cbbb9815a5d085f271d4c0168a19181f106aa93240c22ddb"
@@ -2210,6 +2266,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum utf-8 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f1262dfab4c30d5cb7c07026be00ee343a6cf5027fdc0104a9160f354e5db75c"
"checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122"
"checksum uuid 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcc7e3b898aa6f6c08e5295b6c89258d1331e9ac578cc992fb818759951bdc22"
+"checksum validator 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4a8c44fecf027a477e70a86cd7f4863410adf120ca2cb13408cb099057b8e2d0"
+"checksum validator_derive 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "708ee89305635499f793d0e2dd9d0b1b5d00daba90fdfb1392b87c7279521fab"
"checksum vcpkg 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7ed0f6789c8a85ca41bbc1c9d175422116a9869bd1cf31bb08e1493ecce60380"
"checksum version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6b772017e347561807c1aa192438c5fd74242a670a6cffacc40f2defd1dc069d"
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
diff --git a/Cargo.toml b/Cargo.toml
index efcb4b83..265c4725 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -11,18 +11,20 @@ gettext-rs = "0.4"
heck = "0.3.0"
rpassword = "2.0"
serde_json = "1.0"
+validator = "0.7"
+validator_derive = "0.7"
webfinger = "0.2"
[dependencies.diesel]
features = ["postgres", "r2d2", "chrono"]
version = "*"
-[dependencies.plume-models]
-path = "plume-models"
-
[dependencies.plume-common]
path = "plume-common"
+[dependencies.plume-models]
+path = "plume-models"
+
[dependencies.rocket]
git = "https://github.com/SergioBenitez/Rocket"
rev = "df7111143e466c18d1f56377a8d9530a5a306aba"
@@ -45,4 +47,4 @@ git = "https://github.com/BaptisteGelez/rocket_i18n"
rev = "5b4225d5bed5769482dc926a7e6d6b79f1217be6"
[workspace]
-members = ['plume-models', 'plume-common']
+members = ["plume-models", "plume-common"]
diff --git a/src/main.rs b/src/main.rs
index 6d55a5dc..bdf1387a 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -17,6 +17,9 @@ extern crate rocket_i18n;
extern crate rpassword;
#[macro_use]
extern crate serde_json;
+extern crate validator;
+#[macro_use]
+extern crate validator_derive;
extern crate webfinger;
use rocket_contrib::Template;
From c81bb9ec2572e10da9c4e9ee6c87ea8f7c65a2d0 Mon Sep 17 00:00:00 2001
From: Bat
Date: Fri, 29 Jun 2018 14:56:00 +0200
Subject: [PATCH 002/103] Make forms validatable
---
src/routes/blogs.rs | 13 ++++++++++++-
src/routes/comments.rs | 5 +++--
src/routes/posts.rs | 13 ++++++++++++-
src/routes/session.rs | 5 ++++-
src/routes/user.rs | 16 +++++++++++++++-
5 files changed, 46 insertions(+), 6 deletions(-)
diff --git a/src/routes/blogs.rs b/src/routes/blogs.rs
index 1e627439..0dc44838 100644
--- a/src/routes/blogs.rs
+++ b/src/routes/blogs.rs
@@ -5,6 +5,7 @@ use rocket::{
};
use rocket_contrib::Template;
use serde_json;
+use validator::{Validate, ValidationError};
use plume_common::activity_pub::ActivityStream;
use plume_common::utils;
@@ -49,11 +50,21 @@ fn new_auth() -> Flash{
utils::requires_login("You need to be logged in order to create a new blog", uri!(new))
}
-#[derive(FromForm)]
+#[derive(FromForm, Validate)]
struct NewBlogForm {
+ #[validate(custom = "valid_slug")]
pub title: String
}
+fn valid_slug(title: &str) -> Result<(), ValidationError> {
+ let slug = utils::make_actor_id(title.to_string());
+ if slug.len() == 0 {
+ Err(ValidationError::new("empty_slug"))
+ } else {
+ Ok(())
+ }
+}
+
#[post("/blogs/new", data = "")]
fn create(conn: DbConn, data: LenientForm, user: User) -> Redirect {
let form = data.get();
diff --git a/src/routes/comments.rs b/src/routes/comments.rs
index ee5112bb..78fd2852 100644
--- a/src/routes/comments.rs
+++ b/src/routes/comments.rs
@@ -3,6 +3,7 @@ use rocket::{
response::Redirect
};
use serde_json;
+use validator::Validate;
use plume_common::activity_pub::broadcast;
use plume_models::{
@@ -15,9 +16,10 @@ use plume_models::{
};
use inbox::Inbox;
-#[derive(FromForm, Debug)]
+#[derive(FromForm, Debug, Validate)]
struct NewCommentForm {
pub responding_to: Option,
+ #[validate(length(min = "1"))]
pub content: String
}
@@ -26,7 +28,6 @@ fn create(blog_name: String, slug: String, data: LenientForm, us
let blog = Blog::find_by_fqn(&*conn, blog_name.clone()).unwrap();
let post = Post::find_by_slug(&*conn, slug.clone(), blog.id).unwrap();
let form = data.get();
- println!("form: {:?}", form);
let (new_comment, id) = NewComment::build()
.content(form.content.clone())
diff --git a/src/routes/posts.rs b/src/routes/posts.rs
index 9a518b25..a27b275b 100644
--- a/src/routes/posts.rs
+++ b/src/routes/posts.rs
@@ -4,6 +4,7 @@ use rocket::request::LenientForm;
use rocket::response::{Redirect, Flash};
use rocket_contrib::Template;
use serde_json;
+use validator::{Validate, ValidationError};
use plume_common::activity_pub::{broadcast, ActivityStream};
use plume_common::utils;
@@ -81,13 +82,23 @@ fn new(blog: String, user: User, conn: DbConn) -> Template {
}
}
-#[derive(FromForm)]
+#[derive(FromForm, Validate)]
struct NewPostForm {
+ #[validate(custom = "valid_slug")]
pub title: String,
pub content: String,
pub license: String
}
+fn valid_slug(title: &str) -> Result<(), ValidationError> {
+ let slug = title.to_string().to_kebab_case();
+ if slug.len() == 0 {
+ Err(ValidationError::new("empty_slug"))
+ } else {
+ Ok(())
+ }
+}
+
#[post("/~//new", data = "")]
fn create(blog_name: String, data: LenientForm, user: User, conn: DbConn) -> Redirect {
let blog = Blog::find_by_fqn(&*conn, blog_name.to_string()).unwrap();
diff --git a/src/routes/session.rs b/src/routes/session.rs
index c99548ba..1e033e90 100644
--- a/src/routes/session.rs
+++ b/src/routes/session.rs
@@ -5,6 +5,7 @@ use rocket::{
request::{LenientForm,FlashMessage}
};
use rocket_contrib::Template;
+use validator::{Validate, ValidationError};
use plume_models::{
db_conn::DbConn,
@@ -32,9 +33,11 @@ fn new_message(user: Option, message: Message) -> Template {
}
-#[derive(FromForm)]
+#[derive(FromForm, Validate)]
struct LoginForm {
+ #[validate(length(min = "1"))]
email_or_name: String,
+ #[validate(length(min = "8"))]
password: String
}
diff --git a/src/routes/user.rs b/src/routes/user.rs
index 3e47b8fc..0cc0576b 100644
--- a/src/routes/user.rs
+++ b/src/routes/user.rs
@@ -7,6 +7,7 @@ use rocket::{request::LenientForm,
};
use rocket_contrib::Template;
use serde_json;
+use validator::{Validate, ValidationError};
use plume_common::activity_pub::{
ActivityStream, broadcast, Id, IntoId,
@@ -157,14 +158,27 @@ fn update(_name: String, conn: DbConn, user: User, data: LenientForm Result<(), ValidationError> {
+ if form.password != form.password_confirmation {
+ Err(ValidationError::new("password_match"))
+ } else {
+ Ok(())
+ }
+}
+
#[post("/users/new", data = "")]
fn create(conn: DbConn, data: LenientForm) -> Result {
let form = data.get();
From d54fa51a6d4c11ba04ec1fb26825358fdc9c0e5d Mon Sep 17 00:00:00 2001
From: Matthieu
Date: Sat, 30 Jun 2018 15:21:05 +0200
Subject: [PATCH 003/103] New forms style
---
static/main.css | 36 ++++++++++++++++++++++++++++--------
1 file changed, 28 insertions(+), 8 deletions(-)
diff --git a/static/main.css b/static/main.css
index 5f218a57..99a13a69 100644
--- a/static/main.css
+++ b/static/main.css
@@ -237,6 +237,11 @@ main .article-meta .comments > * { margin-left: 20%; margin-right: 20%; }
font-weight: 600;
}
+/* New comment */
+
+main .article-meta .comments form input[type="submit"]
+{ font-size: 1em; }
+
/* Comment / Respond button */
main .article-meta .comments a.button:before {
@@ -309,30 +314,39 @@ main .article-meta .comments .list {
label {
display: block;
- margin: 1em 0;
+ margin: 1.5em auto;
+ font-size: 1.2em;
+ text-align: center;
}
input {
transition: all 0.1s ease-in;
display: block;
width: 100%;
- margin: auto auto 5em;
- padding: 0.5em;
+ max-width: 40rem;
+ margin: auto;
+ padding: 1em;
box-sizing: border-box;
background: #F4F4F4;
color: #242424;
border: none;
- border-bottom: solid #DADADA 2px;
+ border: solid #DADADA thin;
+ border-radius: 0.5em;
+
+ font-size: 1.2em;
+ font-weight: 400;
+ text-align: center;
}
form input[type="submit"] { margin: 2em auto; }
input:focus {
background: #FAFAFA;
- border-bottom-color: #7765E3;
+ border-color: #7765E3;
}
textarea {
display: block;
width: 100%;
+ max-width: 40rem;
min-height: 4em;
margin: auto;
padding: 1em;
@@ -356,7 +370,7 @@ textarea {
display: inline-block;
border-radius: 0.5em;
- margin: 0.5em 0;
+ margin: 0.5em auto;
padding: 0.75em 1em;
background: transparent;
@@ -365,6 +379,8 @@ textarea {
cursor: pointer;
}
+input[type="submit"]
+{ display: block; }
.button:hover, input[type="submit"]:hover {
background: #7765E399;
color: white;
@@ -375,6 +391,7 @@ textarea {
*/
form.new-post .title {
+ margin: 0 auto;
padding: 0.75em 0;
background: none;
@@ -382,6 +399,7 @@ form.new-post .title {
font-family: "Playfair Display", serif;
font-size: 2em;
+ text-align: left;
}
form.new-post textarea {
min-height: 8em;
@@ -389,17 +407,19 @@ form.new-post textarea {
background: none;
}
form.new-post input[type="submit"] {
+ transition: all 0.2s ease;
display: block;
margin: 1em auto;
- width: 60%;
- background: #DADADA;
+ background: #ECECEC;
color: #242424;
border: none;
font-family: "Playfair Display", serif;
font-size: 1.5em;
}
+form.new-post input[type="submit"]:hover
+{ background: #DADADA; }
/*
* == User ==
From a391f1ae9d6f837828ab881accb9b572324d66e0 Mon Sep 17 00:00:00 2001
From: Dominik Pataky
Date: Thu, 5 Jul 2018 21:58:32 +0200
Subject: [PATCH 004/103] Add German (de) translation
---
po/LINGUAS | 1 +
po/de.po | 284 +++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 285 insertions(+)
create mode 100644 po/de.po
diff --git a/po/LINGUAS b/po/LINGUAS
index 4fec581d..118575b7 100644
--- a/po/LINGUAS
+++ b/po/LINGUAS
@@ -1,3 +1,4 @@
en
fr
pl
+de
diff --git a/po/de.po b/po/de.po
new file mode 100644
index 00000000..be7c4289
--- /dev/null
+++ b/po/de.po
@@ -0,0 +1,284 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: plume\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2018-06-15 16:33-0700\n"
+"PO-Revision-Date: 2018-07-05 21:25+0200\n"
+"Last-Translator: cookie \n"
+"Language-Team: none\n"
+"Language: de\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Poedit 2.0.8\n"
+
+msgid "Latest articles"
+msgstr "Neueste Artikel"
+
+msgid "No posts to see here yet."
+msgstr "Bisher keine Artikel vorhanden."
+
+msgid "New article"
+msgstr "Neuer Artikel"
+
+msgid "New blog"
+msgstr "Neuer Blog"
+
+msgid "Create a blog"
+msgstr "Erstelle einen Blog"
+
+msgid "Title"
+msgstr "Titel"
+
+msgid "Create blog"
+msgstr "Blog erstellen"
+
+msgid "Comment \"{{ post }}\""
+msgstr "Kommentar \"{{ post }}\""
+
+msgid "Content"
+msgstr "Inhalt"
+
+msgid "Submit comment"
+msgstr "Kommentar abschicken"
+
+msgid "Something broke on our side."
+msgstr "Bei dir ist etwas schief gegangen."
+
+msgid "Sorry about that. If you think this is a bug, please report it."
+msgstr "Entschuldige. Wenn du denkst einen Bug gefunden zu haben, kannst du diesen gerne melden."
+
+msgid "Configuration"
+msgstr "Konfiguration"
+
+msgid "Configure your instance"
+msgstr "Konfiguriere deine Instanz"
+
+msgid "Name"
+msgstr "Name"
+
+msgid "Let's go!"
+msgstr "Los geht's!"
+
+msgid "Welcome on {{ instance_name | escape }}"
+msgstr "Willkommen auf {{ instance_name | escape }}"
+
+msgid "Notifications"
+msgstr "Benachrichtigungen"
+
+msgid "Written by {{ link_1 }}{{ url }}{{ link_2 }}{{ name | escape }}{{ link_3 }}"
+msgstr "Geschrieben von {{ link_1 }}{{ url }}{{ link_2 }}{{ name | escape }}{{ link_3 }}"
+
+msgid "This article is under the {{ license }} license."
+msgstr "Dieser Artikel steht unter der {{ license }} Lizenz."
+
+msgid "One like"
+msgid_plural "{{ count }} likes"
+msgstr[0] "Ein Like"
+msgstr[1] "{{ count }} Likes"
+
+msgid "I don't like this anymore"
+msgstr "Nicht mehr Liken"
+
+msgid "Add yours"
+msgstr "Like"
+
+msgid "One reshare"
+msgid_plural "{{ count }} reshares"
+msgstr[0] "Ein Reshare"
+msgstr[1] "{{ count }} Reshares"
+
+msgid "I don't want to reshare this anymore"
+msgstr "Nicht mehr Resharen"
+
+msgid "Reshare"
+msgstr "Resharen"
+
+msgid "Comments"
+msgstr "Kommentare"
+
+msgid "Respond"
+msgstr "Antworten"
+
+msgid "Comment"
+msgstr "Kommentar"
+
+msgid "New post"
+msgstr "Neuer Beitrag"
+
+msgid "Create a post"
+msgstr "Beitrag erstellen"
+
+msgid "Publish"
+msgstr "Veröffentlichen"
+
+msgid "Login"
+msgstr "Login"
+
+msgid "Username or email"
+msgstr "Nutzername oder E-Mail"
+
+msgid "Password"
+msgstr "Passwort"
+
+msgid "Dashboard"
+msgstr "Dashboard"
+
+msgid "Your Dashboard"
+msgstr "Dein Dashboard"
+
+msgid "Your Blogs"
+msgstr "Deine Blogs"
+
+msgid "You don't have any blog yet. Create your own, or ask to join one."
+msgstr "Du hast bisher keinen Blog. Erstelle deinen eigenen oder tritt einem Blog bei."
+
+msgid "Start a new blog"
+msgstr "Starte einen neuen Blog"
+
+msgid "Admin"
+msgstr "Admin"
+
+msgid "It is you"
+msgstr "Das bist du"
+
+msgid "Edit your profile"
+msgstr "Ändere dein Profil"
+
+msgid "Open on {{ instance_url }}"
+msgstr "Öffnen auf {{ instance_url }}"
+
+msgid "Follow"
+msgstr "Folgen"
+
+msgid "Unfollow"
+msgstr "Entfolgen"
+
+msgid "Recently reshared"
+msgstr "Vor Kurzem Reshared"
+
+msgid "One follower"
+msgid_plural "{{ count }} followers"
+msgstr[0] "Ein Follower"
+msgstr[1] "{{ count }} Followers"
+
+msgid "Edit your account"
+msgstr "Ändere deinen Account"
+
+msgid "Your Profile"
+msgstr "Dein Profil"
+
+msgid "Display Name"
+msgstr "Anzeigename"
+
+msgid "Email"
+msgstr "E-Mail"
+
+msgid "Summary"
+msgstr "Zusammenfassung"
+
+msgid "Update account"
+msgstr "Account aktualisieren"
+
+msgid "{{ name | escape }}'s followers"
+msgstr "{{ name | escape }}s Follower"
+
+msgid "Followers"
+msgstr "Follower"
+
+msgid "New Account"
+msgstr "Neuer Account"
+
+msgid "Create an account"
+msgstr "Erstelle einen Account"
+
+msgid "Username"
+msgstr "Nutzername"
+
+msgid "Password confirmation"
+msgstr "Passwort Wiederholung"
+
+msgid "Create account"
+msgstr "Account erstellen"
+
+msgid "Plume"
+msgstr "Plume"
+
+msgid "Menu"
+msgstr "Menü"
+
+msgid "My account"
+msgstr "Mein Account"
+
+msgid "Log Out"
+msgstr "Ausloggen"
+
+msgid "Log In"
+msgstr "Einloggen"
+
+msgid "Register"
+msgstr "Registrieren"
+
+msgid "You need to be logged in order to create a new blog"
+msgstr "Du musst eingeloggt sein, um einen neuen Blog zu erstellen"
+
+msgid "You need to be logged in order to post a comment"
+msgstr "Du musst eingeloggt sein, um einen Kommentar zu schreiben"
+
+msgid "You need to be logged in order to like a post"
+msgstr "Du musst eingeloggt sein, um einen Beitrag zu Liken"
+
+msgid "You need to be logged in order to see your notifications"
+msgstr "Du musst eingeloggt sein, um deine Benachrichtigungen zu sehen"
+
+msgid "You need to be logged in order to write a new post"
+msgstr "Du musst eingeloggt sein, um einen neuen Beitrag zu schreiben"
+
+msgid "You need to be logged in order to reshare a post"
+msgstr "Du musst eingeloggt sein, um einen Beitrag zu resharen"
+
+msgid "Invalid username or password"
+msgstr "Nutzername oder Passwort ungültig"
+
+msgid "You need to be logged in order to access your dashboard"
+msgstr "Du musst eingeloggt sein, um dein Dashboard zu sehen"
+
+msgid "You need to be logged in order to follow someone"
+msgstr "Du musst eingeloggt sein, um jemandem zu folgen"
+
+msgid "You need to be logged in order to edit your profile"
+msgstr "Du musst eingeloggt sein, um dein Profil zu editieren"
+
+msgid "By {{ link_1 }}{{ link_2 }}{{ link_3 }}{{ name | escape }}{{ link_4 }}"
+msgstr "Von {{ link_1 }}{{ link_2 }}{{ link_3 }}{{ name | escape }}{{ link_4 }}"
+
+msgid "{{ data }} reshared your article"
+msgstr "{{ data }} hat deinen Artikel reshared"
+
+msgid "{{ data }} started following you"
+msgstr "{{ data }} folgt dir nun"
+
+msgid "{{ data }} liked your article"
+msgstr "{{ data }} hat deinen Artikel geliked"
+
+msgid "{{ data }} commented your article"
+msgstr "{{ data }} hat deinen Artikel kommentiert"
+
+msgid "We couldn't find this page."
+msgstr "Wir konnten diese Seite nicht finden."
+
+msgid "The link that led you here may be broken."
+msgstr "Der Link, welcher dich hier her führte, ist wohl kaputt."
+
+msgid "You are not authorized."
+msgstr "Nicht berechtigt."
+
+msgid "You are not author in this blog."
+msgstr "Du bist kein Autor in diesem Blog."
+
+msgid "{{ data }} mentioned you."
+msgstr "{{ data }} hat dich erwähnt."
+
+msgid "Your comment"
+msgstr "Dein Kommentar"
From 153400959c8900cf8e46275153c8cd98fcf75dd2 Mon Sep 17 00:00:00 2001
From: Bat
Date: Fri, 6 Jul 2018 11:51:19 +0200
Subject: [PATCH 005/103] Actually validate forms
---
.../2018-04-22-093322_create_instances/up.sql | 2 +-
src/routes/blogs.rs | 26 +++++++---
src/routes/comments.rs | 47 ++++++++++++-----
src/routes/posts.rs | 31 +++++++++---
src/routes/session.rs | 50 ++++++++++---------
src/routes/user.rs | 39 +++++++--------
6 files changed, 122 insertions(+), 73 deletions(-)
diff --git a/migrations/2018-04-22-093322_create_instances/up.sql b/migrations/2018-04-22-093322_create_instances/up.sql
index e6689b0f..46fd4a3c 100644
--- a/migrations/2018-04-22-093322_create_instances/up.sql
+++ b/migrations/2018-04-22-093322_create_instances/up.sql
@@ -1,4 +1,4 @@
--- Your SQL goes here
+l-- Your SQL goes here
CREATE TABLE instances (
id SERIAL PRIMARY KEY,
local_domain VARCHAR NOT NULL,
diff --git a/src/routes/blogs.rs b/src/routes/blogs.rs
index 0dc44838..e996e6c2 100644
--- a/src/routes/blogs.rs
+++ b/src/routes/blogs.rs
@@ -5,7 +5,7 @@ use rocket::{
};
use rocket_contrib::Template;
use serde_json;
-use validator::{Validate, ValidationError};
+use validator::{Validate, ValidationError, ValidationErrors};
use plume_common::activity_pub::ActivityStream;
use plume_common::utils;
@@ -66,15 +66,22 @@ fn valid_slug(title: &str) -> Result<(), ValidationError> {
}
#[post("/blogs/new", data = "")]
-fn create(conn: DbConn, data: LenientForm, user: User) -> Redirect {
+fn create(conn: DbConn, data: LenientForm, user: User) -> Result {
let form = data.get();
let slug = utils::make_actor_id(form.title.to_string());
+ let slug_taken_err = Blog::find_local(&*conn, slug.clone()).ok_or(ValidationError::new("existing_slug"));
- if Blog::find_local(&*conn, slug.clone()).is_some() || slug.len() == 0 {
- Redirect::to(uri!(new))
- } else {
+ let mut errors = match form.validate() {
+ Ok(_) => ValidationErrors::new(),
+ Err(e) => e
+ };
+ if let Err(e) = slug_taken_err {
+ errors.add("title", e)
+ }
+
+ if errors.is_empty() {
let blog = Blog::insert(&*conn, NewBlog::new_local(
- slug.to_string(),
+ slug.clone(),
form.title.to_string(),
String::from(""),
Instance::local_id(&*conn)
@@ -87,7 +94,12 @@ fn create(conn: DbConn, data: LenientForm, user: User) -> Redirect
is_owner: true
});
- Redirect::to(uri!(details: name = slug))
+ Ok(Redirect::to(uri!(details: name = slug.clone())))
+ } else {
+ Err(Template::render("blogs/new", json!({
+ "account": user,
+ "errors": errors.inner()
+ })))
}
}
diff --git a/src/routes/comments.rs b/src/routes/comments.rs
index 78fd2852..5248e9b9 100644
--- a/src/routes/comments.rs
+++ b/src/routes/comments.rs
@@ -2,6 +2,7 @@ use rocket::{
request::LenientForm,
response::Redirect
};
+use rocket_contrib::Template;
use serde_json;
use validator::Validate;
@@ -24,22 +25,44 @@ struct NewCommentForm {
}
#[post("/~///comment", data = "")]
-fn create(blog_name: String, slug: String, data: LenientForm, user: User, conn: DbConn) -> Redirect {
+fn create(blog_name: String, slug: String, data: LenientForm, user: User, conn: DbConn) -> Result {
let blog = Blog::find_by_fqn(&*conn, blog_name.clone()).unwrap();
let post = Post::find_by_slug(&*conn, slug.clone(), blog.id).unwrap();
let form = data.get();
+ form.validate()
+ .map(|_| {
+ let (new_comment, id) = NewComment::build()
+ .content(form.content.clone())
+ .in_response_to_id(form.responding_to.clone())
+ .post(post.clone())
+ .author(user.clone())
+ .create(&*conn);
- let (new_comment, id) = NewComment::build()
- .content(form.content.clone())
- .in_response_to_id(form.responding_to.clone())
- .post(post)
- .author(user.clone())
- .create(&*conn);
+ let instance = Instance::get_local(&*conn).unwrap();
+ instance.received(&*conn, serde_json::to_value(new_comment.clone()).expect("JSON serialization error"))
+ .expect("We are not compatible with ourselve: local broadcast failed (new comment)");
+ broadcast(&user, new_comment, user.get_followers(&*conn));
- let instance = Instance::get_local(&*conn).unwrap();
- instance.received(&*conn, serde_json::to_value(new_comment.clone()).expect("JSON serialization error"))
- .expect("We are not compatible with ourselve: local broadcast failed (new comment)");
- broadcast(&user, new_comment, user.get_followers(&*conn));
+ Redirect::to(format!("/~/{}/{}/#comment-{}", blog_name, slug, id))
+ })
+ .map_err(|errors| {
+ // TODO: de-duplicate this code
+ let comments = Comment::list_by_post(&*conn, post.id);
- Redirect::to(format!("/~/{}/{}/#comment-{}", blog_name, slug, id))
+ Template::render("posts/details", json!({
+ "author": post.get_authors(&*conn)[0].to_json(&*conn),
+ "post": post,
+ "blog": blog,
+ "comments": comments.into_iter().map(|c| c.to_json(&*conn)).collect::>(),
+ "n_likes": post.get_likes(&*conn).len(),
+ "has_liked": user.has_liked(&*conn, &post),
+ "n_reshares": post.get_reshares(&*conn).len(),
+ "has_reshared": user.has_reshared(&*conn, &post),
+ "account": user,
+ "date": &post.creation_date.timestamp(),
+ "previous": form.responding_to.map(|r| Comment::get(&*conn, r).expect("Error retrieving previous comment").to_json(&*conn)),
+ "user_fqn": user.get_fqn(&*conn),
+ "errors": errors
+ }))
+ })
}
diff --git a/src/routes/posts.rs b/src/routes/posts.rs
index a27b275b..7e6cb116 100644
--- a/src/routes/posts.rs
+++ b/src/routes/posts.rs
@@ -4,7 +4,7 @@ use rocket::request::LenientForm;
use rocket::response::{Redirect, Flash};
use rocket_contrib::Template;
use serde_json;
-use validator::{Validate, ValidationError};
+use validator::{Validate, ValidationError, ValidationErrors};
use plume_common::activity_pub::{broadcast, ActivityStream};
use plume_common::utils;
@@ -94,22 +94,32 @@ fn valid_slug(title: &str) -> Result<(), ValidationError> {
let slug = title.to_string().to_kebab_case();
if slug.len() == 0 {
Err(ValidationError::new("empty_slug"))
+ } else if slug == "new" {
+ Err(ValidationError::new("invalid_slug"))
} else {
Ok(())
}
}
#[post("/~//new", data = "")]
-fn create(blog_name: String, data: LenientForm, user: User, conn: DbConn) -> Redirect {
+fn create(blog_name: String, data: LenientForm, user: User, conn: DbConn) -> Result {
let blog = Blog::find_by_fqn(&*conn, blog_name.to_string()).unwrap();
let form = data.get();
let slug = form.title.to_string().to_kebab_case();
+ let slug_taken_err = Blog::find_local(&*conn, slug.clone()).ok_or(ValidationError::new("existing_slug"));
+
+ let mut errors = match form.validate() {
+ Ok(_) => ValidationErrors::new(),
+ Err(e) => e
+ };
+ if let Err(e) = slug_taken_err {
+ errors.add("title", e)
+ }
- if !user.is_author_in(&*conn, blog.clone()) {
- Redirect::to(uri!(super::blogs::details: name = blog_name))
- } else {
- if slug == "new" || Post::find_by_slug(&*conn, slug.clone(), blog.id).is_some() {
- Redirect::to(uri!(new: blog = blog_name))
+ if errors.is_empty() {
+ if !user.is_author_in(&*conn, blog.clone()) {
+ // actually it's not "Ok"…
+ Ok(Redirect::to(uri!(super::blogs::details: name = blog_name)))
} else {
let (content, mentions) = utils::md_to_html(form.content.to_string().as_ref());
@@ -135,7 +145,12 @@ fn create(blog_name: String, data: LenientForm, user: User, conn: D
let act = post.create_activity(&*conn);
broadcast(&user, act, user.get_followers(&*conn));
- Redirect::to(uri!(details: blog = blog_name, slug = slug))
+ Ok(Redirect::to(uri!(details: blog = blog_name, slug = slug)))
}
+ } else {
+ Err(Template::render("posts/new", json!({
+ "account": user,
+ "errors": errors.inner()
+ })))
}
}
diff --git a/src/routes/session.rs b/src/routes/session.rs
index 1e033e90..4f5062ab 100644
--- a/src/routes/session.rs
+++ b/src/routes/session.rs
@@ -1,11 +1,10 @@
-use gettextrs::gettext;
use rocket::{
http::{Cookie, Cookies, uri::Uri},
- response::{Redirect, status::NotFound},
+ response::Redirect,
request::{LenientForm,FlashMessage}
};
use rocket_contrib::Template;
-use validator::{Validate, ValidationError};
+use validator::{Validate, ValidationError, ValidationErrors};
use plume_models::{
db_conn::DbConn,
@@ -42,28 +41,33 @@ struct LoginForm {
}
#[post("/login", data = "")]
-fn create(conn: DbConn, data: LenientForm, flash: Option, mut cookies: Cookies) -> Result> {
+fn create(conn: DbConn, data: LenientForm, flash: Option, mut cookies: Cookies) -> Result {
let form = data.get();
- let user = match User::find_by_email(&*conn, form.email_or_name.to_string()) {
- Some(usr) => Ok(usr),
- None => match User::find_local(&*conn, form.email_or_name.to_string()) {
- Some(usr) => Ok(usr),
- None => Err(gettext("Invalid username or password"))
- }
+ let user = User::find_by_email(&*conn, form.email_or_name.to_string())
+ .map(|u| Ok(u))
+ .unwrap_or_else(|| User::find_local(&*conn, form.email_or_name.to_string()).map(|u| Ok(u)).unwrap_or(Err(())));
+
+ let mut errors = match form.validate() {
+ Ok(_) => ValidationErrors::new(),
+ Err(e) => e
};
- match user {
- Ok(usr) => {
- if usr.auth(form.password.to_string()) {
- cookies.add_private(Cookie::new(AUTH_COOKIE, usr.id.to_string()));
- Ok(Redirect::to(Uri::new(flash
- .and_then(|f| if f.name() == "callback" { Some(f.msg().to_owned()) } else { None })
- .unwrap_or("/".to_owned()))
- ))
- } else {
- Err(NotFound(gettext("Invalid username or password")))
- }
- },
- Err(e) => Err(NotFound(String::from(e)))
+ if let Err(_) = user.clone() {
+ errors.add("email_or_name", ValidationError::new("invalid_login"))
+ } else if !user.clone().expect("User not found").auth(form.password.clone()) {
+ errors.add("email_or_name", ValidationError::new("invalid_login"))
+ }
+
+ if errors.is_empty() {
+ cookies.add_private(Cookie::new(AUTH_COOKIE, user.unwrap().id.to_string()));
+ Ok(Redirect::to(Uri::new(flash
+ .and_then(|f| if f.name() == "callback" { Some(f.msg().to_owned()) } else { None })
+ .unwrap_or("/".to_owned()))
+ ))
+ } else {
+ Err(Template::render("session/login", json!({
+ "account": user,
+ "errors": errors.inner()
+ })))
}
}
diff --git a/src/routes/user.rs b/src/routes/user.rs
index 0cc0576b..d35a56cb 100644
--- a/src/routes/user.rs
+++ b/src/routes/user.rs
@@ -180,29 +180,24 @@ fn passwords_match(form: &NewUserForm) -> Result<(), ValidationError> {
}
#[post("/users/new", data = "")]
-fn create(conn: DbConn, data: LenientForm) -> Result {
+fn create(conn: DbConn, data: LenientForm) -> Result {
let form = data.get();
-
- if form.username.clone().len() < 1 {
- Err(String::from("Username is required"))
- } else if form.email.clone().len() < 1 {
- Err(String::from("Email is required"))
- } else if form.password.clone().len() < 8 {
- Err(String::from("Password should be at least 8 characters long"))
- } else if form.password == form.password_confirmation {
- NewUser::new_local(
- &*conn,
- form.username.to_string(),
- form.username.to_string(),
- false,
- String::from(""),
- form.email.to_string(),
- User::hash_pass(form.password.to_string())
- ).update_boxes(&*conn);
- Ok(Redirect::to(uri!(super::session::new)))
- } else {
- Err(String::from("Passwords don't match"))
- }
+ form.validate()
+ .map(|_| {
+ NewUser::new_local(
+ &*conn,
+ form.username.to_string(),
+ form.username.to_string(),
+ false,
+ String::from(""),
+ form.email.to_string(),
+ User::hash_pass(form.password.to_string())
+ ).update_boxes(&*conn);
+ Redirect::to(uri!(super::session::new))
+ })
+ .map_err(|e| Template::render("users/new", json!({
+ "errors": e.inner()
+ })))
}
#[get("/@//outbox")]
From 5f3afe900f303a558197a3be278223a329610c4f Mon Sep 17 00:00:00 2001
From: Bat
Date: Fri, 6 Jul 2018 19:29:36 +0200
Subject: [PATCH 006/103] Display errors on invalid forms
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
It will probably need a bit of styling…
---
Cargo.lock | 2 ++
Cargo.toml | 2 ++
src/main.rs | 3 +++
src/routes/blogs.rs | 9 ++++++---
src/routes/posts.rs | 11 +++++++----
src/routes/session.rs | 11 ++++++++---
src/routes/user.rs | 17 ++++++++++-------
templates/blogs/new.html.tera | 5 +++--
templates/macros.html.tera | 9 +++++++++
templates/posts/new.html.tera | 15 +++++++++++----
templates/session/login.html.tera | 7 ++-----
templates/users/new.html.tera | 16 +++++-----------
12 files changed, 68 insertions(+), 39 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
index 3e41543e..3304accf 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -999,6 +999,8 @@ dependencies = [
"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)",
"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)",
"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)",
diff --git a/Cargo.toml b/Cargo.toml
index 265c4725..a848910b 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -10,6 +10,8 @@ failure = "0.1"
gettext-rs = "0.4"
heck = "0.3.0"
rpassword = "2.0"
+serde = "1.0"
+serde_derive = "1.0"
serde_json = "1.0"
validator = "0.7"
validator_derive = "0.7"
diff --git a/src/main.rs b/src/main.rs
index bdf1387a..215e2101 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -15,6 +15,9 @@ extern crate rocket_contrib;
extern crate rocket_csrf;
extern crate rocket_i18n;
extern crate rpassword;
+extern crate serde;
+#[macro_use]
+extern crate serde_derive;
#[macro_use]
extern crate serde_json;
extern crate validator;
diff --git a/src/routes/blogs.rs b/src/routes/blogs.rs
index e996e6c2..f7dd94a2 100644
--- a/src/routes/blogs.rs
+++ b/src/routes/blogs.rs
@@ -41,7 +41,9 @@ fn activity_details(name: String, conn: DbConn) -> ActivityStream {
#[get("/blogs/new")]
fn new(user: User) -> Template {
Template::render("blogs/new", json!({
- "account": user
+ "account": user,
+ "errors": null,
+ "form": null
}))
}
@@ -50,7 +52,7 @@ fn new_auth() -> Flash{
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 {
#[validate(custom = "valid_slug")]
pub title: String
@@ -98,7 +100,8 @@ fn create(conn: DbConn, data: LenientForm, user: User) -> Result Template {
}))
} else {
Template::render("posts/new", json!({
- "account": user
+ "account": user,
+ "errors": null,
+ "form": null
}))
}
}
-#[derive(FromForm, Validate)]
+#[derive(FromForm, Validate, Serialize)]
struct NewPostForm {
#[validate(custom = "valid_slug")]
pub title: String,
@@ -113,7 +115,7 @@ fn create(blog_name: String, data: LenientForm, user: User, conn: D
Err(e) => e
};
if let Err(e) = slug_taken_err {
- errors.add("title", e)
+ errors.add("title", e);
}
if errors.is_empty() {
@@ -150,7 +152,8 @@ fn create(blog_name: String, data: LenientForm, user: User, conn: D
} else {
Err(Template::render("posts/new", json!({
"account": user,
- "errors": errors.inner()
+ "errors": errors.inner(),
+ "form": form
})))
}
}
diff --git a/src/routes/session.rs b/src/routes/session.rs
index 4f5062ab..e948d8e0 100644
--- a/src/routes/session.rs
+++ b/src/routes/session.rs
@@ -14,7 +14,9 @@ use plume_models::{
#[get("/login")]
fn new(user: Option) -> Template {
Template::render("session/login", json!({
- "account": user
+ "account": user,
+ "errors": null,
+ "form": null
}))
}
@@ -27,7 +29,9 @@ struct Message {
fn new_message(user: Option, message: Message) -> Template {
Template::render("session/login", json!({
"account": user,
- "message": message.m
+ "message": message.m,
+ "errors": null,
+ "form": null
}))
}
@@ -66,7 +70,8 @@ fn create(conn: DbConn, data: LenientForm, flash: Option ActivityStream
#[get("/users/new")]
fn new(user: Option) -> Template {
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) -> Result{{ "Create a blog" | _ }}
{% endblock content %}
diff --git a/templates/macros.html.tera b/templates/macros.html.tera
index 6a10d1ee..dc6187f9 100644
--- a/templates/macros.html.tera
+++ b/templates/macros.html.tera
@@ -21,3 +21,12 @@
{% endmacro post_card %}
+{% macro input(name, label, errors, form, type="text") %}
+
+ {% if errors is defined and errors[name] %}
+ {% for err in errors[name] %}
+
From 06d590ff3b1c1087da93df94fbd0400a819af540 Mon Sep 17 00:00:00 2001
From: Bat
Date: Sat, 7 Jul 2018 22:57:53 +0200
Subject: [PATCH 009/103] Make form errors i18nalizable
---
po/plume.pot | 34 ++++++++++++++++++++++++++++++++++
templates/macros.html.tera | 2 +-
2 files changed, 35 insertions(+), 1 deletion(-)
diff --git a/po/plume.pot b/po/plume.pot
index e1599c75..ccb727e3 100644
--- a/po/plume.pot
+++ b/po/plume.pot
@@ -281,3 +281,37 @@ msgstr ""
msgid "Your comment"
msgstr ""
+
+msgid "Unknown error"
+msgstr ""
+
+msgid "Invalid name"
+msgstr ""
+
+msgid "A blog with the same name already exists."
+msgstr ""
+
+msgid "Your comment can't be empty"
+msgstr ""
+
+msgid "A post with the same title already exists."
+msgstr ""
+
+msgid "We need an email or a username to identify you"
+msgstr ""
+
+msgid "Your password should be at least 8 characters long"
+msgstr ""
+
+msgid "Passwords are not matching"
+msgstr ""
+
+msgid "Username can't be empty"
+msgstr ""
+
+msgid "Invalid email"
+msgstr ""
+
+msgid "Password should be at least 8 characters long"
+msgstr ""
+
diff --git a/templates/macros.html.tera b/templates/macros.html.tera
index 868ee781..c12a6799 100644
--- a/templates/macros.html.tera
+++ b/templates/macros.html.tera
@@ -25,7 +25,7 @@
{% if errors is defined and errors[name] %}
{% for err in errors[name] %}
-
{{ "{{ count }} authors in this blog: " | _n(singular="One author in this blog: ", count = n_authors) }}
{% for author in authors %}
- {% if author.display_name %}
- {% set name = author.display_name %}
- {% else %}
- {% set name = author.username %}
- {% endif %}
- {{ name }}{% if not loop.last %},{% endif %}
+ {{ author.name }}{% if not loop.last %},{% endif %}
{% endfor %}
diff --git a/templates/macros.html.tera b/templates/macros.html.tera
index 48fbb110..50a192e4 100644
--- a/templates/macros.html.tera
+++ b/templates/macros.html.tera
@@ -1,9 +1,4 @@
{% macro post_card(article) %}
- {% if article.author.display_name %}
- {% set name = article.author.display_name %}
- {% else %}
- {% set name = article.author.username %}
- {% endif %}
{{ "Create a post" | _ }}