Works on template
Use uri! to generate links instead of hardcoded urls Fix #110 Fix invalid links needing to be POST forms Translate login message for boost and like directly from template Put js for search in its own file
This commit is contained in:
parent
70af57c6e1
commit
b4e4b497ee
|
@ -121,12 +121,14 @@ pub fn new(blog: String, user: User, conn: DbConn, intl: I18n) -> Option<Ructe>
|
|||
let medias = Media::for_user(&*conn, user.id);
|
||||
Some(render!(posts::new(
|
||||
&(&*conn, &intl.catalog, Some(user)),
|
||||
b,
|
||||
false,
|
||||
&NewPostForm::default(),
|
||||
true,
|
||||
None,
|
||||
ValidationErrors::default(),
|
||||
Instance::get_local(&*conn).expect("posts::new error: Local instance is null").default_license,
|
||||
medias,
|
||||
true
|
||||
medias
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
@ -143,7 +145,7 @@ pub fn edit(blog: String, slug: String, user: User, conn: DbConn, intl: I18n) ->
|
|||
)))
|
||||
} else {
|
||||
let source = if !post.source.is_empty() {
|
||||
post.source
|
||||
post.source.clone()
|
||||
} else {
|
||||
post.content.get().clone() // fallback to HTML if the markdown was not stored
|
||||
};
|
||||
|
@ -151,6 +153,7 @@ pub fn edit(blog: String, slug: String, user: User, conn: DbConn, intl: I18n) ->
|
|||
let medias = Media::for_user(&*conn, user.id);
|
||||
Some(render!(posts::new(
|
||||
&(&*conn, &intl.catalog, Some(user)),
|
||||
b,
|
||||
true,
|
||||
&NewPostForm {
|
||||
title: post.title.clone(),
|
||||
|
@ -165,10 +168,11 @@ pub fn edit(blog: String, slug: String, user: User, conn: DbConn, intl: I18n) ->
|
|||
draft: true,
|
||||
cover: post.cover_id,
|
||||
},
|
||||
!post.published,
|
||||
Some(post),
|
||||
ValidationErrors::default(),
|
||||
Instance::get_local(&*conn).expect("posts::new error: Local instance is null").default_license,
|
||||
medias,
|
||||
!post.published
|
||||
medias
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
@ -182,7 +186,7 @@ pub fn update(blog: String, slug: String, user: User, conn: DbConn, form: Lenien
|
|||
let new_slug = if !post.published {
|
||||
form.title.to_string().to_kebab_case()
|
||||
} else {
|
||||
post.slug
|
||||
post.slug.clone()
|
||||
};
|
||||
|
||||
let mut errors = match form.validate() {
|
||||
|
@ -260,12 +264,14 @@ pub fn update(blog: String, slug: String, user: User, conn: DbConn, form: Lenien
|
|||
let medias = Media::for_user(&*conn, user.id);
|
||||
let temp = render!(posts::new(
|
||||
&(&*conn, &intl.catalog, Some(user)),
|
||||
b,
|
||||
true,
|
||||
&*form,
|
||||
form.draft.clone(),
|
||||
Some(post),
|
||||
errors.clone(),
|
||||
Instance::get_local(&*conn).expect("posts::new error: Local instance is null").default_license,
|
||||
medias.clone(),
|
||||
form.draft.clone()
|
||||
medias.clone()
|
||||
));
|
||||
Err(Some(temp))
|
||||
}
|
||||
|
@ -378,12 +384,14 @@ pub fn create(blog_name: String, form: LenientForm<NewPostForm>, user: User, con
|
|||
let medias = Media::for_user(&*conn, user.id);
|
||||
Err(Some(render!(posts::new(
|
||||
&(&*conn, &intl.catalog, Some(user)),
|
||||
blog,
|
||||
false,
|
||||
&*form,
|
||||
form.draft,
|
||||
None,
|
||||
errors.clone(),
|
||||
Instance::get_local(&*conn).expect("posts::new error: Local instance is null").default_license,
|
||||
medias,
|
||||
form.draft
|
||||
medias
|
||||
))))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ pub fn new(user: Option<User>, conn: DbConn, intl: I18n) -> Ructe {
|
|||
pub fn new_message(user: Option<User>, m: String, conn: DbConn, intl: I18n) -> Ructe {
|
||||
render!(session::login(
|
||||
&(&*conn, &intl.catalog, user),
|
||||
Some(i18n!(intl.catalog, &m).to_string()),
|
||||
Some(m),
|
||||
&LoginForm::default(),
|
||||
ValidationErrors::default()
|
||||
))
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
window.onload = function(evt) {
|
||||
var form = document.getElementById('form');
|
||||
form.addEventListener('submit', function () {
|
||||
for (var input of form.getElementsByTagName('input')) {
|
||||
if (input.name === '') {
|
||||
input.name = input.id
|
||||
}
|
||||
if (input.name && !input.value) {
|
||||
input.name = '';
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
@use template_utils::*;
|
||||
|
||||
@use routes::*;
|
||||
@(ctx: BaseContext, title: &str, head: Content, header: Content, content: Content)
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
@ -8,10 +8,10 @@
|
|||
<meta charset="utf-8" />
|
||||
<title>@i18n!(ctx.1, title) ⋅ @i18n!(ctx.1, "Plume")</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="stylesheet" href="/static/css/main.css" />
|
||||
<link rel="stylesheet" href="/static/css/feather.css" />
|
||||
<link rel="manifest" href="/manifest.json" />
|
||||
<link rel="icon" type="image/png" href="/static/icons/trwnh/feather-filled/plumeFeatherFilled64.png">
|
||||
<link rel="stylesheet" href="@uri!(static_files: file = "css/main.css")" />
|
||||
<link rel="stylesheet" href="@uri!(static_files: file = "css/feather.css")" />
|
||||
<link rel="manifest" href="@uri!(instance::web_manifest)" />
|
||||
<link rel="icon" type="image/png" href="@uri!(static_files: file = "icons/trwnh/feather-filled/plumeFeatherFilled64.png")">
|
||||
@:head()
|
||||
</head>
|
||||
<body>
|
||||
|
@ -21,8 +21,8 @@
|
|||
</nav>
|
||||
<div id="content">
|
||||
<nav>
|
||||
<a href="/" class="title">
|
||||
<img src="/static/icons/trwnh/feather/plumeFeather256.png">
|
||||
<a href="@uri!(instance::index)" class="title">
|
||||
<img src="@uri!(static_files: file = "icons/trwnh/feather/plumeFeather256.png")">
|
||||
<p>@i18n!(ctx.1, "Plume")</p>
|
||||
</a>
|
||||
<hr/>
|
||||
|
@ -30,28 +30,28 @@
|
|||
</nav>
|
||||
<nav>
|
||||
@if ctx.2.is_some() {
|
||||
<a href="/dashboard">
|
||||
<a href="@uri!(user::dashboard)">
|
||||
<i class="icon icon-home" aria-label="@i18n!(ctx.1, "Dashboard")"></i>
|
||||
<span class="mobile-label">@i18n!(ctx.1, "Dashboard")</span>
|
||||
</a>
|
||||
<a href="/notifications">
|
||||
<a href="@uri!(notifications::notifications)">
|
||||
<i class="icon icon-bell" aria-label="@i18n!(ctx.1, "Notifications")"></i>
|
||||
<span class="mobile-label">@i18n!(ctx.1, "Notifications")</span>
|
||||
</a>
|
||||
<a href="/logout">
|
||||
<a href="@uri!(session::delete)">
|
||||
<i class="icon icon-log-out" aria-label="@i18n!(ctx.1, "Log Out")"></i>
|
||||
<span class="mobile-label">@i18n!(ctx.1, "Log Out")</span>
|
||||
</a>
|
||||
<a href="/me" title="@i18n!(ctx.1, "My account")">
|
||||
<a href="@uri!(user::me)" title="@i18n!(ctx.1, "My account")">
|
||||
@avatar(ctx.0, &ctx.2.clone().unwrap(), Size::Small, false, &ctx.1)
|
||||
<span class="mobile-label">@i18n!(ctx.1, "My account")</span>
|
||||
</a>
|
||||
} else {
|
||||
<a href="/login">
|
||||
<a href="@uri!(session::new)">
|
||||
<i class="icon icon-log-in"></i>
|
||||
<span class="mobile-label">@i18n!(ctx.1, "Log In")</span>
|
||||
</a>
|
||||
<a href="/users/new">
|
||||
<a href="@uri!(user::new)">
|
||||
<i class="icon icon-user-plus"></i>
|
||||
<span class="mobile-label">@i18n!(ctx.1, "Register")</span>
|
||||
</a>
|
||||
|
@ -64,13 +64,13 @@
|
|||
</main>
|
||||
<footer>
|
||||
<span>@concat!("Plume ", env!("CARGO_PKG_VERSION"))</span>
|
||||
<a href="/about">@i18n!(ctx.1, "About this instance")</a>
|
||||
<a href="@uri!(instance::about)">@i18n!(ctx.1, "About this instance")</a>
|
||||
<a href="https://github.com/Plume-org/Plume">@i18n!(ctx.1, "Source code")</a>
|
||||
<a href="https://riot.im/app/#/room/#plume:disroot.org">@i18n!(ctx.1, "Matrix room")</a>
|
||||
@if ctx.2.clone().map(|a| a.is_admin).unwrap_or(false) {
|
||||
<a href="/admin">@i18n!(ctx.1, "Administration")</a>
|
||||
<a href="@uri!(instance::admin)">@i18n!(ctx.1, "Administration")</a>
|
||||
}
|
||||
</footer>
|
||||
<script src="/static/js/menu.js"></script>
|
||||
<script src="@uri!(static_files: file = "js/menu.js")"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -3,18 +3,19 @@
|
|||
@use plume_models::users::User;
|
||||
@use templates::{base, partials::post_card};
|
||||
@use template_utils::*;
|
||||
@use routes::*;
|
||||
|
||||
@(ctx: BaseContext, blog: Blog, fqn: String, authors: &Vec<User>, total_articles: usize, page: i32, n_pages: i32, is_author: bool, posts: Vec<Post>)
|
||||
|
||||
@:base(ctx, blog.title.as_ref(), {}, {
|
||||
<a href="/~/@fqn">@blog.title</a>
|
||||
<a href="@uri!(blogs::details: name = &fqn)">@blog.title</a>
|
||||
}, {
|
||||
<h1>@blog.title <small>~@fqn</small></h1>
|
||||
<p>@blog.summary</p>
|
||||
<p>
|
||||
@i18n!(ctx.1, "One author in this blog: ", "{0} authors in this blog: ", authors.len())
|
||||
@for author in authors {
|
||||
<a class="author" href="/@@/@author.get_fqn(ctx.0)">@author.name(ctx.0)</a>
|
||||
<a class="author" href="@uri!(user::details: name = author.get_fqn(ctx.0))">@author.name(ctx.0)</a>
|
||||
}
|
||||
</p>
|
||||
<p>
|
||||
|
@ -24,13 +25,13 @@
|
|||
<section>
|
||||
<h2>
|
||||
@i18n!(ctx.1, "Latest articles")
|
||||
<small><a href="/~/@fqn/atom.xml" title="Atom feed">@icon!("rss")</a></small>
|
||||
<small><a href="@uri!(blogs::atom_feed: name = &fqn)" title="Atom feed">@icon!("rss")</a></small>
|
||||
</h2>
|
||||
@if posts.len() < 1 {
|
||||
<p>@i18n!(ctx.1, "No posts to see here yet.")</p>
|
||||
}
|
||||
@if is_author {
|
||||
<a href="/~/@fqn/new/" class="button inline-block">@i18n!(ctx.1, "New article")</a>
|
||||
<a href="@uri!(posts::new: blog = &fqn)" class="button inline-block">@i18n!(ctx.1, "New article")</a>
|
||||
}
|
||||
<div class="cards">
|
||||
@for article in posts {
|
||||
|
@ -42,7 +43,7 @@
|
|||
@if is_author {
|
||||
<h2>@i18n!(ctx.1, "Danger zone")</h2>
|
||||
<p>@i18n!(ctx.1, "Be very careful, any action taken here can't be cancelled.")</p>
|
||||
<form method="post" action="/~/@fqn/delete">
|
||||
<form method="post" action="@uri!(blogs::delete: name = &fqn)">
|
||||
<input type="submit" class="inline-block button destructive" value="@i18n!(ctx.1, "Delete this blog")">
|
||||
</form>
|
||||
}
|
||||
|
|
|
@ -2,12 +2,13 @@
|
|||
@use templates::base;
|
||||
@use template_utils::*;
|
||||
@use routes::blogs::NewBlogForm;
|
||||
@use routes::*;
|
||||
|
||||
@(ctx: BaseContext, form: &NewBlogForm, errors: ValidationErrors)
|
||||
|
||||
@:base(ctx, "New Blog", {}, {}, {
|
||||
<h1>@i18n!(ctx.1, "Create a blog")</h1>
|
||||
<form method="post">
|
||||
<form method="post" action="@uri!(blogs::create)">
|
||||
@input!(ctx.1, title (text), "Title", form, errors, "required minlength=\"1\"")
|
||||
<input type="submit" value="@i18n!(ctx.1, "Create blog")"/>
|
||||
</form>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
@use plume_models::{instance::Instance, users::User};
|
||||
@use templates::base;
|
||||
@use template_utils::*;
|
||||
@use plume_models::{instance::Instance, users::User};
|
||||
@use routes::*;
|
||||
|
||||
@(ctx: BaseContext, instance: Instance, admin: User, n_users: usize, n_articles: usize, n_instances: i64)
|
||||
|
||||
|
@ -23,7 +24,7 @@
|
|||
<div>
|
||||
<p>@i18n!(ctx.1, "Administred by")</p>
|
||||
@avatar(ctx.0, &admin, Size::Small, false, ctx.1)
|
||||
<p><a href="/@@/@admin.get_fqn(ctx.0)">@admin.name(ctx.0)</a><small>@@@admin.get_fqn(ctx.0)</small></p>
|
||||
<p><a href="@uri!(user::details: name = admin.get_fqn(ctx.0))">@admin.name(ctx.0)</a><small>@@@admin.get_fqn(ctx.0)</small></p>
|
||||
</div>
|
||||
</section>
|
||||
<p>@i18n!(ctx.1, "Runs Plume {0}"; env!("CARGO_PKG_VERSION"))</p>
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
@use plume_models::instance::Instance;
|
||||
@use validator::ValidationErrors;
|
||||
@use templates::base;
|
||||
@use template_utils::*;
|
||||
@use plume_models::instance::Instance;
|
||||
@use routes::instance::InstanceSettingsForm;
|
||||
@use validator::ValidationErrors;
|
||||
@use routes::*;
|
||||
|
||||
@(ctx: BaseContext, instance: Instance, form: InstanceSettingsForm, errors: ValidationErrors)
|
||||
|
||||
|
@ -10,12 +11,12 @@
|
|||
<h1>@i18n!(ctx.1, "Administration")</h1>
|
||||
|
||||
@tabs(&[
|
||||
("/admin", i18n!(ctx.1, "Configuration"), true),
|
||||
("/admin/instances", i18n!(ctx.1, "Instances"), false),
|
||||
("/admin/users", i18n!(ctx.1, "Users"), false),
|
||||
(&uri!(instance::admin).to_string(), i18n!(ctx.1, "Configuration"), true),
|
||||
(&uri!(instance::admin_instances).to_string(), i18n!(ctx.1, "Instances"), false),
|
||||
(&uri!(instance::admin_users).to_string(), i18n!(ctx.1, "Users"), false),
|
||||
])
|
||||
|
||||
<form method="post">
|
||||
<form method="post" action="@uri!(instance::update_settings)">
|
||||
@input!(ctx.1, name (text), "Name", form, errors.clone(), "props")
|
||||
|
||||
<label for="open_registrations">
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
@use plume_models::posts::Post;
|
||||
@use templates::{base, partials::post_card};
|
||||
@use template_utils::*;
|
||||
@use plume_models::posts::Post;
|
||||
@use routes::*;
|
||||
|
||||
@(ctx: BaseContext, articles: Vec<Post>, page: i32, n_pages: i32)
|
||||
|
||||
|
@ -9,16 +10,16 @@
|
|||
|
||||
@if let Some(_) = ctx.2 {
|
||||
@tabs(&[
|
||||
("/", i18n!(ctx.1, "Latest articles"), false),
|
||||
("/feed", i18n!(ctx.1, "Your feed"), false),
|
||||
("/federated", i18n!(ctx.1, "Federated feed"), true),
|
||||
("/local", i18n!(ctx.1, "Local feed"), false),
|
||||
(&uri!(instance::index).to_string(), i18n!(ctx.1, "Latest articles"), false),
|
||||
(&uri!(instance::feed).to_string(), i18n!(ctx.1, "Your feed"), false),
|
||||
(&uri!(instance::federated).to_string(), i18n!(ctx.1, "Federated feed"), true),
|
||||
(&uri!(instance::local).to_string(), i18n!(ctx.1, "Local feed"), false),
|
||||
])
|
||||
} else {
|
||||
@tabs(&[
|
||||
("/", i18n!(ctx.1, "Latest articles"), false),
|
||||
("/federated", i18n!(ctx.1, "Federated feed"), true),
|
||||
("/local", i18n!(ctx.1, "Local feed"), false),
|
||||
(&uri!(instance::index).to_string(), i18n!(ctx.1, "Latest articles"), false),
|
||||
(&uri!(instance::federated).to_string(), i18n!(ctx.1, "Federated feed"), true),
|
||||
(&uri!(instance::local).to_string(), i18n!(ctx.1, "Local feed"), false),
|
||||
])
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
@use plume_models::posts::Post;
|
||||
@use templates::{base, partials::post_card};
|
||||
@use template_utils::*;
|
||||
@use plume_models::posts::Post;
|
||||
@use routes::*;
|
||||
|
||||
@(ctx: BaseContext, articles: Vec<Post>, page: i32, n_pages: i32)
|
||||
|
||||
|
@ -8,10 +9,10 @@
|
|||
<h1>@i18n!(ctx.1, "Your feed")</h1>
|
||||
|
||||
@tabs(&[
|
||||
("/", i18n!(ctx.1, "Latest articles"), false),
|
||||
("/feed", i18n!(ctx.1, "Your feed"), true),
|
||||
("/federated", i18n!(ctx.1, "Federated feed"), false),
|
||||
("/local", i18n!(ctx.1, "Local feed"), false),
|
||||
(&uri!(instance::index).to_string(), i18n!(ctx.1, "Latest articles"), false),
|
||||
(&uri!(instance::feed).to_string(), i18n!(ctx.1, "Your feed"), true),
|
||||
(&uri!(instance::federated).to_string(), i18n!(ctx.1, "Federated feed"), false),
|
||||
(&uri!(instance::local).to_string(), i18n!(ctx.1, "Local feed"), false),
|
||||
])
|
||||
|
||||
@if !articles.is_empty() {
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
@use template_utils::*;
|
||||
@use plume_models::instance::Instance;
|
||||
@use plume_models::posts::Post;
|
||||
@use routes::*;
|
||||
|
||||
@(ctx: BaseContext, instance: Instance, n_users: i32, n_articles: i32, local: Vec<Post>, federated: Vec<Post>, user_feed: Option<Vec<Post>>)
|
||||
|
||||
|
@ -10,25 +11,25 @@
|
|||
|
||||
@if ctx.2.is_some() {
|
||||
@tabs(&[
|
||||
("/", i18n!(ctx.1, "Latest articles"), true),
|
||||
("/feed", i18n!(ctx.1, "Your feed"), false),
|
||||
("/federated", i18n!(ctx.1, "Federated feed"), false),
|
||||
("/local", i18n!(ctx.1, "Local feed"), false),
|
||||
(&uri!(instance::index).to_string(), i18n!(ctx.1, "Latest articles"), true),
|
||||
(&uri!(instance::feed).to_string(), i18n!(ctx.1, "Your feed"), false),
|
||||
(&uri!(instance::federated).to_string(), i18n!(ctx.1, "Federated feed"), false),
|
||||
(&uri!(instance::local).to_string(), i18n!(ctx.1, "Local feed"), false),
|
||||
])
|
||||
|
||||
@:home_feed(ctx, user_feed.unwrap_or_default(), "/feed", "Your feed")
|
||||
@:home_feed(ctx, federated, "/federated", "Federated feed")
|
||||
@:home_feed(ctx, local, "/local", "Local feed")
|
||||
@:home_feed(ctx, user_feed.unwrap_or_default(), &uri!(instance::feed).to_string(), "Your feed")
|
||||
@:home_feed(ctx, federated, &uri!(instance::federated).to_string(), "Federated feed")
|
||||
@:home_feed(ctx, local, &uri!(instance::local).to_string(), "Local feed")
|
||||
@:instance_description(ctx, instance, n_users, n_articles)
|
||||
} else {
|
||||
@tabs(&[
|
||||
("/", i18n!(ctx.1, "Latest articles"), true),
|
||||
("/federated", i18n!(ctx.1, "Federated feed"), false),
|
||||
("/local", i18n!(ctx.1, "Local feed"), false),
|
||||
(&uri!(instance::index).to_string(), i18n!(ctx.1, "Latest articles"), true),
|
||||
(&uri!(instance::federated).to_string(), i18n!(ctx.1, "Federated feed"), false),
|
||||
(&uri!(instance::local).to_string(), i18n!(ctx.1, "Local feed"), false),
|
||||
])
|
||||
|
||||
@:home_feed(ctx, federated, "/federated", "Federated feed")
|
||||
@:home_feed(ctx, local, "/local", "Local feed")
|
||||
@:home_feed(ctx, federated, &uri!(instance::federated).to_string(), "Federated feed")
|
||||
@:home_feed(ctx, local, &uri!(instance::local).to_string(), "Local feed")
|
||||
@:instance_description(ctx, instance, n_users, n_articles)
|
||||
}
|
||||
})
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
@use plume_models::instance::Instance;
|
||||
@use templates::base;
|
||||
@use template_utils::*;
|
||||
@use plume_models::instance::Instance;
|
||||
@use routes::*;
|
||||
|
||||
@(ctx: BaseContext, instance: Instance, instances: Vec<Instance>, page: i32, n_pages: i32)
|
||||
|
||||
|
@ -8,9 +9,9 @@
|
|||
<h1>@i18n!(ctx.1, "Instances")</h1>
|
||||
|
||||
@tabs(&[
|
||||
("/admin", i18n!(ctx.1, "Configuration"), false),
|
||||
("/admin/instances", i18n!(ctx.1, "Instances"), true),
|
||||
("/admin/users", i18n!(ctx.1, "Users"), false),
|
||||
(&uri!(instance::admin).to_string(), i18n!(ctx.1, "Configuration"), false),
|
||||
(&uri!(instance::admin_instances).to_string(), i18n!(ctx.1, "Instances"), true),
|
||||
(&uri!(instance::admin_users).to_string(), i18n!(ctx.1, "Users"), false),
|
||||
])
|
||||
|
||||
<div class="list">
|
||||
|
@ -21,7 +22,7 @@
|
|||
<small>@instance.public_domain</small>
|
||||
</p>
|
||||
@if !instance.local {
|
||||
<form class="inline" method="post" action="/admin/instances/@instance.id/block">
|
||||
<form class="inline" method="post" action="@uri!(instance::toggle_block: id = instance.id)">
|
||||
<input type="submit" value="@i18n!(ctx.1, if instance.blocked { "Unblock" } else { "Block"})">
|
||||
</form>
|
||||
}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
@use templates::{base, partials::post_card};
|
||||
@use template_utils::*;
|
||||
@use plume_models::posts::Post;
|
||||
@use plume_models::instance::Instance;
|
||||
@use templates::{base, partials::post_card};
|
||||
@use template_utils::*;
|
||||
@use routes::*;
|
||||
|
||||
@(ctx: BaseContext, instance: Instance, articles: Vec<Post>, page: i32, n_pages: i32)
|
||||
|
||||
|
@ -10,16 +11,16 @@
|
|||
|
||||
@if let Some(_) = ctx.2 {
|
||||
@tabs(&[
|
||||
("/", i18n!(ctx.1, "Latest articles"), false),
|
||||
("/feed", i18n!(ctx.1, "Your feed"), false),
|
||||
("/federated", i18n!(ctx.1, "Federated feed"), false),
|
||||
("/local", i18n!(ctx.1, "Local feed"), true),
|
||||
(&uri!(instance::index).to_string(), i18n!(ctx.1, "Latest articles"), false),
|
||||
(&uri!(instance::feed).to_string(), i18n!(ctx.1, "Your feed"), false),
|
||||
(&uri!(instance::federated).to_string(), i18n!(ctx.1, "Federated feed"), false),
|
||||
(&uri!(instance::local).to_string(), i18n!(ctx.1, "Local feed"), true),
|
||||
])
|
||||
} else {
|
||||
@tabs(&[
|
||||
("/", i18n!(ctx.1, "Latest articles"), false),
|
||||
("/federated", i18n!(ctx.1, "Federated feed"), false),
|
||||
("/local", i18n!(ctx.1, "Local feed"), true),
|
||||
(&uri!(instance::index).to_string(), i18n!(ctx.1, "Latest articles"), false),
|
||||
(&uri!(instance::federated).to_string(), i18n!(ctx.1, "Federated feed"), false),
|
||||
(&uri!(instance::local).to_string(), i18n!(ctx.1, "Local feed"), true),
|
||||
])
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
@use plume_models::users::User;
|
||||
@use templates::base;
|
||||
@use template_utils::*;
|
||||
@use plume_models::users::User;
|
||||
@use routes::*;
|
||||
|
||||
@(ctx: BaseContext, users: Vec<User>, page: i32, n_pages: i32)
|
||||
|
||||
|
@ -8,9 +9,9 @@
|
|||
<h1>@i18n!(ctx.1, "Users")</h1>
|
||||
|
||||
@tabs(&[
|
||||
("/admin", i18n!(ctx.1, "Configuration"), false),
|
||||
("/admin/instances", i18n!(ctx.1, "Instances"), false),
|
||||
("/admin/users", i18n!(ctx.1, "Users"), true),
|
||||
(&uri!(instance::admin).to_string(), i18n!(ctx.1, "Configuration"), false),
|
||||
(&uri!(instance::admin_instances).to_string(), i18n!(ctx.1, "Instances"), false),
|
||||
(&uri!(instance::admin_users).to_string(), i18n!(ctx.1, "Users"), true),
|
||||
])
|
||||
|
||||
<div class="list">
|
||||
|
@ -18,11 +19,11 @@
|
|||
<div class="flex">
|
||||
@avatar(ctx.0, &user, Size::Small, false, ctx.1)
|
||||
<p class="grow">
|
||||
<a href="/@@/@user.get_fqn(ctx.0)">@user.name(ctx.0)</a>
|
||||
<a href="@uri!(user::details: name = user.get_fqn(ctx.0))">@user.name(ctx.0)</a>
|
||||
<small>@format!("@{}", user.username)</small>
|
||||
</p>
|
||||
@if !user.is_admin {
|
||||
<form class="inline" method="post" action="/admin/users/@user.id/ban">
|
||||
<form class="inline" method="post" action="@uri!(instance::ban: id = user.id)">
|
||||
<input type="submit" value="@i18n!(ctx.1, "Ban")">
|
||||
</form>
|
||||
}
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
@use plume_models::medias::{Media, MediaCategory};
|
||||
@use templates::base;
|
||||
@use template_utils::*;
|
||||
@use plume_models::medias::{Media, MediaCategory};
|
||||
@use routes::*;
|
||||
|
||||
@(ctx: BaseContext, media: Media)
|
||||
|
||||
@:base(ctx, "Media details", {}, {}, {
|
||||
<h1>@i18n!(ctx.1, "Media details")</h1>
|
||||
<section>
|
||||
<a href="/medias">@i18n!(ctx.1, "Go back to the gallery")</a>
|
||||
<a href="@uri!(medias::list)">@i18n!(ctx.1, "Go back to the gallery")</a>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
|
@ -24,11 +25,11 @@
|
|||
</div>
|
||||
<div>
|
||||
@if media.category() == MediaCategory::Image {
|
||||
<form class="inline" method="post" action="/medias/@media.id/avatar">
|
||||
<form class="inline" method="post" action="@uri!(medias::set_avatar: id = media.id)">
|
||||
<input class="button" type="submit" value="@i18n!(ctx.1, "Use as avatar")">
|
||||
</form>
|
||||
}
|
||||
<form class="inline" method="post" action="/medias/@media.id/delete">
|
||||
<form class="inline" method="post" action="@uri!(medias::delete: id = media.id)">
|
||||
<input class="button" type="submit" value="@i18n!(ctx.1, "Delete")">
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
@use plume_models::medias::Media;
|
||||
@use templates::base;
|
||||
@use template_utils::*;
|
||||
@use plume_models::medias::Media;
|
||||
@use routes::*;
|
||||
|
||||
@(ctx: BaseContext, medias: Vec<Media>)
|
||||
|
||||
@:base(ctx, "Your media", {}, {}, {
|
||||
<h1>@i18n!(ctx.1, "Your media")</h1>
|
||||
<div>
|
||||
<a href="/medias/new" class="inline-block button">@i18n!(ctx.1, "Upload")</a>
|
||||
<a href="@uri!(medias::new)" class="inline-block button">@i18n!(ctx.1, "Upload")</a>
|
||||
</div>
|
||||
|
||||
<section>
|
||||
|
@ -19,9 +20,11 @@
|
|||
<div class="card flex">
|
||||
@Html(media.preview_html(ctx.0))
|
||||
<main class="grow">
|
||||
<p><a href="/medias/@media.id">@media.alt_text</a></p>
|
||||
<p><a href="@uri!(medias::details: id = media.id)">@media.alt_text</a></p>
|
||||
</main>
|
||||
<a href="/medias/@media.id/delete">@i18n!(ctx.1, "Delete")</a>
|
||||
<form action="@uri!(medias::delete: id = media.id)" class="inline" method="POST">
|
||||
<input type="submit" value="@i18n!(ctx.1, "Delete")"/>
|
||||
</form>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
@use templates::base;
|
||||
@use template_utils::*;
|
||||
@use routes::*;
|
||||
|
||||
@(ctx: BaseContext)
|
||||
|
||||
@:base(ctx, "Media upload", {}, {}, {
|
||||
<h1>@i18n!(ctx.1, "Media upload")</h1>
|
||||
<form method="post" enctype="multipart/form-data">
|
||||
<form method="post" enctype="multipart/form-data" action="@uri!(medias::upload)">
|
||||
<label for="alt">
|
||||
@i18n!(ctx.1, "Description")
|
||||
<small>@i18n!(ctx.1, "Useful for visually impaired people and licensing")</small>
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
@use template_utils::*;
|
||||
@use plume_models::comments::Comment;
|
||||
@use plume_models::users::User;
|
||||
@use routes::*;
|
||||
|
||||
@(ctx: BaseContext, comm: &Comment, author: User)
|
||||
|
||||
<div class="comment" id="comment-@comm.id">
|
||||
<a class="author" href="/@@/@author.get_fqn(ctx.0)/">
|
||||
<a class="author" href="@uri!(user::details: name = author.get_fqn(ctx.0))">
|
||||
@avatar(ctx.0, &author, Size::Small, true, ctx.1)
|
||||
<span class="display-name">@author.name(ctx.0)</span>
|
||||
<small>@author.get_fqn(ctx.0)</small>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
@use template_utils::*;
|
||||
@use plume_models::instance::Instance;
|
||||
@use routes::*;
|
||||
|
||||
@(ctx: BaseContext, instance: Instance, n_users: i32, n_articles: i32)
|
||||
|
||||
|
@ -12,7 +13,7 @@
|
|||
<p>@i18n!(ctx.1, "Authors can manage various blogs from an unique website.")</p>
|
||||
<p>@i18n!(ctx.1, "Articles are also visible on other Plume websites, and you can interact with them directly from other platforms like Mastodon.")</p>
|
||||
</main>
|
||||
<a href="/users/new">@i18n!(ctx.1, "Create your account")</a>
|
||||
<a href="@uri!(user::new)">@i18n!(ctx.1, "Create your account")</a>
|
||||
</div>
|
||||
<div class="presentation card">
|
||||
<h2>@i18n!(ctx.1, "About {0}"; instance.name)</h2>
|
||||
|
@ -27,7 +28,7 @@
|
|||
</div>
|
||||
</section>
|
||||
</main>
|
||||
<a href="/about">@i18n!(ctx.1, "Read the detailed rules")</a>
|
||||
<a href="@uri!(instance::about)">@i18n!(ctx.1, "Read the detailed rules")</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
@use template_utils::*;
|
||||
@use plume_models::posts::Post;
|
||||
@use template_utils::*;
|
||||
@use routes::*;
|
||||
|
||||
@(ctx: BaseContext, article: Post)
|
||||
|
||||
|
@ -7,20 +8,20 @@
|
|||
@if article.cover_id.is_some() {
|
||||
<div class="cover" style="background-image: url('@Html(article.cover_url(ctx.0).unwrap_or_default())')"></div>
|
||||
}
|
||||
<h3><a href="@article.url(ctx.0)">@article.title</a></h3>
|
||||
<h3><a href="@uri!(posts::details: blog = article.get_blog(ctx.0).get_fqn(ctx.0), slug = &article.slug)">@article.title</a></h3>
|
||||
<main>
|
||||
<p>@article.subtitle</p>
|
||||
</main>
|
||||
<p class="author">
|
||||
@Html(i18n!(ctx.1, "By {0}"; format!(
|
||||
"<a href=\"/@/{}/\">{}</a>",
|
||||
escape(&article.get_authors(ctx.0)[0].get_fqn(ctx.0)),
|
||||
"<a href=\"{}\">{}</a>",
|
||||
uri!(user::details: name = article.get_authors(ctx.0)[0].get_fqn(ctx.0)),
|
||||
escape(&article.get_authors(ctx.0)[0].name(ctx.0))
|
||||
)))
|
||||
@if article.published {
|
||||
⋅ @article.creation_date.format("%B %e, %Y")
|
||||
}
|
||||
⋅ <a href="/~/@article.get_blog(ctx.0).get_fqn(ctx.0)/">@article.get_blog(ctx.0).title</a>
|
||||
⋅ <a href="@uri!(blogs::details: name = article.get_blog(ctx.0).get_fqn(ctx.0))">@article.get_blog(ctx.0).title</a>
|
||||
@if !article.published {
|
||||
⋅ @i18n!(ctx.1, "Draft")
|
||||
}
|
||||
|
|
|
@ -7,33 +7,36 @@
|
|||
@use plume_models::users::User;
|
||||
@use validator::ValidationErrors;
|
||||
@use routes::comments::NewCommentForm;
|
||||
@use routes::*;
|
||||
|
||||
@(ctx: BaseContext, article: Post, blog: Blog, comment_form: &NewCommentForm, comment_errors: ValidationErrors, tags: Vec<Tag>, comments: Vec<Comment>, previous_comment: Option<Comment>, n_likes: usize, n_reshares: usize, has_liked: bool, has_reshared: bool, is_following: bool, author: User)
|
||||
|
||||
@:base(ctx, &article.title.clone(), {
|
||||
<meta property="og:title" content="article.title"/>
|
||||
<meta property="og:title" content="@article.title"/>
|
||||
<meta property="og:type" content="article"/>
|
||||
@if article.cover_id.is_some() {
|
||||
<meta property="og:image" content="@Html(article.cover_url(ctx.0).unwrap_or_default())"/>
|
||||
}
|
||||
<meta property="og:url" content="@Html(article.url(ctx.0))"/>
|
||||
<meta property="og:url" content="@uri!(posts::details: blog = blog.get_fqn(ctx.0), slug = &article.slug)"/>
|
||||
<meta property="og:description" content="@article.subtitle"/>
|
||||
}, {
|
||||
<a href="/~/@blog.get_fqn(ctx.0)">@blog.title</a>
|
||||
<a href="@uri!(blogs::details: name = blog.get_fqn(ctx.0))">@blog.title</a>
|
||||
}, {
|
||||
<h1 class="article">@&article.title</h1>
|
||||
<h2 class="article">@&article.subtitle</h2>
|
||||
<div class="article-info">
|
||||
<span class="author">
|
||||
@Html(i18n!(ctx.1, "Written by {0}"; format!("<a href=\"/@/{}/\">{}</a>", escape(&author.get_fqn(ctx.0)), escape(&author.name(ctx.0)))))
|
||||
@Html(i18n!(ctx.1, "Written by {0}"; format!("<a href=\"{}\">{}</a>",
|
||||
uri!(user::details: name = &author.get_fqn(ctx.0)),
|
||||
escape(&author.name(ctx.0)))))
|
||||
</span>
|
||||
—
|
||||
<span class="date">@article.creation_date.format("%B %e, %Y")</span>
|
||||
@if ctx.2.clone().map(|u| u.id == author.id).unwrap_or(false) {
|
||||
—
|
||||
<a href="@article.url(ctx.0)/edit">@i18n!(ctx.1, "Edit")</a>
|
||||
<a href="@uri!(posts::edit: blog = blog.get_fqn(ctx.0), slug = &article.slug)">@i18n!(ctx.1, "Edit")</a>
|
||||
—
|
||||
<form class="inline" method="post" action="@article.url(ctx.0)/delete">
|
||||
<form class="inline" method="post" action="@uri!(posts::delete: blog_name = blog.get_fqn(ctx.0), slug = &article.slug)">
|
||||
<input onclick="return confirm('Are you sure you?')" type="submit" value="@i18n!(ctx.1, "Delete this article")">
|
||||
</form>
|
||||
}
|
||||
|
@ -53,28 +56,26 @@
|
|||
<ul class="tags">
|
||||
@for tag in tags {
|
||||
@if !tag.is_hashtag {
|
||||
<li><a href="/tag/@tag.tag">@tag.tag</a></li>
|
||||
<li><a href="@uri!(tags::tag: name = &tag.tag)">@tag.tag</a></li>
|
||||
}
|
||||
}
|
||||
</ul>
|
||||
<div class="flex">
|
||||
@avatar(ctx.0, &author, Size::Medium, true, ctx.1)
|
||||
<div class="grow">
|
||||
<h2><a href="/@@/@author.get_fqn(ctx.0)">@author.name(ctx.0)</a></h2>
|
||||
<h2><a href="@uri!(user::details: name = author.get_fqn(ctx.0))">@author.name(ctx.0)</a></h2>
|
||||
<p>@Html(&author.summary)</h2>
|
||||
</div>
|
||||
<a href="/@@/@author.get_fqn(ctx.0)/follow" class="button">
|
||||
@if is_following {
|
||||
@i18n!(ctx.1, "Unfollow")
|
||||
} else {
|
||||
@i18n!(ctx.1, "Follow")
|
||||
@if !ctx.2.as_ref().map(|u| u.id == author.id).unwrap_or(false) {
|
||||
<form action="@uri!(user::follow: name = author.get_fqn(ctx.0))" method="POST">
|
||||
<input type="submit" class="button" value="@if is_following {@i18n!(ctx.1, "Unfollow")} else {@i18n!(ctx.1, "Follow")}">
|
||||
</form>
|
||||
}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@if ctx.2.is_some() {
|
||||
<div class="actions">
|
||||
<form class="likes" action="@article.url(ctx.0)/like" method="POST">
|
||||
<form class="likes" action="@uri!(likes::create: blog = blog.get_fqn(ctx.0), slug = &article.slug)" method="POST">
|
||||
<p aria-label="@i18n!(ctx.1, "One like", "{0} likes", &n_likes)" title="@i18n!(ctx.1, "One like", "{0} likes", n_likes)">
|
||||
@n_likes
|
||||
</p>
|
||||
|
@ -85,7 +86,7 @@
|
|||
<button type="submit" class="action">@icon!("heart") @i18n!(ctx.1, "Add yours")</button>
|
||||
}
|
||||
</form>
|
||||
<form class="reshares" action="@article.url(ctx.0)/reshare" method="POST">
|
||||
<form class="reshares" action="@uri!(reshares::create: blog = blog.get_fqn(ctx.0), slug = &article.slug)" method="POST">
|
||||
<p aria-label="@i18n!(ctx.1, "One boost", "{0} boost", &n_reshares)" title="@i18n!(ctx.1, "One boost", "{0} boosts", n_reshares)">
|
||||
@n_reshares
|
||||
</p>
|
||||
|
@ -104,14 +105,14 @@
|
|||
<p aria-label="@i18n!(ctx.1, "One like", "{0} likes", &n_likes)" title="@i18n!(ctx.1, "One like", "{0} likes", n_likes)">
|
||||
@n_likes
|
||||
</p>
|
||||
<a href="/login?m=Login%20to%20like" class="action">@icon!("heart") @i18n!(ctx.1, "Add yours")</a>
|
||||
<a href="@uri!(session::new_message: m = i18n!(ctx.1, "Login to like"))" class="action">@icon!("heart") @i18n!(ctx.1, "Add yours")</a>
|
||||
</div>
|
||||
|
||||
<div class="reshares">
|
||||
<p aria-label="@i18n!(ctx.1, "One boost", "{0} boost", &n_reshares)" title="@i18n!(ctx.1, "One boost", "{0} boosts", n_reshares)">
|
||||
@n_reshares
|
||||
</p>
|
||||
<a href="/login?m=Login%20to%20boost" class="action">@icon!("repeat") @i18n!(ctx.1, "Boost")</a>
|
||||
<a href="@uri!(session::new_message: m = i18n!(ctx.1, "Login to boost"))" class="action">@icon!("repeat") @i18n!(ctx.1, "Boost")</a>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
@ -120,7 +121,7 @@
|
|||
<h2>@i18n!(ctx.1, "Comments")</h2>
|
||||
|
||||
@if ctx.2.is_some() {
|
||||
<form method="post" action="@article.url(ctx.0)/comment">
|
||||
<form method="post" action="@uri!(comments::create: blog_name = blog.get_fqn(ctx.0), slug = &article.slug)">
|
||||
@input!(ctx.1, warning (optional text), "Content warning", comment_form, comment_errors, "")
|
||||
|
||||
<label for="plume-editor">@i18n!(ctx.1, "Your comment")</label>
|
||||
|
|
|
@ -3,9 +3,12 @@
|
|||
@use validator::{ValidationErrors, ValidationErrorsKind};
|
||||
@use std::borrow::Cow;
|
||||
@use plume_models::medias::*;
|
||||
@use plume_models::blogs::Blog;
|
||||
@use plume_models::posts::Post;
|
||||
@use routes::posts::NewPostForm;
|
||||
@use routes::*;
|
||||
|
||||
@(ctx: BaseContext, editing: bool, form: &NewPostForm, errors: ValidationErrors, default_license: String, medias: Vec<Media>, is_draft: bool)
|
||||
@(ctx: BaseContext, blog: Blog, editing: bool, form: &NewPostForm, is_draft: bool, article: Option<Post>, errors: ValidationErrors, default_license: String, medias: Vec<Media>)
|
||||
|
||||
@:base(ctx, &i18n!(ctx.1, if editing { "Edit {0}" } else { "New post" }; &form.title), {}, {}, {
|
||||
<h1>
|
||||
|
@ -15,7 +18,11 @@
|
|||
@i18n!(ctx.1, "Create a new post")
|
||||
}
|
||||
</h1>
|
||||
<form class="new-post" method="post">
|
||||
@if let Some(article) = article {
|
||||
<form class="new-post" method="post" action="@uri!(posts::update: blog = blog.actor_id, slug = &article.slug)">
|
||||
} else {
|
||||
<form class="new-post" method="post" action="@uri!(posts::new: blog = blog.actor_id)">
|
||||
}
|
||||
@input!(ctx.1, title (text), "Title", form, errors.clone(), "required")
|
||||
@input!(ctx.1, subtitle (optional text), "Subtitle", form, errors.clone(), "")
|
||||
|
||||
|
@ -63,5 +70,5 @@
|
|||
}
|
||||
}
|
||||
</form>
|
||||
<script src="/static/js/autoExpand.js"></script>
|
||||
<script src="@uri!(static_files: file = "js/autoExpand.js")"></script>
|
||||
})
|
||||
|
|
|
@ -1,34 +1,20 @@
|
|||
@use templates::base;
|
||||
@use template_utils::*;
|
||||
@use routes::*;
|
||||
|
||||
@(ctx: BaseContext, now: &str)
|
||||
|
||||
@:base(ctx, "Search", {
|
||||
<script>
|
||||
window.onload = function(evt) @{
|
||||
var form = document.getElementById('form');
|
||||
form.addEventListener('submit', function () @{
|
||||
for (var input of form.getElementsByTagName('input')) @{
|
||||
if (input.name === '') @{
|
||||
input.name = input.id
|
||||
@}
|
||||
if (input.name && !input.value) @{
|
||||
input.name = '';
|
||||
@}
|
||||
@}
|
||||
@});
|
||||
@}
|
||||
</script>
|
||||
}, {}, {
|
||||
@:base(ctx, "Search", {}, {}, {
|
||||
<h1>@i18n!(ctx.1, "Search")</h1>
|
||||
<form method="get" id="form">
|
||||
<input id="q" name="q" placeholder="Your query" type="search">
|
||||
<br/>
|
||||
<details>
|
||||
<summary>Advanced search</summary>
|
||||
@input!(ctx.1, title (text), "Title matching these words", "placeholder=\"Title\"")
|
||||
@input!(ctx.1, subtitle (text), "Subtitle matching these words", "placeholder=\"Subtitle\"")
|
||||
@input!(ctx.1, content (text), "Content matching these words", "placeholder=\"Content\"")
|
||||
@input!(ctx.1, after (date), "From this date", &format!("max={}", now)))
|
||||
@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", "placeholder=\"Tags\"")
|
||||
|
@ -40,4 +26,5 @@
|
|||
</details>
|
||||
<input type="submit" value="Search"/>
|
||||
</form>
|
||||
<script src="@uri!(static_files: file = "js/search.js")"></script>
|
||||
})
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
@use templates::base;
|
||||
@use validator::ValidationErrors;
|
||||
@use routes::session::LoginForm;
|
||||
@use routes::*;
|
||||
|
||||
@(ctx: BaseContext, message: Option<String>, form: &LoginForm, errors: ValidationErrors)
|
||||
|
||||
|
@ -10,7 +11,7 @@
|
|||
@if let Some(message) = message {
|
||||
<p>@message</p>
|
||||
}
|
||||
<form method="post">
|
||||
<form method="post" action="@uri!(session::create)">
|
||||
@input!(ctx.1, email_or_name (text), "Username or email", form, errors.clone(), "minlenght=\"1\"")
|
||||
@input!(ctx.1, password (password), "Password", form, errors, "minlenght=\"1\"")
|
||||
<input type="submit" value="@i18n!(ctx.1, "Login")" />
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
@use template_utils::*;
|
||||
@use plume_models::blogs::Blog;
|
||||
@use plume_models::posts::Post;
|
||||
@use routes::*;
|
||||
|
||||
@(ctx: BaseContext, blogs: Vec<Blog>, drafts: Vec<Post>)
|
||||
|
||||
|
@ -16,11 +17,11 @@
|
|||
<div class="cards">
|
||||
@for blog in blogs {
|
||||
<div class="card">
|
||||
<h3><a href="/~/@blog.actor_id/">@blog.title</a></h3>
|
||||
<h3><a href="@uri!(blogs::details: name = blog.actor_id)">@blog.title</a></h3>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<a class="button" href="/blogs/new">@i18n!(ctx.1, "Start a new blog")</a>
|
||||
<a class="button" href="@uri!(blogs::new)">@i18n!(ctx.1, "Start a new blog")</a>
|
||||
</section>
|
||||
|
||||
@if !drafts.is_empty() {
|
||||
|
@ -36,6 +37,6 @@
|
|||
|
||||
<section>
|
||||
<h2>@i18n!(ctx.1, "Your media")</h2>
|
||||
<a class="button" href="/medias">@i18n!(ctx.1, "Go to your gallery")</a>
|
||||
<a class="button" href="@uri!(medias::list)">@i18n!(ctx.1, "Go to your gallery")</a>
|
||||
</section>
|
||||
})
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
@use template_utils::*;
|
||||
@use plume_models::posts::Post;
|
||||
@use plume_models::users::User;
|
||||
@use routes::*;
|
||||
|
||||
@(ctx: BaseContext, user: User, follows: bool, is_remote: bool, remote_url: String, recents: Vec<Post>, reshares: Vec<Post>)
|
||||
|
||||
|
@ -9,14 +10,14 @@
|
|||
@:header(ctx, &user, follows, is_remote, remote_url)
|
||||
|
||||
@tabs(&[
|
||||
(&format!("/@/{}", user.get_fqn(ctx.0)), i18n!(ctx.1, "Articles"), true),
|
||||
(&format!("/@/{}/followers", user.get_fqn(ctx.0)), i18n!(ctx.1, "Followers"), false)
|
||||
(&uri!(user::details: name= user.get_fqn(ctx.0)).to_string(), i18n!(ctx.1, "Articles"), true),
|
||||
(&uri!(user::followers: name = user.get_fqn(ctx.0)).to_string(), i18n!(ctx.1, "Followers"), false)
|
||||
])
|
||||
|
||||
@if !recents.is_empty() {
|
||||
<h2>
|
||||
@i18n!(ctx.1, "Latest articles")
|
||||
<small><a href="/@@/@user.get_fqn(ctx.0)/atom.xml" title="@i18n!(ctx.1, "Atom feed")">@icon!("rss")</a></small>
|
||||
<small><a href="@uri!(user::atom_feed: name = user.get_fqn(ctx.0))" title="@i18n!(ctx.1, "Atom feed")">@icon!("rss")</a></small>
|
||||
</h2>
|
||||
<div class="cards">
|
||||
@for article in recents {
|
||||
|
|
|
@ -2,12 +2,14 @@
|
|||
@use template_utils::*;
|
||||
@use routes::user::UpdateUserForm;
|
||||
@use validator::ValidationErrors;
|
||||
@use routes::*;
|
||||
|
||||
@(ctx: BaseContext, form: UpdateUserForm, errors: ValidationErrors)
|
||||
|
||||
@:base(ctx, "Edit your account", {}, {}, {
|
||||
@if let Some(u) = ctx.2.clone() {
|
||||
<h1>@i18n!(ctx.1, "Your Profile")</h1>
|
||||
<form method="post">
|
||||
<form method="post" action="@uri!(user::update: _name = u.username.clone())">
|
||||
<!-- Rocket hack to use various HTTP methods -->
|
||||
<input type=hidden name="_method" value="put">
|
||||
|
||||
|
@ -20,11 +22,12 @@
|
|||
|
||||
<h2>@i18n!(ctx.1, "Danger zone")</h2>
|
||||
<p>@i18n!(ctx.1, "Be very careful, any action taken here can't be cancelled.")
|
||||
@if !ctx.2.clone().expect("Editing profile while not connected").is_admin {
|
||||
<form method="post" action="/@@/@ctx.2.clone().expect("Editing profile while not connected").get_fqn(ctx.0)/delete">
|
||||
@if !u.is_admin {
|
||||
<form method="post" action="@uri!(user::delete: name = u.username)">
|
||||
<input type="submit" class="inline-block button destructive" value="@i18n!(ctx.1, "Delete your account")">
|
||||
</form>
|
||||
} else {
|
||||
<p>@i18n!(ctx.1, "Sorry, but as an admin, you can't leave your instance.")</p>
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
@use templates::{base, users::header};
|
||||
@use template_utils::*;
|
||||
@use plume_models::users::User;
|
||||
@use routes::*;
|
||||
|
||||
@(ctx: BaseContext, user: User, follows: bool, is_remote: bool, remote_url: String, followers: Vec<User>, page: i32, n_pages: i32)
|
||||
|
||||
|
@ -8,14 +9,14 @@
|
|||
@:header(ctx, &user, follows, is_remote, remote_url)
|
||||
|
||||
@tabs(&[
|
||||
(&format!("/@/{}", user.get_fqn(ctx.0)), i18n!(ctx.1, "Articles"), false),
|
||||
(&format!("/@/{}/followers", user.get_fqn(ctx.0)), i18n!(ctx.1, "Followers"), true)
|
||||
(&uri!(user::details: name= user.get_fqn(ctx.0)).to_string(), i18n!(ctx.1, "Articles"), false),
|
||||
(&uri!(user::followers: name = user.get_fqn(ctx.0)).to_string(), i18n!(ctx.1, "Followers"), true)
|
||||
])
|
||||
|
||||
<div class="cards">
|
||||
@for follower in followers {
|
||||
<div class="card">
|
||||
<h3><a href="/@@/@follower.get_fqn(ctx.0)/">@follower.name(ctx.0)</a> <small>@format!("@{}", follower.get_fqn(ctx.0))</small></h3>
|
||||
<h3><a href="@uri!(user::details: name = follower.get_fqn(ctx.0))">@follower.name(ctx.0)</a> <small>@format!("@{}", follower.get_fqn(ctx.0))</small></h3>
|
||||
<main><p>@Html(follower.summary)</p></main>
|
||||
</div>
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
@use template_utils::*;
|
||||
@use plume_models::users::User;
|
||||
@use routes::*;
|
||||
|
||||
@(ctx: BaseContext, user: &User, follows: bool, is_remote: bool, instance_url: String)
|
||||
|
||||
|
@ -19,7 +20,7 @@
|
|||
|
||||
@if ctx.2.clone().map(|u| u.id == user.id).unwrap_or(false) {
|
||||
<span class="badge">@i18n!(ctx.1, "It is you")</span>
|
||||
<a href="/@@/@user.username/edit" class="button inline-block">@i18n!(ctx.1, "Edit your profile")</a>
|
||||
<a href="@uri!(user::edit: name = &user.username)" class="button inline-block">@i18n!(ctx.1, "Edit your profile")</a>
|
||||
}
|
||||
</p>
|
||||
</div>
|
||||
|
@ -29,7 +30,7 @@
|
|||
}
|
||||
|
||||
@if ctx.2.clone().map(|u| u.id != user.id).unwrap_or(false) {
|
||||
<form class="inline" method="post" action="/@@/@user.get_fqn(ctx.0)/follow/">
|
||||
<form class="inline" method="post" action="@uri!(user::follow: name = user.get_fqn(ctx.0))">
|
||||
@if follows {
|
||||
<input type="submit" value="@i18n!(ctx.1, "Unfollow")">
|
||||
} else {
|
||||
|
|
|
@ -2,13 +2,14 @@
|
|||
@use template_utils::*;
|
||||
@use routes::user::NewUserForm;
|
||||
@use validator::ValidationErrors;
|
||||
@use routes::*;
|
||||
|
||||
@(ctx: BaseContext, enabled: bool, form: &NewUserForm, errors: ValidationErrors)
|
||||
|
||||
@:base(ctx, "Edit your account", {}, {}, {
|
||||
@if enabled {
|
||||
<h1>@i18n!(ctx.1, "Create an account")</h1>
|
||||
<form method="post">
|
||||
<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\"")
|
||||
|
|
Loading…
Reference in New Issue