-
-
Notifications
You must be signed in to change notification settings - Fork 114
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add a helper DSL method for builder plugins * Add helpers plugin documentation * Reflow the ERB and Beyond documentation * Excute helper blocks in builder scope by default * Use correct helper terminology * Switch to using instance_exec
- Loading branch information
1 parent
c8a72d8
commit 2ac8e2b
Showing
7 changed files
with
254 additions
and
53 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# frozen_string_literal: true | ||
|
||
module Bridgetown | ||
module Builders | ||
module DSL | ||
module Helpers | ||
def helper(helper_name, method_name = nil, helpers_scope: false, &block) | ||
builder_self = self | ||
m = Module.new | ||
|
||
if block && !helpers_scope | ||
m.define_method helper_name do |*args| | ||
builder_self.instance_exec(*args, &block) | ||
end | ||
else | ||
block = method(method_name) if method_name | ||
m.define_method helper_name, &block | ||
end | ||
|
||
Bridgetown::RubyTemplateView::Helpers.include(m) | ||
|
||
functions << { name: name, filter: m } | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
# frozen_string_literal: true | ||
|
||
require "helper" | ||
|
||
class HelpersBuilder < Builder | ||
def build | ||
helper "block_based" do |something| | ||
"Block Based #{something} #{self.class}" | ||
end | ||
|
||
helper "within_helpers_scope", helpers_scope: true do |something| | ||
"Within Helpers Scope Based #{something} #{self.class} #{slugify("I Am Groot")}" | ||
end | ||
|
||
helper "method_based", :method_based | ||
end | ||
|
||
def method_based(something) | ||
"Method Based #{something} #{self.class}" | ||
end | ||
end | ||
|
||
class TestHelpers < BridgetownUnitTest | ||
context "adding helpers" do | ||
setup do | ||
Bridgetown.sites.clear | ||
@site = Site.new(site_configuration) | ||
Builders::DocumentsGenerator.clear_documents_to_generate | ||
@generator = Builders::DocumentsGenerator.new(@site.config) | ||
@builder = HelpersBuilder.new("HelpersBuilder", @site) | ||
Builders::DocumentsGenerator.add("im-a-post.md", proc { | ||
title "I'm a post!" | ||
date "2019-05-01" | ||
}) | ||
@generator.generate(@site) | ||
@erb_view = Bridgetown::ERBView.new(@site.posts.docs.first) | ||
end | ||
|
||
should "work with blocks" do | ||
content = "This is the <%= block_based page[:title] %> helper" | ||
tmpl = Tilt::ErubiTemplate.new( | ||
outvar: "@_erbout", | ||
engine_class: Erubi::CaptureEndEngine | ||
) { content } | ||
result = tmpl.render(@erb_view) | ||
assert_equal "This is the Block Based I'm a post! HelpersBuilder helper", result | ||
end | ||
|
||
should "allow execution within helpers scope" do | ||
content = "This is the <%= within_helpers_scope page[:title] %> helper" | ||
tmpl = Tilt::ErubiTemplate.new( | ||
outvar: "@_erbout", | ||
engine_class: Erubi::CaptureEndEngine | ||
) { content } | ||
result = tmpl.render(@erb_view) | ||
assert_equal "This is the Within Helpers Scope Based I'm a post! Bridgetown::RubyTemplateView::Helpers i-am-groot helper", result | ||
end | ||
|
||
should "work with methods" do | ||
content = "This is the <%= method_based page[:title] %> helper" | ||
tmpl = Tilt::ErubiTemplate.new( | ||
outvar: "@_erbout", | ||
engine_class: Erubi::CaptureEndEngine | ||
) { content } | ||
result = tmpl.render(@erb_view) | ||
assert_equal "This is the Method Based I'm a post! HelpersBuilder helper", result | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
--- | ||
title: Helpers | ||
hide_in_toc: true | ||
order: 0 | ||
category: plugins | ||
--- | ||
|
||
Helpers are Ruby methods you can provide to Tilt-based templates ([ERB, Slim, etc.](/docs/erb-and-beyond)) to transform data or output new content in various ways. | ||
|
||
Example: | ||
|
||
```ruby | ||
class Helpers < SiteBuilder | ||
def build | ||
helper "cache_busting_url" do |url| | ||
"http://www.example.com/#{url}?#{Time.now.to_i}" | ||
end | ||
end | ||
end | ||
``` | ||
|
||
```erb | ||
<%= cache_busting_url "mydynamicfile.js" %> | ||
``` | ||
|
||
outputs: | ||
|
||
``` | ||
http://www.example.com/mydynamicfile.js?1586194585 | ||
``` | ||
|
||
## Supporting Arguments | ||
|
||
You can accept multiple arguments to your helper by simply adding them to your block or method, and optional ones are simply specified with a default value (perhaps `nil` or `false`). For example: | ||
|
||
```ruby | ||
def Helpers < SiteBuilder | ||
def build | ||
helper "multiply_and_optionally_add" do |input, multiply_by, add_by = nil| | ||
value = input * multiply_by | ||
add_by ? value + add_by : value | ||
end | ||
end | ||
end | ||
``` | ||
|
||
Then just use it like this: | ||
|
||
```erb | ||
5 times 10 equals <%= multiply_and_optionally_add 5, 10 %> | ||
output: 5 times 10 equals 50 | ||
5 times 10 plus 3 equals <%= multiply_and_optionally_add 5, 10, 3 %> | ||
output: 5 times 10 plus 3 equals 53 | ||
``` | ||
|
||
## Using Instance Methods | ||
|
||
As with other parts of the Builder API, you can also use an instance method to register your helper: | ||
|
||
```ruby | ||
def Helpers < SiteBuilder | ||
def build | ||
helper "cache_busting_url", :bust_it | ||
end | ||
|
||
def bust_it(url) | ||
"http://www.example.com/#{url}?#{Time.now.to_i}" | ||
end | ||
end | ||
``` | ||
|
||
## Helper Execution Scope | ||
|
||
By default, the code within the helper block or method is executed within the scope of the builder object. This means you will not have access to other helpers you may expecting to call. For example, if you want to call `slugify` from your helper, it will cause an error. | ||
|
||
To remedy this, simply pass the `helpers_scope: true` argument when defining a helper block. Then you can call other helpers as part of your code block (but not methods within your builder). | ||
|
||
```ruby | ||
def Helpers < SiteBuilder | ||
def build | ||
helper "slugify_and_upcase", helpers_scope: true do |url| | ||
slugify(url).upcase | ||
end | ||
end | ||
end | ||
``` | ||
|
||
## Helpers vs. Filters vs. Tags | ||
|
||
Filters and tags are aspects of the [Liquid](/docs/liquid) template engine which comes installed by default. The behavior of both filters and tags are roughly analogous to helpers in [Tilt-based templates](/docs/erb-and-beyond). Specialized Bridgetown filters are also made available as helpers, as are a few tags such as `webpack_path`. |