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

Simplify access to data syntax and Roda rendering #890

Merged
merged 4 commits into from
May 4, 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
91 changes: 46 additions & 45 deletions bridgetown-core/lib/bridgetown-core/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,69 +26,70 @@ def initialize(*)
# Strings rather than symbols are used for compatibility with YAML.
DEFAULTS = {
# Where things are
"root_dir" => Dir.pwd,
"plugins_dir" => "plugins",
"source" => "src",
"destination" => "output",
"collections_dir" => "",
"cache_dir" => ".bridgetown-cache",
"layouts_dir" => "_layouts",
"components_dir" => "_components",
"islands_dir" => "_islands",
"partials_dir" => "_partials",
"collections" => {},
"taxonomies" => {
"root_dir" => Dir.pwd,
"plugins_dir" => "plugins",
"source" => "src",
"destination" => "output",
"collections_dir" => "",
"cache_dir" => ".bridgetown-cache",
"layouts_dir" => "_layouts",
"components_dir" => "_components",
"islands_dir" => "_islands",
"partials_dir" => "_partials",
"collections" => {},
"taxonomies" => {
category: { key: "categories", title: "Category" }, tag: { key: "tags", title: "Tag" },
},
"autoload_paths" => [],
"inflector" => nil,
"eager_load_paths" => [],
"autoloader_collapsed_paths" => [],
"additional_watch_paths" => [],
"autoload_paths" => [],
"inflector" => nil,
"eager_load_paths" => [],
"autoloader_collapsed_paths" => [],
"additional_watch_paths" => [],

# Handling Reading
"include" => [".htaccess", "_redirects", ".well-known"],
"exclude" => [],
"keep_files" => [".git", ".svn", "_bridgetown"],
"encoding" => "utf-8",
"markdown_ext" => "markdown,mkdown,mkdn,mkd,md",
"strict_front_matter" => false,
"slugify_mode" => "pretty",
"include" => [".htaccess", "_redirects", ".well-known"],
"exclude" => [],
"keep_files" => [".git", ".svn", "_bridgetown"],
"encoding" => "utf-8",
"markdown_ext" => "markdown,mkdown,mkdn,mkd,md",
"strict_front_matter" => false,
"slugify_mode" => "pretty",

# Filtering Content
"future" => false,
"unpublished" => false,
"ruby_in_front_matter" => true,
"future" => false,
"unpublished" => false,
"ruby_in_front_matter" => true,

# Conversion
"content_engine" => "resource",
"markdown" => "kramdown",
"highlighter" => "rouge",
"content_engine" => "resource",
"markdown" => "kramdown",
"highlighter" => "rouge",
"support_data_as_view_methods" => true,

# Serving
"port" => "4000",
"host" => "127.0.0.1",
"base_path" => "/",
"show_dir_listing" => false,
"port" => "4000",
"host" => "127.0.0.1",
"base_path" => "/",
"show_dir_listing" => false,

# Output Configuration
"available_locales" => [:en],
"default_locale" => :en,
"prefix_default_locale" => false,
"permalink" => nil, # default is set according to content engine
"timezone" => nil, # use the local timezone
"available_locales" => [:en],
"default_locale" => :en,
"prefix_default_locale" => false,
"permalink" => nil, # default is set according to content engine
"timezone" => nil, # use the local timezone

"quiet" => false,
"verbose" => false,
"defaults" => [],
"quiet" => false,
"verbose" => false,
"defaults" => [],

"liquid" => {
"liquid" => {
"error_mode" => "warn",
"strict_filters" => false,
"strict_variables" => false,
},

"kramdown" => {
"kramdown" => {
"auto_ids" => true,
"toc_levels" => (1..6).to_a,
"entity_output" => "as_char",
Expand All @@ -102,7 +103,7 @@ def initialize(*)
"mark_highlighting" => true,
},

"development" => {
"development" => {
"fast_refresh" => true,
},
}.each_with_object(Configuration.new) { |(k, v), hsh| hsh[k] = v.freeze }.freeze
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ module Loaders
# %}~~~
# ~~~~
class Ruby < Base
HEADER = %r!\A[~`#-]{3,}(?:ruby|<%|{%)\s*\n!
BLOCK = %r!#{HEADER.source}(.*?\n?)^((?:%>|%})?[~`#-]{3,}\s*$\n?)!m
HEADER = %r!\A[~`#-]{3,}(?:ruby|<%|{%)[ \t]*\n!
BLOCK = %r!#{HEADER.source}(.*?\n?)^((?:%>|%})?[~`#-]{3,}[ \t]*$\n?)!m

# Determines whether a given file has Ruby front matter
#
Expand All @@ -77,9 +77,9 @@ def self.header?(file)
def read(file_contents, file_path:)
if (ruby_content = file_contents.match(BLOCK)) && should_execute_inline_ruby?
Result.new(
content: ruby_content.post_match,
content: ruby_content.post_match.lstrip,
front_matter: process_ruby_data(ruby_content[1], file_path, 2),
line_count: ruby_content[1].lines.size
line_count: ruby_content[1].lines.size - 1
)
elsif self.class.header?(file_path)
Result.new(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ module Loaders
# ---
# ~~~
class YAML < Base
HEADER = %r!\A---\s*\n!
BLOCK = %r!\A(---\s*\n.*?\n?)^((---|\.\.\.)\s*$\n?)!m
HEADER = %r!\A---[ \t]*\n!
BLOCK = %r!#{HEADER.source}(.*?\n?)^((---|\.\.\.)[ \t]*$\n?)!m

# Determines whether a given file has YAML front matter
#
Expand All @@ -31,7 +31,7 @@ def read(file_contents, **)
yaml_content = file_contents.match(BLOCK) or return

Result.new(
content: yaml_content.post_match,
content: yaml_content.post_match.lstrip,
front_matter: YAMLParser.load(yaml_content[1]),
line_count: yaml_content[1].lines.size - 1
)
Expand Down
8 changes: 5 additions & 3 deletions bridgetown-core/lib/bridgetown-core/model/builder_origin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,11 @@ def read
@data
end

def exists?
false
end
def front_matter_line_count = @data[:_front_matter_line_count_]

def original_path = @data[:_original_path_] || relative_path

def exists? = false

def read_data_from_builder
builder = Kernel.const_get(url.host.gsub(".", "::"))
Expand Down
33 changes: 16 additions & 17 deletions bridgetown-core/lib/bridgetown-core/ruby_template_view.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,16 @@ def initialize(convertible)
end
@paginator = resource.paginator if resource.respond_to?(:paginator)
@site = resource.site
@support_data_as_view_methods = @site.config.support_data_as_view_methods
end

def data
resource.data
end
def data = resource.data

def partial(_partial_name = nil, **_options)
raise "Must be implemented in a subclass"
end
def collections = site.collections

def site_drop = site.site_payload.site

def partial(_partial_name = nil, **_options) = raise("Must be implemented in a subclass")

def render(item, **options, &)
if item.respond_to?(:render_in)
Expand All @@ -57,14 +58,6 @@ def render(item, **options, &)
end
end

def collections
site.collections
end

def site_drop
site.site_payload.site
end

def liquid_render(component, options = {}, &block)
options[:_block_content] = capture(&block) if block && respond_to?(:capture)
render_statement = _render_statement(component, options)
Expand All @@ -83,9 +76,17 @@ def helpers
@helpers ||= Helpers.new(self, site)
end

def data_key?(key, *args, **kwargs)
return false unless @support_data_as_view_methods

args.empty? && kwargs.empty? && !block_given? && data.key?(key)
end

def method_missing(method_name, ...)
if helpers.respond_to?(method_name.to_sym)
helpers.send(method_name.to_sym, ...)
elsif data_key?(method_name, ...)
data[method_name]
else
super
end
Expand All @@ -95,9 +96,7 @@ def respond_to_missing?(method_name, include_private = false)
helpers.respond_to?(method_name.to_sym, include_private) || super
end

def inspect
"#<#{self.class} layout=#{layout&.label} resource=#{resource.relative_path}>"
end
def inspect = "#<#{self.class} layout=#{layout&.label} resource=#{resource.relative_path}>"

private

Expand Down
4 changes: 3 additions & 1 deletion bridgetown-core/test/resources/src/_layouts/default.erb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
---
<!doctype html>
<html>
<head></head>
<head>
<title><%= title %></title>
</head>
<body>
<%= yield %>
</body>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
~~~ruby
{ title: "I'm a Second Level Page" }
{ title: "I'm a Second Level Page", layout: :default }
~~~

That's **nice**.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
~~~ruby
{ title: "I'm a Second Level Page in French" }
{ title: "I'm a Second Level Page in French", layout: :default }
~~~

C'est **bien**.
Expand Down
2 changes: 2 additions & 0 deletions bridgetown-core/test/test_locales.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@ class TestLocales < BridgetownUnitTest

should "have the correct permalink and locale in English" do
assert_equal "/second-level-page/", @english_resource.relative_url
assert_includes @english_resource.output, "<title>I&#39;m a Second Level Page</title>"
assert_includes @english_resource.output, "<p>Locale: en</p>"
end

should "have the correct permalink and locale in French" do
assert_equal "/fr/second-level-page/", @french_resource.relative_url
assert_includes @french_resource.output, "<title>I&#39;m a Second Level Page in French</title>"
assert_includes @french_resource.output, "<p>C’est <strong>bien</strong>.</p>\n\n<p>Locale: fr</p>"

assert_includes @french_resource.output, <<-HTML
Expand Down
2 changes: 1 addition & 1 deletion bridgetown-routes/.rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ inherit_from: ../.rubocop.yml
AllCops:
Exclude:
- "*.gemspec"
- "test/ssr/src/_islands/**/*.rb"
- "test/ssr/src/**/*.rb"
22 changes: 14 additions & 8 deletions bridgetown-routes/lib/bridgetown-routes/code_blocks.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ module CodeBlocks
class << self
attr_accessor :blocks

def add_route(name, file_code = nil, &block)
def add_route(name, file_code = nil, front_matter_line_count = nil, &block)
block.instance_variable_set(:@_route_file_code, file_code) if file_code
if front_matter_line_count
block.instance_variable_set(:@_front_matter_line_count, front_matter_line_count)
end

@blocks ||= {}
@blocks[name] = block
Expand All @@ -31,17 +34,20 @@ def eval_route_file(file, file_slug, app) # rubocop:disable Lint/UnusedMethodArg
code = File.read(file)
code_postmatch = nil
ruby_content = code.match(Bridgetown::FrontMatter::Loaders::Ruby::BLOCK)
front_matter_line_count = nil
if ruby_content
code = ruby_content[1]
code_postmatch = ruby_content.post_match
code_postmatch = ruby_content.post_match.lstrip
front_matter_line_count = code.lines.count - 1
code.concat("\nrender_with {}") unless code.match?(%r!^\s*render_with\s|\(!)
end

code = <<~RUBY
add_route(#{file_slug.inspect}, #{code_postmatch.inspect}) do |r|
#{code}
end
RUBY
instance_eval(code, file, ruby_content ? 1 : 0)
# rubocop:disable Style/DocumentDynamicEvalDefinition, Style/EvalWithLocation
code_proc = Kernel.eval(
"proc {|r| #{code} }", TOPLEVEL_BINDING, file, ruby_content ? 2 : 1
)
add_route(file_slug, code_postmatch, front_matter_line_count, &code_proc)
# rubocop:enable Style/DocumentDynamicEvalDefinition, Style/EvalWithLocation
end
end
end
Expand Down
15 changes: 11 additions & 4 deletions bridgetown-routes/lib/roda/plugins/bridgetown_routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,16 @@ def run_file_route(file, slug:)
response.instance_variable_set(
:@_route_file_code, route_block.instance_variable_get(:@_route_file_code)
) # could be nil
response.instance_variable_set(
:@_front_matter_line_count,
route_block.instance_variable_get(:@_front_matter_line_count)
) # could be nil
instance_exec(request, &route_block)
end

def front_matter(&block)
b = block.binding
denylisted = %i(r app code ruby_content code_postmatch)
denylisted = %i(r argv)
data = b.local_variables.filter_map do |key|
next if denylisted.any? key

Expand Down Expand Up @@ -99,7 +103,9 @@ def render_with(data: {}, &) # rubocop:todo Metrics/AbcSize, Metrics/MethodLengt
)
).read do
data[:_collection_] = bridgetown_site.collections.pages
data[:_original_path_] = path
data[:_relative_path_] = source_path
data[:_front_matter_line_count_] = response._front_matter_line_count
data[:_content_] = code
data
end
Expand Down Expand Up @@ -149,9 +155,10 @@ def file_routes

module ResponseMethods
# template string provided, if available, by the saved code block
def _route_file_code
@_route_file_code
end
def _route_file_code = @_route_file_code

# we need to know where the real template starts for good error reporting
def _front_matter_line_count = @_front_matter_line_count

def _fake_resource_view(view_class:, roda_app:, bridgetown_site:)
@_fake_resource_views ||= {}
Expand Down
18 changes: 18 additions & 0 deletions bridgetown-routes/test/ssr/src/_routes/bare_route.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module DoubleNumbers
def double
self * 2
end
end
Numeric.include DoubleNumbers

class DoublingArray < Array
def double_map
map(&:double)
end
end

r.get Integer do |num|
numbers = DoublingArray.new([1, 2, 3, num]).double_map

{ numbers: }
end
Loading