add custom handlers for index

This commit is contained in:
Manuel Gugger 2022-08-29 13:06:44 +02:00
parent 3e2b765678
commit 420bdbceaf
9 changed files with 91 additions and 14 deletions

View File

@ -7,10 +7,10 @@ use azure_auth::{AppDataTrait as AzureAuthAppDataTrait, AzureAuth, UserInfo};
use oauth2::basic::BasicClient; use oauth2::basic::BasicClient;
use oauth2::RedirectUrl; use oauth2::RedirectUrl;
use sea_orm::{ConnectOptions, DatabaseConnection}; use sea_orm::{ConnectOptions, DatabaseConnection};
use actix_web::http::header::ContentType;
use std::env; use std::env;
use std::time::Duration; use std::time::Duration;
use tera::{Context, Tera}; use tera::{Context, Tera};
use actix_web::Error;
mod entity; mod entity;
use entity::{Post, Comment}; use entity::{Post, Comment};
@ -32,6 +32,16 @@ impl ActixAdminAppDataTrait for AppState {
} }
} }
trait AppDataTrait {
fn get_tmpl(&self) -> &Tera;
}
impl AppDataTrait for AppState {
fn get_tmpl(&self) -> &Tera {
&self.tmpl
}
}
impl AzureAuthAppDataTrait for AppState { impl AzureAuthAppDataTrait for AppState {
fn get_oauth(&self) -> &BasicClient { fn get_oauth(&self) -> &BasicClient {
&self.oauth &self.oauth
@ -39,18 +49,41 @@ impl AzureAuthAppDataTrait for AppState {
} }
async fn custom_handler< async fn custom_handler<
T: ActixAdminAppDataTrait, T: ActixAdminAppDataTrait + AppDataTrait,
E: ActixAdminViewModelTrait, E: ActixAdminViewModelTrait,
>( >(
_session: Session, session: Session,
_data: web::Data<T>, data: web::Data<T>,
_text: String _text: String
) -> HttpResponse { ) -> Result<HttpResponse, Error> {
HttpResponse::Ok()
.content_type(ContentType::plaintext()) let mut ctx = Context::new();
.body("data") ctx.extend(get_admin_ctx(session, &data));
let body = data.get_tmpl()
.render("custom_handler.html", &ctx).unwrap();
Ok(HttpResponse::Ok().content_type("text/html").body(body))
} }
async fn custom_index<
T: ActixAdminAppDataTrait + AppDataTrait
>(
session: Session,
data: web::Data<T>,
_text: String
) -> Result<HttpResponse, Error> {
let mut ctx = Context::new();
ctx.extend(get_admin_ctx(session, &data));
let body = data.get_tmpl()
.render("custom_index.html", &ctx).unwrap();
Ok(HttpResponse::Ok().content_type("text/html").body(body))
}
async fn index(session: Session, data: web::Data<AppState>) -> HttpResponse { async fn index(session: Session, data: web::Data<AppState>) -> HttpResponse {
let login = session.get::<UserInfo>("user_info").unwrap(); let login = session.get::<UserInfo>("user_info").unwrap();
let web_auth_link = if login.is_some() { let web_auth_link = if login.is_some() {
@ -82,6 +115,9 @@ fn create_actix_admin_builder() -> ActixAdminBuilder {
let mut admin_builder = ActixAdminBuilder::new(configuration); let mut admin_builder = ActixAdminBuilder::new(configuration);
admin_builder.add_entity::<AppState, Post>(&post_view_model); admin_builder.add_entity::<AppState, Post>(&post_view_model);
admin_builder.add_entity::<AppState, Comment>(&comment_view_model); admin_builder.add_entity::<AppState, Comment>(&comment_view_model);
admin_builder.add_custom_handler_for_index::<AppState>(
web::get().to(custom_index::<AppState>)
);
admin_builder.add_custom_handler_for_entity::<AppState, Comment>( admin_builder.add_custom_handler_for_entity::<AppState, Comment>(
"/custom_handler", "/custom_handler",
web::get().to(custom_handler::<AppState, Comment>) web::get().to(custom_handler::<AppState, Comment>)
@ -111,7 +147,9 @@ async fn main() {
.expect("Invalid redirect URL"), .expect("Invalid redirect URL"),
); );
let tera = Tera::new(concat!(env!("CARGO_MANIFEST_DIR"), "/templates/**/*")).unwrap(); let mut tera = Tera::parse(concat!(env!("CARGO_MANIFEST_DIR"), "/templates/**/*")).unwrap();
tera.extend(&TERA).unwrap();
let _tera_res = tera.build_inheritance_chains();
let db_url = env::var("DATABASE_URL").expect("DATABASE_URL is not set in .env file"); let db_url = env::var("DATABASE_URL").expect("DATABASE_URL is not set in .env file");
let mut opt = ConnectOptions::new(db_url); let mut opt = ConnectOptions::new(db_url);

View File

@ -0,0 +1,5 @@
{% extends "base.html" %}
{% block content %}
custom handler
{% endblock content %}

View File

@ -0,0 +1,5 @@
{% extends "base.html" %}
{% block content %}
custom index
{% endblock content %}

View File

@ -1,4 +1,4 @@
{% extends "base.html" %} {% extends "example_base.html" %}
{% block content %} {% block content %}
<ul> <ul>

View File

@ -8,6 +8,7 @@ use crate::routes::{create_get, create_post, delete, delete_many, edit_get, edit
pub struct ActixAdminBuilder { pub struct ActixAdminBuilder {
pub scopes: HashMap<String, actix_web::Scope>, pub scopes: HashMap<String, actix_web::Scope>,
pub actix_admin: ActixAdmin, pub actix_admin: ActixAdmin,
pub custom_index: Option<Route>
} }
pub trait ActixAdminBuilderTrait { pub trait ActixAdminBuilderTrait {
@ -21,6 +22,10 @@ pub trait ActixAdminBuilderTrait {
path: &str, path: &str,
route: Route route: Route
); );
fn add_custom_handler_for_index<T: ActixAdminAppDataTrait + 'static>(
&mut self,
route: Route
);
fn get_scope<T: ActixAdminAppDataTrait + 'static>(self) -> actix_web::Scope; fn get_scope<T: ActixAdminAppDataTrait + 'static>(self) -> actix_web::Scope;
fn get_actix_admin(&self) -> ActixAdmin; fn get_actix_admin(&self) -> ActixAdmin;
} }
@ -34,6 +39,7 @@ impl ActixAdminBuilderTrait for ActixAdminBuilder {
configuration: configuration configuration: configuration
}, },
scopes: HashMap::new(), scopes: HashMap::new(),
custom_index: None
} }
} }
@ -58,6 +64,13 @@ impl ActixAdminBuilderTrait for ActixAdminBuilder {
self.actix_admin.view_models.insert(key, view_model.clone()); self.actix_admin.view_models.insert(key, view_model.clone());
} }
fn add_custom_handler_for_index<T: ActixAdminAppDataTrait + 'static>(
&mut self,
route: Route
) {
self.custom_index = Some(route);
}
fn add_custom_handler_for_entity<T: ActixAdminAppDataTrait + 'static, E: ActixAdminViewModelTrait + 'static>( fn add_custom_handler_for_entity<T: ActixAdminAppDataTrait + 'static, E: ActixAdminViewModelTrait + 'static>(
&mut self, &mut self,
path: &str, path: &str,
@ -83,7 +96,11 @@ impl ActixAdminBuilderTrait for ActixAdminBuilder {
} }
fn get_scope<T: ActixAdminAppDataTrait + 'static>(mut self) -> actix_web::Scope { fn get_scope<T: ActixAdminAppDataTrait + 'static>(mut self) -> actix_web::Scope {
let mut admin_scope = web::scope("/admin").route("/", web::get().to(index::<T>)); let index_handler = match self.custom_index {
Some(handler) => handler,
_ => web::get().to(index::<T>)
};
let mut admin_scope = web::scope("/admin").route("/", index_handler);
for entity_name in self.actix_admin.entity_names { for entity_name in self.actix_admin.entity_names {
let scope = self.scopes.remove(&entity_name).unwrap(); let scope = self.scopes.remove(&entity_name).unwrap();
admin_scope = admin_scope.service(scope); admin_scope = admin_scope.service(scope);

View File

@ -18,7 +18,8 @@ pub mod prelude {
pub use actix_admin_macros::{ DeriveActixAdmin, DeriveActixAdminModel, DeriveActixAdminViewModel, DeriveActixAdminEnumSelectList, DeriveActixAdminModelSelectList }; pub use actix_admin_macros::{ DeriveActixAdmin, DeriveActixAdminModel, DeriveActixAdminViewModel, DeriveActixAdminEnumSelectList, DeriveActixAdminModelSelectList };
pub use crate::{ ActixAdminAppDataTrait, ActixAdmin, ActixAdminConfiguration }; pub use crate::{ ActixAdminAppDataTrait, ActixAdmin, ActixAdminConfiguration };
pub use crate::{ hashmap, ActixAdminSelectListTrait }; pub use crate::{ hashmap, ActixAdminSelectListTrait };
pub use crate::routes::{ create_or_edit_post }; pub use crate::routes::{ create_or_edit_post, get_admin_ctx };
pub use crate::{ TERA };
} }
use crate::prelude::*; use crate::prelude::*;
@ -34,7 +35,7 @@ macro_rules! hashmap {
// globals // globals
lazy_static! { lazy_static! {
static ref TERA: Tera = { pub static ref TERA: Tera = {
let mut tera = Tera::new(concat!(env!("CARGO_MANIFEST_DIR"), "/templates/**/*")).unwrap(); let mut tera = Tera::new(concat!(env!("CARGO_MANIFEST_DIR"), "/templates/**/*")).unwrap();
tera.register_filter("get_html_input_type", get_html_input_type); tera.register_filter("get_html_input_type", get_html_input_type);
tera.register_filter("get_html_input_class", get_html_input_class); tera.register_filter("get_html_input_class", get_html_input_class);

View File

@ -8,6 +8,17 @@ use crate::TERA;
use super::{ add_auth_context }; use super::{ add_auth_context };
pub fn get_admin_ctx<T: ActixAdminAppDataTrait>(session: Session, data: &web::Data<T>) -> Context {
let actix_admin = data.get_actix_admin();
let mut ctx = Context::new();
ctx.insert("entity_names", &actix_admin.entity_names);
add_auth_context(&session, actix_admin, &mut ctx);
ctx
}
pub async fn index<T: ActixAdminAppDataTrait>(session: Session, data: web::Data<T>) -> Result<HttpResponse, Error> { pub async fn index<T: ActixAdminAppDataTrait>(session: Session, data: web::Data<T>) -> Result<HttpResponse, Error> {
let actix_admin = data.get_actix_admin(); let actix_admin = data.get_actix_admin();

View File

@ -5,7 +5,7 @@ mod create_or_edit_post;
pub use create_or_edit_post::{ create_post, edit_post, create_or_edit_post }; pub use create_or_edit_post::{ create_post, edit_post, create_or_edit_post };
mod index; mod index;
pub use index::index; pub use index::{ index, get_admin_ctx };
mod list; mod list;
pub use list::list; pub use list::list;