Releases: stephannv/blueprint
New docs, style builder, tokens, safe rendering and breaking changes
Overhauled docs
The Blueprint Docs was revised.
Style Variants (Experimental)
Simplify the management of CSS class combinations:
class AlertComponent
include Blueprint::HTML
style_builder do
base "alert"
variants do
type {
info "alert-info"
danger "alert-danger"
}
size {
xs "text-xs p-2"
md "text-md p-4"
lg "text-lg p-6"
}
closable {
yes "alert-closable"
}
special {
yes "alert-special"
no "alert-default"
}
end
defaults type: :info, size: :md
end
def blueprint
div(class: build_style(type: :danger, size: :lg, closable: true)) do
"My styled alert component"
end
end
end
puts AlertComponent.build_style(type: :info, size: :xs, special: false)
# "alert alert-info text-xs p-2 alert-default"
puts AlertComponent.new.to_s
# <div class="alert alert-danger text-lg p-6 alert-closable">
# My styled alert component
# </div>
Tokens (Experimental)
Allows to build classes based on conditionals.
class UserComponent
include Blueprint::HTML
def blueprint
h1 class: tokens(admin?: "is-admin", moderator?: "is-moderator") do
"Jane Doe"
end
end
def admin?
false
end
def moderator?
true
end
end
puts UserComponent.new.to_s
# <h1 class="is-moderator">
# Jane Doe
# </h1>
Add #safe
helper
The #safe
method wraps the given object in a Blueprint::SafeValue
, indicating to Blueprint that the content should be rendered without escaping.
BREAKING: Change #to_html
to #to_s
Instead of MyComponent.new.to_html
you should use MyComponent.new.to_s
.
BREAKING: Remove some utils methods
The methods #plain(&)
and #comment(&)
were removed, but you still can use the #plain(content : String)
and #comment(content : String)
.
BREAKING: Remove #unsafe_raw
#unsafe_raw
was removed in favor of #raw
.
# BEFORE
unsafe_raw "<script>My Script</script>"
# AFTER
raw safe("<script>My Script</script>")
BREAKING: Remove Blueprint::RawHTML
The Blueprint::RawHTML
included in 0.7.0 was removed. A module focused on performance will be planned in the future.
Include Blueprint::HTML::ComponenentRegistrar by default
You don't need to require and include Blueprint::HTML::ComponenentRegistrar
, it is already included when you include Blueprint::HTML
.
v0.7.0
What's Changed
- Allow passing comment via argument
comment "Cool comment here"
- Allow rendering unsafe content using
unsafe_raw
unsafe_raw "<script>alert('Danger!')</script>"
- Add
RawHtml
to priorize performance over safety
require "blueprint/raw_html"
class MyHTML
include Blueprint::RawHTML
def blueprint
div "<script>alert('Danger!')</script>" # this will not be escaped
end
end
- Code refactoring to improve performance
- Fix safety when passing content to elements via argument
Full Changelog: v0.6.0...v0.7.0
v0.6.0
What's Changed
- feat: Allow passing element content without using block by @stephannv in #53
h1 { "Hello World!" }
# or just
h1 "Hello World!"
Full Changelog: v0.5.1...v0.6.0
v0.5.1
Fix Crystal version string requirement.
Full Changelog: v0.5.0...v0.5.1
v0.5.0
What's Changed
Performance improvements: Increased speed execution by 15%.
v0.5.0 364.46k ( 2.74µs) (± 0.52%) 7.95kB/op fastest
v0.4.0 317.83k ( 3.15µs) (± 0.76%) 8.99kB/op 1.15× slower
- fix: Ignore nil elements from array attribute parsing by @stephannv in #48
- perf: Use String::Builder to improve render times by @stephannv in #51
Full Changelog: v0.4.0...v0.5.0
v0.4.0 - SVG support
Full details: https://blueprint.gunbolt.org/changelogs/v0.4.0/
What's Changed
- feat: Support SVG rendering by @stephannv in #42
Full Changelog: v0.3.0...v0.4.0
v0.3.0
Full details: https://blueprint.gunbolt.org/changelogs/v0.3.0/
What's Changed
- feat: Add experimental Blueprint::HTML.builder by @stephannv in #39
Full Changelog: v0.2.0...v0.3.0
v0.2.0
Highlights
Conditional rendering
It's possible to override #render?
method to control blueprint render.
class Example
include Blueprint::HTML
private def blueprint
h1 { "Example" }
end
private def render?
false
end
end
example = Example.new
example.to_html # => ""
Array attributes
Arrays passed as attribute values will be flattened and joined with " "
.
class Example
include Blueprint::HTML
private def blueprint
h1(class: ["a", "b", ["c", "d"]) { "Example" }
end
end
example = Example.new
example.to_html # => "<h1 class="a b c d">Example</h1>"
Enveloping
By overriding the #envelope(&)
method, you can create a wrapper around blueprint content. This is useful when defining layouts for pages
class Layout
include Blueprint::HTML
private def blueprint(&)
html do
body do
yield
end
end
end
end
class BasePage
include Blueprint::HTML
private def envelope(&)
render(Layout.new) { yield }
end
end
class Example < BasePage
def blueprint
h1 { "Example" }
end
end
example = Example.new
example.to_html # => "<html><body><h1>Hello</h1></body></html>"
Log
- config: Config linter by @stephannv in #24
- config: Add last 3 crystals versions to CI by @stephannv in #25
- feat: Allow conditional rendering by @stephannv in #26
- config: Reorganize CI by @stephannv in #27
- refactor: Clean up code by @stephannv in #28
- docs: Add CHANGELOG.md by @stephannv in #29
- test: Fix newline gsub by @stephannv in #31
- refactor: Minor code refactor by @stephannv in #32
- feat: Handle array attributes by @stephannv in #33
- config: Caching shards on CI by @stephannv in #34
- docs: Add struct usage to README by @stephannv in #35
- feat: Add
envelope(&)
method by @stephannv in #36 - docs: Mention generics to handle multiple layouts by @stephannv in #37
Full Changelog: v0.1.0...v0.2.0
v0.1.0 - First alpha release
This is a alpha version. I believe this shard is ready to be tested on side projects since it has the core features implemented (eg. can build full pages, can compose page with components, escapes content and attributes values).