🍻 Primera revista a las traducciones por contexto
This commit is contained in:
parent
71b0b0889d
commit
0de26a4737
28 changed files with 307 additions and 187 deletions
|
|
@ -54,7 +54,7 @@ tracing-unwrap = { version = "0.10.0", default-features = false }
|
|||
tracing-actix-web = "0.7.4"
|
||||
|
||||
fluent-templates = "0.8.0"
|
||||
unic-langid = "0.9.1"
|
||||
unic-langid = { version = "0.9.1", features = ["macros"] }
|
||||
|
||||
actix-web = "4"
|
||||
actix-session = { version = "0.7.2", features = ["cookie-session"] }
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ mod figfont;
|
|||
|
||||
use crate::core::{module, module::ModuleStaticRef};
|
||||
use crate::html::Markup;
|
||||
use crate::response::fatal_error::FatalError;
|
||||
use crate::response::page::ResultPage;
|
||||
use crate::response::FatalError;
|
||||
use crate::{config, locale, server, trace, LazyStatic};
|
||||
|
||||
#[cfg(feature = "database")]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,12 @@
|
|||
mod context;
|
||||
pub use context::{ContextOp, RenderContext};
|
||||
|
||||
mod definition;
|
||||
pub use definition::{component_mut, component_ref, AnyComponent, BaseComponent, ComponentTrait};
|
||||
|
||||
mod arc;
|
||||
pub use arc::ComponentArc;
|
||||
|
||||
mod bundle;
|
||||
pub use bundle::ComponentsBundle;
|
||||
|
||||
|
|
|
|||
32
pagetop/src/core/component/arc.rs
Normal file
32
pagetop/src/core/component/arc.rs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
use crate::core::component::{ComponentTrait, RenderContext};
|
||||
use crate::html::{html, Markup};
|
||||
|
||||
use std::sync::{Arc, RwLock};
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
pub struct ComponentArc(Option<Arc<RwLock<dyn ComponentTrait>>>);
|
||||
|
||||
impl ComponentArc {
|
||||
pub fn new(component: impl ComponentTrait) -> Self {
|
||||
ComponentArc(Some(Arc::new(RwLock::new(component))))
|
||||
}
|
||||
|
||||
pub fn replace(&mut self, component: impl ComponentTrait) {
|
||||
self.0 = Some(Arc::new(RwLock::new(component)));
|
||||
}
|
||||
|
||||
pub fn weight(&self) -> isize {
|
||||
match &self.0 {
|
||||
Some(component) => component.read().unwrap().weight(),
|
||||
_ => 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn render(&self, rcx: &mut RenderContext) -> Markup {
|
||||
html! {
|
||||
@if let Some(component) = &self.0 {
|
||||
(component.write().unwrap().render(rcx))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,8 @@
|
|||
use crate::core::component::ComponentTrait;
|
||||
use crate::html::{html, Markup, RenderContext};
|
||||
|
||||
use std::sync::{Arc, RwLock};
|
||||
use crate::core::component::{ComponentArc, ComponentTrait, RenderContext};
|
||||
use crate::html::{html, Markup};
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
pub struct ComponentsBundle(Vec<Arc<RwLock<dyn ComponentTrait>>>);
|
||||
pub struct ComponentsBundle(Vec<ComponentArc>);
|
||||
|
||||
impl ComponentsBundle {
|
||||
pub fn new() -> Self {
|
||||
|
|
@ -12,13 +10,13 @@ impl ComponentsBundle {
|
|||
}
|
||||
|
||||
pub fn new_with(component: impl ComponentTrait) -> Self {
|
||||
let mut container = ComponentsBundle::new();
|
||||
container.add(component);
|
||||
container
|
||||
let mut bundle = ComponentsBundle::new();
|
||||
bundle.add(component);
|
||||
bundle
|
||||
}
|
||||
|
||||
pub fn add(&mut self, component: impl ComponentTrait) {
|
||||
self.0.push(Arc::new(RwLock::new(component)));
|
||||
self.0.push(ComponentArc::new(component));
|
||||
}
|
||||
|
||||
pub fn clear(&mut self) {
|
||||
|
|
@ -27,10 +25,10 @@ impl ComponentsBundle {
|
|||
|
||||
pub fn render(&self, rcx: &mut RenderContext) -> Markup {
|
||||
let mut components = self.0.clone();
|
||||
components.sort_by_key(|c| c.read().unwrap().weight());
|
||||
components.sort_by_key(|c| c.weight());
|
||||
html! {
|
||||
@for c in components.iter() {
|
||||
(" ")(c.write().unwrap().render(rcx))(" ")
|
||||
(" ")(c.render(rcx))(" ")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use crate::core::module::{all::theme_by_single_name, ThemeStaticRef};
|
||||
use crate::html::{html, Assets, IdentifierValue, JavaScript, Markup, StyleSheet};
|
||||
use crate::locale::{LanguageIdentifier, LANGID};
|
||||
use crate::server::HttpRequest;
|
||||
use crate::{concat_string, config, util, LazyStatic};
|
||||
|
||||
|
|
@ -23,6 +24,7 @@ pub enum ContextOp {
|
|||
|
||||
#[rustfmt::skip]
|
||||
pub struct RenderContext {
|
||||
language : &'static LanguageIdentifier,
|
||||
theme : ThemeStaticRef,
|
||||
request : Option<HttpRequest>,
|
||||
stylesheets: Assets<StyleSheet>,
|
||||
|
|
@ -35,6 +37,7 @@ impl Default for RenderContext {
|
|||
#[rustfmt::skip]
|
||||
fn default() -> Self {
|
||||
RenderContext {
|
||||
language : &LANGID,
|
||||
theme : *DEFAULT_THEME,
|
||||
request : None,
|
||||
stylesheets: Assets::<StyleSheet>::new(),
|
||||
|
|
@ -81,6 +84,10 @@ impl RenderContext {
|
|||
|
||||
/// Context GETTERS.
|
||||
|
||||
pub(crate) fn language(&self) -> &LanguageIdentifier {
|
||||
self.language
|
||||
}
|
||||
|
||||
pub(crate) fn theme(&self) -> ThemeStaticRef {
|
||||
self.theme
|
||||
}
|
||||
|
|
@ -1,9 +1,12 @@
|
|||
use crate::html::{html, Markup, RenderContext};
|
||||
use crate::core::component::RenderContext;
|
||||
use crate::html::{html, Markup};
|
||||
use crate::util::single_type_name;
|
||||
use crate::Handle;
|
||||
use crate::{define_handle, Handle};
|
||||
|
||||
pub use std::any::Any as AnyComponent;
|
||||
|
||||
define_handle!(COMPONENT_UNDEFINED);
|
||||
|
||||
pub trait BaseComponent {
|
||||
fn render(&mut self, rcx: &mut RenderContext) -> Markup;
|
||||
}
|
||||
|
|
@ -13,7 +16,9 @@ pub trait ComponentTrait: AnyComponent + BaseComponent + Send + Sync {
|
|||
where
|
||||
Self: Sized;
|
||||
|
||||
fn handle(&self) -> Handle;
|
||||
fn handle(&self) -> Handle {
|
||||
COMPONENT_UNDEFINED
|
||||
}
|
||||
|
||||
fn name(&self) -> String {
|
||||
single_type_name::<Self>().to_owned()
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use crate::core::component::{AnyComponent, ComponentTrait};
|
||||
use crate::html::{html, Markup, RenderContext};
|
||||
use crate::core::component::{AnyComponent, ComponentTrait, RenderContext};
|
||||
use crate::html::{html, Markup};
|
||||
use crate::{define_handle, Handle};
|
||||
|
||||
define_handle!(HTML_MARKUP);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use crate::html::RenderContext;
|
||||
use crate::core::component::RenderContext;
|
||||
|
||||
pub type IsRenderable = fn(&RenderContext) -> bool;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use super::ModuleTrait;
|
||||
|
||||
use crate::core::component::{ComponentTrait, HtmlMarkup};
|
||||
use crate::html::{html, Favicon, Markup, RenderContext};
|
||||
use crate::core::component::{ComponentTrait, RenderContext};
|
||||
use crate::html::{html, Favicon, Markup};
|
||||
use crate::response::page::Page;
|
||||
use crate::{concat_string, config};
|
||||
|
||||
|
|
@ -118,20 +118,4 @@ pub trait ThemeTrait: ModuleTrait + Send + Sync {
|
|||
}
|
||||
*/
|
||||
}
|
||||
|
||||
fn error_404_not_found(&self) -> HtmlMarkup {
|
||||
HtmlMarkup::new().with(html! {
|
||||
div {
|
||||
h1 { ("RESOURCE NOT FOUND") }
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn error_403_access_denied(&self) -> HtmlMarkup {
|
||||
HtmlMarkup::new().with(html! {
|
||||
div {
|
||||
h1 { ("FORBIDDEN ACCESS") }
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,9 +8,6 @@ pub use assets::javascript::{JavaScript, ModeJS};
|
|||
pub use assets::stylesheet::{StyleSheet, TargetMedia};
|
||||
pub use assets::Assets;
|
||||
|
||||
mod context;
|
||||
pub use context::{ContextOp, RenderContext};
|
||||
|
||||
mod favicon;
|
||||
pub use favicon::Favicon;
|
||||
|
||||
|
|
|
|||
|
|
@ -85,59 +85,12 @@ pub mod server;
|
|||
// Tipos de respuestas a peticiones web.
|
||||
pub mod response;
|
||||
|
||||
// Funciones útiles.
|
||||
// Funciones útiles y macros declarativas.
|
||||
pub mod util;
|
||||
|
||||
// Prepara y ejecuta la aplicación.
|
||||
pub mod app;
|
||||
|
||||
// *************************************************************************************************
|
||||
// MACROS DECLARATIVAS.
|
||||
// *************************************************************************************************
|
||||
|
||||
#[macro_export]
|
||||
/// Macro para construir grupos de pares clave-valor.
|
||||
///
|
||||
/// ```rust#ignore
|
||||
/// let args = args![
|
||||
/// "userName" => "Roberto",
|
||||
/// "photoCount" => 3,
|
||||
/// "userGender" => "male"
|
||||
/// ];
|
||||
/// ```
|
||||
macro_rules! args {
|
||||
( $($key:expr => $value:expr),* ) => {{
|
||||
let mut a = std::collections::HashMap::new();
|
||||
$(
|
||||
a.insert(String::from($key), $value.into());
|
||||
)*
|
||||
a
|
||||
}};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! define_handle {
|
||||
( $HANDLE:ident ) => {
|
||||
pub const $HANDLE: $crate::Handle =
|
||||
$crate::util::handle(module_path!(), file!(), line!(), column!());
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! serve_static_files {
|
||||
( $cfg:ident, $dir:expr, $embed:ident ) => {{
|
||||
let static_files = &$crate::config::SETTINGS.dev.static_files;
|
||||
if static_files.is_empty() {
|
||||
$cfg.service($crate::server::ResourceFiles::new($dir, $embed()));
|
||||
} else {
|
||||
$cfg.service(
|
||||
$crate::server::ActixFiles::new($dir, $crate::concat_string!(static_files, $dir))
|
||||
.show_files_listing(),
|
||||
);
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
// *************************************************************************************************
|
||||
// RE-EXPORTA API ÚNICA.
|
||||
// *************************************************************************************************
|
||||
|
|
|
|||
|
|
@ -92,34 +92,49 @@
|
|||
//! ```
|
||||
|
||||
use crate::html::{Markup, PreEscaped};
|
||||
use crate::{config, trace, LazyStatic};
|
||||
use crate::{args, config, trace, LazyStatic};
|
||||
|
||||
use unic_langid::LanguageIdentifier;
|
||||
use unic_langid::langid;
|
||||
|
||||
pub use fluent_templates;
|
||||
pub use fluent_templates::fluent_bundle::FluentValue;
|
||||
pub use fluent_templates::{static_loader as static_locale, Loader, StaticLoader as Locales};
|
||||
|
||||
pub use unic_langid::LanguageIdentifier;
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
static LANGUAGES: LazyStatic<HashMap<String, (LanguageIdentifier, &str)>> = LazyStatic::new(|| {
|
||||
args![
|
||||
"en" => (langid!("en-US"), "English"),
|
||||
"en-US" => (langid!("en-US"), "English (...)"),
|
||||
"es" => (langid!("es-ES"), "Spanish"),
|
||||
"es-ES" => (langid!("es-ES"), "Spanish (Spain)")
|
||||
]
|
||||
});
|
||||
|
||||
static DEFAULT_LANGID: LazyStatic<LanguageIdentifier> = LazyStatic::new(|| langid!("en-US"));
|
||||
|
||||
/// Almacena el Identificador de Idioma Unicode
|
||||
/// ([Unicode Language Identifier](https://unicode.org/reports/tr35/tr35.html#Unicode_language_identifier))
|
||||
/// para la aplicación, obtenido de `SETTINGS.app.language`.
|
||||
pub static LANGID: LazyStatic<LanguageIdentifier> =
|
||||
LazyStatic::new(|| match config::SETTINGS.app.language.parse() {
|
||||
Ok(language) => language,
|
||||
Err(_) => {
|
||||
trace::warn!(
|
||||
"{}, {} \"{}\"! {}, {}",
|
||||
"Failed to parse language",
|
||||
"unrecognized Unicode Language Identifier",
|
||||
config::SETTINGS.app.language,
|
||||
"Using \"en-US\"",
|
||||
"check the settings file",
|
||||
);
|
||||
"en-US".parse().unwrap()
|
||||
}
|
||||
});
|
||||
pub static LANGID: LazyStatic<&LanguageIdentifier> =
|
||||
LazyStatic::new(
|
||||
|| match LANGUAGES.get(config::SETTINGS.app.language.as_str()) {
|
||||
Some((langid, _)) => langid,
|
||||
_ => {
|
||||
trace::warn!(
|
||||
"{}, {} \"{}\"! {}, {}",
|
||||
"Failed to parse language",
|
||||
"unrecognized Unicode Language Identifier",
|
||||
config::SETTINGS.app.language,
|
||||
"Using \"en-US\"",
|
||||
"check the settings file",
|
||||
);
|
||||
&*DEFAULT_LANGID
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
#[macro_export]
|
||||
/// Define un conjunto de elementos de localización y funciones locales de traducción.
|
||||
|
|
@ -128,7 +143,7 @@ macro_rules! define_locale {
|
|||
use $crate::locale::*;
|
||||
|
||||
static_locale! {
|
||||
static $LOCALES = {
|
||||
pub static $LOCALES = {
|
||||
locales: $dir_locales,
|
||||
$( core_locales: $core_locales, )?
|
||||
fallback_language: "en-US",
|
||||
|
|
@ -151,7 +166,7 @@ pub enum Locale<'a> {
|
|||
),
|
||||
}
|
||||
|
||||
pub fn t(key: &str, locale: Locale) -> String {
|
||||
pub fn _t(key: &str, locale: Locale) -> String {
|
||||
match locale {
|
||||
Locale::From(locales) => locales.lookup(&LANGID, key).unwrap_or(key.to_string()),
|
||||
Locale::With(locales, args) => locales
|
||||
|
|
@ -164,6 +179,6 @@ pub fn t(key: &str, locale: Locale) -> String {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn e(key: &str, locale: Locale) -> Markup {
|
||||
PreEscaped(t(key, locale))
|
||||
pub fn _e(key: &str, locale: Locale) -> Markup {
|
||||
PreEscaped(_t(key, locale))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ pub use crate::{hook_action, hook_before_render_component};
|
|||
pub use crate::server;
|
||||
pub use crate::server::HttpMessage;
|
||||
|
||||
pub use crate::response::{page::*, FatalError, ResponseError};
|
||||
pub use crate::response::fatal_error::*;
|
||||
pub use crate::response::{page::*, ResponseError};
|
||||
|
||||
pub use crate::app::Application;
|
||||
|
|
|
|||
|
|
@ -4,5 +4,4 @@ pub use actix_web::ResponseError;
|
|||
|
||||
pub mod page;
|
||||
|
||||
mod fatal_error;
|
||||
pub use fatal_error::FatalError;
|
||||
pub mod fatal_error;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,8 @@
|
|||
mod error403;
|
||||
pub use error403::ERROR_403;
|
||||
mod error404;
|
||||
pub use error404::ERROR_404;
|
||||
|
||||
use crate::response::{page::Page, ResponseError};
|
||||
use crate::server::http::{header::ContentType, StatusCode};
|
||||
use crate::server::{HttpRequest, HttpResponse};
|
||||
|
|
@ -24,11 +29,10 @@ impl fmt::Display for FatalError {
|
|||
FatalError::BadRequest(_) => write!(f, "Bad Client Data"),
|
||||
// Error 403.
|
||||
FatalError::AccessDenied(request) => {
|
||||
let mut error_page = Page::new(request.clone());
|
||||
let error_content = error_page.context().theme().error_403_access_denied();
|
||||
let error_page = Page::new(request.clone());
|
||||
if let Ok(page) = error_page
|
||||
.with_title("Error FORBIDDEN")
|
||||
.with_this_in("region-content", error_content)
|
||||
.with_this_in("region-content", error403::Error403)
|
||||
.with_template("error")
|
||||
.render()
|
||||
{
|
||||
|
|
@ -39,11 +43,10 @@ impl fmt::Display for FatalError {
|
|||
}
|
||||
// Error 404.
|
||||
FatalError::NotFound(request) => {
|
||||
let mut error_page = Page::new(request.clone());
|
||||
let error_content = error_page.context().theme().error_404_not_found();
|
||||
let error_page = Page::new(request.clone());
|
||||
if let Ok(page) = error_page
|
||||
.with_title("Error RESOURCE NOT FOUND")
|
||||
.with_this_in("region-content", error_content)
|
||||
.with_this_in("region-content", error404::Error404)
|
||||
.with_template("error")
|
||||
.render()
|
||||
{
|
||||
|
|
|
|||
33
pagetop/src/response/fatal_error/error403.rs
Normal file
33
pagetop/src/response/fatal_error/error403.rs
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
use crate::core::component::{AnyComponent, ComponentTrait, RenderContext};
|
||||
use crate::html::{html, Markup};
|
||||
use crate::{define_handle, Handle};
|
||||
|
||||
define_handle!(ERROR_403);
|
||||
|
||||
pub struct Error403;
|
||||
|
||||
impl ComponentTrait for Error403 {
|
||||
fn new() -> Self {
|
||||
Self
|
||||
}
|
||||
|
||||
fn handle(&self) -> Handle {
|
||||
ERROR_403
|
||||
}
|
||||
|
||||
fn default_render(&self, _rcx: &mut RenderContext) -> Markup {
|
||||
html! {
|
||||
div {
|
||||
h1 { ("FORBIDDEN ACCESS") }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn as_ref_any(&self) -> &dyn AnyComponent {
|
||||
self
|
||||
}
|
||||
|
||||
fn as_mut_any(&mut self) -> &mut dyn AnyComponent {
|
||||
self
|
||||
}
|
||||
}
|
||||
33
pagetop/src/response/fatal_error/error404.rs
Normal file
33
pagetop/src/response/fatal_error/error404.rs
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
use crate::core::component::{AnyComponent, ComponentTrait, RenderContext};
|
||||
use crate::html::{html, Markup};
|
||||
use crate::{define_handle, Handle};
|
||||
|
||||
define_handle!(ERROR_404);
|
||||
|
||||
pub struct Error404;
|
||||
|
||||
impl ComponentTrait for Error404 {
|
||||
fn new() -> Self {
|
||||
Self
|
||||
}
|
||||
|
||||
fn handle(&self) -> Handle {
|
||||
ERROR_404
|
||||
}
|
||||
|
||||
fn default_render(&self, _rcx: &mut RenderContext) -> Markup {
|
||||
html! {
|
||||
div {
|
||||
h1 { ("RESOURCE NOT FOUND") }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn as_ref_any(&self) -> &dyn AnyComponent {
|
||||
self
|
||||
}
|
||||
|
||||
fn as_mut_any(&mut self) -> &mut dyn AnyComponent {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
|
@ -2,10 +2,8 @@ use super::{BeforeRenderPageHook, ResultPage, HOOK_BEFORE_RENDER_PAGE};
|
|||
|
||||
use crate::core::component::*;
|
||||
use crate::core::hook::{action_ref, run_actions};
|
||||
use crate::html::{
|
||||
html, AttributeValue, Classes, ClassesOp, ContextOp, Favicon, Markup, RenderContext, DOCTYPE,
|
||||
};
|
||||
use crate::response::FatalError;
|
||||
use crate::html::{html, AttributeValue, Classes, ClassesOp, Favicon, Markup, DOCTYPE};
|
||||
use crate::response::fatal_error::FatalError;
|
||||
use crate::{config, fn_builder, locale, server, trace, LazyStatic};
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,11 @@
|
|||
//! Funciones útiles.
|
||||
//! Funciones útiles y macros declarativas.
|
||||
|
||||
use crate::Handle;
|
||||
|
||||
// *************************************************************************************************
|
||||
// FUNCIONES ÚTILES.
|
||||
// *************************************************************************************************
|
||||
|
||||
// https://stackoverflow.com/a/71464396
|
||||
pub const fn handle(
|
||||
module_path: &'static str,
|
||||
|
|
@ -50,3 +54,50 @@ pub fn partial_type_name(type_name: &'static str, last: usize) -> &'static str {
|
|||
pub fn single_type_name<T: ?Sized>() -> &'static str {
|
||||
partial_type_name(std::any::type_name::<T>(), 1)
|
||||
}
|
||||
|
||||
// *************************************************************************************************
|
||||
// MACROS DECLARATIVAS.
|
||||
// *************************************************************************************************
|
||||
|
||||
#[macro_export]
|
||||
/// Macro para construir grupos de pares clave-valor.
|
||||
///
|
||||
/// ```rust#ignore
|
||||
/// let args = args![
|
||||
/// "userName" => "Roberto",
|
||||
/// "photoCount" => 3,
|
||||
/// "userGender" => "male"
|
||||
/// ];
|
||||
/// ```
|
||||
macro_rules! args {
|
||||
( $($key:expr => $value:expr),* ) => {{
|
||||
let mut a = std::collections::HashMap::new();
|
||||
$(
|
||||
a.insert(String::from($key), $value.into());
|
||||
)*
|
||||
a
|
||||
}};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! define_handle {
|
||||
( $HANDLE:ident ) => {
|
||||
pub const $HANDLE: $crate::Handle =
|
||||
$crate::util::handle(module_path!(), file!(), line!(), column!());
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! serve_static_files {
|
||||
( $cfg:ident, $dir:expr, $embed:ident ) => {{
|
||||
let static_files = &$crate::config::SETTINGS.dev.static_files;
|
||||
if static_files.is_empty() {
|
||||
$cfg.service($crate::server::ResourceFiles::new($dir, $embed()));
|
||||
} else {
|
||||
$cfg.service(
|
||||
$crate::server::ActixFiles::new($dir, $crate::concat_string!(static_files, $dir))
|
||||
.show_files_listing(),
|
||||
);
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue