ezidam: icons: moved to own module, macro to generate struct constants, ability to use as tera templates

This commit is contained in:
Philippe Loctaux 2023-03-30 23:40:34 +02:00
parent 0c04322189
commit f5fee63a15
6 changed files with 74 additions and 14 deletions

View file

@ -0,0 +1,59 @@
use rocket_dyn_templates::tera::Tera;
pub struct Icon {
/// Lowercase name of icon
name: &'static str,
/// Find icons on https://tabler-icons.io
pub svg: &'static str,
}
/// Macro to generate icons
///
/// # Arguments
///
/// * `name` - Name of icon in lowercase
/// * `cap_name` - Capitalized name of icon
/// * `svg` - Icon in svg
macro_rules! icons {
($($name:expr, $cap_name:ident, $svg:expr),+) => {
$(
#[allow(non_upper_case_globals)]
pub const $cap_name: Icon = Icon {
name: $name,
svg: $svg,
};
)+
};
}
impl Icon {
icons! {
"home", Home, r#"<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-home" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M5 12l-2 0l9 -9l9 9l-2 0"></path><path d="M5 12v7a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-7"></path><path d="M9 21v-6a2 2 0 0 1 2 -2h2a2 2 0 0 1 2 2v6"></path></svg>"#,
"logout", Logout, r#"<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-logout" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M14 8v-2a2 2 0 0 0 -2 -2h-7a2 2 0 0 0 -2 2v12a2 2 0 0 0 2 2h7a2 2 0 0 0 2 -2v-2"></path><path d="M7 12h14l-3 -3m0 6l3 -3"></path></svg>"#,
"settings", Settings, r#"<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-settings" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M10.325 4.317c.426 -1.756 2.924 -1.756 3.35 0a1.724 1.724 0 0 0 2.573 1.066c1.543 -.94 3.31 .826 2.37 2.37a1.724 1.724 0 0 0 1.065 2.572c1.756 .426 1.756 2.924 0 3.35a1.724 1.724 0 0 0 -1.066 2.573c.94 1.543 -.826 3.31 -2.37 2.37a1.724 1.724 0 0 0 -2.572 1.065c-.426 1.756 -2.924 1.756 -3.35 0a1.724 1.724 0 0 0 -2.573 -1.066c-1.543 .94 -3.31 -.826 -2.37 -2.37a1.724 1.724 0 0 0 -1.065 -2.572c-1.756 -.426 -1.756 -2.924 0 -3.35a1.724 1.724 0 0 0 1.066 -2.573c-.94 -1.543 .826 -3.31 2.37 -2.37c1 .608 2.296 .07 2.572 -1.065z"></path><path d="M9 12a3 3 0 1 0 6 0a3 3 0 0 0 -6 0"></path></svg>"#,
"apps", Apps, r#"<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-apps" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M4 4m0 1a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1z"></path><path d="M4 14m0 1a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1z"></path><path d="M14 14m0 1a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1z"></path><path d="M14 7l6 0"></path><path d="M17 4l0 6"></path>svg>"#,
"plus", Plus, r#"<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-plus" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M12 5l0 14"></path><path d="M5 12l14 0"></path></svg>"#
}
}
/// Add icons as tera templates
///
/// To call an icon in tera: `{% include "icons/icon_name" %}`
pub fn icons_to_templates(tera: &mut Tera) {
let icons = [
Icon::Home,
Icon::Logout,
Icon::Settings,
Icon::Apps,
Icon::Plus,
];
// For each icon, it will output: ("icons/name", "<svg>...</svg>")
let tera_icons = icons
.iter()
.map(|icon| (format!("icons/{}", icon.name), icon.svg));
// Add icons as tera templates
tera.add_raw_templates(tera_icons)
.expect("failed to add icons");
}

View file

