rainier_view/lib.rs
1//! # rainier-view
2//!
3//! The **V** in MVC: a [`View`] value a controller returns, a [`ViewEngine`]
4//! port, and [`TemplateEngine`] — the file-backed template engine. The directive
5//! syntax will be familiar from PHP templating engines.
6//!
7//! ```
8//! use rainier_view::{MemoryEngine, View, ViewEngine};
9//!
10//! let engine = MemoryEngine::new().with(
11//! "posts.index",
12//! "<ul>@foreach(posts as post)<li>{{ post.title }}</li>@endforeach</ul>",
13//! );
14//!
15//! let view = View::with("posts.index", serde_json::json!({
16//! "posts": [{ "title": "Hello & welcome" }],
17//! })).unwrap();
18//!
19//! assert_eq!(
20//! engine.render_view(&view).unwrap(),
21//! "<ul><li>Hello & welcome</li></ul>",
22//! );
23//! ```
24//!
25//! ## Escaped by default
26//!
27//! `{{ … }}` HTML-escapes; `{!! … !!}` does not. The safe form is the short
28//! one, so the way you write a value without thinking is the way that cannot
29//! inject a `<script>`. Emitting raw HTML is possible but has to be asked for.
30//!
31//! ## A deliberately small language
32//!
33//! `{{ }}`, `{!! !!}`, `@if`/`@elseif`/`@else`, `@foreach`, `@include`, and
34//! `@extends`/`@section`/`@yield`. There is no arbitrary expression evaluation
35//! and no way to call a function, because a template that can compute is a
36//! template that ends up holding business logic. Prepare the data in the
37//! controller; let the template lay it out.
38
39#![deny(missing_docs)]
40#![deny(rustdoc::broken_intra_doc_links)]
41
42pub mod engine;
43pub mod template;
44
45pub use engine::{escape_html, MemoryEngine, TemplateEngine, View, ViewEngine};
46pub use template::{CompareOp, Condition, Expr, Literal, Node, Template};