Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support pipe in Serbea 2.0, add new pure Ruby template syntax (WIP) #817

Merged
merged 19 commits into from
Apr 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 15 additions & 11 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@ PATH
rake (>= 13.0)
roda (~> 3.46)
rouge (>= 3.0, < 5.0)
serbea (~> 1.0)
serbea (~> 2.1)
signalize (~> 1.3)
streamlined (>= 0.5.2)
serbea (~> 1.0)
thor (~> 1.1)
tilt (~> 2.0)
zeitwerk (~> 2.5)
Expand Down Expand Up @@ -76,7 +78,7 @@ GEM
colorator (1.1.0)
concurrent-ruby (1.2.3)
connection_pool (2.4.1)
csv (3.2.8)
csv (3.3.0)
diff-lcs (1.5.1)
docile (1.4.0)
drb (2.2.1)
Expand All @@ -94,7 +96,7 @@ GEM
i18n (1.14.4)
concurrent-ruby (~> 1.0)
jaro_winkler (1.5.6)
json (2.7.1)
json (2.7.2)
kramdown (2.4.0)
rexml
kramdown-parser-gfm (1.1.0)
Expand Down Expand Up @@ -133,13 +135,13 @@ GEM
parser (3.3.0.5)
ast (~> 2.4.1)
racc
public_suffix (5.0.4)
public_suffix (5.0.5)
racc (1.7.3)
rack (3.0.9.1)
rack (3.0.10)
rack-test (2.1.0)
rack (>= 1.3)
rainbow (3.1.1)
rake (13.1.0)
rake (13.2.1)
rb-fsevent (0.11.2)
rb-inotify (0.10.1)
ffi (~> 1.0)
Expand All @@ -150,7 +152,7 @@ GEM
rexml (3.2.6)
roda (3.78.0)
rack
rouge (4.2.0)
rouge (4.2.1)
rspec-mocks (3.13.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.13.0)
Expand All @@ -171,12 +173,11 @@ GEM
rubocop-bridgetown (0.4.1)
rubocop (~> 1.23)
rubocop-performance (~> 1.12)
rubocop-performance (1.20.2)
rubocop-performance (1.21.0)
rubocop (>= 1.48.1, < 2.0)
rubocop-ast (>= 1.30.0, < 2.0)
rubocop-ast (>= 1.31.1, < 2.0)
ruby-progressbar (1.13.0)
serbea (1.0.1)
activesupport (>= 6.0)
serbea (2.1.0)
erubi (>= 1.10)
tilt (~> 2.0)
shoulda (4.0.0)
Expand Down Expand Up @@ -209,6 +210,9 @@ GEM
thor (~> 1.0)
tilt (~> 2.0)
yard (~> 0.9, >= 0.9.24)
streamlined (0.5.2)
serbea (>= 2.1)
zeitwerk (~> 2.5)
terminal-table (3.0.2)
unicode-display_width (>= 1.1.1, < 3)
thor (1.3.1)
Expand Down
2 changes: 1 addition & 1 deletion bridgetown-builder/lib/bridgetown-builder/plugin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
21 changes: 0 additions & 21 deletions bridgetown-builder/test/test_hooks.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion bridgetown-core/bridgetown-core.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,9 @@ 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", "< 5.0"])
s.add_runtime_dependency("serbea", "~> 1.0")
s.add_runtime_dependency("serbea", "~> 2.1")
s.add_runtime_dependency("signalize", "~> 1.3")
s.add_runtime_dependency("streamlined", ">= 0.5.2")
s.add_runtime_dependency("thor", "~> 1.1")
s.add_runtime_dependency("tilt", "~> 2.0")
s.add_runtime_dependency("zeitwerk", "~> 2.5")
Expand Down
2 changes: 2 additions & 0 deletions bridgetown-core/lib/bridgetown-core.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,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
Expand Down
1 change: 1 addition & 0 deletions bridgetown-core/lib/bridgetown-core/component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

module Bridgetown
class Component
include Bridgetown::Streamlined
extend Forwardable

def_delegators :@view_context, :liquid_render, :partial
Expand Down
1 change: 1 addition & 0 deletions bridgetown-core/lib/bridgetown-core/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ def run_initializers!(context:) # rubocop:todo Metrics/AbcSize, Metrics/Cyclomat
dsl = ConfigurationDSL.new(scope: self, data: self)
dsl.instance_variable_set(:@context, context)
dsl.instance_exec(dsl, &init_init.block)
dsl._run_builtins!
self.url = cached_url if cached_url # restore local development URL if need be

setup_load_paths! appending: true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,12 @@ def _setup_initializer(name:, require_gem:, require_initializer:)
def _in_require_denylist?(name)
REQUIRE_DENYLIST.include?(name.to_sym)
end

# Initializers that are part of the Bridgetown boot sequence. Site owners can override
# defaults by running any of these manually…init is no-op if the initializer was already run.
def _run_builtins!
init :streamlined
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,6 @@ def capture(*args)
end

class ERBView < RubyTemplateView
include ERBCapture

