From e14b27b1047577eaf21775cc60528e1fea651d9a Mon Sep 17 00:00:00 2001
From: Jared White
Date: Mon, 9 Oct 2023 20:34:15 -0700
Subject: [PATCH] Support `pipe` in Serbea 2.0, add new pure Ruby template
syntax
---
Gemfile.lock | 4 +-
.../lib/bridgetown-builder/plugin.rb | 2 +-
bridgetown-builder/test/test_hooks.rb | 21 ------
bridgetown-core/bridgetown-core.gemspec | 2 +-
bridgetown-core/lib/bridgetown-core.rb | 10 +++
.../converters/erb_templates.rb | 2 +
.../converters/ruby_templates.rb | 66 ++++++++++++++++++-
.../src/_events/2020-12-25-christmas.html | 2 +-
.../test/resources/src/_pages/i-am-ruby.rb | 26 +++++++-
.../resources/src/_partials/_a_partial.rb | 3 +
.../src/_partials/_an_erb_partial.erb | 1 +
bridgetown-core/test/test_resource.rb | 15 ++++-
bridgetown-website/Gemfile.lock | 4 +-
13 files changed, 123 insertions(+), 35 deletions(-)
create mode 100644 bridgetown-core/test/resources/src/_partials/_a_partial.rb
create mode 100644 bridgetown-core/test/resources/src/_partials/_an_erb_partial.erb
diff --git a/Gemfile.lock b/Gemfile.lock
index 0432e6034..3811b583e 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -25,7 +25,7 @@ PATH
rake (>= 13.0)
roda (~> 3.46)
rouge (~> 3.0)
- serbea (~> 1.0)
+ serbea (~> 2.0)
thor (~> 1.1)
tilt (~> 2.0)
zeitwerk (~> 2.5)
@@ -199,7 +199,7 @@ GEM
rubocop-ast (>= 0.4.0)
ruby-progressbar (1.13.0)
ruby2_keywords (0.0.5)
- serbea (1.0.1)
+ serbea (2.0.0)
activesupport (>= 6.0)
erubi (>= 1.10)
tilt (~> 2.0)
diff --git a/bridgetown-builder/lib/bridgetown-builder/plugin.rb b/bridgetown-builder/lib/bridgetown-builder/plugin.rb
index 456d98e52..c1e2656b0 100644
--- a/bridgetown-builder/lib/bridgetown-builder/plugin.rb
+++ b/bridgetown-builder/lib/bridgetown-builder/plugin.rb
@@ -57,7 +57,7 @@ def initialize(name = nil, current_site = nil)
def doc(*)
raise Bridgetown::Errors::FatalException,
- "The `doc' method has been removed. Please use the `new_resource' builder DSL instead"
+ "The `doc' method has been removed. Please use the `add_resource' builder DSL instead"
end
end
end
diff --git a/bridgetown-builder/test/test_hooks.rb b/bridgetown-builder/test/test_hooks.rb
index 58e10ce9f..253086e21 100644
--- a/bridgetown-builder/test/test_hooks.rb
+++ b/bridgetown-builder/test/test_hooks.rb
@@ -11,15 +11,6 @@ def build
hook :site, :pre_read do
site.config[:pre_read_hook_ran] = true
end
-
- hook :site, :post_read do
- if site.data[:languages]
- doc "#{site.data[:languages][1]}.md" do
- title "Ruby"
- date "2020-05-17"
- end
- end
- end
end
end
@@ -48,18 +39,6 @@ class TestHooks < BridgetownUnitTest
assert @site.config[:after_reset_hook_ran]
assert @site.config[:pre_read_hook_ran]
end
-
- # TODO: get working with Resource
- # should "work alongside Document Builder" do
- # @site.reset
- # @site.setup
- # @site.read
- # @generator = Builders::DocumentsGenerator.new(@site.config)
- # @generator.generate(@site)
-
- # post = @site.posts.docs.find { |doc| doc.data[:title] == "Ruby" }
- # assert_includes post.destination(""), "/dest/2020/05/17/ruby.html"
- # end
end
context "SiteBuilder" do
diff --git a/bridgetown-core/bridgetown-core.gemspec b/bridgetown-core/bridgetown-core.gemspec
index 1aaa7ab33..6c9e02b30 100644
--- a/bridgetown-core/bridgetown-core.gemspec
+++ b/bridgetown-core/bridgetown-core.gemspec
@@ -48,7 +48,7 @@ Gem::Specification.new do |s|
s.add_runtime_dependency("rake", ">= 13.0")
s.add_runtime_dependency("roda", "~> 3.46")
s.add_runtime_dependency("rouge", "~> 3.0")
- s.add_runtime_dependency("serbea", "~> 1.0")
+ s.add_runtime_dependency("serbea", "~> 2.0")
s.add_runtime_dependency("thor", "~> 1.1")
s.add_runtime_dependency("tilt", "~> 2.0")
s.add_runtime_dependency("zeitwerk", "~> 2.5")
diff --git a/bridgetown-core/lib/bridgetown-core.rb b/bridgetown-core/lib/bridgetown-core.rb
index 130fde455..efd652a35 100644
--- a/bridgetown-core/lib/bridgetown-core.rb
+++ b/bridgetown-core/lib/bridgetown-core.rb
@@ -60,6 +60,8 @@ def require_all(path)
# Ensure we can set up fallbacks so the default locale gets used
I18n::Backend::Simple.include I18n::Backend::Fallbacks
+# Monkey patches:
+
module HashWithDotAccess
class Hash # :nodoc:
def to_liquid
@@ -68,6 +70,14 @@ def to_liquid
end
end
+class Enumerator
+ def html_map(&block)
+ results = map.each(&block)
+
+ results.join.html_safe
+ end
+end
+
# Create our little String subclass for Ruby Front Matter
class Rb < String; end
diff --git a/bridgetown-core/lib/bridgetown-core/converters/erb_templates.rb b/bridgetown-core/lib/bridgetown-core/converters/erb_templates.rb
index 552fc9efe..e4b0208df 100644
--- a/bridgetown-core/lib/bridgetown-core/converters/erb_templates.rb
+++ b/bridgetown-core/lib/bridgetown-core/converters/erb_templates.rb
@@ -1,6 +1,7 @@
# frozen_string_literal: true
require "tilt/erubi"
+require "serbea/pipeline"
module Bridgetown
class OutputBuffer < ActiveSupport::SafeBuffer
@@ -74,6 +75,7 @@ def capture(*args)
class ERBView < RubyTemplateView
include ERBCapture
+ include Serbea::Pipeline::Helper
def h(input)
Erubi.h(input)
diff --git a/bridgetown-core/lib/bridgetown-core/converters/ruby_templates.rb b/bridgetown-core/lib/bridgetown-core/converters/ruby_templates.rb
index 649ff43a6..da4eba087 100644
--- a/bridgetown-core/lib/bridgetown-core/converters/ruby_templates.rb
+++ b/bridgetown-core/lib/bridgetown-core/converters/ruby_templates.rb
@@ -1,16 +1,76 @@
# frozen_string_literal: true
module Bridgetown
+ class PureRubyView < ERBView
+ # @yield a block which should be HTML escaped
+ def text(input, &blk)
+ if blk
+ h(pipe(input, &blk))
+ else
+ h(input)
+ end
+ end
+
+ def render(item = nil, **options, &block) # rubocop:disable Metrics
+ return @_erbout if !block && item.nil? && !options.key?(:html)
+
+ if options.key?(:html) || (block && item.nil?)
+ result = options.key?(:html) ? options[:html].presence : yield
+ return result if result.is_a?(OutputBuffer)
+
+ @_erbout ||= OutputBuffer.new
+ @_erbout << result.to_s.html_safe
+
+ return @_erbout
+ end
+
+ if item.respond_to?(:render_in)
+ result = item.render_in(self, &block)
+ result&.html_safe
+ else
+ partial(item, **options, &block)&.html_safe
+ end
+ end
+
+ def _render_partial(partial_name, options)
+ partial_path = _partial_path(partial_name, "rb")
+ return super unless File.exist?(partial_path)
+
+ (@_locals_stack ||= []).push(options)
+ (@_buffer_stack ||= []).push(@_erbout)
+ @_erbout = OutputBuffer.new
+
+ tmpl = site.tmp_cache["partial-tmpl:#{partial_path}"] ||=
+ options.keys.map do |k|
+ "#{k}=locals[:#{k}];"
+ end.push(File.read(partial_path)).join
+
+ instance_eval(tmpl).to_s.tap do
+ @_locals_stack.pop
+ @_erbout = @_buffer_stack.pop
+ end
+ end
+
+ def _output_buffer
+ @_erbout # might be nil
+ end
+
+ def locals
+ @_locals_stack&.last || {}
+ end
+ end
+
module Converters
class RubyTemplates < Converter
priority :highest
input :rb
def convert(content, convertible)
- erb_view = Bridgetown::ERBView.new(convertible)
- erb_view.instance_eval(
+ rb_view = Bridgetown::PureRubyView.new(convertible)
+ results = rb_view.instance_eval(
content, convertible.path.to_s, line_start(convertible)
- ).to_s
+ )
+ rb_view._output_buffer || results.to_s
end
end
end
diff --git a/bridgetown-core/test/resources/src/_events/2020-12-25-christmas.html b/bridgetown-core/test/resources/src/_events/2020-12-25-christmas.html
index d1c472b37..da8e5abfc 100644
--- a/bridgetown-core/test/resources/src/_events/2020-12-25-christmas.html
+++ b/bridgetown-core/test/resources/src/_events/2020-12-25-christmas.html
@@ -6,4 +6,4 @@
end
%>---
-Fa <%= 8.times.map { "la" }.join(" ") %>!
\ No newline at end of file
+Fa <%= pipe(8) { times | map(->(_) { "la" }) | join(" ") | concat("!") } %>
\ No newline at end of file
diff --git a/bridgetown-core/test/resources/src/_pages/i-am-ruby.rb b/bridgetown-core/test/resources/src/_pages/i-am-ruby.rb
index 5ef5b3805..7fda84b9b 100644
--- a/bridgetown-core/test/resources/src/_pages/i-am-ruby.rb
+++ b/bridgetown-core/test/resources/src/_pages/i-am-ruby.rb
@@ -2,11 +2,31 @@
front_matter do
layout :default
title "I am Ruby. Here me roar!"
+ include_markdown true
end
###
-markdownify <<~MARKDOWN
+render html: <<-HTML
+ Hello #{text "
world
"}
+ #{ render "a_partial", abc: 123 }
+ #{ render "an_erb_partial", abc: 456 }
+HTML
- > Well, _this_ is quite interesting! =)
+if data.include_markdown
+ render do
+ markdownify <<~MARKDOWN
-MARKDOWN
+ > Well, _this_ is quite interesting! =)
+
+ MARKDOWN
+ end
+end
+
+render html: <<-HTML
+
+ #{3.times.html_map do |i| <<-HTML
+ - #{text i}
+ HTML
+ end}
+
+HTML
diff --git a/bridgetown-core/test/resources/src/_partials/_a_partial.rb b/bridgetown-core/test/resources/src/_partials/_a_partial.rb
new file mode 100644
index 000000000..10c5ee196
--- /dev/null
+++ b/bridgetown-core/test/resources/src/_partials/_a_partial.rb
@@ -0,0 +1,3 @@
+render html: <<~HTML
+
+HTML
\ No newline at end of file
diff --git a/bridgetown-core/test/resources/src/_partials/_an_erb_partial.erb b/bridgetown-core/test/resources/src/_partials/_an_erb_partial.erb
new file mode 100644
index 000000000..7e4aeaca4
--- /dev/null
+++ b/bridgetown-core/test/resources/src/_partials/_an_erb_partial.erb
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/bridgetown-core/test/test_resource.rb b/bridgetown-core/test/test_resource.rb
index e26486766..2bc141dc8 100644
--- a/bridgetown-core/test/test_resource.rb
+++ b/bridgetown-core/test/test_resource.rb
@@ -316,14 +316,27 @@ class TestResource < BridgetownUnitTest
@site = resources_site
@site.process
@dest_file = File.read(dest_dir("i-am-ruby/index.html"))
+ Serbea::Pipeline.raise_on_missing_filters = true
+ # rubocop:disable Layout/TrailingWhitespace
assert_includes @dest_file, <<~HTML
+ Hello <p>world</p>
+
+
+
Well, this is quite interesting! =)
-
+
+
HTML
+ # rubocop:enable Layout/TrailingWhitespace
end
end
diff --git a/bridgetown-website/Gemfile.lock b/bridgetown-website/Gemfile.lock
index d5ac51708..327b349fe 100644
--- a/bridgetown-website/Gemfile.lock
+++ b/bridgetown-website/Gemfile.lock
@@ -25,7 +25,7 @@ PATH
rake (>= 13.0)
roda (~> 3.46)
rouge (~> 3.0)
- serbea (~> 1.0)
+ serbea (~> 2.0)
thor (~> 1.1)
tilt (~> 2.0)
zeitwerk (~> 2.5)
@@ -119,7 +119,7 @@ GEM
ruby2js (5.1.0)
parser
regexp_parser (~> 2.1.1)
- serbea (1.0.1)
+ serbea (2.0.0)
activesupport (>= 6.0)
erubi (>= 1.10)
tilt (~> 2.0)