weaver 0.8.0 → 0.8.1

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.
@@ -0,0 +1,25 @@
1
+ module Weaver
2
+ # Page where all content is centered
3
+ class CenterPage < Page
4
+ def initialize(title, global_settings, options, &block)
5
+ super
6
+ end
7
+
8
+ def generate(level)
9
+ elem = Elements.new(self, {})
10
+ elem.instance_eval(&@block)
11
+
12
+ @body_class = 'gray-bg'
13
+ @content = <<-CONTENT
14
+ <div class="middle-box text-center animated fadeInDown">
15
+ <div>
16
+ #{elem.generate}
17
+ </div>
18
+ </div>
19
+ CONTENT
20
+ super
21
+ end
22
+ end
23
+ end
24
+
25
+ Weaver::Weave.register_page_type(:center_page, Weaver::CenterPage)
@@ -0,0 +1,26 @@
1
+ module Weaver
2
+ # Empty page
3
+ class EmptyPage < Page
4
+ def initialize(title, global_settings, options, &block)
5
+ super
6
+ end
7
+
8
+ def generate(level)
9
+ elem = Elements.new(self, {})
10
+ elem.instance_eval(&@block)
11
+ @body_class = 'gray-bg'
12
+ @content = <<-CONTENT
13
+ <div id="wrapper">
14
+ <div class="wrapper-content">
15
+ <div class="container">
16
+ #{elem.generate}
17
+ </div>
18
+ </div>
19
+ </div>
20
+ CONTENT
21
+ super
22
+ end
23
+ end
24
+ end
25
+
26
+ Weaver::Weave.register_page_type(:empty_page, Weaver::EmptyPage)
@@ -0,0 +1,39 @@
1
+ require 'weaver/page_types/structured_page'
2
+ module Weaver
3
+ # Pages with navigation menus
4
+ class NavPage < StructuredPage
5
+ def initialize(title, global_settings, options, &block)
6
+ super
7
+ @menu = Menu.new
8
+ end
9
+
10
+ def menu(&block)
11
+ @menu.instance_eval(&block)
12
+ end
13
+
14
+ def brand(text, link = '/')
15
+ @brand = text
16
+ @brand_link = link
17
+ end
18
+ end
19
+
20
+ # Menu used in nav pages
21
+ class Menu
22
+ attr_accessor :items
23
+ def initialize
24
+ @items = []
25
+ end
26
+
27
+ def nav(name, icon = :question, url = nil, options = {}, &block)
28
+ if url && !block
29
+ @items << { name: name, link: url, icon: icon, options: options }
30
+ elsif block
31
+ menu = Menu.new
32
+ menu.instance_eval(&block)
33
+ @items << { name: name, menu: menu, icon: icon, options: options }
34
+ else
35
+ @items << { name: name, link: '#', icon: icon, options: options }
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,35 @@
1
+ require 'weaver/page_types/structured_page'
2
+ module Weaver
3
+ # Page with no navigation bar
4
+ class NonNavPage < StructuredPage
5
+ def initialize(title, global_settings, options, &block)
6
+ super
7
+ end
8
+
9
+ def generate(level)
10
+ instance_eval &@block
11
+ rows = @rows.map do |row|
12
+ <<-ENDROW
13
+ <div class="row #{row.extra_classes}">
14
+ #{row.generate}
15
+ </div>
16
+ ENDROW
17
+ end.join
18
+
19
+ @body_class = 'gray-bg'
20
+
21
+ @content = <<-CONTENT
22
+ <div id="wrapper">
23
+ <div class="wrapper-content">
24
+ <div class="container">
25
+ #{rows}
26
+ </div>
27
+ </div>
28
+ </div>
29
+ CONTENT
30
+ super
31
+ end
32
+ end
33
+ end
34
+
35
+ Weaver::Weave.register_page_type(:nonnav_page, Weaver::NonNavPage)
@@ -0,0 +1,234 @@
1
+ module Weaver
2
+ # Base page class
3
+ class Page
4
+ attr_accessor :scripts, :onload_scripts
5
+
6
+ def initialize(title, global_settings, options, &block)
7
+ @title = title
8
+ @content = ''
9
+ @body_class = nil
10
+ @anchors = {}
11
+ @global_settings = global_settings
12
+ @options = options
13
+ @scripts = []
14
+ @top_content = ''
15
+
16
+ @scripts_once = {}
17
+ @onload_scripts = []
18
+
19
+ @requested_scripts = {}
20
+ @requested_css = {}
21
+
22
+ @background = Elements.new(self, @anchors)
23
+
24
+ @block = Proc.new &block
25
+ end
26
+
27
+ def create_anchor(name)
28
+ @anchors[name] = [] unless @anchors[name]
29
+
30
+ anchor_array = @anchors[name]
31
+
32
+ anchor_name = "#{name}#{anchor_array.length}"
33
+ anchor_array << anchor_name
34
+
35
+ anchor_name
36
+ end
37
+
38
+ def root
39
+ @global_settings[:root]
40
+ end
41
+
42
+ def request_js(path)
43
+ @requested_scripts[path] = true
44
+ end
45
+
46
+ def request_css(path)
47
+ @requested_css[path] = true
48
+ end
49
+
50
+ def on_page_load(script)
51
+ @onload_scripts << script
52
+ end
53
+
54
+ def write_script_once(script)
55
+ @scripts_once[script] = true
56
+ end
57
+
58
+ def background(&block)
59
+ @background.instance_eval(&block)
60
+ end
61
+
62
+ def top(&block)
63
+ elem = Elements.new(self, @anchors)
64
+ elem.instance_eval(&block)
65
+
66
+ @top_content = elem.generate
67
+ end
68
+
69
+ def generate(back_folders, options = {})
70
+ if @options[:cache_file]
71
+ expired = @options[:cache_expired]
72
+ cache_exist = File.exist?("cache/cachedpage#{@options[:cache_file]}")
73
+
74
+ if cache_exist && !expired
75
+ puts "Weaver Hit cache for file: #{@options[:cache_file]}"
76
+ puts "- expired: #{expired}"
77
+ puts "- cache_exist: #{cache_exist}"
78
+ return File.read("cache/cachedpage#{@options[:cache_file]}")
79
+ end
80
+ puts "Weaver Miss cache for file: #{@options[:cache_file]}"
81
+ puts "- expired: #{expired}"
82
+ puts "- cache_exist: #{cache_exist}"
83
+ end
84
+
85
+ scripts = @scripts.join("\n")
86
+
87
+ mod = '../' * back_folders
88
+
89
+ style = <<-ENDSTYLE
90
+ <link href="#{mod}css/style.css" rel="stylesheet">
91
+ ENDSTYLE
92
+
93
+ style = '' if options[:style] == :empty
94
+
95
+ body_tag = '<body>'
96
+
97
+ body_tag = "<body class='#{@body_class}'>" if @body_class
98
+
99
+ loading_bar = ''
100
+ loading_bar = "<script src='#{mod}js/plugins/pace/pace.min.js'></script>" if @loading_bar_visible
101
+
102
+ extra_scripts = @requested_scripts.map do |key, _value|
103
+ <<-SCRIPT_DECL
104
+ <script src="#{mod}#{key}"></script>
105
+ SCRIPT_DECL
106
+ end.join "\n"
107
+
108
+ extra_css = @requested_css.map do |key, _value|
109
+ <<-STYLESHEET_DECL
110
+ <link href="#{mod}#{key}" rel="stylesheet">
111
+ STYLESHEET_DECL
112
+ end.join "\n"
113
+
114
+ extra_one_time_scripts = @scripts_once.map do |key, _value|
115
+ <<-SCRIPT_DECL
116
+ #{key}
117
+ SCRIPT_DECL
118
+ end.join "\n"
119
+
120
+ onload_scripts = @onload_scripts.map do |value|
121
+ <<-SCRIPT_DECL
122
+ #{value}
123
+ SCRIPT_DECL
124
+ end.join "\n"
125
+
126
+ extra_stuff = ''
127
+
128
+ if @global_settings[:mixpanel_token]
129
+ extra_stuff += '<!-- start Mixpanel --><script type="text/javascript">(function(e,a){if(!a.__SV){var b=window;try{var c,l,i,j=b.location,g=j.hash;c=function(a,b){return(l=a.match(RegExp(b+"=([^&]*)")))?l[1]:null};g&&c(g,"state")&&(i=JSON.parse(decodeURIComponent(c(g,"state"))),"mpeditor"===i.action&&(b.sessionStorage.setItem("_mpcehash",g),history.replaceState(i.desiredHash||"",e.title,j.pathname+j.search)))}catch(m){}var k,h;window.mixpanel=a;a._i=[];a.init=function(b,c,f){function e(b,a){var c=a.split(".");2==c.length&&(b=b[c[0]],a=c[1]);b[a]=function(){b.push([a].concat(Array.prototype.slice.call(arguments,
130
+ 0)))}}var d=a;"undefined"!==typeof f?d=a[f]=[]:f="mixpanel";d.people=d.people||[];d.toString=function(b){var a="mixpanel";"mixpanel"!==f&&(a+="."+f);b||(a+=" (stub)");return a};d.people.toString=function(){return d.toString(1)+".people (stub)"};k="disable time_event track track_pageview track_links track_forms register register_once alias unregister identify name_tag set_config reset opt_in_tracking opt_out_tracking has_opted_in_tracking has_opted_out_tracking clear_opt_in_out_tracking people.set people.set_once people.unset people.increment people.append people.union people.track_charge people.clear_charges people.delete_user".split(" ");
131
+ for(h=0;h<k.length;h++)e(d,k[h]);a._i.push([b,c,f])};a.__SV=1.2;b=e.createElement("script");b.type="text/javascript";b.async=!0;b.src="undefined"!==typeof MIXPANEL_CUSTOM_LIB_URL?MIXPANEL_CUSTOM_LIB_URL:"file:"===e.location.protocol&&"//cdn4.mxpnl.com/libs/mixpanel-2-latest.min.js".match(/^\/\//)?"https://cdn4.mxpnl.com/libs/mixpanel-2-latest.min.js":"//cdn4.mxpnl.com/libs/mixpanel-2-latest.min.js";c=e.getElementsByTagName("script")[0];c.parentNode.insertBefore(b,c)}})(document,window.mixpanel||[]);
132
+ mixpanel.init("' + @global_settings[:mixpanel_token] + '");</script><!-- end Mixpanel -->'
133
+ end
134
+
135
+ if @global_settings[:google_tracking_code]
136
+ extra_stuff += <<-GOOGLE
137
+ <!-- Global site tag (gtag.js) - Google Analytics -->
138
+ <script async src="https://www.googletagmanager.com/gtag/js?id=#{@global_settings[:google_tracking_code]}"></script>
139
+ <script>
140
+ window.dataLayer = window.dataLayer || [];
141
+ function gtag(){dataLayer.push(arguments);}
142
+ gtag('js', new Date());
143
+
144
+ gtag('config', '#{@global_settings[:google_tracking_code]}');
145
+ </script>
146
+ GOOGLE
147
+ end
148
+
149
+ result = <<-SKELETON
150
+ <!DOCTYPE html>
151
+ <html>
152
+ <!-- Generated using weaver: https://github.com/davidsiaw/weaver -->
153
+ <head>
154
+
155
+ <meta charset="utf-8">
156
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
157
+
158
+ <title>#{@title}</title>
159
+
160
+ <link href="#{mod}css/bootstrap.min.css" rel="stylesheet">
161
+ <link href="#{mod}font-awesome/css/font-awesome.css" rel="stylesheet">
162
+ <link href="#{mod}css/plugins/iCheck/custom.css" rel="stylesheet">
163
+
164
+ #{style}
165
+
166
+ <link href="#{mod}css/animate.css" rel="stylesheet">
167
+
168
+ #{extra_css}
169
+
170
+ #{extra_stuff}
171
+
172
+ </head>
173
+
174
+ #{body_tag}
175
+
176
+ <div id="background" style="z-index: -999; position:absolute; left:0px; right:0px; width:100%; height:100%">
177
+ #{@background.generate}
178
+ </div>
179
+
180
+ <div id="content" style="z-index: 0">
181
+ #{@top_content}
182
+ #{@content}
183
+ </div>
184
+
185
+ <!-- Mainly scripts -->
186
+ <script src="#{mod}js/jquery-3.1.1.min.js"></script>
187
+ <script src="#{mod}js/jquery-ui-1.10.4.min.js"></script>
188
+ <script src="#{mod}js/bootstrap.min.js"></script>
189
+ <script src="#{mod}js/plugins/metisMenu/jquery.metisMenu.js"></script>
190
+ <script src="#{mod}js/plugins/slimscroll/jquery.slimscroll.min.js"></script>
191
+ <script type="text/x-mathjax-config">
192
+ MathJax.Hub.Config({
193
+ asciimath2jax: {
194
+ delimiters: [['$$$MATH$$$','$$$ENDMATH$$$']]
195
+ }
196
+ });
197
+ </script>
198
+ <script src="#{mod}js/MathJax/MathJax.js?config=AM_HTMLorMML-full" async></script>
199
+
200
+ #{extra_scripts}
201
+
202
+
203
+ <!-- Custom and plugin javascript -->
204
+ <script src="#{mod}js/weaver.js"></script>
205
+ #{loading_bar}
206
+
207
+ <script>
208
+ #{scripts}
209
+ #{extra_one_time_scripts}
210
+
211
+ $( document ).ready(function() {
212
+
213
+ #{onload_scripts}
214
+
215
+ });
216
+ </script>
217
+
218
+
219
+
220
+ </body>
221
+
222
+ </html>
223
+
224
+ SKELETON
225
+
226
+ if @options[:cache_file]
227
+ FileUtils.mkdir_p 'cache'
228
+ File.write("cache/cachedpage#{@options[:cache_file]}", result)
229
+ end
230
+
231
+ result
232
+ end
233
+ end
234
+ end
@@ -0,0 +1,17 @@
1
+ module Weaver
2
+ # Raw oage with no html
3
+ class RawPage < Page
4
+ def initialize(title, global_settings, options, &block)
5
+ super
6
+ end
7
+
8
+ def generate(_back_folders, _options = {})
9
+ elem = Elements.new(self, {})
10
+ elem.instance_eval(&@block)
11
+
12
+ elem.generate
13
+ end
14
+ end
15
+ end
16
+
17
+ Weaver::Weave.register_page_type(:raw_page, Weaver::RawPage)
@@ -0,0 +1,119 @@
1
+ require 'weaver/page_types/nav_page'
2
+ module Weaver
3
+ class SideNavPage < NavPage
4
+ def initialize(title, global_settings, options, &block)
5
+ super
6
+ @body_class = "#{@body_class} fixed-sidebar"
7
+ end
8
+
9
+ def keep_icons_when_hidden
10
+ arr = @body_class.to_s.split(' ')
11
+ @body_class = arr.reject { |x| x == 'fixed-sidebar' }.join(' ')
12
+ end
13
+
14
+ def generate(level)
15
+ instance_eval &@block
16
+ rows = @rows.map do |row|
17
+ <<-ENDROW
18
+ <div class="row #{row.extra_classes}" style="#{row.style}">
19
+ #{row.generate}
20
+ </div>
21
+ ENDROW
22
+ end.join
23
+
24
+ menu = @menu
25
+
26
+ navigation = Elements.new(self, @anchors)
27
+ navigation.instance_eval do
28
+ menu.items.each do |item|
29
+ li item[:options] do
30
+ if item.key? :menu
31
+
32
+ hyperlink '/#' do
33
+ icon item[:icon]
34
+ span class: 'nav-label' do
35
+ text item[:name]
36
+ end
37
+ span class: 'fa arrow' do
38
+ text ''
39
+ end
40
+ end
41
+
42
+ open = ''
43
+ open = 'collapse in' if item[:options][:open]
44
+ ul class: "nav nav-second-level #{open}" do
45
+ item[:menu].items.each do |inneritem|
46
+ li inneritem[:options] do
47
+ if inneritem.key?(:menu)
48
+ raise 'Second level menu not supported'
49
+ else
50
+ hyperlink (inneritem[:link]).to_s do
51
+ icon inneritem[:icon]
52
+ span class: 'nav-label' do
53
+ text inneritem[:name]
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ elsif
61
+ hyperlink (item[:link]).to_s do
62
+ icon item[:icon]
63
+ span class: 'nav-label' do
64
+ text item[:name]
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+
72
+ brand_content = ''
73
+
74
+ if @brand
75
+ brand_content = <<-BRAND_CONTENT
76
+
77
+ <li>
78
+ <a href="#{root}"><i class="fa fa-home"></i> <span class="nav-label">#{@brand}</span> <span class="label label-primary pull-right"></span></a>
79
+ </li>
80
+ BRAND_CONTENT
81
+ end
82
+
83
+ @loading_bar_visible = true
84
+ @content =
85
+ <<-ENDBODY
86
+ <div id="wrapper">
87
+
88
+ <nav class="navbar-default navbar-static-side" role="navigation">
89
+ <div class="sidebar-collapse">
90
+ <ul class="nav" id="side-menu">
91
+
92
+ #{brand_content}
93
+ #{navigation.generate}
94
+
95
+ </ul>
96
+ </div>
97
+ </nav>
98
+ <div id="page-wrapper" class="gray-bg">
99
+ <div class="row border-bottom">
100
+ <nav class="navbar navbar-static-top " role="navigation" style="margin-bottom: 0">
101
+ <div class="navbar-header">
102
+ <a class="navbar-minimalize minimalize-styl-2 btn btn-primary " href="#"><i class="fa fa-bars"></i> </a>
103
+ </div>
104
+ <ul class="nav navbar-top-links navbar-right">
105
+ <!-- NAV RIGHT -->
106
+ </ul>
107
+ </nav>
108
+ </div>
109
+ #{rows}
110
+ </div>
111
+ </div>
112
+ ENDBODY
113
+
114
+ super
115
+ end
116
+ end
117
+ end
118
+
119
+ Weaver::Weave.register_page_type(:sidenav_page, Weaver::SideNavPage)