foxpage 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +7 -8
- data/lib/fox_page/app_parts/configuration.rb +1 -0
- data/lib/fox_page/builders/assets.rb +1 -1
- data/lib/fox_page/builders/models.rb +23 -0
- data/lib/fox_page/builders/pages.rb +64 -13
- data/lib/fox_page/controller.rb +33 -0
- data/lib/fox_page/helpers/render_helper.rb +2 -2
- data/lib/fox_page/model.rb +177 -0
- data/lib/fox_page/refinements/camelize.rb +6 -0
- data/lib/fox_page/refinements/constantize.rb +19 -0
- data/lib/fox_page/refinements/pluralize.rb +15 -0
- data/lib/fox_page/refinements/singularize.rb +15 -0
- data/lib/fox_page/refinements/underscore.rb +19 -0
- data/lib/fox_page/router.rb +62 -8
- data/lib/fox_page/server.rb +1 -0
- data/lib/fox_page/site_builder.rb +2 -0
- data/lib/fox_page/version.rb +1 -1
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 98eb0f68d2163136732589c5da391975f8164e5c4e985dccd0bd24e893bc3045
|
4
|
+
data.tar.gz: e45d62a4c2a508010d066eab5fe822f8bc0a740c89b219a08d5a93e587b1ed8d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e6ae9e51e8c3defd140e169df2d9126e2227922af918dab4d4cdd69ed356214e680850f941f15d450b9656b130fc2a8ec03321864060f42eebe0d86dac33eeb3
|
7
|
+
data.tar.gz: 6dd3289ed9aba23e9b74f14fcdbc46d902f9ce4ed05c291b20707525b5061a6666ff2cd60f9dd15c238c8dfac866e4315a09dcb225ffa5b2d5672133e1024bf7
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
foxpage (0.
|
4
|
+
foxpage (0.2.0)
|
5
5
|
haml (~> 5.1)
|
6
6
|
listen (~> 3.1)
|
7
7
|
sassc (~> 2.0)
|
@@ -18,7 +18,7 @@ GEM
|
|
18
18
|
concurrent-ruby (1.1.5)
|
19
19
|
diff-lcs (1.3)
|
20
20
|
ffi (1.11.1)
|
21
|
-
haml (5.1.
|
21
|
+
haml (5.1.2)
|
22
22
|
temple (>= 0.8.0)
|
23
23
|
tilt
|
24
24
|
jaro_winkler (1.5.2)
|
@@ -57,18 +57,17 @@ GEM
|
|
57
57
|
unicode-display_width (>= 1.4.0, < 1.6)
|
58
58
|
ruby-progressbar (1.10.1)
|
59
59
|
ruby_dep (1.5.0)
|
60
|
-
sassc (2.
|
60
|
+
sassc (2.2.1)
|
61
61
|
ffi (~> 1.9)
|
62
|
-
|
63
|
-
sprockets (4.0.0.beta9)
|
62
|
+
sprockets (4.0.0.beta10)
|
64
63
|
concurrent-ruby (~> 1.0)
|
65
64
|
rack (> 1, < 3)
|
66
|
-
temple (0.8.
|
65
|
+
temple (0.8.2)
|
67
66
|
thor (0.20.3)
|
68
|
-
tilt (2.0.
|
67
|
+
tilt (2.0.10)
|
69
68
|
unicode-display_width (1.5.0)
|
70
69
|
webrick (1.4.2)
|
71
|
-
zeitwerk (2.1.
|
70
|
+
zeitwerk (2.1.10)
|
72
71
|
|
73
72
|
PLATFORMS
|
74
73
|
ruby
|
@@ -25,6 +25,7 @@ module FoxPage
|
|
25
25
|
# Set up application code loader
|
26
26
|
@code_loader = Zeitwerk::Loader.new.tap do |loader|
|
27
27
|
loader.push_dir(@root.join("app/controllers"))
|
28
|
+
loader.push_dir(@root.join("app/models"))
|
28
29
|
loader.push_dir(@root.join("app/helpers"))
|
29
30
|
loader.enable_reloading
|
30
31
|
loader.setup
|
@@ -20,7 +20,7 @@ module FoxPage
|
|
20
20
|
|
21
21
|
def image_assets
|
22
22
|
image_assets_path = app.root.join("app/assets/images")
|
23
|
-
Dir.glob("#{image_assets_path}/**/*.{png,jpg,gif,jpeg}")
|
23
|
+
Dir.glob("#{image_assets_path}/**/*.{png,jpg,gif,jpeg,svg}")
|
24
24
|
.map { |full_path| full_path.sub(%r{\A#{image_assets_path}/}, "") }
|
25
25
|
end
|
26
26
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module FoxPage
|
4
|
+
module Builders
|
5
|
+
module Models
|
6
|
+
def load_models
|
7
|
+
inject_app_to_models
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def inject_app_to_models
|
13
|
+
return if already_injected?
|
14
|
+
|
15
|
+
FoxPage::Model.instance_variable_set(:@__app, app)
|
16
|
+
end
|
17
|
+
|
18
|
+
def already_injected?
|
19
|
+
FoxPage::Model.instance_variable_get(:@__app)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -7,36 +7,66 @@ module FoxPage
|
|
7
7
|
module Builders
|
8
8
|
module Pages
|
9
9
|
using Refinements::Camelize
|
10
|
+
using Refinements::Constantize
|
10
11
|
|
11
12
|
def build_pages
|
12
13
|
app.routes.each do |path, route|
|
13
|
-
|
14
|
+
if route.generate_all
|
15
|
+
model = route.generate_all.camelize.constantize
|
14
16
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
17
|
+
model.all.each do |item|
|
18
|
+
target_path = format(path, id: item.id)
|
19
|
+
build_single_page(target_path, route, id: item.id)
|
20
|
+
end
|
21
|
+
next
|
20
22
|
end
|
23
|
+
|
24
|
+
build_single_page(path, route)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def build_single_page(target_path, route, params = {})
|
29
|
+
if params.empty?
|
30
|
+
params_log_str = ""
|
31
|
+
else
|
32
|
+
params_log_str = "(#{params.inspect})"
|
33
|
+
route = route.dup
|
34
|
+
route.params = OpenStruct.new(route.params.to_h.merge(params))
|
35
|
+
end
|
36
|
+
|
37
|
+
puts "PAGE\t#{target_path} => #{route.base_name}##{route.method_name}#{params_log_str}"
|
38
|
+
|
39
|
+
target_file = File.join(output_directory, target_path)
|
40
|
+
unless route.single_file
|
41
|
+
FileUtils.mkdir_p(target_file)
|
42
|
+
target_file = File.join(target_file, "index.html")
|
43
|
+
end
|
44
|
+
|
45
|
+
File.open(target_file, "w") do |f|
|
46
|
+
f.puts render_route(route, target_path)
|
21
47
|
end
|
22
48
|
end
|
23
49
|
|
24
|
-
def render_route(route)
|
25
|
-
controller = spiced_controller(route).new
|
50
|
+
def render_route(route, path)
|
51
|
+
controller = spiced_controller(route, path).new
|
26
52
|
controller.method(route.method_name).call
|
27
53
|
|
28
|
-
layout =
|
54
|
+
layout = layout_for(controller, route)
|
29
55
|
page = Tilt.new(page_path(route))
|
30
56
|
|
31
57
|
controller.instance_eval do
|
32
|
-
layout
|
58
|
+
if layout
|
59
|
+
layout.render(self) { page.render(self) }
|
60
|
+
else
|
61
|
+
page.render(self)
|
62
|
+
end
|
33
63
|
end
|
34
64
|
end
|
35
65
|
|
36
66
|
# for the sake of keeping the original classes sane while building, we
|
37
67
|
# create a subclass of the original dynamically and inject common helpers
|
38
68
|
# to it and also run before_actions
|
39
|
-
def spiced_controller(route) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/LineLength
|
69
|
+
def spiced_controller(route, path) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/LineLength
|
40
70
|
Class.new(route.controller).tap do |klass| # rubocop:disable Metrics/BlockLength, Metrics/LineLength
|
41
71
|
klass.include(Helpers::AppHelper.new(app))
|
42
72
|
klass.include(Helpers::AssetsHelper)
|
@@ -57,6 +87,18 @@ module FoxPage
|
|
57
87
|
# same difference
|
58
88
|
end
|
59
89
|
|
90
|
+
klass.define_method(:params) do
|
91
|
+
route.params
|
92
|
+
end
|
93
|
+
|
94
|
+
klass.define_method(:current_path) do
|
95
|
+
path
|
96
|
+
end
|
97
|
+
|
98
|
+
klass.define_method(:current_controller_name) do
|
99
|
+
route.base_name
|
100
|
+
end
|
101
|
+
|
60
102
|
klass.define_method(:inspect) do |*args|
|
61
103
|
# report that we are actually the controller, not some random
|
62
104
|
# anonymous class
|
@@ -89,9 +131,18 @@ module FoxPage
|
|
89
131
|
end
|
90
132
|
end
|
91
133
|
|
92
|
-
def
|
134
|
+
def layout_for(controller, route)
|
135
|
+
layout = controller.class.superclass.instance_variable_get(:@__use_layout_for)&.[](route.method_name)
|
136
|
+
return if layout == false
|
137
|
+
|
138
|
+
Tilt.new(layout_path(controller, layout))
|
139
|
+
end
|
140
|
+
|
141
|
+
def layout_path(controller, layout)
|
142
|
+
layout ||= controller.class.layout
|
143
|
+
|
93
144
|
File
|
94
|
-
.join(views_path,
|
145
|
+
.join(views_path, layout)
|
95
146
|
.tap(&method(:validate_file_exists))
|
96
147
|
end
|
97
148
|
|
data/lib/fox_page/controller.rb
CHANGED
@@ -13,5 +13,38 @@ module FoxPage
|
|
13
13
|
@__before_actions ||= []
|
14
14
|
@__before_actions << method_name
|
15
15
|
end
|
16
|
+
|
17
|
+
# Instructs the site builder to generate pages for all records of `model`.
|
18
|
+
def self.generate_all(model)
|
19
|
+
@__generate_all = model
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.use_layout(layout)
|
23
|
+
@__use_layout = layout
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.method_added(method_name)
|
27
|
+
return unless @__generate_all.nil? || @__use_layout.nil?
|
28
|
+
|
29
|
+
set_method_option(method_name, "generate_all")
|
30
|
+
set_method_option(method_name, "use_layout")
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.set_method_option(method_name, option)
|
34
|
+
ivar_name = :"@__#{option}"
|
35
|
+
ivar_for_name = :"@__#{option}_for"
|
36
|
+
|
37
|
+
ivar_val = instance_variable_get(ivar_name)
|
38
|
+
return if ivar_val.nil?
|
39
|
+
|
40
|
+
instance_variable_set(ivar_name, nil)
|
41
|
+
unless instance_variable_get(ivar_for_name)
|
42
|
+
instance_variable_set(ivar_for_name, {})
|
43
|
+
end
|
44
|
+
|
45
|
+
instance_variable_get(ivar_for_name)[method_name] = ivar_val
|
46
|
+
end
|
47
|
+
|
48
|
+
private_class_method :set_method_option
|
16
49
|
end
|
17
50
|
end
|
@@ -3,14 +3,14 @@
|
|
3
3
|
module FoxPage
|
4
4
|
module Helpers
|
5
5
|
module RenderHelper
|
6
|
-
def render(view)
|
6
|
+
def render(view, params = {})
|
7
7
|
full_path = Dir.glob(app.root.join("app/views/#{view}.*")).first
|
8
8
|
|
9
9
|
unless full_path
|
10
10
|
raise ArgumentError, "Could not find template for #{view}"
|
11
11
|
end
|
12
12
|
|
13
|
-
Tilt.new(full_path).render(self)
|
13
|
+
Tilt.new(full_path).render(self, params)
|
14
14
|
end
|
15
15
|
end
|
16
16
|
end
|
@@ -0,0 +1,177 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "yaml"
|
4
|
+
|
5
|
+
module FoxPage
|
6
|
+
class Model
|
7
|
+
using Refinements::Camelize
|
8
|
+
using Refinements::Pluralize
|
9
|
+
using Refinements::Singularize
|
10
|
+
using Refinements::ToDeepOpenStruct
|
11
|
+
using Refinements::Underscore
|
12
|
+
|
13
|
+
@__data = []
|
14
|
+
|
15
|
+
VALID_STORAGE_TYPES = %i[yaml dir].freeze
|
16
|
+
DEFAULT_STORAGE_TYPE = :yaml
|
17
|
+
private_constant :VALID_STORAGE_TYPES
|
18
|
+
private_constant :DEFAULT_STORAGE_TYPE
|
19
|
+
|
20
|
+
def self.[](storage_type = DEFAULT_STORAGE_TYPE, storage_type_opts = {})
|
21
|
+
unless VALID_STORAGE_TYPES.include?(storage_type)
|
22
|
+
raise ArgumentError,
|
23
|
+
"type must be one of #{VALID_STORAGE_TYPES.join(',')}"
|
24
|
+
end
|
25
|
+
|
26
|
+
@__tmp_storage_type = storage_type
|
27
|
+
@__tmp_storage_type_opts = storage_type_opts
|
28
|
+
|
29
|
+
self
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.inherited(subclass)
|
33
|
+
set_ivar_if_unset subclass, :storage_type, DEFAULT_STORAGE_TYPE
|
34
|
+
set_ivar_if_unset subclass, :storage_type_opts, {}
|
35
|
+
|
36
|
+
subclass.reload_all(@__app)
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.set_ivar_if_unset(subclass, ivar, default)
|
40
|
+
target_ivar = :"@__#{ivar}"
|
41
|
+
return if subclass.instance_variable_get(target_ivar)
|
42
|
+
|
43
|
+
tmp_ivar = :"@__tmp_#{ivar}"
|
44
|
+
value = instance_variable_get tmp_ivar
|
45
|
+
instance_variable_set tmp_ivar, nil
|
46
|
+
|
47
|
+
subclass.instance_variable_set target_ivar, value || default
|
48
|
+
end
|
49
|
+
private_class_method :set_ivar_if_unset
|
50
|
+
|
51
|
+
def self.reload_all(app)
|
52
|
+
data_name = name.to_s.underscore.pluralize
|
53
|
+
puts "MODEL\t#{data_name}"
|
54
|
+
|
55
|
+
case @__storage_type
|
56
|
+
when :yaml
|
57
|
+
@__data = YAML.load_file(
|
58
|
+
app.root.join("data", data_name + ".yml")
|
59
|
+
).to_deep_ostruct.map { |ostruct| new(ostruct) }
|
60
|
+
when :dir
|
61
|
+
default_opts = { extension: :md }
|
62
|
+
opts = default_opts.merge(@__storage_type_opts)
|
63
|
+
files = Dir[app.root.join("data", data_name, "*.#{opts.fetch(:extension)}")]
|
64
|
+
|
65
|
+
@__data = files.map do |fn|
|
66
|
+
id = File.basename(fn, ".#{opts.fetch(:extension)}")
|
67
|
+
content = IO.read(fn)
|
68
|
+
|
69
|
+
front_matter = {}
|
70
|
+
if content =~ /\A(---\n.*\n)^(?:---)\s*$\n?/m
|
71
|
+
content = Regexp.last_match.post_match
|
72
|
+
front_matter = YAML.safe_load(Regexp.last_match[1], [Time])
|
73
|
+
end
|
74
|
+
|
75
|
+
new front_matter.merge(id: id, content: content).to_deep_ostruct
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# e.g. in ProjectCategory: has_many :projects, referenced_by: nil
|
81
|
+
#
|
82
|
+
# nil = default of self.class.name underscored
|
83
|
+
def self.has_many(what, referenced_by: nil) # rubocop:disable Naming/PredicateName, Metrics/LineLength
|
84
|
+
referenced_by ||= name.to_s.underscore
|
85
|
+
association_class = Kernel.const_get(what.to_s.singularize.camelize)
|
86
|
+
|
87
|
+
define_method(what.to_s) do
|
88
|
+
association_class.where(referenced_by => name.to_s)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# e.g. in Project: belongs_to :project_category, referenced_by: :name
|
93
|
+
def self.belongs_to(what, referenced_by: :name)
|
94
|
+
association_class = Kernel.const_get(what.to_s.camelize)
|
95
|
+
|
96
|
+
define_method("__#{what}_value") do
|
97
|
+
@__ostruct[what]
|
98
|
+
end
|
99
|
+
|
100
|
+
define_method(what) do
|
101
|
+
association_class.find(referenced_by => public_send("__#{what}_value"))
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
# define a parser method for attributes
|
106
|
+
# @example
|
107
|
+
# require "time"
|
108
|
+
#
|
109
|
+
# class BlogPost < FoxPage::Model[:dir]
|
110
|
+
# def_parser :date do |date|
|
111
|
+
# Time.parse(date)
|
112
|
+
# end
|
113
|
+
# end
|
114
|
+
#
|
115
|
+
# # in the blog posts' front matter:
|
116
|
+
# # ---
|
117
|
+
# # title: foo
|
118
|
+
# # date: Sat 13 Jul 13:38:43 CEST 2019
|
119
|
+
# # ---
|
120
|
+
#
|
121
|
+
# # then, anywhere else:
|
122
|
+
# blog_post.date # => 2019-07-13 13:38:43 +0200
|
123
|
+
# blog_post.date.class # => Time
|
124
|
+
def self.def_parser(attribute, &parser)
|
125
|
+
define_method(attribute) do
|
126
|
+
parser.call(@__ostruct[attribute])
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def self.all
|
131
|
+
@__data
|
132
|
+
end
|
133
|
+
|
134
|
+
def self.each(&block)
|
135
|
+
@__data.each(&block)
|
136
|
+
end
|
137
|
+
|
138
|
+
def self.find(filter)
|
139
|
+
@__data.find do |object|
|
140
|
+
filter.all? do |key, value|
|
141
|
+
value_key_name = "__#{key}_value"
|
142
|
+
key = value_key_name if object.respond_to?(value_key_name)
|
143
|
+
|
144
|
+
object.public_send(key) == value
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def self.where(filter)
|
150
|
+
@__data.select do |object|
|
151
|
+
filter.all? do |key, value|
|
152
|
+
value_key_name = "__#{key}_value"
|
153
|
+
key = value_key_name if object.respond_to?(value_key_name)
|
154
|
+
|
155
|
+
object.public_send(key) == value
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def initialize(ostruct)
|
161
|
+
@__ostruct = ostruct
|
162
|
+
end
|
163
|
+
|
164
|
+
def method_missing(method, *args, &block)
|
165
|
+
hash_ostruct = @__ostruct.to_h
|
166
|
+
return super unless hash_ostruct.key?(method.to_sym)
|
167
|
+
|
168
|
+
hash_ostruct[method.to_sym]
|
169
|
+
end
|
170
|
+
|
171
|
+
def respond_to_missing?(method, *)
|
172
|
+
return true if @__ostruct.to_h.key?(method.to_sym)
|
173
|
+
|
174
|
+
super
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module FoxPage
|
4
|
+
module Refinements
|
5
|
+
module Constantize
|
6
|
+
refine String do
|
7
|
+
def constantize
|
8
|
+
Kernel.const_get(self)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
refine Symbol do
|
13
|
+
def constantize
|
14
|
+
to_s.constantize
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module FoxPage
|
4
|
+
module Refinements
|
5
|
+
module Underscore
|
6
|
+
refine String do
|
7
|
+
def underscore
|
8
|
+
gsub(/([a-z\d])([A-Z])/, '\1_\2').downcase
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
refine Symbol do
|
13
|
+
def underscore
|
14
|
+
to_s.underscore.to_sym
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/fox_page/router.rb
CHANGED
@@ -21,36 +21,90 @@ module FoxPage
|
|
21
21
|
routes
|
22
22
|
end
|
23
23
|
|
24
|
-
def root(target)
|
25
|
-
routes["/"] = parse_target(target)
|
24
|
+
def root(target, params: {})
|
25
|
+
routes["/"] = parse_target(target, params: params)
|
26
26
|
end
|
27
27
|
|
28
|
-
def map(mapping)
|
28
|
+
def map(mapping, params: {}, single_file: false)
|
29
29
|
mapping.each do |path, target|
|
30
|
-
routes[path] = parse_target(target)
|
30
|
+
routes[path] = parse_target(target, params: params, single_file: single_file)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
RESOURCE_ACTIONS = %i[index show].freeze
|
35
|
+
|
36
|
+
def resources(name, path: name, only: RESOURCE_ACTIONS)
|
37
|
+
actions = only.map(&:to_sym)
|
38
|
+
base_name = name.to_s
|
39
|
+
controller = controller_for(base_name)
|
40
|
+
base_path = "/#{path}"
|
41
|
+
|
42
|
+
# show action needs some additional stuff to make it work
|
43
|
+
# since we have to know all the ids beforehand
|
44
|
+
if actions.delete :show
|
45
|
+
method_name = :show
|
46
|
+
validate_controller_method(controller, method_name)
|
47
|
+
route_path = "#{base_path}/%<id>s"
|
48
|
+
|
49
|
+
routes[route_path] = make_target(
|
50
|
+
base_name: base_name,
|
51
|
+
controller: controller,
|
52
|
+
method_name: method_name,
|
53
|
+
params: {},
|
54
|
+
generate_all: controller.instance_variable_get(:@__generate_all_for)&.[](method_name)
|
55
|
+
)
|
56
|
+
end
|
57
|
+
|
58
|
+
actions.each do |action|
|
59
|
+
method_name = action
|
60
|
+
validate_controller_method(controller, method_name)
|
61
|
+
route_path = method_name == :index ? base_path : "#{base_path}/#{method_name}"
|
62
|
+
|
63
|
+
routes[route_path] = make_target(
|
64
|
+
base_name: base_name,
|
65
|
+
controller: controller,
|
66
|
+
method_name: method_name
|
67
|
+
)
|
31
68
|
end
|
32
69
|
end
|
33
70
|
|
34
71
|
private
|
35
72
|
|
36
|
-
def parse_target(target)
|
73
|
+
def parse_target(target, params: {}, single_file: false)
|
37
74
|
base_name, method_name = target.split("#")
|
38
|
-
controller =
|
75
|
+
controller = controller_for(base_name)
|
39
76
|
method_name = method_name.to_sym
|
40
77
|
|
41
78
|
validate_controller_method(controller, method_name)
|
42
79
|
|
43
|
-
|
80
|
+
make_target(
|
44
81
|
base_name: base_name,
|
45
82
|
controller: controller,
|
46
|
-
method_name: method_name
|
83
|
+
method_name: method_name,
|
84
|
+
params: params,
|
85
|
+
single_file: single_file
|
47
86
|
)
|
48
87
|
end
|
49
88
|
|
89
|
+
def controller_for(base_name)
|
90
|
+
Kernel.const_get("#{base_name}_controller".camelize)
|
91
|
+
end
|
92
|
+
|
50
93
|
def validate_controller_method(controller, method_name)
|
51
94
|
return if controller.instance_methods.include?(method_name)
|
52
95
|
|
53
96
|
raise ArgumentError, "#{controller} does not define ##{method_name}"
|
54
97
|
end
|
98
|
+
|
99
|
+
def make_target(base_name:, controller:, method_name:, params: {}, generate_all: nil, single_file: false)
|
100
|
+
OpenStruct.new(
|
101
|
+
base_name: base_name,
|
102
|
+
controller: controller,
|
103
|
+
method_name: method_name,
|
104
|
+
params: OpenStruct.new(params),
|
105
|
+
generate_all: generate_all,
|
106
|
+
single_file: single_file
|
107
|
+
)
|
108
|
+
end
|
55
109
|
end
|
56
110
|
end
|
data/lib/fox_page/server.rb
CHANGED
@@ -6,6 +6,7 @@ module FoxPage
|
|
6
6
|
class SiteBuilder
|
7
7
|
include Builders::Assets
|
8
8
|
include Builders::FileCopy
|
9
|
+
include Builders::Models
|
9
10
|
include Builders::Pages
|
10
11
|
|
11
12
|
def self.build(app)
|
@@ -24,6 +25,7 @@ module FoxPage
|
|
24
25
|
|
25
26
|
FileUtils.mkdir_p output_directory
|
26
27
|
|
28
|
+
load_models
|
27
29
|
build_assets
|
28
30
|
build_pages
|
29
31
|
copy_public_files
|
data/lib/fox_page/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: foxpage
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Georg Gadinger
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-10-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -228,6 +228,7 @@ files:
|
|
228
228
|
- lib/fox_page/application.rb
|
229
229
|
- lib/fox_page/builders/assets.rb
|
230
230
|
- lib/fox_page/builders/file_copy.rb
|
231
|
+
- lib/fox_page/builders/models.rb
|
231
232
|
- lib/fox_page/builders/pages.rb
|
232
233
|
- lib/fox_page/cli.rb
|
233
234
|
- lib/fox_page/controller.rb
|
@@ -235,8 +236,13 @@ files:
|
|
235
236
|
- lib/fox_page/helpers/app_helper.rb
|
236
237
|
- lib/fox_page/helpers/assets_helper.rb
|
237
238
|
- lib/fox_page/helpers/render_helper.rb
|
239
|
+
- lib/fox_page/model.rb
|
238
240
|
- lib/fox_page/refinements/camelize.rb
|
241
|
+
- lib/fox_page/refinements/constantize.rb
|
242
|
+
- lib/fox_page/refinements/pluralize.rb
|
243
|
+
- lib/fox_page/refinements/singularize.rb
|
239
244
|
- lib/fox_page/refinements/to_deep_open_struct.rb
|
245
|
+
- lib/fox_page/refinements/underscore.rb
|
240
246
|
- lib/fox_page/router.rb
|
241
247
|
- lib/fox_page/server.rb
|
242
248
|
- lib/fox_page/site_builder.rb
|