/
node.rb
139 lines (110 loc) · 3.8 KB
/
node.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
module Cms::PublicFilter::Node
extend ActiveSupport::Concern
include Cms::PublicFilter::Layout
private
def init_context
self.params = ActionController::Parameters.new
self.request = ActionDispatch::Request.new("rack.input" => "", "REQUEST_METHOD" => "GET")
self.response = ActionDispatch::Response.new
@site.reload if @site.changed?
@node.reload if @node.changed?
end
def render_node(node)
spec = recognize_node(node, @cur_main_path)
return unless spec
@cur_node = node
controller = node.route.sub(/\/.*/, "/agents/#{spec[:cell]}")
agent = new_agent controller
agent.controller.request.path_parameters.merge! spec
agent.controller.params.merge! spec
agent.render spec[:action]
end
def render_layout_with_pagination_cache(layout, cache_key)
@layout_cache ||= {}
# no cache
if cache_key.nil?
return render_to_string html: render_layout(layout).html_safe, layout: "cms/page"
end
# use cache
if @layout_cache[cache_key]
return @layout_cache[cache_key].sub(/<!-- layout_yield -->/, response.body)
end
# set cache
html = render_to_string html: render_layout(layout).html_safe, layout: "cms/page"
@layout_cache[cache_key] = html.sub(/(<!-- layout_yield -->).*?<!-- \/layout_yield -->/m, '\\1')
html
end
def delete_layout_cache(cache_key)
@layout_cache.delete(cache_key) if @layout_cache
end
public
def recognize_node(node, path)
action = path.sub(/^\/#{::Regexp.escape(node.filename)}/, "")
rest = action.delete_suffix("index.html")
rest = action if ::File.extname(rest).present?
path = "/.s#{@cur_site.id}/nodes/#{node.route}#{rest}"
recognize_agent path
end
def find_node(path)
node = Cms::Node.site(@cur_site).in_path(path).order_by(depth: -1).to_a.first
return unless node
@preview || node.public? ? node : nil
end
def generate_node(node, opts = {})
path = opts[:url] || "#{node.filename}/index.html"
return if Cms::Page.site(node.site).and_public.filename(path).first
return unless node.serve_static_file?
@cur_site = node.site
@cur_path = opts[:url] || node.url
@cur_main_path = @cur_path.sub(@cur_site.url, "/")
@csrf_token = false
params.merge! opts[:params] if opts[:params]
begin
@exists = true
response.body = render_node node
response.content_type ||= "text/html"
rescue StandardError => e
@exists = false
return if e.to_s == "404"
return if e.is_a? Mongoid::Errors::DocumentNotFound
raise e
end
if node.view_layout == "cms/redirect"
@redirect_link = Sys::TrustedUrlValidator.url_restricted? ? trusted_url!(node.redirect_link) : node.redirect_link
html = render_to_string html: "", layout: "cms/redirect"
elsif response.media_type == "text/html" && node.layout
html = render_layout_with_pagination_cache(node.layout, opts[:cache])
else
html = response.body
end
file = opts[:file] || "#{node.path}/index.html"
Fs.write_data_if_modified file, html
end
def generate_node_with_pagination(node, opts = {})
node_perf_log(node, page: 1) do
if generate_node(node, cache: node.filename)
@task.log "#{node.url}index.html" if @task
end
end
max = opts[:max] || 1000
num = max
2.upto(max) do |i|
file = "#{node.path}/index.p#{i}.html"
node_perf_log(node, page: i) do
if generate_node(node, file: file, params: { page: i }, cache: node.filename)
@task.log "#{node.url}index.p#{i}.html" if @task
end
end
if !@exists
num = i
break
end
end
delete_layout_cache(node.filename)
num.upto(max) do |i|
file = "#{node.path}/index.p#{i}.html"
break unless Fs.exist?(file)
Fs.rm_rf file
end
end
end