Getting started
Basic Usage
After installing the shard, you will need to follow three steps to start using Blueprint:
- Require
"blueprint/html"
- Include
Blueprint::HTML
module - Define a
#blueprint
method to write the HTML structure inside.
Your view class is now defined, to render it it's necessary to instantiate it
and call #to_html
method.
Blueprints Are Just POCOs
You are using just Plain Old Crystal Objects (POCOs). The Blueprint::HTML
just
add helper methods to handle the HTML building stuff and your class can have its
own logic. For example, if you want pass data to your view object:
It is possible even use structs instead of classes:
struct Card
include Blueprint::HTML
private def blueprint
div(class: "card") { "Hello" }
end
end
# or using `record` macro
record Alert, message : String do
include Blueprint::HTML
private def blueprint
div(class: "alert") { @message }
end
end
card = Card.new
card.to_html # => <div class="card">Hello</div>
alert = Alert.new(message: "Hello")
alert.to_html # => <div class="alert">Hello</div>
Passing Content
If you want to pass content when rendering a blueprint, you should define the
#blueprint(&)
method and yield the block.
Code style
If you are new to Crystal, know that blocks can be passed using do ... end
or
{ ... }
. All of these are equivalent:
# With `do ... end` blocks
private def blueprint
html lang: "pt-BR" do
head do
title do
"Blueprint"
end
end
body do
h1 class: "heading" do
"Hello World"
end
end
end
end
# With `{ ... }` blocks
private def blueprint
html lang: "pt-BR" {
head {
title {
"Blueprint"
}
}
body {
h1 class: "heading" {
"Hello World"
}
}
}
end
It's a personal or team preference, you can stick to one style or mix two
styles (eg. Use do ... end
for multiline blocks and { ... }
for inline
blocks). But note that in Crystal the difference between using do ... end
and
{ ... }
is that do ... end
binds to the left-most call, while { ... }
binds to the right-most call:
With do ... end
blocks:
private def blueprint
render Alert.new do
"Hello World"
end
end
# The above is same as
private def blueprint
render(Alert.new) do
"Hello World"
end
end
While using { ... }
blocks:
private def blueprint
render Alert.new {
"Hello World"
}
end
# The above is same as
private def blueprint
render(Alert.new {
"Hello World"
})
end
The above example will raise an error Error: 'Alert.new' is not expected to
be invoked with a block, but a block was given
, to fix this you need to add
parentheses to render
call when using with { ... }
.