@ -5,6 +5,7 @@ mod database;
mod error;
mod file_from_bytes;
mod guards;
mod icons;
mod id;
mod menu;
mod oauth;
@ -21,6 +22,7 @@ pub fn rocket_setup(rocket_builder: Rocket<Build>) -> Rocket<Build> {
use cache::CacheControl;
use database::Database;
use error::catchers;
use icons::icons_to_templates;
use response_timer::ResponseTimer;
use rocket::fs::FileServer;
use rocket_dyn_templates::Template;
@ -35,7 +37,10 @@ pub fn rocket_setup(rocket_builder: Rocket<Build>) -> Rocket<Build> {
let rocket_builder = Database::rocket(rocket_builder);
// Templates
let rocket_builder = rocket_builder.attach(Template::fairing());
let rocket_builder = rocket_builder.attach(Template::custom(|engines| {
// Add icons as tera templates
icons_to_templates(&mut engines.tera)
}));
// Static assets
let rocket_builder = rocket_builder.mount("/", FileServer::from("static"));

View file

@ -1,4 +1,3 @@
mod icons;
mod items;
mod template;

View file

@ -1,5 +0,0 @@
/// Find icons on https://tabler-icons.io
pub const HOME: &str = r#"<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-home" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M5 12l-2 0l9 -9l9 9l-2 0"></path><path d="M5 12v7a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-7"></path><path d="M9 21v-6a2 2 0 0 1 2 -2h2a2 2 0 0 1 2 2v6"></path></svg>"#;
pub const LOGOUT: &str = r#"<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-logout" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M14 8v-2a2 2 0 0 0 -2 -2h-7a2 2 0 0 0 -2 2v12a2 2 0 0 0 2 2h7a2 2 0 0 0 2 -2v-2"></path><path d="M7 12h14l-3 -3m0 6l3 -3"></path></svg>"#;
pub const SETTINGS: &str = r#"<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-settings" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M10.325 4.317c.426 -1.756 2.924 -1.756 3.35 0a1.724 1.724 0 0 0 2.573 1.066c1.543 -.94 3.31 .826 2.37 2.37a1.724 1.724 0 0 0 1.065 2.572c1.756 .426 1.756 2.924 0 3.35a1.724 1.724 0 0 0 -1.066 2.573c.94 1.543 -.826 3.31 -2.37 2.37a1.724 1.724 0 0 0 -2.572 1.065c-.426 1.756 -2.924 1.756 -3.35 0a1.724 1.724 0 0 0 -2.573 -1.066c-1.543 .94 -3.31 -.826 -2.37 -2.37a1.724 1.724 0 0 0 -1.065 -2.572c-1.756 -.426 -1.756 -2.924 0 -3.35a1.724 1.724 0 0 0 1.066 -2.573c-.94 -1.543 .826 -3.31 2.37 -2.37c1 .608 2.296 .07 2.572 -1.065z"></path><path d="M9 12a3 3 0 1 0 6 0a3 3 0 0 0 -6 0"></path></svg>"#;
pub const APPS: &str = r#"<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-apps" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M4 4m0 1a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1z"></path><path d="M4 14m0 1a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1z"></path><path d="M14 14m0 1a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1z"></path><path d="M14 7l6 0"></path><path d="M17 4l0 6"></path>svg>"#;

View file

@ -1,4 +1,5 @@
use crate::menu::{icons, MainItem, SubItem};
use crate::icons::Icon;
use crate::menu::{MainItem, SubItem};
use crate::routes;
use rocket::uri;
@ -24,28 +25,28 @@ impl AdminMenu {
id: AdminMenu::Exit.id(),
label: "Exit admin panel",
link: uri!(routes::root::homepage).to_string(),
icon: icons::LOGOUT,
icon: Icon::Logout.svg,
sub: None,
},
MainItem {
id: AdminMenu::Dashboard.id(),
label: "Admin dashboard",
link: uri!(routes::admin::dashboard::admin_dashboard).to_string(),
icon: icons::HOME,
icon: Icon::Home.svg,
sub: None,
},
MainItem {
id: AdminMenu::Apps.id(),
label: "Applications",
link: uri!(routes::admin::apps::admin_apps).to_string(),
icon: icons::APPS,
icon: Icon::Apps.svg,
sub: None,
},
MainItem {
id: AdminMenu::Settings.id(),
label: "Server settings",
link: uri!(routes::admin::settings::settings_branding).to_string(),
icon: icons::SETTINGS,
icon: Icon::Settings.svg,
sub: Some(vec![
SubItem {
label: "Branding",

View file

@ -1,4 +1,5 @@
use crate::menu::{icons, MainItem};
use crate::icons::Icon;
use crate::menu::MainItem;
use crate::routes;
use rocket::uri;
@ -17,7 +18,7 @@ impl UserMenu {
id: UserMenu::Home.id(),
label: "Home",
link: uri!(routes::root::homepage).to_string(),
icon: icons::HOME,
icon: Icon::Home.svg,
sub: None,
}]
}