Skip to content

Commit ce6a2f6

Browse files
authored
Merge pull request #5 from tram-rb/refactoring
Refactor section definitions (extract sections)
2 parents 9b5bd5c + e417111 commit ce6a2f6

File tree

2 files changed

+51
-37
lines changed

2 files changed

+51
-37
lines changed

lib/tram/page.rb

Lines changed: 15 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -3,41 +3,35 @@
33
class Tram::Page
44
extend ::Dry::Initializer
55

6+
require_relative "page/section"
7+
68
class << self
79
attr_accessor :i18n_scope
810

911
def section(name, options = {})
10-
@__sections ||= []
11-
12-
n = name.to_sym
13-
if @__sections.map(&:first).include?(n)
14-
raise "Section #{n} already exists"
15-
end
12+
name = name.to_sym
13+
raise "Section #{name} already exists" if sections.key? name
1614

17-
n = define_section_method(n, options)
18-
@__sections << [n, options]
15+
section = Section.new(name, options)
16+
sections[name] = section
17+
define_method(name, &section.block) if section.block
1918
end
2019

2120
def url_helper(name)
2221
raise "Rails url_helpers module is not defined" unless defined?(Rails)
2322
delegate name, to: :"Rails.application.routes.url_helpers"
2423
end
2524

26-
private
27-
28-
def define_section_method(n, options)
29-
return n unless options[:value]
30-
define_method(n) { instance_exec(&options[:value]) }
31-
n
25+
def sections
26+
@sections ||= {}
3227
end
3328
end
3429

35-
def to_h(options = {})
36-
data = page_methods(options).map do |(name, opts)|
37-
value = public_send(opts[:method] || name)
38-
[name, value]
39-
end
40-
Hash[data]
30+
def to_h(except: nil, only: nil, **)
31+
obj = self.class.sections.values.map { |s| s.call(self) }.reduce({}, :merge)
32+
obj = obj.reject { |k, _| Array(except).map(&:to_sym).include? k } if except
33+
obj = obj.select { |k, _| Array(only).map(&:to_sym).include? k } if only
34+
obj
4135
end
4236

4337
private
@@ -47,21 +41,5 @@ def t(key)
4741
I18n.t key, scope: [Tram::Page.i18n_scope, self.class.name.underscore]
4842
end
4943

50-
def page_methods(options)
51-
methods = self.class.instance_variable_get(:"@__sections") || []
52-
except = Array(options[:except])
53-
only = Array(options[:only])
54-
methods.reject do |(name, opts)|
55-
(except.any? && except.include?(name)) ||
56-
(only.any? && !only.include?(name)) ||
57-
__hide?(opts)
58-
end
59-
end
60-
61-
def __hide?(opts)
62-
black, white = opts.values_at(:unless, :if)
63-
(black && public_send(black)) || (white && !public_send(white))
64-
end
44+
self.i18n_scope = "pages"
6545
end
66-
67-
Tram::Page.i18n_scope = "pages"

lib/tram/page/section.rb

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# frozen_string_literal: true
2+
3+
class Tram::Page
4+
#
5+
# Contains class-level definition (name and options) for a section
6+
# with a method [#call] that extracts the section part of hash
7+
# from an instance of [Tram::Page]
8+
#
9+
class Section
10+
extend Dry::Initializer
11+
param :name, proc(&:to_sym)
12+
option :method, proc(&:to_s), default: -> { name }, as: :method_name
13+
option :value, proc(&:to_proc), optional: true, as: :block
14+
option :if, proc(&:to_s), optional: true, as: :positive
15+
option :unless, proc(&:to_s), optional: true, as: :negative
16+
option :skip, true.method(:&), optional: true
17+
18+
# @param [Tram::Page] page
19+
# @return [Hash] a part of the section
20+
def call(page)
21+
skip_on?(page) ? {} : { name => value_at(page) }
22+
end
23+
24+
private
25+
26+
def skip_on?(page)
27+
return true if skip
28+
return true if positive && !page.public_send(positive)
29+
return true if negative && page.public_send(negative)
30+
end
31+
32+
def value_at(page)
33+
block ? page.instance_exec(&block) : page.public_send(method_name)
34+
end
35+
end
36+
end

0 commit comments

Comments
 (0)