Expand description
§hypo
A tiny crate that renders html through macros.
Hypotext is the source leading to the hypertext.
§Design
- Minimal interface
- One macro per element, which take attributes and children
- Composition favored over a complex DSL
- Formatting support
- Macros are used in functional style
- Syntax is chosen carefully to be accepted by rustfmt
- Zero intermediary allocations
- Only allocates on full template render
- Render without std if buffer is available
- Zero procedural macros
- Only declarative macros
- Even those are tiny and simple
- Zero dependencies
- Can be used with zero dependencies
- Couple dependencies might be enabled via features
§Usage
use hypo::*;
let page = html!(
head!(
meta!(charset = "UTF-8"),
title!("hypotext")
),
body!(
class = "container",
"leads to hypertext"
)
);§Render trait
The Render trait is the bedrock of this library. Every value interpolated into the markup needs to implement it.
The interpolation happens basically in two places:
- Children of elements
div!(children) - Value of attributes
div!(key = value)
In order to understand this crate design, it’s important to keep in mind the types that implement this trait. Here’s a quick list of the most important ones and their behavior.
char,&strandString(implies escaping)Raw(defined in this library, string that skips escaping)- all integer types (implies allocation without
perffeature) Vec,arrayandMap(concatenation of items)- tuples (size up to 16, concatenation too)
Option(renders nothing on None)Result(just renders both sides)
§Control flow
This crate does not provide any syntax for control flow primitives.
It prioritize native structs that implement Render so the user can use it’s combinatory methods and primitives to achieve some interesting control flow results.
let section = |header: Option<&'static str>, rows: Vec<&'static str>| {
section!(
// if-let adjacent
header.map(|h| h1!(('¡', h, '!'))),
// if adjacent
(!rows.is_empty()).then_some(
// for adjacent
ul!(rows.into_iter().map(|row| li!(row)))
)
// else adjacent
.ok_or("no rows")
)
};§Note on attributes
This crate design takes special care to support some common cases on real world situations. At this point in the documentation, you already know everything you need to figure this out yourself, but I’ll mention three examples that might not be that obvious at first glance.
// Some renders attribute normally
input!(value = Some("oiblz")).render(&mut s);
assert_eq!(s, r#"<input value="oiblz">"#);
// None means nothing gets rendered and even attribute key is taken out
input!(value = None::<&str>).render(&mut s);
assert_eq!(s, r#"<input>"#);let path = "/about";
a!(href = ("https://oiblz", path)).render(&mut s);
// tuple concatenates, so it works for interpolation without allocation
assert_eq!(s, r#"<a href="https://oiblz/about"></a>"#);// boolean values are for boolean attributes
select!(checked = true).render(&mut s);
assert_eq!(s, r#"<select checked></select>"#);
// false omits the attribute, true places it without value
select!(checked = false).render(&mut s);
assert_eq!(s, r#"<select></select>"#);// consecutive attribute keys means join with space
button!(class = "bg-red", class = true.then_some("warning")).render(&mut s);
// so in this case you can have a class always present, while another is optional
assert_eq!(s, r#"<button class="bg-red warning"></button>"#);§Feature flags
No features are enabled by default, which means this crate does not carry any dependencies. But hear me out…
-
axum: The
Rawstruct now implementsaxum::response::IntoResponse, which means it can be directly returned from route functions like magic. -
kebab: Attributes will have the underline (_) replaced by a dash (-) in compile time. This is useful for cleanly adding an
hx-getfor example, for no runtime cost. -
perf: The Render implementation for numbers won’t use Display, instead leveraging a performance oriented library. This might give you a rendering performance boost if you have lots of numbers.
§Versus
-
vy, the main inspiration of this library.
- Hypotext has syntax that allows for conditional attributes and classes, without giving up formatting.
- Hypotext has no procedural macros, even with all features enabled.
- I’d pick hypotext over it because it’s simpler and more powerful.
-
maud, de facto compiled html macro dsl.
- Hypotext has way less dsl, which could work as a pro or a con.
- Hypotext has no procedural macros, even with all features enabled.
- Hypotext does not allocate intermediary containers.
- I’d pick maud if you prefer it’s dsl.
-
askama, actual html templates jinja style.
- Hypotext has a simpler syntax for composition (just functions).
- Hypotext will avoid the html change of context, which could work as a pro or con.
- I’d pick askama if you want to have raw html files.
§Thanks for reading all of this.
Macros§
- a
- Hyperlink
- abbr
- Abbreviation
- address
- Contact information for a page or article element
- area
- Hyperlink or dead area on an image map
- article
- Self-contained syndicatable or reusable composition
- aside
- Sidebar for tangentially related content
- audio
- Audio player
- b
- Keywords
- base
- Base URL and default target navigable for hyperlinks and forms
- bdi
- Text directionality isolation
- bdo
- Text directionality formatting
- blockquote
- A section quoted from another source
- body
- Document body
- br
- Line break, e.g. in poem or postal address
- button
- Button control
- canvas
- Scriptable bitmap canvas
- caption
- Table caption
- cite
- Title of a work
- code
- Computer code
- col
- Table column
- colgroup
- Group of columns in a table
- data
- Machine-readable equivalent
- datalist
- Container for options for combo box control
- dd
- Content for corresponding dt element(s)
- del
- A removal from the document
- details
- Disclosure control for hiding details
- dfn
- Defining instance
- dialog
- Dialog box or window
- div
- Generic flow container, or container for name-value groups in dl elements
- dl
- Association list consisting of zero or more name-value groups
- dt
- Legend for corresponding dd element(s)
- element
- renders arbitrary element
- em
- Stress emphasis
- embed
- Plugin
- fieldset
- Group of form controls
- figcaption
- Caption for figure
- figure
- Figure with optional caption
- footer
- Footer for a page or section
- form
- User-submittable form
- h1
- Heading 1
- h2
- Heading 2
- h3
- Heading 3
- h4
- Heading 4
- h5
- Heading 5
- h6
- Heading 6
- head
- Container for document metadata
- header
- Introductory or navigational aids for a page or section
- hgroup
- Heading container
- hr
- Thematic break
- html
- Root element
- i
- Alternate voice
- iframe
- Child navigable
- img
- Image
- input
- Form control
- ins
- An addition to the document
- kbd
- User input
- label
- Caption for a form control
- legend
- Caption for fieldset
- li
- List item
- link
- Link metadata
- main
- Container for the dominant contents of the document
- map
- Image map
- mark
- Highlight
- math
- mathml root
- menu
- Menu of commands
- meta
- Text metadata
- meter
- Gauge
- nav
- Section with navigational links
- noscript
- Fallback content for script
- object
- Image, child navigable, or plugin
- ol
- Ordered list
- optgroup
- Group of options in a list box
- option
- Option in a list box or combo box control
- output
- Calculated output value
- p
- Paragraph
- picture
- Image
- pre
- Block of preformatted text
- progress
- Progress bar
- q
- Quotation
- rp
- Parenthesis for ruby annotation text
- rt
- Ruby annotation text
- ruby
- Ruby annotation(s)
- s
- Inaccurate text
- samp
- Computer output
- script
- Embedded script
- search
- Container for search controls
- section
- Generic document or application section
- select
- List box control
- selectedcontent
- Mirrors content from an option
- slot
- Shadow tree slot
- small
- Side comment
- source
- Image source for img or media source for video or audio
- span
- Generic phrasing container
- strong
- Importance
- style
- Embedded styling information
- sub
- Subscript
- summary
- Caption for details
- sup
- Superscript
- svg
- svg root
- table
- Table
- tbody
- Group of rows in a table
- td
- Table cell
- template
- Template
- textarea
- Multiline text controls
- tfoot
- Group of footer rows in a table
- th
- Table header cell
- thead
- Group of heading rows in a table
- time
- Machine-readable equivalent of date- or time-related data
- title
- Document title
- tr
- Table row
- track
- Timed text track
- u
- Unarticulated annotation
- ul
- List
- var
- Variable
- video
- Video player
- wbr
- Line breaking opportunity
Structs§
- Raw
- renders directly without any escaping
Constants§
- DOCTYPE
- the canonical html doctype
Traits§
- Render
- what can be rendered to html
Functions§
- render
- render template into a raw string