def h(input)
Erubi.h(input)
end
Expand Down
59 changes: 56 additions & 3 deletions bridgetown-core/lib/bridgetown-core/converters/ruby_templates.rb
Original file line number Diff line number Diff line change
@@ -1,16 +1,69 @@
# frozen_string_literal: true

require "streamlined/renderable"

module Bridgetown
class PureRubyView < ERBView
def render(item = nil, **options, &block) # rubocop:disable Metrics
return @_erbout if !block && options.empty? && item.nil?

if item.is_a?(Proc) || (block && item.nil?)
result = item.is_a?(Proc) ? item.() : 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&.to_s&.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
Expand Down
46 changes: 6 additions & 40 deletions bridgetown-core/lib/bridgetown-core/helpers.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
# frozen_string_literal: true

require "streamlined/helpers"
require "active_support/html_safe_translation"

module Bridgetown
class RubyTemplateView
class Helpers
include Bridgetown::Filters
include Bridgetown::Filters::FromLiquid
include ::Streamlined::Helpers

# @return [Bridgetown::RubyTemplateView]
attr_reader :view
Expand Down Expand Up @@ -114,28 +116,13 @@ def link_to(text, relative_path = nil, options = {}, &block)
elsif relative_path.nil?
raise ArgumentError, "You must provide a relative path"
end
segments = attributes_from_options({ href: url_for(relative_path) }.merge(options))
segments = html_attributes({ href: url_for(relative_path) }.merge(options))

safe("<a #{segments}>#{text}</a>")
end

# Create a set of attributes from a hash.
#
# @param options [Hash] key-value pairs of HTML attributes
# @return [String]
def attributes_from_options(options)
segments = []
options.each do |attr, option|
attr = dashed(attr)
if option.is_a?(Hash)
option = option.transform_keys { |key| "#{attr}-#{dashed(key)}" }
segments << attributes_from_options(option)
else
segments << attribute_segment(attr, option)
end
end
safe(segments.join(" "))
end
# Provide backwards compatibility via Streamlined helper
alias_method :attributes_from_options, :html_attributes

# Delegates to <tt>I18n#translate</tt> but also performs two additional
# functions.
Expand Down Expand Up @@ -294,30 +281,9 @@ def dsd_style

style_tag.html_safe
end

# TODO: docu
def bypass_tracking(...) = Signalize.untracked(...)

private

# Covert an underscored value into a dashed string.
#
# @example "foo_bar_baz" => "foo-bar-baz"
#
# @param value [String|Symbol]
# @return [String]
def dashed(value)
value.to_s.tr("_", "-")
end

# Create an attribute segment for a tag.
#
# @param attr [String] the HTML attribute name
# @param value [String] the attribute value
# @return [String]
def attribute_segment(attr, value)
"#{attr}=\"#{Utils.xml_escape(value)}\""
end
end
end
end
18 changes: 18 additions & 0 deletions bridgetown-core/lib/bridgetown-core/ruby_template_view.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,29 @@
# frozen_string_literal: true

require "digest"
require "serbea/pipeline"
require "streamlined/helpers"
require "streamlined/renderable"

module Bridgetown
module Streamlined
include ::Streamlined::Renderable
include Serbea::Pipeline::Helper
include ERBCapture

def helper(name, &helper_block)
self.class.define_method(name) do |*args, **kwargs, &block|
helper_block.call(*args, **kwargs, &block)
end
end
alias_method :macro, :helper
end

class RubyTemplateView
require "bridgetown-core/helpers"

include Bridgetown::Streamlined

attr_reader :layout, :resource, :paginator, :site, :content
alias_method :page, :resource

Expand Down
2 changes: 1 addition & 1 deletion bridgetown-core/lib/roda/plugins/bridgetown_server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def self.load_dependencies(app) # rubocop:disable Metrics
app.plugin :json
app.plugin :json_parser
app.plugin :indifferent_params
app.plugin :cookies
app.plugin :cookies, path: "/"
app.plugin :public, root: Bridgetown::Current.preloaded_configuration.destination
app.plugin :not_found do
output_folder = Bridgetown::Current.preloaded_configuration.destination
Expand Down
2 changes: 1 addition & 1 deletion bridgetown-core/lib/site_template/Gemfile.erb
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,4 @@ gem "puma", "< 7"
# gem "nokogiri", "~> 1.13"

# Or for faster parsing of HTML-only resources via Inspectors, use Nokolexbor:
# gem "nokolexbor", "~> 0.4"
# gem "nokolexbor", "~> 0.5"
17 changes: 17 additions & 0 deletions bridgetown-core/test/resources/src/_components/ruby_html_text.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
class RubyHtmlText < Bridgetown::Component
def template
# blub = ->(input, str, replace_str) { input.sub(str, replace_str) }

macro :flub do |input, str, replace_str|
input.sub str, replace_str
end

html -> {
<<~HTML
<p>This is #{text -> { "<b>escaped!</b>" }}</p>
#{html "piping <i>bad</i>", -> { text | concat(" <b>good</b>") | markdownify }}
#{text "_yipee_", -> { markdownify | flub("yipee", "yay") | html_safe }}
HTML
}
end
end
Loading
Loading