Skip to content

Commit

Permalink
Add a view feature for zino-http
Browse files Browse the repository at this point in the history
  • Loading branch information
photino committed Dec 16, 2024
1 parent 216f229 commit ba1abac
Show file tree
Hide file tree
Showing 14 changed files with 88 additions and 88 deletions.
28 changes: 14 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,20 +76,20 @@ This project is licensed under the [MIT license][license].

If you have any problems or ideas, please don't hesitate to [open an issue][zino-issue].

[`zino-core`]: https://github.com/zino-rs/zino/tree/main/zino-core
[`zino-auth`]: https://github.com/zino-rs/zino/tree/main/zino-auth
[`zino-channel`]: https://github.com/zino-rs/zino/tree/main/zino-channel
[`zino-storage`]: https://github.com/zino-rs/zino/tree/main/zino-storage
[`zino-http`]: https://github.com/zino-rs/zino/tree/main/zino-http
[`zino-derive`]: https://github.com/zino-rs/zino/tree/main/zino-derive
[`zino-model`]: https://github.com/zino-rs/zino/tree/main/zino-model
[`zino-extra`]: https://github.com/zino-rs/zino/tree/main/zino-extra
[`zino-actix`]: https://github.com/zino-rs/zino/tree/main/zino-actix
[`zino-axum`]: https://github.com/zino-rs/zino/tree/main/zino-axum
[`zino-ntex`]: https://github.com/zino-rs/zino/tree/main/zino-ntex
[`zino-dioxus`]: https://github.com/zino-rs/zino/tree/main/zino-dioxus
[`zino-amis`]: https://github.com/zino-rs/zino/tree/main/zino-amis
[`zino-cli`]: https://github.com/zino-rs/zino/tree/main/zino-cli
[`zino-core`]: https://github.com/zino-rs/zino/tree/main/crates/zino-core
[`zino-auth`]: https://github.com/zino-rs/zino/tree/main/crates/zino-auth
[`zino-channel`]: https://github.com/zino-rs/zino/tree/main/crates/zino-channel
[`zino-storage`]: https://github.com/zino-rs/zino/tree/main/crates/zino-storage
[`zino-http`]: https://github.com/zino-rs/zino/tree/main/crates/zino-http
[`zino-derive`]: https://github.com/zino-rs/zino/tree/main/crates/zino-derive
[`zino-model`]: https://github.com/zino-rs/zino/tree/main/crates/zino-model
[`zino-extra`]: https://github.com/zino-rs/zino/tree/main/crates/zino-extra
[`zino-actix`]: https://github.com/zino-rs/zino/tree/main/crates/zino-actix
[`zino-axum`]: https://github.com/zino-rs/zino/tree/main/crates/zino-axum
[`zino-ntex`]: https://github.com/zino-rs/zino/tree/main/crates/zino-ntex
[`zino-dioxus`]: https://github.com/zino-rs/zino/tree/main/crates/zino-dioxus
[`zino-amis`]: https://github.com/zino-rs/zino/tree/main/crates/zino-amis
[`zino-cli`]: https://github.com/zino-rs/zino/tree/main/crates/zino-cli
[zino]: https://crates.io/crates/zino
[zino-docs]: https://docs.rs/zino
[zino-core]: https://crates.io/crates/zino-core
Expand Down
16 changes: 0 additions & 16 deletions crates/zino-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,7 @@ all-validators = [
cookie = ["dep:cookie", "reqwest?/cookies"]
crypto-sm = ["dep:ctr", "dep:sm3", "dep:sm4"]
debug = [
"minijinja?/debug",
"minijinja?/preserve_order",
"serde_json/preserve_order",
"tera?/preserve_order",
"toml/preserve_order",
"utoipa?/preserve_order",
"utoipa?/preserve_path_order",
Expand All @@ -58,7 +55,6 @@ full = [
"openapi",
"orm",
"tracing-log",
"view",
]
http-client = ["dep:reqwest-middleware", "dep:reqwest-tracing", "reqwest"]
locale = ["random_word"]
Expand Down Expand Up @@ -97,9 +93,6 @@ validator-credit-card = ["validator", "dep:card-validate"]
validator-email = ["validator"]
validator-phone-number = ["validator", "dep:phonenumber"]
validator-regex = ["validator"]
view = ["dep:minijinja"]
view-minijinja = ["view", "dep:minijinja"]
view-tera = ["view", "dep:tera"]

[dependencies]
aes-gcm-siv = "0.11.1"
Expand Down Expand Up @@ -161,11 +154,6 @@ optional = true
default-features = false
features = ["http-listener"]

[dependencies.minijinja]
version = "2.5.0"
optional = true
features = ["loader"]

[dependencies.phonenumber]
version = "0.3.6"
optional = true
Expand Down Expand Up @@ -237,10 +225,6 @@ features = [
"uuid",
]

[dependencies.tera]
version = "1.20.0"
optional = true

[dependencies.toml]
version = "0.8.19"
default-features = false
Expand Down
1 change: 0 additions & 1 deletion crates/zino-core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ The following optional features are available:
| `tracing-log` | Enables the `tracing-log` for [`tracing-subscriber`]. | No |
| `tracing-subscriber` | Enables the integration with [`tracing-subscriber`]. | No |
| `validator` | Enables the common validation rules. | No |
| `view` | Enables the HTML template rendering. | No |

[`zino`]: https://github.com/zino-rs/zino
[`tracing-subscriber`]: https://crates.io/crates/tracing-subscriber
Expand Down
4 changes: 0 additions & 4 deletions crates/zino-core/src/application/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,6 @@ pub trait Application {
#[cfg(feature = "http-client")]
http_client::init::<Self>();

// View template
#[cfg(feature = "view")]
crate::view::init::<Self>();

// Initializes the directories to ensure that they are ready for use
for path in SHARED_DIRS.values() {
if !path.exists() {
Expand Down
2 changes: 0 additions & 2 deletions crates/zino-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ mod openapi;

#[cfg(feature = "orm")]
pub mod orm;
#[cfg(feature = "view")]
pub mod view;

pub mod application;
pub mod crypto;
Expand Down
26 changes: 25 additions & 1 deletion crates/zino-http/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,26 @@ rustdoc-args = ["--cfg", "docsrs"]
[features]
auth = ["zino-auth"]
cookie = ["dep:cookie", "reqwest/cookies", "zino-core/cookie"]
debug = [
"minijinja?/debug",
"minijinja?/preserve_order",
"serde_json/preserve_order",
"tera?/preserve_order",
"toml/preserve_order",
"zino-core/debug",
]
i18n = ["dep:fluent", "dep:intl-memoizer", "dep:unic-langid"]
http02 = ["dep:http02"]
jwt = ["dep:jwt-simple", "auth", "zino-auth/jwt"]
metrics = ["dep:metrics", "zino-core/metrics"]
openapi = ["zino-core/openapi"]
view = ["zino-core/view"]
view = ["dep:convert_case", "dep:minijinja"]
view-minijinja = ["view", "dep:minijinja"]
view-tera = ["view", "dep:tera"]

[dependencies]
bytes = "1.9.0"
cfg-if = "1.0"
etag = "4.0.0"
futures = "0.3.31"
http = "1.2.0"
Expand All @@ -50,6 +61,10 @@ smallvec = "1.13.2"
tracing = "0.1.41"
url = "2.5.4"

[dependencies.convert_case]
version = "0.6.0"
optional = true

[dependencies.cookie]
version = "0.18.1"
optional = true
Expand Down Expand Up @@ -77,6 +92,11 @@ features = ["pure-rust"]
version = "0.24.1"
optional = true

[dependencies.minijinja]
version = "2.5.0"
optional = true
features = ["loader"]

[dependencies.reqwest]
version = "0.12.9"
default-features = false
Expand All @@ -95,6 +115,10 @@ features = ["derive"]
version = "1.0.133"
features = ["raw_value"]

[dependencies.tera]
version = "1.20.0"
optional = true

[dependencies.toml]
version = "0.8.19"
default-features = false
Expand Down
1 change: 1 addition & 0 deletions crates/zino-http/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ The following optional features are available:
|----------------------|--------------------------------------------------------|----------|
| `auth` | Enables the authentication and authorization. | No |
| `cookie` | Enables the support for cookies. | No |
| `debug` | Enables the features for ease of debugging. | No |
| `i18n` | Enables the support for internationalization. | No |
| `jwt` | Enables the support for JSON Web Token. | No |
| `metrics` | Enables the [`metrics`] exporter. | No |
Expand Down
3 changes: 3 additions & 0 deletions crates/zino-http/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ pub mod timing;
#[cfg(feature = "i18n")]
pub mod i18n;

#[cfg(feature = "view")]
pub mod view;

#[cfg(feature = "i18n")]
#[doc(no_inline)]
pub use fluent::fluent_args;
2 changes: 1 addition & 1 deletion crates/zino-http/src/response/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ impl<S: ResponseCode> Response<S> {
if let Some(data) = value.as_object_mut() {
let mut map = zino_core::Map::new();
map.append(data);
zino_core::view::render(template_name, map)
crate::view::render(template_name, map)
} else {
Err(zino_core::warn!("invalid template data"))
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,32 @@
use crate::{error::Error, state::State, warn, Map};
use convert_case::{Case, Casing};
use minijinja::Environment;
use std::{path::PathBuf, sync::OnceLock};
use std::sync::LazyLock;
use zino_core::{
application::{Agent, Application},
error::Error,
extension::TomlTableExt,
Map,
};

/// Renders a template with the given data using [`minijinja`](https://crates.io/crates/minijinja).
pub fn render(template_name: &str, data: Map) -> Result<String, Error> {
let view_engine = SHARED_VIEW_ENGINE
.get()
.ok_or_else(|| warn!("fail to get the `jinja` view engine"))?;
let template = view_engine.get_template(template_name)?;
let template = SHARED_VIEW_ENGINE.get_template(template_name)?;
template.render(data).map_err(Error::from)
}

/// Loads templates.
pub(crate) fn load_templates(app_state: &'static State<Map>, template_dir: PathBuf) {
/// Shared view engine.
static SHARED_VIEW_ENGINE: LazyLock<Environment> = LazyLock::new(|| {
let app_state = Agent::shared_state();
let mut template_dir = "templates";
if let Some(view) = app_state.get_config("view") {
if let Some(dir) = view.get_str("template-dir") {
template_dir = dir;
}
}

let mut view_engine = Environment::new();
let app_env = app_state.env();
let template_dir = Agent::parse_path(template_dir);
view_engine.set_debug(app_env.is_dev());
view_engine.set_loader(minijinja::path_loader(template_dir));
view_engine.add_global("APP_ENV", app_env.as_str());
Expand All @@ -25,10 +36,5 @@ pub(crate) fn load_templates(app_state: &'static State<Map>, template_dir: PathB
view_engine.add_global(key, value);
}
}
SHARED_VIEW_ENGINE
.set(view_engine)
.expect("fail to set the `jinja` view engine");
}

/// Shared view engine.
static SHARED_VIEW_ENGINE: OnceLock<Environment> = OnceLock::new();
view_engine
});
Original file line number Diff line number Diff line change
Expand Up @@ -9,30 +9,14 @@
//! | `view-minijinja` | Enables the `minijinja` template engine. | No |
//! | `view-tera` | Enables the `tera` template engine. | No |
use crate::{application::Application, extension::TomlTableExt};

cfg_if::cfg_if! {
if #[cfg(feature = "view-tera")] {
mod tera;

use self::tera::load_templates;
pub use self::tera::render;
} else {
mod minijinja;

use self::minijinja::load_templates;
pub use self::minijinja::render;
}
}

/// Intializes view engine.
pub(crate) fn init<APP: Application + ?Sized>() {
let app_state = APP::shared_state();
let mut template_dir = "templates";
if let Some(view) = app_state.get_config("view") {
if let Some(dir) = view.get_str("template-dir") {
template_dir = dir;
}
}
load_templates(app_state, APP::parse_path(template_dir));
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,31 @@
use crate::{error::Error, state::State, warn, Map};
use std::{path::PathBuf, sync::OnceLock};
use std::sync::OnceLock;
use tera::{Context, Tera};
use zino_core::{
application::{Agent, Application},
error::Error,
extension::TomlTableExt,
Map,
};

/// Renders a template with the given data using [`tera`](https://crates.io/crates/tera).
pub fn render(template_name: &str, data: Map) -> Result<String, Error> {
let view_engine = SHARED_VIEW_ENGINE
.get()
.ok_or_else(|| warn!("fail to get the `tera` view engine"))?;
let context = Context::from_value(data.into())?;
view_engine
SHARED_VIEW_ENGINE
.render(template_name, &context)
.map_err(Error::from)
}

/// Loads templates.
pub(crate) fn load_templates(app_state: &'static State<Map>, template_dir: PathBuf) {
/// Shared view engine.
static SHARED_VIEW_ENGINE: LazyLock<Tera> = LazyLock::new(|| {
let app_state = Agent::shared_state();
let mut template_dir = "templates";
if let Some(view) = app_state.get_config("view") {
if let Some(dir) = view.get_str("template-dir") {
template_dir = dir;
}
}

let template_dir = Agent::parse_path(template_dir);
let dir_glob = template_dir.to_string_lossy().into_owned() + "/**/*";
let mut view_engine = Tera::new(dir_glob.as_str()).expect("fail to parse html templates");
view_engine.autoescape_on(vec![".html", ".html.tera", ".tera"]);
Expand All @@ -23,10 +34,5 @@ pub(crate) fn load_templates(app_state: &'static State<Map>, template_dir: PathB
.full_reload()
.expect("fail to reload html templates");
}
SHARED_VIEW_ENGINE
.set(view_engine)
.expect("fail to set the `tera` view engine");
}

/// Shared view engine.
static SHARED_VIEW_ENGINE: OnceLock<Tera> = OnceLock::new();
view_engine
});
4 changes: 2 additions & 2 deletions crates/zino/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ axum = ["dep:zino-axum", "dep:zino-http"]
cookie = ["zino-core/cookie", "zino-http?/cookie"]
dioxus = ["zino-dioxus"]
dioxus-desktop = ["dioxus", "zino-dioxus/desktop"]
debug = ["zino-core/debug"]
debug = ["zino-core/debug", "zino-http?/debug"]
default = ["logger"]
i18n = ["dep:zino-http", "zino-http/i18n"]
jwt = ["auth", "zino-auth/jwt", "zino-http?/jwt"]
Expand All @@ -42,7 +42,7 @@ ntex = ["dep:zino-http", "dep:zino-ntex"]
oidc = ["auth", "zino-core/oidc"]
opa = ["auth", "zino-auth/opa"]
orm = ["zino-axum?/orm", "zino-core/orm"]
view = ["zino-core/view", "zino-http?/view"]
view = ["dep:zino-http", "zino-http/view"]

[dependencies]
cfg-if = "1.0"
Expand Down
1 change: 0 additions & 1 deletion examples/axum-app/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ features = [
"env-filter",
"orm-mysql",
"validator-email",
"view-tera",
]

[dependencies.zino-derive]
Expand Down

0 comments on commit ba1abac

Please sign in to comment.