Use Ructe (#327)
All the template are now compiled at compile-time with the `ructe` crate.
I preferred to use it instead of askama because it allows more complex Rust expressions, where askama only supports a small subset of expressions and doesn't allow them everywhere (for instance, `{{ macro!() | filter }}` would result in a parsing error).
The diff is quite huge, but there is normally no changes in functionality.
Fixes #161 and unblocks #110 and #273
This commit is contained in:
@@ -1,41 +0,0 @@
|
||||
{% extends "base" %}
|
||||
{% import "macros" as macros %}
|
||||
|
||||
{% block title %}
|
||||
About {{ instance.name }}
|
||||
{% endblock title %}
|
||||
|
||||
{% block content %}
|
||||
<h1>{{ "About {{ instance_name }}" | _(instance_name=instance.name) }}</h1>
|
||||
<section>
|
||||
{{ instance.short_description_html | safe }}
|
||||
</section>
|
||||
<div class="banner">
|
||||
<section class="stats">
|
||||
<div>
|
||||
<p>{{ "Home to" | _ }}</p>
|
||||
<em>{{ n_users }}</em>
|
||||
<p>{{ "people" | _ }}</p>
|
||||
</div>
|
||||
<div>
|
||||
<p>{{ "Who wrote" | _ }}</p>
|
||||
<em>{{ n_articles }}</em>
|
||||
<p>{{ "articles" | _ }}</p>
|
||||
</div>
|
||||
<div>
|
||||
<p>{{ "And connected to" | _ }}</p>
|
||||
<em>{{ n_instances }}</em>
|
||||
<p>{{ "other instances" | _ }}</p>
|
||||
</div>
|
||||
<div>
|
||||
<p>{{ "Administred by" | _ }}</p>
|
||||
{{ macros::avatar(user=admin) }}
|
||||
<p><a href="/@/{{ admin.fqn }}">{{ admin.name }}</a><small>(@{{ admin.fqn }})</small></p>
|
||||
</div>
|
||||
</section>
|
||||
<p>{{ "Runs Plume {{ version }}" | _(version=version) }}
|
||||
</div>
|
||||
<section>
|
||||
{{ instance.long_description_html | safe }}
|
||||
</section>
|
||||
{% endblock content %}
|
||||
@@ -0,0 +1,34 @@
|
||||
@use templates::base;
|
||||
@use template_utils::*;
|
||||
@use plume_models::{instance::Instance, users::User};
|
||||
|
||||
@(ctx: BaseContext, instance: Instance, admin: User, n_users: usize, n_articles: usize, n_instances: i64)
|
||||
|
||||
@:base(ctx, i18n!(ctx.1, "About {0}"; instance.name.clone()).as_str(), {}, {}, {
|
||||
<h1>@i18n!(ctx.1, "About {0}"; instance.name)</h1>
|
||||
<section>
|
||||
@Html(instance.short_description_html)
|
||||
</section>
|
||||
<div class="banner">
|
||||
<section class="stats">
|
||||
<div>
|
||||
<p>@Html(i18n!(ctx.1, "Home to <em>{0}</em> users"; n_users))</p>
|
||||
</div>
|
||||
<div>
|
||||
<p>@Html(i18n!(ctx.1, "Who wrote <em>{0}</em> articles"; n_articles))</p>
|
||||
</div>
|
||||
<div>
|
||||
<p>@Html(i18n!(ctx.1, "And connected to <em>{0}</em> other instances"; n_instances))</p>
|
||||
</div>
|
||||
<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>
|
||||
</div>
|
||||
</section>
|
||||
<p>@i18n!(ctx.1, "Runs Plume {0}"; env!("CARGO_PKG_VERSION"))</p>
|
||||
</div>
|
||||
<section>
|
||||
@Html(instance.long_description_html)
|
||||
</section>
|
||||
})
|
||||
@@ -1,35 +0,0 @@
|
||||
{% extends "base" %}
|
||||
{% import "macros" as macros %}
|
||||
|
||||
{% block title %}
|
||||
{{ "Administration of {{ instance.name }}" | _(instance=instance) }}
|
||||
{% endblock title %}
|
||||
|
||||
{% block content %}
|
||||
<h1>{{ "Administration" | _ }}</h1>
|
||||
|
||||
{{ macros::tabs(links=['/admin', '/admin/instances', '/admin/users'], titles=['Configuration', 'Instances', 'Users'], selected=1) }}
|
||||
|
||||
<form method="post">
|
||||
{{ macros::input(name="name", label="Name", errors=errors, form=form, props='minlenght="1"', default=instance) }}
|
||||
|
||||
<label for="open_registrations">
|
||||
{% if instance.open_registrations %}
|
||||
<input type="checkbox" name="open_registrations" id="open_registrations" checked>
|
||||
{% else %}
|
||||
<input type="checkbox" name="open_registrations" id="open_registrations">
|
||||
{% endif %}
|
||||
{{ "Allow anyone to register" | _ }}
|
||||
</label>
|
||||
|
||||
<label for="short_description">{{ "Short description" | _ }}<small>{{ "Markdown is supported" | _ }}</small></label>
|
||||
<textarea id="short_description" name="short_description">{{ form.short_description | default(value=instance.short_description | safe) }}</textarea>
|
||||
|
||||
<label for="long_description">{{ "Long description" | _ }}<small>{{ "Markdown is supported" | _ }}</small></label>
|
||||
<textarea id="long_description" name="long_description">{{ form.long_description | default(value=instance.long_description | safe) }}</textarea>
|
||||
|
||||
{{ macros::input(name="default_license", label="Default license", errors=errors, form=form, props='minlenght="1"', default=instance) }}
|
||||
|
||||
<input type="submit" value="{{ "Save settings" | _ }}"/>
|
||||
</form>
|
||||
{% endblock content %}
|
||||
@@ -0,0 +1,39 @@
|
||||
@use templates::base;
|
||||
@use template_utils::*;
|
||||
@use plume_models::instance::Instance;
|
||||
@use routes::instance::InstanceSettingsForm;
|
||||
@use validator::ValidationErrors;
|
||||
|
||||
@(ctx: BaseContext, instance: Instance, form: InstanceSettingsForm, errors: ValidationErrors)
|
||||
|
||||
@:base(ctx, i18n!(ctx.1, "Administration of {0}"; instance.name.clone()).as_str(), {}, {}, {
|
||||
<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),
|
||||
])
|
||||
|
||||
<form method="post">
|
||||
@input!(ctx.1, name (text), "Name", form, errors.clone(), "props")
|
||||
|
||||
<label for="open_registrations">
|
||||
@if instance.open_registrations {
|
||||
<input type="checkbox" name="open_registrations" id="open_registrations" checked>
|
||||
} else {
|
||||
<input type="checkbox" name="open_registrations" id="open_registrations">
|
||||
}
|
||||
@i18n!(ctx.1, "Allow anyone to register")
|
||||
|
||||
<label for="short_description">@i18n!(ctx.1, "Short description")<small>@i18n!(ctx.1, "Markdown is supported")</small></label>
|
||||
<textarea id="short_description" name="short_description">@Html(form.short_description)</textarea>
|
||||
|
||||
<label for="long_description">@i18n!(ctx.1, "Long description")<small>@i18n!(ctx.1, "Markdown is supported")</small></label>
|
||||
<textarea id="long_description" name="long_description">@Html(form.long_description)</textarea>
|
||||
|
||||
@input!(ctx.1, default_license (text), "Default license", form, errors, "minlenght=\"1\"")
|
||||
|
||||
<input type="submit" value="@i18n!(ctx.1, "Save settings")"/>
|
||||
</form>
|
||||
})
|
||||
@@ -1,32 +0,0 @@
|
||||
<section class="spaced">
|
||||
<div class="cards">
|
||||
<div class="presentation card">
|
||||
<h2>{{ "What is Plume?" | _ }}</h2>
|
||||
<main>
|
||||
<p>{{ "Plume is a decentralized blogging engine." | _ }}</p>
|
||||
<p>{{ "Authors can manage various blogs from an unique website." | _ }}</p>
|
||||
<p>{{ "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">{{ "Create your account" | _ }}</a>
|
||||
</div>
|
||||
<div class="presentation card">
|
||||
<h2>{{ "About {{ instance_name }}" | _(instance_name=instance.name) }}</h2>
|
||||
<main>
|
||||
{{ instance.short_description_html | safe }}
|
||||
<section class="stats">
|
||||
<div>
|
||||
<p>{{ "Home to" | _ }}</p>
|
||||
<em>{{ n_users }}</em>
|
||||
<p>{{ "people" | _ }}</p>
|
||||
</div>
|
||||
<div>
|
||||
<p>{{ "Who wrote" | _ }}</p>
|
||||
<em>{{ n_articles }}</em>
|
||||
<p>{{ "articles" | _ }}</p>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
<a href="/about">{{ "Read the detailed rules" | _ }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -1,23 +0,0 @@
|
||||
{% extends "base" %}
|
||||
{% import "macros" as macros %}
|
||||
|
||||
{% block title %}
|
||||
{{ "All the articles of the Fediverse" | _ }}
|
||||
{% endblock title %}
|
||||
|
||||
{% block content %}
|
||||
<h1>{{ "All the articles of the Fediverse" | _ }}</h1>
|
||||
|
||||
{% if account %}
|
||||
{{ macros::tabs(links=['/', '/feed', '/federated', '/local'], titles=['Latest articles', 'Your feed', 'Federated feed', 'Local feed'], selected=3) }}
|
||||
{% else %}
|
||||
{{ macros::tabs(links=['/', '/federated', '/local'], titles=['Latest articles', 'Federated feed', 'Local feed'], selected=2) }}
|
||||
{% endif %}
|
||||
|
||||
<div class="cards">
|
||||
{% for article in articles %}
|
||||
{{ macros::post_card(article=article) }}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{{ macros::paginate(page=page, total=n_pages) }}
|
||||
{% endblock content %}
|
||||
@@ -0,0 +1,31 @@
|
||||
@use templates::{base, partials::post_card};
|
||||
@use template_utils::*;
|
||||
@use plume_models::posts::Post;
|
||||
|
||||
@(ctx: BaseContext, articles: Vec<Post>, page: i32, n_pages: i32)
|
||||
|
||||
@:base(ctx, "All the articles of the Fediverse", {}, {}, {
|
||||
<h1>@i18n!(ctx.1, "All the articles of the Fediverse")</h1>
|
||||
|
||||
@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),
|
||||
])
|
||||
} else {
|
||||
@tabs(&[
|
||||
("/", i18n!(ctx.1, "Latest articles"), false),
|
||||
("/federated", i18n!(ctx.1, "Federated feed"), true),
|
||||
("/local", i18n!(ctx.1, "Local feed"), false),
|
||||
])
|
||||
}
|
||||
|
||||
<div class="cards">
|
||||
@for article in articles {
|
||||
@:post_card(ctx, article)
|
||||
}
|
||||
</div>
|
||||
@paginate(ctx.1, page, n_pages)
|
||||
})
|
||||
@@ -1,25 +0,0 @@
|
||||
{% extends "base" %}
|
||||
{% import "macros" as macros %}
|
||||
|
||||
{% block title %}
|
||||
{{ "Your feed" | _ }}
|
||||
{% endblock title %}
|
||||
|
||||
{% block content %}
|
||||
<h1>
|
||||
{{ "Your feed" | _ }}
|
||||
</h1>
|
||||
|
||||
{{ macros::tabs(links=['/', '/feed', '/federated', '/local'], titles=['Latest articles', 'Your feed', 'Federated feed', 'Local feed'], selected=2) }}
|
||||
|
||||
{% if articles | length > 0 %}
|
||||
<div class="cards">
|
||||
{% for article in articles %}
|
||||
{{ macros::post_card(article=article) }}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{{ macros::paginate(page=page, total=n_pages) }}
|
||||
{% else %}
|
||||
<p class="center">{{ "Nothing to see here yet. Try to follow more people." | _ }}</p>
|
||||
{% endif %}
|
||||
{% endblock content %}
|
||||
@@ -0,0 +1,27 @@
|
||||
@use templates::{base, partials::post_card};
|
||||
@use template_utils::*;
|
||||
@use plume_models::posts::Post;
|
||||
|
||||
@(ctx: BaseContext, articles: Vec<Post>, page: i32, n_pages: i32)
|
||||
|
||||
@:base(ctx, "Your feed", {}, {}, {
|
||||
<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),
|
||||
])
|
||||
|
||||
@if !articles.is_empty() {
|
||||
<div class="cards">
|
||||
@for article in articles {
|
||||
@:post_card(ctx, article)
|
||||
}
|
||||
</div>
|
||||
} else {
|
||||
<p class="center">@i18n!(ctx.1, "Nothing to see here yet. Try to follow more people.")</p>
|
||||
}
|
||||
@paginate(ctx.1, page, n_pages)
|
||||
})
|
||||
@@ -1,25 +0,0 @@
|
||||
{% extends "base" %}
|
||||
{% import "macros" as macros %}
|
||||
|
||||
{% block title %}
|
||||
{{ instance.name }}
|
||||
{% endblock title %}
|
||||
|
||||
{% block content %}
|
||||
<h1>{{ "Welcome to {{ instance_name | escape }}" | _(instance_name=instance.name) }}</h1>
|
||||
|
||||
{% if account %}
|
||||
{{ macros::tabs(links=['/', '/feed', '/federated', '/local'], titles=['Latest articles', 'Your feed', 'Federated feed', 'Local feed'], selected=1) }}
|
||||
|
||||
{{ macros::home_feed(title='Your feed', link='/feed', articles=user_feed) }}
|
||||
{{ macros::home_feed(title='Federated feed', link='/federated', articles=federated) }}
|
||||
{{ macros::home_feed(title='Local feed', link='/local', articles=local) }}
|
||||
{% include "instance/description" %}
|
||||
{% else %}
|
||||
{{ macros::tabs(links=['/', '/federated', '/local'], titles=['Latest articles', 'Federated feed', 'Local feed'], selected=1) }}
|
||||
|
||||
{{ macros::home_feed(title='Federated feed', link='/federated', articles=federated) }}
|
||||
{% include "instance/description" %}
|
||||
{{ macros::home_feed(title='Local feed', link='/local', articles=local) }}
|
||||
{% endif %}
|
||||
{% endblock content %}
|
||||
@@ -0,0 +1,34 @@
|
||||
@use templates::{base, partials::*};
|
||||
@use template_utils::*;
|
||||
@use plume_models::instance::Instance;
|
||||
@use plume_models::posts::Post;
|
||||
|
||||
@(ctx: BaseContext, instance: Instance, n_users: i32, n_articles: i32, local: Vec<Post>, federated: Vec<Post>, user_feed: Option<Vec<Post>>)
|
||||
|
||||
@:base(ctx, instance.name.clone().as_ref(), {}, {}, {
|
||||
<h1>@i18n!(ctx.1, "Welcome on {}"; instance.name.as_str())</h1>
|
||||
|
||||
@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),
|
||||
])
|
||||
|
||||
@: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")
|
||||
@: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),
|
||||
])
|
||||
|
||||
@:home_feed(ctx, federated, "/federated", "Federated feed")
|
||||
@:home_feed(ctx, local, "/local", "Local feed")
|
||||
@:instance_description(ctx, instance, n_users, n_articles)
|
||||
}
|
||||
})
|
||||
@@ -1,33 +0,0 @@
|
||||
{% extends "base" %}
|
||||
{% import "macros" as macros %}
|
||||
|
||||
{% block title %}
|
||||
{{ "Administration of {{ instance.name }}" | _(instance=instance) }}
|
||||
{% endblock title %}
|
||||
|
||||
{% block content %}
|
||||
<h1>{{ "Instances" | _ }}</h1>
|
||||
|
||||
{{ macros::tabs(links=['/admin', '/admin/instances', '/admin/users'], titles=['Configuration', 'Instances', 'Users'], selected=2) }}
|
||||
|
||||
<div class="list">
|
||||
{% for instance in instances %}
|
||||
<div class="flex">
|
||||
<p class="grow">
|
||||
<a href="https://{{ instance.public_domain }}">{{ instance.name }}</a>
|
||||
<small>{{ instance.public_domain }}</small>
|
||||
</p>
|
||||
{% if not instance.local %}
|
||||
<form class="inline" method="post" action="/admin/instances/{{ instance.id }}/block">
|
||||
{% if instance.blocked %}
|
||||
<input type="submit" value="{{ 'Unblock' | _ }}">
|
||||
{% else %}
|
||||
<input type="submit" value="{{ 'Block' | _ }}">
|
||||
{% endif %}
|
||||
</form>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{{ macros::paginate(page=page, total=n_pages) }}
|
||||
{% endblock content %}
|
||||
@@ -0,0 +1,32 @@
|
||||
@use templates::base;
|
||||
@use template_utils::*;
|
||||
@use plume_models::instance::Instance;
|
||||
|
||||
@(ctx: BaseContext, instance: Instance, instances: Vec<Instance>, page: i32, n_pages: i32)
|
||||
|
||||
@:base(ctx, i18n!(ctx.1, "Administration of {0}"; instance.name.clone()).as_str(), {}, {}, {
|
||||
<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),
|
||||
])
|
||||
|
||||
<div class="list">
|
||||
@for instance in instances {
|
||||
<div class="flex">
|
||||
<p class="grow">
|
||||
<a href="https://@instance.public_domain">@instance.name</a>
|
||||
<small>@instance.public_domain</small>
|
||||
</p>
|
||||
@if !instance.local {
|
||||
<form class="inline" method="post" action="/admin/instances/@instance.id/block">
|
||||
<input type="submit" value="@i18n!(ctx.1, if instance.blocked { "Unblock" } else { "Block"})">
|
||||
</form>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
@paginate(ctx.1, page, n_pages)
|
||||
})
|
||||
@@ -1,23 +0,0 @@
|
||||
{% extends "base" %}
|
||||
{% import "macros" as macros %}
|
||||
|
||||
{% block title %}
|
||||
{{ "Articles from {{ instance.name }}" | _(instance=instance) }}
|
||||
{% endblock title %}
|
||||
|
||||
{% block content %}
|
||||
<h1>{{ "Articles from {{ instance.name }}" | _(instance=instance) }}</h1>
|
||||
|
||||
{% if account %}
|
||||
{{ macros::tabs(links=['/', '/feed', '/federated', '/local'], titles=['Latest articles', 'Your feed', 'Federated feed', 'Local feed'], selected=4) }}
|
||||
{% else %}
|
||||
{{ macros::tabs(links=['/', '/federated', '/local'], titles=['Latest articles', 'Federated feed', 'Local feed'], selected=3) }}
|
||||
{% endif %}
|
||||
|
||||
<div class="cards">
|
||||
{% for article in articles %}
|
||||
{{ macros::post_card(article=article) }}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{{ macros::paginate(page=page, total=n_pages) }}
|
||||
{% endblock content %}
|
||||
@@ -0,0 +1,32 @@
|
||||
@use templates::{base, partials::post_card};
|
||||
@use template_utils::*;
|
||||
@use plume_models::posts::Post;
|
||||
@use plume_models::instance::Instance;
|
||||
|
||||
@(ctx: BaseContext, instance: Instance, articles: Vec<Post>, page: i32, n_pages: i32)
|
||||
|
||||
@:base(ctx, i18n!(ctx.1, "Articles from {}"; instance.name.clone()).as_str(), {}, {}, {
|
||||
<h1>@i18n!(ctx.1, "Articles from {}"; instance.name)</h1>
|
||||
|
||||
@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),
|
||||
])
|
||||
} else {
|
||||
@tabs(&[
|
||||
("/", i18n!(ctx.1, "Latest articles"), false),
|
||||
("/federated", i18n!(ctx.1, "Federated feed"), false),
|
||||
("/local", i18n!(ctx.1, "Local feed"), true),
|
||||
])
|
||||
}
|
||||
|
||||
<div class="cards">
|
||||
@for article in articles {
|
||||
@:post_card(ctx, article)
|
||||
}
|
||||
</div>
|
||||
@paginate(ctx.1, page, n_pages)
|
||||
})
|
||||
@@ -1,30 +0,0 @@
|
||||
{% extends "base" %}
|
||||
{% import "macros" as macros %}
|
||||
|
||||
{% block title %}
|
||||
{{ "Users" | _ }}
|
||||
{% endblock title %}
|
||||
|
||||
{% block content %}
|
||||
<h1>{{ "Users" | _ }}</h1>
|
||||
|
||||
{{ macros::tabs(links=['/admin', '/admin/instances', '/admin/users'], titles=['Configuration', 'Instances', 'Users'], selected=3) }}
|
||||
|
||||
<div class="list">
|
||||
{% for user in users %}
|
||||
<div class="flex">
|
||||
{{ macros::avatar(user=user) }}
|
||||
<p class="grow">
|
||||
<a href="/@/{{ user.fqn }}">{{ user.name }}</a>
|
||||
<small>@{{ user.username }}</small>
|
||||
</p>
|
||||
{% if not user.is_admin %}
|
||||
<form class="inline" method="post" href="/admin/users/{{ user.id }}/ban">
|
||||
<input type="submit" value="{{ 'Ban' | _ }}">
|
||||
</form>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{{ macros::paginate(page=page, total=n_pages) }}
|
||||
{% endblock content %}
|
||||
@@ -0,0 +1,33 @@
|
||||
@use templates::base;
|
||||
@use template_utils::*;
|
||||
@use plume_models::users::User;
|
||||
|
||||
@(ctx: BaseContext, users: Vec<User>, page: i32, n_pages: i32)
|
||||
|
||||
@:base(ctx, "Users", {}, {}, {
|
||||
<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),
|
||||
])
|
||||
|
||||
<div class="list">
|
||||
@for user in users {
|
||||
<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>
|
||||
<small>@format!("@{}", user.username)</small>
|
||||
</p>
|
||||
@if !user.is_admin {
|
||||
<form class="inline" method="post" action="/admin/users/@user.id/ban">
|
||||
<input type="submit" value="@i18n!(ctx.1, "Ban")">
|
||||
</form>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
@paginate(ctx.1, page, n_pages)
|
||||
})
|
||||
Reference in New Issue
Block a user