nexmo-oas-renderer 0.7.1 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/Gemfile.lock +16 -7
- data/lib/nexmo/oas/renderer/app.rb +2 -4
- data/lib/nexmo/oas/renderer/presenters/api_specification.rb +1 -1
- data/lib/nexmo/oas/renderer/presenters/open_api_specification.rb +1 -1
- data/lib/nexmo/oas/renderer/public/assets/stylesheets/nexmo-oas-renderer.css +1 -1
- data/lib/nexmo/oas/renderer/version.rb +1 -1
- data/lib/nexmo/oas/renderer/views/open_api/_model.erb +1 -1
- data/lib/nexmo/oas/renderer/views/open_api/_parameter_groups.erb +7 -37
- data/lib/nexmo/oas/renderer/views/open_api/_tabbed_parameters.erb +53 -0
- data/nexmo-oas-renderer.gemspec +1 -0
- metadata +17 -53
- data/lib/nexmo/oas/renderer/filters/anchor.rb +0 -17
- data/lib/nexmo/oas/renderer/filters/audio.rb +0 -21
- data/lib/nexmo/oas/renderer/filters/block_escape.rb +0 -24
- data/lib/nexmo/oas/renderer/filters/break.rb +0 -13
- data/lib/nexmo/oas/renderer/filters/code.rb +0 -64
- data/lib/nexmo/oas/renderer/filters/code_snippet.rb +0 -194
- data/lib/nexmo/oas/renderer/filters/code_snippet_list.rb +0 -33
- data/lib/nexmo/oas/renderer/filters/code_snippets.rb +0 -158
- data/lib/nexmo/oas/renderer/filters/collapsible.rb +0 -27
- data/lib/nexmo/oas/renderer/filters/columns.rb +0 -50
- data/lib/nexmo/oas/renderer/filters/concept_list.rb +0 -33
- data/lib/nexmo/oas/renderer/filters/dynamic_content.rb +0 -30
- data/lib/nexmo/oas/renderer/filters/external_link.rb +0 -32
- data/lib/nexmo/oas/renderer/filters/frontmatter.rb +0 -14
- data/lib/nexmo/oas/renderer/filters/heading.rb +0 -61
- data/lib/nexmo/oas/renderer/filters/icon.rb +0 -22
- data/lib/nexmo/oas/renderer/filters/indent.rb +0 -20
- data/lib/nexmo/oas/renderer/filters/inline_escape.rb +0 -17
- data/lib/nexmo/oas/renderer/filters/js_sequence_diagram.rb +0 -21
- data/lib/nexmo/oas/renderer/filters/label.rb +0 -32
- data/lib/nexmo/oas/renderer/filters/language.rb +0 -15
- data/lib/nexmo/oas/renderer/filters/markdown.rb +0 -85
- data/lib/nexmo/oas/renderer/filters/modal.rb +0 -41
- data/lib/nexmo/oas/renderer/filters/partial.rb +0 -28
- data/lib/nexmo/oas/renderer/filters/php_inliner.rb +0 -15
- data/lib/nexmo/oas/renderer/filters/screenshot.rb +0 -26
- data/lib/nexmo/oas/renderer/filters/tab.rb +0 -250
- data/lib/nexmo/oas/renderer/filters/techio.rb +0 -24
- data/lib/nexmo/oas/renderer/filters/tooltip.rb +0 -22
- data/lib/nexmo/oas/renderer/filters/tutorial_link.rb +0 -27
- data/lib/nexmo/oas/renderer/filters/tutorials.rb +0 -28
- data/lib/nexmo/oas/renderer/filters/unfreeze.rb +0 -20
- data/lib/nexmo/oas/renderer/filters/user_personalization.rb +0 -43
- data/lib/nexmo/oas/renderer/lib/core_ext/string.rb +0 -14
- data/lib/nexmo/oas/renderer/lib/redcarpet.rb +0 -14
- data/lib/nexmo/oas/renderer/models/code_snippet.rb +0 -75
- data/lib/nexmo/oas/renderer/models/tutorial.rb +0 -83
- data/lib/nexmo/oas/renderer/pipelines/markdown_pipeline.rb +0 -52
- data/lib/nexmo/oas/renderer/services/code_language_api.rb +0 -98
- data/lib/nexmo/oas/renderer/views/code_snippets/_application_messages_dispatch.html.erb +0 -9
- data/lib/nexmo/oas/renderer/views/code_snippets/_application_rtc.html.erb +0 -41
- data/lib/nexmo/oas/renderer/views/code_snippets/_application_voice.html.erb +0 -24
- data/lib/nexmo/oas/renderer/views/code_snippets/_code_only.html.erb +0 -6
- data/lib/nexmo/oas/renderer/views/code_snippets/_configure_client.html.erb +0 -20
- data/lib/nexmo/oas/renderer/views/code_snippets/_dependencies.html.erb +0 -11
- data/lib/nexmo/oas/renderer/views/code_snippets/_write_code.html.erb +0 -13
- data/lib/nexmo/oas/renderer/views/code_snippets/list/plain.html.erb +0 -10
- data/lib/nexmo/oas/renderer/views/tutorials/_index.html.erb +0 -32
- data/lib/nexmo/oas/renderer/views/tutorials/index.html.erb +0 -7
- data/lib/nexmo/oas/renderer/views/tutorials/list/plain.html.erb +0 -5
- data/lib/nexmo/oas/renderer/views/tutorials/show.html.erb +0 -8
@@ -1,41 +0,0 @@
|
|
1
|
-
module Nexmo
|
2
|
-
module OAS
|
3
|
-
module Renderer
|
4
|
-
module Filters
|
5
|
-
class Modal < Banzai::Filter
|
6
|
-
def call(input)
|
7
|
-
modals = []
|
8
|
-
|
9
|
-
input.gsub!(/@\[(.+?)\]\((.+?)\)/) do |_s|
|
10
|
-
id = 'M' + SecureRandom.hex(12)
|
11
|
-
modals << { document: $2, id: id }
|
12
|
-
"<a href='javascript:void(0)' data-modal='#{id}' class='Vlt-modal-trigger Vlt-text-link'>#{$1}</a>"
|
13
|
-
end
|
14
|
-
|
15
|
-
modals = modals.map do |modal|
|
16
|
-
filename = modal[:document]
|
17
|
-
raise "Could not find modal #{filename}" unless File.exist? filename
|
18
|
-
|
19
|
-
document = File.read(filename)
|
20
|
-
output = MarkdownPipeline.new.call(document)
|
21
|
-
|
22
|
-
modal = <<~HEREDOC
|
23
|
-
<div class="Vlt-modal" id="#{modal[:id]}">
|
24
|
-
<div class="Vlt-modal__panel">
|
25
|
-
<div class="Vlt-modal__content">
|
26
|
-
#{output}
|
27
|
-
</div>
|
28
|
-
</div>
|
29
|
-
</div>
|
30
|
-
HEREDOC
|
31
|
-
|
32
|
-
"FREEZESTART#{Base64.urlsafe_encode64(modal)}FREEZEEND"
|
33
|
-
end
|
34
|
-
|
35
|
-
input + modals.join("\n")
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
@@ -1,28 +0,0 @@
|
|
1
|
-
module Nexmo
|
2
|
-
module OAS
|
3
|
-
module Renderer
|
4
|
-
module Filters
|
5
|
-
class Partial < Banzai::Filter
|
6
|
-
def call(input)
|
7
|
-
input.gsub(/```partial(.+?)```/m) do |_s|
|
8
|
-
config = YAML.safe_load($1)
|
9
|
-
content = File.read(config['source'])
|
10
|
-
|
11
|
-
active = options[:code_language] ? options[:code_language].key == config['platform'] : false
|
12
|
-
|
13
|
-
if config['platform']
|
14
|
-
<<~HEREDOC
|
15
|
-
<div class="js-platform" data-platform="#{config['platform']}" data-active="#{active}">
|
16
|
-
#{content.render_markdown}
|
17
|
-
</div>
|
18
|
-
HEREDOC
|
19
|
-
else
|
20
|
-
content
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
@@ -1,26 +0,0 @@
|
|
1
|
-
module Nexmo
|
2
|
-
module OAS
|
3
|
-
module Renderer
|
4
|
-
module Filters
|
5
|
-
class Screenshot < Banzai::Filter
|
6
|
-
def call(input)
|
7
|
-
input.gsub(/```screenshot(.+?)```/m) do |_s|
|
8
|
-
config = YAML.safe_load($1)
|
9
|
-
if config['image'] && File.file?(config['image'])
|
10
|
-
"![Screenshot](#{config['image'].gsub('public', '')})"
|
11
|
-
else
|
12
|
-
<<~HEREDOC
|
13
|
-
## Missing image
|
14
|
-
To fix this run:
|
15
|
-
```
|
16
|
-
$ rake screenshots:update
|
17
|
-
```
|
18
|
-
HEREDOC
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
@@ -1,250 +0,0 @@
|
|
1
|
-
module Nexmo
|
2
|
-
module OAS
|
3
|
-
module Renderer
|
4
|
-
module Filters
|
5
|
-
class Tab < Banzai::Filter
|
6
|
-
def call(input)
|
7
|
-
input.gsub(/^(\s*)```tabbed_(examples|content)(.+?)```/m) do |_s|
|
8
|
-
@indentation = $1
|
9
|
-
@mode = $2
|
10
|
-
@config = YAML.safe_load($3)
|
11
|
-
validate_config
|
12
|
-
html
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
private
|
17
|
-
|
18
|
-
def create_tabs(content)
|
19
|
-
tab = Nokogiri::XML::Element.new 'div', @document
|
20
|
-
tab['class'] = 'Vlt-tabs__link'
|
21
|
-
tab['class'] += ' Vlt-tabs__link_active' if content[:active]
|
22
|
-
|
23
|
-
if content[:language]
|
24
|
-
tab['data-language'] = content[:language].key
|
25
|
-
tab['data-language-type'] = content[:language].type
|
26
|
-
tab['data-language-linkable'] = content[:language].linkable?
|
27
|
-
end
|
28
|
-
|
29
|
-
if content[:platform]
|
30
|
-
tab['data-language'] = content[:platform].languages.map(&:key).join(',')
|
31
|
-
tab['data-platform'] = content[:platform].key
|
32
|
-
tab['data-platform-type'] = content[:platform].type
|
33
|
-
tab['data-platform-linkable'] = content[:platform].linkable?
|
34
|
-
end
|
35
|
-
|
36
|
-
tab_link = Nokogiri::XML::Element.new 'span', @document
|
37
|
-
if content[:language]
|
38
|
-
# We don't currently have icons for JSON/XML
|
39
|
-
if ['json', 'xml'].include? content[:language].key.downcase
|
40
|
-
tab_link.content = content[:tab_title]
|
41
|
-
elsif content[:language].key == 'objective_c' || content[:language].key == 'swift'
|
42
|
-
tab_link.inner_html = '<svg><use xlink:href="/assets/images/brands/ios.svg#ios" /></svg><span>' + content[:tab_title] + '</span>'
|
43
|
-
else
|
44
|
-
tab_link.inner_html = "<svg><use xlink:href=\"/assets/images/brands/#{content[:language].key}.svg##{content[:language].key}\" /></svg><span>" + content[:tab_title] + '</span>'
|
45
|
-
end
|
46
|
-
elsif content[:platform]
|
47
|
-
tab_link.inner_html = "<svg><use xlink:href=\"/assets/images/brands/#{content[:platform].key}.svg##{content[:platform].key}\" /></svg><span>" + content[:tab_title] + '</span>'
|
48
|
-
else
|
49
|
-
tab_link.content = content[:tab_title]
|
50
|
-
end
|
51
|
-
|
52
|
-
tab.add_child(tab_link)
|
53
|
-
@tabs.add_child(tab)
|
54
|
-
end
|
55
|
-
|
56
|
-
def create_content(content)
|
57
|
-
tabs_panel = Nokogiri::XML::Element.new 'div', @document
|
58
|
-
tabs_panel['class'] = 'Vlt-tabs__panel'
|
59
|
-
tabs_panel['class'] += ' Vlt-tabs__panel_active' if content[:active]
|
60
|
-
|
61
|
-
element = Nokogiri::XML::Element.new 'p', @document
|
62
|
-
element['aria-labelledby'] = "\"#{content[:id]}\""
|
63
|
-
element['aria-hidden'] = true
|
64
|
-
element.inner_html = content[:body]
|
65
|
-
|
66
|
-
tabs_panel.add_child(element)
|
67
|
-
@tabs_content.add_child(tabs_panel)
|
68
|
-
end
|
69
|
-
|
70
|
-
def tabbed_code_examples?
|
71
|
-
@mode == 'examples'
|
72
|
-
end
|
73
|
-
|
74
|
-
def tabbed_content?
|
75
|
-
@mode == 'content'
|
76
|
-
end
|
77
|
-
|
78
|
-
def html
|
79
|
-
html = <<~HEREDOC
|
80
|
-
<div class="Vlt-tabs">
|
81
|
-
<div class="Vlt-tabs__header Vlt-tabs__header--bordered"></div>
|
82
|
-
<div class="Vlt-tabs__content">
|
83
|
-
</div>
|
84
|
-
</div>
|
85
|
-
HEREDOC
|
86
|
-
|
87
|
-
@document = Nokogiri::HTML::DocumentFragment.parse(html)
|
88
|
-
@tabs = @document.at_css('.Vlt-tabs__header')
|
89
|
-
@tabs_content = @document.at_css('.Vlt-tabs__content')
|
90
|
-
|
91
|
-
contents.each do |content|
|
92
|
-
create_tabs(content)
|
93
|
-
create_content(content)
|
94
|
-
end
|
95
|
-
|
96
|
-
source = @document.to_html
|
97
|
-
|
98
|
-
"#{@indentation}FREEZESTART#{Base64.urlsafe_encode64(source)}FREEZEEND"
|
99
|
-
end
|
100
|
-
|
101
|
-
def contents
|
102
|
-
list = content_from_source if @config['source']
|
103
|
-
list = content_from_tabs if @config['tabs']
|
104
|
-
|
105
|
-
list ||= []
|
106
|
-
|
107
|
-
return list unless list.any?
|
108
|
-
|
109
|
-
list = resolve_language(list)
|
110
|
-
|
111
|
-
if tabbed_code_examples?
|
112
|
-
list = format_code(list)
|
113
|
-
list = resolve_code(list)
|
114
|
-
list = resolve_tab_title(list)
|
115
|
-
end
|
116
|
-
|
117
|
-
list = sort_contents(list)
|
118
|
-
resolve_active_tab(list)
|
119
|
-
|
120
|
-
list
|
121
|
-
end
|
122
|
-
|
123
|
-
def validate_config
|
124
|
-
return if @config && (@config['source'] || @config['tabs'])
|
125
|
-
raise 'Source or tabs must be present in this tabbed_example config'
|
126
|
-
end
|
127
|
-
|
128
|
-
def content_from_source
|
129
|
-
source_path = @config['source']
|
130
|
-
source_path += '/*' if tabbed_code_examples?
|
131
|
-
source_path += '/*.md' if tabbed_content?
|
132
|
-
|
133
|
-
files = Dir[source_path]
|
134
|
-
raise "Empty content_from_source file list in #{source_path}" if files.empty?
|
135
|
-
files.map do |content_path|
|
136
|
-
raise "Could not find content_from_source file: #{content_path}" unless File.exist? content_path
|
137
|
-
source = File.read(content_path)
|
138
|
-
|
139
|
-
content = {
|
140
|
-
id: SecureRandom.hex,
|
141
|
-
source: source,
|
142
|
-
}
|
143
|
-
|
144
|
-
if tabbed_code_examples?
|
145
|
-
language_key = File.basename(content_path, '.*').downcase
|
146
|
-
content[:language_key] = language_key
|
147
|
-
end
|
148
|
-
|
149
|
-
if tabbed_content?
|
150
|
-
content[:frontmatter] = YAML.safe_load(source)
|
151
|
-
content[:language_key] = content[:frontmatter]['language']
|
152
|
-
content[:platform_key] = content[:frontmatter]['platform']
|
153
|
-
content[:tab_title] = content[:frontmatter]['title']
|
154
|
-
content[:body] = MarkdownPipeline.new(options).call(source)
|
155
|
-
end
|
156
|
-
|
157
|
-
content
|
158
|
-
end
|
159
|
-
end
|
160
|
-
|
161
|
-
def content_from_tabs
|
162
|
-
@config['tabs'].map do |title, config|
|
163
|
-
file_path = config['source']
|
164
|
-
raise "Could not find content_from_tabs file: #{config['source']}" unless File.exist? file_path
|
165
|
-
source = File.read(file_path)
|
166
|
-
|
167
|
-
config.symbolize_keys.merge({
|
168
|
-
id: SecureRandom.hex,
|
169
|
-
source: source,
|
170
|
-
language_key: title.dup.downcase,
|
171
|
-
})
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
def resolve_language(contents)
|
176
|
-
contents.map do |content|
|
177
|
-
if content[:language_key]
|
178
|
-
content[:language] = CodeLanguageAPI.find(content[:language_key])
|
179
|
-
end
|
180
|
-
|
181
|
-
if content[:platform_key]
|
182
|
-
content[:platform] = CodeLanguageAPI.find(content[:platform_key])
|
183
|
-
end
|
184
|
-
|
185
|
-
content
|
186
|
-
end
|
187
|
-
end
|
188
|
-
|
189
|
-
def format_code(contents)
|
190
|
-
contents.each do |content|
|
191
|
-
if content[:from_line] || content[:to_line]
|
192
|
-
lines = content[:source].lines
|
193
|
-
total_lines = lines.count
|
194
|
-
from_line = (content[:from_line] || 1) - 1
|
195
|
-
to_line = (content[:to_line] || total_lines) - 1
|
196
|
-
content[:source] = lines[from_line..to_line].join
|
197
|
-
end
|
198
|
-
|
199
|
-
content[:source].unindent! if content[:unindent]
|
200
|
-
end
|
201
|
-
end
|
202
|
-
|
203
|
-
def resolve_code(contents)
|
204
|
-
contents.map do |content|
|
205
|
-
@formatter ||= Rouge::Formatters::HTML.new
|
206
|
-
lexer = content[:language].lexer
|
207
|
-
highlighted_source = @formatter.format(lexer.lex(content[:source]))
|
208
|
-
body = <<~HEREDOC
|
209
|
-
<pre class="highlight #{content[:language_key]}"><code>#{highlighted_source}</code></pre>
|
210
|
-
HEREDOC
|
211
|
-
|
212
|
-
content.merge!({ body: body })
|
213
|
-
end
|
214
|
-
end
|
215
|
-
|
216
|
-
def resolve_tab_title(contents)
|
217
|
-
contents.map do |content|
|
218
|
-
content.merge!({ tab_title: content[:language].label })
|
219
|
-
end
|
220
|
-
end
|
221
|
-
|
222
|
-
def sort_contents(contents)
|
223
|
-
contents.sort_by do |content|
|
224
|
-
next content[:language].weight if content[:language]
|
225
|
-
next content[:frontmatter]['menu_weight'] || 999 if content[:frontmatter]
|
226
|
-
999
|
227
|
-
end
|
228
|
-
end
|
229
|
-
|
230
|
-
def resolve_active_tab(contents)
|
231
|
-
active_index = nil
|
232
|
-
|
233
|
-
if options[:code_language]
|
234
|
-
contents.each_with_index do |content, index|
|
235
|
-
%i[language_key platform_key].each do |key|
|
236
|
-
active_index = index if content[key] == options[:code_language].key
|
237
|
-
end
|
238
|
-
end
|
239
|
-
end
|
240
|
-
|
241
|
-
@tabs['data-has-initial-tab'] = active_index.present?
|
242
|
-
active_index ||= 0
|
243
|
-
|
244
|
-
contents[active_index][:active] = true
|
245
|
-
end
|
246
|
-
end
|
247
|
-
end
|
248
|
-
end
|
249
|
-
end
|
250
|
-
end
|
@@ -1,24 +0,0 @@
|
|
1
|
-
module Nexmo
|
2
|
-
module OAS
|
3
|
-
module Renderer
|
4
|
-
module Filters
|
5
|
-
class Techio < Banzai::Filter
|
6
|
-
def call(input)
|
7
|
-
input.gsub(/```techio(.+?)```/m) do |_s|
|
8
|
-
config = YAML.safe_load($1)
|
9
|
-
|
10
|
-
techio = <<~HEREDOC
|
11
|
-
<div class="techio-container">
|
12
|
-
<iframe width="100%" frameborder="0" scrolling="no" allowtransparency="true" style="visibility: hidden" src="https://tech.io/playground-widget#{config['path']}/#{config['title']}"></iframe>
|
13
|
-
<script>if(typeof window.techioScriptInjected==="undefined"){window.techioScriptInjected=true;var d=document,s=d.createElement("script");s.src="https://files.codingame.com/codingame/iframe-v-1-4.js";(d.head||d.body).appendChild(s);}</script>
|
14
|
-
</div>
|
15
|
-
HEREDOC
|
16
|
-
|
17
|
-
"FREEZESTART#{Base64.urlsafe_encode64(techio)}FREEZEEND"
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
@@ -1,22 +0,0 @@
|
|
1
|
-
module Nexmo
|
2
|
-
module OAS
|
3
|
-
module Renderer
|
4
|
-
module Filters
|
5
|
-
class Tooltip < Banzai::Filter
|
6
|
-
def call(input)
|
7
|
-
input.gsub(/\^\[([a-zA-Z0-9\s:\-]+)\]\((.+?)\)/) do
|
8
|
-
tooltip = <<~HEREDOC
|
9
|
-
<span class="Vlt-tooltip Vlt-tooltip--top" title="#{$2}" tabindex="0">
|
10
|
-
#{$1}
|
11
|
-
<svg class="Vlt-icon Vlt-icon--smaller Vlt-icon--text-bottom Vlt-blue" aria-hidden="true"><use xlink:href="/assets/symbol/volta-icons.svg#Vlt-icon-help-negative"/></svg>
|
12
|
-
</span>
|
13
|
-
HEREDOC
|
14
|
-
|
15
|
-
"FREEZESTART#{Base64.urlsafe_encode64(tooltip)}FREEZEEND"
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
@@ -1,27 +0,0 @@
|
|
1
|
-
module Nexmo
|
2
|
-
module OAS
|
3
|
-
module Renderer
|
4
|
-
module Filters
|
5
|
-
class TutorialLink < Banzai::Filter
|
6
|
-
def call(input)
|
7
|
-
@input = input
|
8
|
-
|
9
|
-
document.css('a').each_with_index do |link, _index|
|
10
|
-
if link['href']&.start_with?('/tutorials/')
|
11
|
-
link['data-turbolinks'] = 'false'
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
@document.to_html
|
16
|
-
end
|
17
|
-
|
18
|
-
private
|
19
|
-
|
20
|
-
def document
|
21
|
-
@document ||= Nokogiri::HTML::DocumentFragment.parse(@input)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
@@ -1,28 +0,0 @@
|
|
1
|
-
require_relative '../models/tutorial'
|
2
|
-
require 'banzai'
|
3
|
-
require 'yaml'
|
4
|
-
|
5
|
-
module Nexmo
|
6
|
-
module OAS
|
7
|
-
module Renderer
|
8
|
-
module Filters
|
9
|
-
class Tutorials < Banzai::Filter
|
10
|
-
def call(input)
|
11
|
-
input.gsub(/```tutorials(.+?)```/m) do |_s|
|
12
|
-
config = YAML.safe_load($1)
|
13
|
-
@product = config['product']
|
14
|
-
@tutorials = Models::Tutorial.by_product(@product)
|
15
|
-
|
16
|
-
# Default to plain layout, but allow people to override it
|
17
|
-
config['layout'] = 'list/plain' unless config['layout']
|
18
|
-
|
19
|
-
erb = File.read("#{API.root}/views/tutorials/#{config['layout']}.html.erb")
|
20
|
-
html = ERB.new(erb).result(binding)
|
21
|
-
"FREEZESTART#{Base64.urlsafe_encode64(html)}FREEZEEND"
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|