zwr 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/zwr +26 -69
- data/lib/tasks/zwr.rake +6 -222
- data/lib/zwr/app_template.rb +147 -0
- data/lib/zwr/templates/angular-local-storage.js +446 -0
- data/lib/zwr/templates/app.js.coffee +37 -0
- data/lib/zwr/templates/application.css.scss +21 -0
- data/lib/zwr/templates/application.html.haml +90 -0
- data/lib/zwr/templates/application.js.coffee +3 -0
- data/lib/zwr/templates/home.html.haml +16 -0
- data/lib/zwr/templates/home_controller.js.coffee +9 -0
- data/lib/zwr/templates/home_controller.rb +5 -0
- data/lib/zwr/templates/index.html.haml +32 -0
- data/zwr.gemspec +2 -2
- metadata +12 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 398179725f92cb0c0ce5afc8f067bef68ed3d39d
|
4
|
+
data.tar.gz: d226f243e785a7f906c98f6f5f924a91121a08e8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0f2fc81920c996f4a48f57cef4cac72280fba64c9d6d672aabcfe5d1bb959fa97f20a714b39c1cf3ba7e6ed49cc809da453bbf6f960adedec99cf648cf5b7911
|
7
|
+
data.tar.gz: b7266d2e3efe33c699b25be1f36f97d28e2e1e7f68607de869949d4ac5fd87cbcb71c4cdd8f02a3100d32672a804475ab62d604a0e5d592326b6fd764d56d768
|
data/bin/zwr
CHANGED
@@ -39,14 +39,28 @@ OptionParser.new do |opts|
|
|
39
39
|
@options[:activerecord] = false
|
40
40
|
end
|
41
41
|
end
|
42
|
+
|
43
|
+
@options[:angular] = true
|
44
|
+
opts.on("--skip-angular", %(Skip angular. If you use Angular, it will also generate the
|
45
|
+
Main controller to start the angular app, which
|
46
|
+
will be set as root.)) do |v|
|
47
|
+
@options[:angular] = not(v)
|
48
|
+
end
|
49
|
+
|
50
|
+
@options[:devise] = true
|
51
|
+
opts.on("--skip-devise", %(Skip Devise . If you use Devise, it will also generate the User
|
52
|
+
model and some helper controllers.)) do |v|
|
53
|
+
@options[:devise] = not(v)
|
54
|
+
end
|
42
55
|
end.parse!
|
43
56
|
|
44
57
|
def putsv txt
|
45
58
|
puts txt.to_s if @options[:verbose]
|
46
59
|
end
|
47
60
|
|
48
|
-
putsv "
|
49
|
-
putsv "
|
61
|
+
putsv " \033[35mzwr\033[0m running!"
|
62
|
+
putsv " \033[35moptions\033[0m #{@options.map{|k,v| "#{k}=#{v}"}.join(' ')}."
|
63
|
+
putsv " \033[35mexec\033[0m #{ARGV.join}."
|
50
64
|
|
51
65
|
def show_usage
|
52
66
|
puts "Usage:"
|
@@ -63,74 +77,17 @@ when 'new'
|
|
63
77
|
elsif `git status 2>&1` != "fatal: Not a git repository (or any of the parent directories): .git\n"
|
64
78
|
puts "You are in a git repo, and that is not good!"
|
65
79
|
else
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
`echo "gem 'bootstrap-sass', '~> 3.2.0'" >> Gemfile`
|
77
|
-
#`echo "gem 'autoprefixer-rails', '~> 3.2.0'" >> Gemfile`
|
78
|
-
|
79
|
-
`echo "gem 'puma', platforms: :ruby" >> Gemfile`
|
80
|
-
`echo "gem 'haml-rails'" >> Gemfile`
|
81
|
-
`echo "gem 'angularjs-rails'" >> Gemfile`
|
82
|
-
`echo "gem 'angular-rails-templates'" >> Gemfile`
|
83
|
-
`echo "gem 'angular-ui-bootstrap-rails'" >> Gemfile`
|
84
|
-
`echo "# following should solve the CSRF token with angular" >> Gemfile`
|
85
|
-
`echo "gem 'angular_rails_csrf'" >> Gemfile`
|
86
|
-
`echo "gem 'devise', '~> 3.3.0'" >> Gemfile`
|
87
|
-
`echo "gem 'redcarpet'" >> Gemfile`
|
88
|
-
`echo "gem 'paperclip', '~> 4.2'" >> Gemfile`
|
89
|
-
`echo "gem 'html2haml'" >> Gemfile`
|
90
|
-
|
91
|
-
# Following are for Mongo only, will add it later
|
92
|
-
if @options[:mongoid]
|
93
|
-
`echo "gem 'mongoid', '~> 4.0.0',github: 'mongoid/mongoid'" >> Gemfile`
|
94
|
-
`echo "gem 'bson_ext'" >> Gemfile`
|
95
|
-
end
|
96
|
-
|
97
|
-
`echo "gem 'factory_girl_rails', '~> 4.0'" >> Gemfile`
|
98
|
-
|
99
|
-
`echo "gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw]" >> Gemfile`
|
100
|
-
`echo "gem 'tzinfo', platforms: [:mingw, :mswin, :x64_mingw]" >> Gemfile`
|
101
|
-
|
102
|
-
putsv "README as we like it!"
|
103
|
-
putsv `rm README.rdoc`
|
104
|
-
`echo "Application #{ARGV[1]} generated bu the zwr generator." > README.markdown`
|
105
|
-
|
106
|
-
if @options[:bundle]
|
107
|
-
putsv "bundling up... This may take a few minutes..."
|
108
|
-
putsv `bundle install`
|
109
|
-
end
|
110
|
-
putsv "zwring..."
|
111
|
-
putsv `rake zwr:install`
|
112
|
-
if @options[:ruby_ver]
|
113
|
-
putsv "creating .ruby-version"
|
114
|
-
`rvm --ruby-version use #{@options[:ruby_ver]} >> .ruby-version`
|
115
|
-
end
|
116
|
-
if @options[:mongoid]
|
117
|
-
putsv "configuration for mongoid"
|
118
|
-
`rails g mongoid:config`
|
119
|
-
end
|
120
|
-
putsv "database generation"
|
121
|
-
putsv `rake db:migrate`
|
122
|
-
putsv "praxing"
|
123
|
-
putsv `prax link`
|
124
|
-
putsv `prax start`
|
125
|
-
putsv "git it up"
|
126
|
-
putsv `git init`
|
127
|
-
putsv `git add -A`
|
128
|
-
putsv `git commit -sm "initial commit - zwr new #{ARGV[1]}"`
|
129
|
-
putsv `git remote add origin git@github.com:zmilojko/#{ARGV[1]}.git`
|
130
|
-
puts "Completed. If there was no errors above, you should be good to go!"
|
131
|
-
puts "In your browser, open http://#{ARGV[1]}.dev"
|
80
|
+
cmd = <<-CMD.gsub /^ *$\n/, ''
|
81
|
+
rails new #{ARGV[1]} --skip-bundle --skip-spring
|
82
|
+
#{"--skip-active-record" if not @options[:activerecord]}
|
83
|
+
-m #{File.expand_path('../../lib/zwr/app_template.rb', __FILE__)}
|
84
|
+
#{"use-mongoid" if @options[:mongoid]}
|
85
|
+
#{"use-angular" if @options[:angular]}
|
86
|
+
#{"use-devise" if @options[:devise]}
|
87
|
+
CMD
|
88
|
+
putsv " \033[35mexec\033[0m #{cmd.strip}"
|
89
|
+
exec(cmd.gsub(/\r/," ").gsub(/\n/," ").gsub(/ /," "))
|
132
90
|
end
|
133
|
-
|
134
91
|
when 'deploy'
|
135
92
|
if ARGV.length < 2
|
136
93
|
puts "Not enough parameters"
|
data/lib/tasks/zwr.rake
CHANGED
@@ -1,183 +1,18 @@
|
|
1
1
|
require 'active_support'
|
2
2
|
require 'active_support/core_ext'
|
3
3
|
require 'rake'
|
4
|
-
#require 'rails/generators'
|
5
|
-
|
6
|
-
class Pathname
|
7
|
-
def remove_line(line)
|
8
|
-
insert(text: "", instead_of: line)
|
9
|
-
end
|
10
|
-
|
11
|
-
# Will insert LINES after or instead of the LINE that matches given argument
|
12
|
-
def insert(text: nil, after: nil, instead_of: nil, before: nil, for_each_line: false)
|
13
|
-
raise "You must specify text: argument or give a block that will preform the writing" unless text or block_given?
|
14
|
-
raise "You cannot specify both after: and instead_of: arguments. Pick one." if after and instead_of
|
15
|
-
raise "You cannot specify both after: and before: arguments. Pick one." if after and before
|
16
|
-
raise "You cannot specify both instead_of: and before: arguments. Pick one." if instead_of and before
|
17
|
-
if after || instead_of || before
|
18
|
-
content = File.read(self)
|
19
|
-
File.open(self, "w") do |file|
|
20
|
-
content.lines.each do |line|
|
21
|
-
if line.match(after || instead_of || before)
|
22
|
-
file.puts line if after
|
23
|
-
if text
|
24
|
-
file.puts text if text != ""
|
25
|
-
else
|
26
|
-
yield file, line
|
27
|
-
end
|
28
|
-
file.puts line if before
|
29
|
-
else
|
30
|
-
file.puts line
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
else
|
35
|
-
File.open(self, "a") do |file|
|
36
|
-
if text
|
37
|
-
file.puts text
|
38
|
-
else
|
39
|
-
yield file
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
4
|
|
46
5
|
namespace :zwr do
|
47
|
-
desc "installs
|
6
|
+
desc "installs icon and other details into the new app."
|
48
7
|
task :install do
|
49
8
|
projectname = Rails.root.basename.to_s
|
50
|
-
puts "
|
9
|
+
puts " \033[35mcreate\033[0m public/favicon.ico"
|
51
10
|
FileUtils.cp "#{File.dirname( __FILE__ )}/../../app/assets/images/favicon.ico", Rails.root.join('public')
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
%html
|
56
|
-
%head
|
57
|
-
%title #{projectname.capitalize}
|
58
|
-
%meta(name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0")
|
59
|
-
-# android stand alone mode
|
60
|
-
%meta(name="mobile-web-app-capable" content="yes")
|
61
|
-
%link(rel="icon" sizes="192x192" href="/assets/icon.png")
|
62
|
-
-# iOS stand alone mode
|
63
|
-
%meta(name="apple-mobile-web-app-capable" content="yes")
|
64
|
-
%meta(name="apple-mobile-web-app-status-bar-style" content="black")
|
65
|
-
%link(rel="apple-touch-icon" href="/assets/icon.png")
|
66
|
-
%link(rel="apple-touch-startup-image" href="/assets/icon.png")
|
67
|
-
-# windows 8.1, maybe mobile, maybe not
|
68
|
-
%meta(name="application-name" content="ID Pickup")
|
69
|
-
%meta(name="msapplication-navbutton-color" content="#FF3300")
|
70
|
-
%meta(name="msapplication-square150x150logo" content="assets/icon.png")
|
71
|
-
%meta(name="msapplication-square310x310logo" content="assets/icon.png")
|
72
|
-
%meta(name="msapplication-square70x70logo" content="assets/icon.png")
|
73
|
-
%meta(name="msapplication-wide310x150logo" content="assets/icon.png")
|
74
|
-
%meta(name="msapplication-TileColor" content="#FF3300")
|
75
|
-
%meta(name="msapplication-TileImage" content="assets/icon.png")
|
76
|
-
%meta(name="msapplication-tooltip" content="ID Pickup")
|
77
|
-
= stylesheet_link_tag 'application', media: 'all'
|
78
|
-
= javascript_include_tag 'application'
|
79
|
-
= csrf_meta_tags
|
80
|
-
%body
|
81
|
-
.container
|
82
|
-
%nav.navbar.navbar-static-top.navbar-inverse(role="navigation")
|
83
|
-
.container-fluid
|
84
|
-
-# Title
|
85
|
-
.navbar-header.pull-left
|
86
|
-
%a.navbar-brand(href="#")
|
87
|
-
=image_tag "logo.png", height: '20'
|
88
|
-
#{projectname.capitalize}
|
89
|
-
-# Sticky menu, on the right
|
90
|
-
#navbar-steady.navbar-header.pull-right
|
91
|
-
%ul.nav.navbar-nav.pull-left
|
92
|
-
-# Static menu items
|
93
|
-
%li.pull-left.hidden-xs
|
94
|
-
%a(href="#") Static 1
|
95
|
-
-# notice that the first to pull right will be right most!
|
96
|
-
%li.pull-right
|
97
|
-
%a(href="#") Static 2
|
98
|
-
-# Static text, like the username
|
99
|
-
%li.navbar-text.pull-right
|
100
|
-
%span.hidden-xs Welcome,
|
101
|
-
%span guest
|
102
|
-
-# following button should ALWAYS be there, unless there is no colapsable items
|
103
|
-
%button.navbar-toggle.collapsed(type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-expanded="false" aria-controls="navbar")
|
104
|
-
%span.sr-only Toggle navigation
|
105
|
-
%span.icon-bar
|
106
|
-
%span.icon-bar
|
107
|
-
%span.icon-bar
|
108
|
-
#navbar.navbar-collapse.collapse
|
109
|
-
%ul.nav.navbar-nav
|
110
|
-
%li.active
|
111
|
-
%a(href="#") Left 1
|
112
|
-
%li
|
113
|
-
%a(href="#") Left 2
|
114
|
-
%li
|
115
|
-
%a.dropdown-toggle(href="#" data-toggle="dropdown")
|
116
|
-
Drop
|
117
|
-
%span.caret
|
118
|
-
%ul.dropdown-menu(role="menu")
|
119
|
-
%li.dropdown-header Header for submenu group
|
120
|
-
%li
|
121
|
-
%a(href="#") Submenu 1
|
122
|
-
%li
|
123
|
-
%a(href="#") Submenu 2
|
124
|
-
%li
|
125
|
-
%a(href="#") Submenu 3
|
126
|
-
%li.divider
|
127
|
-
%li.dropdown-header Header for others
|
128
|
-
%li
|
129
|
-
%a(href="#") Submenu 4
|
130
|
-
%li
|
131
|
-
%a(href="#") Submenu 5
|
132
|
-
%ul.nav.navbar-nav.navbar-right
|
133
|
-
%li
|
134
|
-
%a(href="#") Right 1
|
135
|
-
%li
|
136
|
-
%a(href="#") Right 2
|
137
|
-
.alert.alert-success(role="alert")=success_notice
|
138
|
-
.alert.alert-info(role="alert")=notice
|
139
|
-
.alert.alert-warning(role="alert")=alert_warning
|
140
|
-
.alert.alert-danger(role="alert")=alert
|
141
|
-
= yield
|
142
|
-
FILE_CONTENT
|
143
|
-
File.delete Rails.root.join('app/assets/javascripts/application.js')
|
144
|
-
File.write(Rails.root.join('app/assets/javascripts/app.js.coffee'), <<-FILE_CONTENT.strip_heredoc)
|
145
|
-
#= require angular
|
146
|
-
#= require angular-route
|
147
|
-
#= require angular-resource
|
148
|
-
#= require angular-rails-templates
|
149
|
-
#= require_tree ./templates
|
150
|
-
#= require main
|
151
|
-
#= require_tree ./includes
|
152
|
-
#= require_tree ./directives
|
153
|
-
#= require_tree ./services
|
154
|
-
#= require_tree ./controllers
|
155
|
-
#= require angular-ui-bootstrap
|
156
|
-
FILE_CONTENT
|
157
|
-
File.write(Rails.root.join('app/assets/javascripts/application.js.coffee'),<<-FILE_CONTENT.strip_heredoc)
|
158
|
-
#= require jquery
|
159
|
-
#= require jquery_ujs
|
160
|
-
#= require bootstrap-sprockets
|
161
|
-
FILE_CONTENT
|
162
|
-
File.delete Rails.root.join('app/assets/stylesheets/application.css')
|
163
|
-
File.write(Rails.root.join('app/assets/stylesheets/application.css.scss'),<<-FILE_CONTENT.strip_heredoc)
|
164
|
-
/*
|
165
|
-
*= require_self
|
166
|
-
*/
|
167
|
-
@import "bootstrap-sprockets";
|
168
|
-
@import "bootstrap";
|
169
|
-
@import "zwr";
|
170
|
-
FILE_CONTENT
|
171
|
-
File.write(Rails.root.join('db/seeds.rb'),<<-FILE_CONTENT.strip_heredoc)
|
172
|
-
Dir[Rails.root.join('db/seeds/*.rb')].each { |file| load file }
|
173
|
-
FILE_CONTENT
|
174
|
-
Dir.mkdir Rails.root.join('db/seeds')
|
175
|
-
File.write(Rails.root.join('config/initializers/markdown.rb'),<<-FILE_CONTENT.strip_heredoc)
|
176
|
-
# Initializes a Markdown parser
|
177
|
-
Markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML, autolink: true, tables: true)
|
178
|
-
FILE_CONTENT
|
11
|
+
|
12
|
+
`sed '/turbolinks/d' -i Gemfile`
|
13
|
+
`sed "s/# gem 'theruby/gem 'theruby/" -i Gemfile`
|
179
14
|
end
|
180
|
-
|
15
|
+
|
181
16
|
desc "prepares production branch ready to roll"
|
182
17
|
task :prepare do
|
183
18
|
Dir.chdir Rails.root
|
@@ -210,55 +45,4 @@ namespace :zwr do
|
|
210
45
|
`git push -uf origin production`
|
211
46
|
end
|
212
47
|
end
|
213
|
-
desc "creates user scaffod and devise object"
|
214
|
-
task :user do
|
215
|
-
#Rails::Generators.invoke("devise:install")
|
216
|
-
puts `rails g devise:install`
|
217
|
-
#Rails::Generators.invoke("scaffold",["User", "name:string","email:string",
|
218
|
-
# "password:string","password_confirmation:string",
|
219
|
-
# "admin:boolean"])
|
220
|
-
puts `rails g scaffold User name:string email:string password:string password_confirmation:string admin:boolean`
|
221
|
-
puts "Removing app/models/user.rb"
|
222
|
-
File.delete Rails.root.join('app/models/user.rb')
|
223
|
-
puts "Renaming test/models/user_test.rb to test/models/user_test_orig.rb"
|
224
|
-
File.rename Rails.root.join('test/models/user_test.rb'), Rails.root.join('test/models/user_test_orig.rb')
|
225
|
-
puts "Removing test/factories/users.rb"
|
226
|
-
File.delete Rails.root.join('test/factories/users.rb')
|
227
|
-
#Rails::Generators.invoke("devise", ["User"])
|
228
|
-
puts `rails g devise User`
|
229
|
-
Rails.root.join("Gemfile").insert text: "gem 'bootstrap_form'"
|
230
|
-
Rails.root.join("app/assets/stylesheets/application.css.scss").insert text: '@import "rails_bootstrap_forms";'
|
231
|
-
Rails.root.join("app/models/user.rb").insert after: "field :encrypted_password" do |file|
|
232
|
-
file.puts ' field :name, type: String, default: ""'
|
233
|
-
file.puts ' field :admin, type: Boolean, default: ""'
|
234
|
-
end
|
235
|
-
Rails.root.join("app/views/layouts/application.html.haml").insert before: "= yield" do |file|
|
236
|
-
file.puts ' - if notice'
|
237
|
-
file.puts ' .alert.alert-info(role="alert")=notice'
|
238
|
-
file.puts ' - if alert'
|
239
|
-
file.puts ' .alert.alert-danger(role="alert")=alert'
|
240
|
-
end
|
241
|
-
Rails.root.join("app/views/users/_form.html.haml").insert text: "= bootstrap_form_for @user do |f|",
|
242
|
-
instead_of: "form_for @user do"
|
243
|
-
Rails.root.join("app/views/users/_form.html.haml").insert text: " #error_explanation.alert.alert-danger",
|
244
|
-
instead_of: "error_explanation"
|
245
|
-
Rails.root.join("app/views/users/_form.html.haml").insert text: " = f.password_field :password_confirmation",
|
246
|
-
instead_of: "f.text_field :password_confirmation"
|
247
|
-
Rails.root.join("app/views/users/_form.html.haml").insert text: " = f.password_field :password",
|
248
|
-
instead_of: "f.text_field :password"
|
249
|
-
Rails.root.join("app/views/users/_form.html.haml").remove_line "f.label :name"
|
250
|
-
Rails.root.join("app/views/users/_form.html.haml").remove_line "f.label :email"
|
251
|
-
Rails.root.join("app/views/users/_form.html.haml").remove_line "f.label :password"
|
252
|
-
Rails.root.join("app/views/users/_form.html.haml").remove_line "f.label :password_confirmation"
|
253
|
-
Rails.root.join("app/views/users/_form.html.haml").remove_line "f.label :admin"
|
254
|
-
Rails.root.join("config/routes.rb").insert instead_of: "resources :users" do |file|
|
255
|
-
file.puts " scope '/admin' do"
|
256
|
-
file.puts " resources :users, as: 'users'"
|
257
|
-
file.puts " end"
|
258
|
-
end
|
259
|
-
puts `bundle install`
|
260
|
-
puts `git add -A`
|
261
|
-
puts `git commit -sm "rake zwr:user"`
|
262
|
-
puts `prax restart`
|
263
|
-
end
|
264
48
|
end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
puts " \033[35mzwr\033[0m Now applying ZWR template."
|
2
|
+
puts " \033[35mapp\033[0m #{@app_name}."
|
3
|
+
puts " \033[35margs\033[0m #{@args.join ", "}."
|
4
|
+
|
5
|
+
def tpl(filename)
|
6
|
+
File.read(File.expand_path("../templates/#{filename}", __FILE__))
|
7
|
+
.gsub("APP_NAME",@app_name)
|
8
|
+
end
|
9
|
+
|
10
|
+
use_angular = @args.include? 'use-angular'
|
11
|
+
use_mongoid = @args.include? 'use-mongoid'
|
12
|
+
use_devise = @args.include? 'use-devise'
|
13
|
+
|
14
|
+
gem 'zwr'
|
15
|
+
gem 'bootstrap-sass', '~> 3.2.0'
|
16
|
+
gem 'bootstrap_form'
|
17
|
+
gem 'puma', platforms: :ruby
|
18
|
+
gem 'haml-rails'
|
19
|
+
|
20
|
+
if use_angular
|
21
|
+
gem 'angularjs-rails'
|
22
|
+
gem 'angular-rails-templates'
|
23
|
+
gem 'angular-ui-bootstrap-rails'
|
24
|
+
gem 'angular_rails_csrf'
|
25
|
+
file 'app/assets/javascripts/controllers/.keep'
|
26
|
+
file 'app/assets/javascripts/directives/.keep'
|
27
|
+
file 'app/assets/javascripts/includes/.keep'
|
28
|
+
file 'app/assets/javascripts/services/.keep'
|
29
|
+
file 'app/assets/javascripts/templates/.keep'
|
30
|
+
file 'app/assets/javascripts/app.js.coffee', tpl('app.js.coffee')
|
31
|
+
file 'app/assets/javascripts/includes/angular-local-storage.js',
|
32
|
+
tpl('angular-local-storage.js')
|
33
|
+
file 'app/assets/javascripts/templates/home.html.haml',
|
34
|
+
tpl('home.html.haml')
|
35
|
+
file 'app/assets/javascripts/controllers/home_controller.js.coffee',
|
36
|
+
tpl('home_controller.js.coffee')
|
37
|
+
file 'app/views/home/index.html.haml', tpl('index.html.haml')
|
38
|
+
file 'app/controllers/home_controller.rb', tpl('home_controller.rb')
|
39
|
+
append_file 'config/initializers/assets.rb',
|
40
|
+
'Rails.application.config.assets.precompile += %w( app.js )'
|
41
|
+
route "root to: 'home#index'"
|
42
|
+
end
|
43
|
+
|
44
|
+
gem 'redcarpet'
|
45
|
+
gem 'paperclip'
|
46
|
+
gem 'html2haml'
|
47
|
+
|
48
|
+
if use_mongoid
|
49
|
+
gem 'mongoid', '~> 4.0.0',github: 'mongoid/mongoid'
|
50
|
+
gem 'bson_ext'
|
51
|
+
run 'bundle install --quiet'
|
52
|
+
generate 'mongoid:config'
|
53
|
+
end
|
54
|
+
|
55
|
+
gem 'factory_girl_rails', '~> 4.0'
|
56
|
+
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw]
|
57
|
+
gem 'tzinfo', platforms: [:mingw, :mswin, :x64_mingw]
|
58
|
+
|
59
|
+
if use_devise
|
60
|
+
gem 'devise', '~> 3.3.0'
|
61
|
+
generate 'devise:install'
|
62
|
+
generate :scaffold, 'User', 'name:string', 'email:string',
|
63
|
+
'password:string', 'password_confirmation:string', 'admin:boolean'
|
64
|
+
remove_file 'app/models/user.rb'
|
65
|
+
run 'cp test/models/user_test.rb test/models/user_test_orig.rb'
|
66
|
+
remove_file 'test/models/user_test.rb'
|
67
|
+
remove_file 'test/factories/users.rb'
|
68
|
+
remove_file 'test/fixtures/users.yml'
|
69
|
+
run 'rm -f db/migrate/*_create_users.rb'
|
70
|
+
generate :devise, 'User'
|
71
|
+
if use_mongoid
|
72
|
+
inject_into_file 'app/models/user.rb', <<-FILE.strip_heredoc, before: "## Database authenticatable\n"
|
73
|
+
## ZWR generated fields
|
74
|
+
field :name, type: String, default: ""
|
75
|
+
field :admin, type: Boolean, default: ""
|
76
|
+
|
77
|
+
FILE
|
78
|
+
gsub_file 'app/models/user.rb', "## Database authenticatable", " ## Database authenticatable"
|
79
|
+
gsub_file "test/test_helper.rb","# Add more helper methods to be used by all tests here...",
|
80
|
+
"include FactoryGirl::Syntax::Methods"
|
81
|
+
else
|
82
|
+
filename = Dir.glob("db/migrate/*_devise_create_users.rb")[0]
|
83
|
+
puts " \033[35mfound\033[0m #{filename}"
|
84
|
+
inject_into_file(filename, <<-FILE, :after => "Database authenticatable\n")
|
85
|
+
t.string :name
|
86
|
+
t.boolean :admin
|
87
|
+
FILE
|
88
|
+
gsub_file "test/test_helper.rb","fixtures :all", "include FactoryGirl::Syntax::Methods"
|
89
|
+
end
|
90
|
+
gsub_file "app/views/users/_form.html.haml","form_for @user do","bootstrap_form_for @user do"
|
91
|
+
gsub_file "app/views/users/_form.html.haml","error_explanation","error_explanation.alert.alert-danger"
|
92
|
+
gsub_file "app/views/users/_form.html.haml","f.text_field :password","f.password_field :password"
|
93
|
+
gsub_file "app/views/users/_form.html.haml","= f.label :name",""
|
94
|
+
gsub_file "app/views/users/_form.html.haml","= f.label :email",""
|
95
|
+
gsub_file "app/views/users/_form.html.haml","= f.label :password_confirmation",""
|
96
|
+
gsub_file "app/views/users/_form.html.haml","= f.label :password",""
|
97
|
+
gsub_file "app/views/users/_form.html.haml","= f.label :admin",""
|
98
|
+
gsub_file "config/routes.rb","resources :users", <<-FILE.strip_heredoc
|
99
|
+
scope '/admin' do
|
100
|
+
resources :users, as: 'users'
|
101
|
+
end
|
102
|
+
FILE
|
103
|
+
inject_into_file 'test/factories/users.rb', <<-FILE.strip_heredoc, after: "factory :user do\n"
|
104
|
+
email 'user@example.com'
|
105
|
+
password '1234567890'
|
106
|
+
password_confirmation '1234567890'
|
107
|
+
FILE
|
108
|
+
gsub_file "test/controllers/users_controller_test.rb","@user = users(:one)",
|
109
|
+
"User.delete_all\n @user = create(:user)"
|
110
|
+
gsub_file "test/controllers/users_controller_test.rb","@user.email", '"xxx#{@user.email}"'
|
111
|
+
end
|
112
|
+
|
113
|
+
remove_file 'README.rdoc'
|
114
|
+
file 'README.markdown', 'Application #{ARGV[1]} generated bu the zwr generator.'
|
115
|
+
|
116
|
+
remove_file 'app/views/layouts/application.html.erb'
|
117
|
+
file 'app/views/layouts/application.html.haml', tpl('application.html.haml')
|
118
|
+
|
119
|
+
remove_file 'app/assets/javascripts/application.js'
|
120
|
+
file 'app/assets/javascripts/application.js.coffee', tpl('application.js.coffee')
|
121
|
+
|
122
|
+
remove_file 'app/assets/stylesheets/application.css'
|
123
|
+
file 'app/assets/stylesheets/application.css.scss', tpl('application.css.scss')
|
124
|
+
|
125
|
+
remove_file 'db/seeds.rb'
|
126
|
+
file 'db/seeds.rb', "Dir[Rails.root.join('db/seeds/*.rb')].each { |file| load file }"
|
127
|
+
|
128
|
+
initializer 'markdown.rb',
|
129
|
+
'Markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML, autolink: true, tables: true)'
|
130
|
+
|
131
|
+
file 'db/seeds/.keep'
|
132
|
+
|
133
|
+
|
134
|
+
|
135
|
+
rake 'zwr:install'
|
136
|
+
rake 'db:migrate'
|
137
|
+
|
138
|
+
unless use_mongoid
|
139
|
+
run 'bundle install --quiet'
|
140
|
+
end
|
141
|
+
|
142
|
+
# Git commands should be the last so that they catch all the files!
|
143
|
+
git init: '-q'
|
144
|
+
git add: '-A'
|
145
|
+
git commit: "-q -asm 'zwr new #{@app_name}'"
|
146
|
+
git remote: "add origin git@github.com:zmilojko/#{@app_name}.git"
|
147
|
+
|
@@ -0,0 +1,446 @@
|
|
1
|
+
/*jshint globalstrict:true*/
|
2
|
+
'use strict';
|
3
|
+
|
4
|
+
var isDefined = angular.isDefined,
|
5
|
+
isUndefined = angular.isUndefined,
|
6
|
+
isNumber = angular.isNumber,
|
7
|
+
isObject = angular.isObject,
|
8
|
+
isArray = angular.isArray,
|
9
|
+
extend = angular.extend,
|
10
|
+
toJson = angular.toJson,
|
11
|
+
fromJson = angular.fromJson;
|
12
|
+
|
13
|
+
|
14
|
+
// Test if string is only contains numbers
|
15
|
+
// e.g '1' => true, "'1'" => true
|
16
|
+
function isStringNumber(num) {
|
17
|
+
return /^-?\d+\.?\d*$/.test(num.replace(/["']/g, ''));
|
18
|
+
}
|
19
|
+
|
20
|
+
var angularLocalStorage = angular.module('LocalStorageModule', []);
|
21
|
+
|
22
|
+
angularLocalStorage.provider('localStorageService', function() {
|
23
|
+
|
24
|
+
// You should set a prefix to avoid overwriting any local storage variables from the rest of your app
|
25
|
+
// e.g. localStorageServiceProvider.setPrefix('youAppName');
|
26
|
+
// With provider you can use config as this:
|
27
|
+
// myApp.config(function (localStorageServiceProvider) {
|
28
|
+
// localStorageServiceProvider.prefix = 'yourAppName';
|
29
|
+
// });
|
30
|
+
this.prefix = 'ls';
|
31
|
+
|
32
|
+
// You could change web storage type localstorage or sessionStorage
|
33
|
+
this.storageType = 'localStorage';
|
34
|
+
|
35
|
+
// Cookie options (usually in case of fallback)
|
36
|
+
// expiry = Number of days before cookies expire // 0 = Does not expire
|
37
|
+
// path = The web path the cookie represents
|
38
|
+
this.cookie = {
|
39
|
+
expiry: 30,
|
40
|
+
path: '/'
|
41
|
+
};
|
42
|
+
|
43
|
+
// Send signals for each of the following actions?
|
44
|
+
this.notify = {
|
45
|
+
setItem: true,
|
46
|
+
removeItem: false
|
47
|
+
};
|
48
|
+
|
49
|
+
// Setter for the prefix
|
50
|
+
this.setPrefix = function(prefix) {
|
51
|
+
this.prefix = prefix;
|
52
|
+
return this;
|
53
|
+
};
|
54
|
+
|
55
|
+
// Setter for the storageType
|
56
|
+
this.setStorageType = function(storageType) {
|
57
|
+
this.storageType = storageType;
|
58
|
+
return this;
|
59
|
+
};
|
60
|
+
|
61
|
+
// Setter for cookie config
|
62
|
+
this.setStorageCookie = function(exp, path) {
|
63
|
+
this.cookie = {
|
64
|
+
expiry: exp,
|
65
|
+
path: path
|
66
|
+
};
|
67
|
+
return this;
|
68
|
+
};
|
69
|
+
|
70
|
+
// Setter for cookie domain
|
71
|
+
this.setStorageCookieDomain = function(domain) {
|
72
|
+
this.cookie.domain = domain;
|
73
|
+
return this;
|
74
|
+
};
|
75
|
+
|
76
|
+
// Setter for notification config
|
77
|
+
// itemSet & itemRemove should be booleans
|
78
|
+
this.setNotify = function(itemSet, itemRemove) {
|
79
|
+
this.notify = {
|
80
|
+
setItem: itemSet,
|
81
|
+
removeItem: itemRemove
|
82
|
+
};
|
83
|
+
return this;
|
84
|
+
};
|
85
|
+
|
86
|
+
this.$get = ['$rootScope', '$window', '$document', '$parse', function($rootScope, $window, $document, $parse) {
|
87
|
+
var self = this;
|
88
|
+
var prefix = self.prefix;
|
89
|
+
var cookie = self.cookie;
|
90
|
+
var notify = self.notify;
|
91
|
+
var storageType = self.storageType;
|
92
|
+
var webStorage;
|
93
|
+
|
94
|
+
// When Angular's $document is not available
|
95
|
+
if (!$document) {
|
96
|
+
$document = document;
|
97
|
+
} else if ($document[0]) {
|
98
|
+
$document = $document[0];
|
99
|
+
}
|
100
|
+
|
101
|
+
// If there is a prefix set in the config lets use that with an appended period for readability
|
102
|
+
if (prefix.substr(-1) !== '.') {
|
103
|
+
prefix = !!prefix ? prefix + '.' : '';
|
104
|
+
}
|
105
|
+
var deriveQualifiedKey = function(key) {
|
106
|
+
return prefix + key;
|
107
|
+
};
|
108
|
+
// Checks the browser to see if local storage is supported
|
109
|
+
var browserSupportsLocalStorage = (function () {
|
110
|
+
try {
|
111
|
+
var supported = (storageType in $window && $window[storageType] !== null);
|
112
|
+
|
113
|
+
// When Safari (OS X or iOS) is in private browsing mode, it appears as though localStorage
|
114
|
+
// is available, but trying to call .setItem throws an exception.
|
115
|
+
//
|
116
|
+
// "QUOTA_EXCEEDED_ERR: DOM Exception 22: An attempt was made to add something to storage
|
117
|
+
// that exceeded the quota."
|
118
|
+
var key = deriveQualifiedKey('__' + Math.round(Math.random() * 1e7));
|
119
|
+
if (supported) {
|
120
|
+
webStorage = $window[storageType];
|
121
|
+
webStorage.setItem(key, '');
|
122
|
+
webStorage.removeItem(key);
|
123
|
+
}
|
124
|
+
|
125
|
+
return supported;
|
126
|
+
} catch (e) {
|
127
|
+
storageType = 'cookie';
|
128
|
+
$rootScope.$broadcast('LocalStorageModule.notification.error', e.message);
|
129
|
+
return false;
|
130
|
+
}
|
131
|
+
}());
|
132
|
+
|
133
|
+
|
134
|
+
|
135
|
+
// Directly adds a value to local storage
|
136
|
+
// If local storage is not available in the browser use cookies
|
137
|
+
// Example use: localStorageService.add('library','angular');
|
138
|
+
var addToLocalStorage = function (key, value) {
|
139
|
+
// Let's convert undefined values to null to get the value consistent
|
140
|
+
if (isUndefined(value)) {
|
141
|
+
value = null;
|
142
|
+
} else if (isObject(value) || isArray(value) || isNumber(+value || value)) {
|
143
|
+
value = toJson(value);
|
144
|
+
}
|
145
|
+
|
146
|
+
// If this browser does not support local storage use cookies
|
147
|
+
if (!browserSupportsLocalStorage || self.storageType === 'cookie') {
|
148
|
+
if (!browserSupportsLocalStorage) {
|
149
|
+
$rootScope.$broadcast('LocalStorageModule.notification.warning', 'LOCAL_STORAGE_NOT_SUPPORTED');
|
150
|
+
}
|
151
|
+
|
152
|
+
if (notify.setItem) {
|
153
|
+
$rootScope.$broadcast('LocalStorageModule.notification.setitem', {key: key, newvalue: value, storageType: 'cookie'});
|
154
|
+
}
|
155
|
+
return addToCookies(key, value);
|
156
|
+
}
|
157
|
+
|
158
|
+
try {
|
159
|
+
if (isObject(value) || isArray(value)) {
|
160
|
+
value = toJson(value);
|
161
|
+
}
|
162
|
+
if (webStorage) {webStorage.setItem(deriveQualifiedKey(key), value)};
|
163
|
+
if (notify.setItem) {
|
164
|
+
$rootScope.$broadcast('LocalStorageModule.notification.setitem', {key: key, newvalue: value, storageType: self.storageType});
|
165
|
+
}
|
166
|
+
} catch (e) {
|
167
|
+
$rootScope.$broadcast('LocalStorageModule.notification.error', e.message);
|
168
|
+
return addToCookies(key, value);
|
169
|
+
}
|
170
|
+
return true;
|
171
|
+
};
|
172
|
+
|
173
|
+
// Directly get a value from local storage
|
174
|
+
// Example use: localStorageService.get('library'); // returns 'angular'
|
175
|
+
var getFromLocalStorage = function (key) {
|
176
|
+
|
177
|
+
if (!browserSupportsLocalStorage || self.storageType === 'cookie') {
|
178
|
+
if (!browserSupportsLocalStorage) {
|
179
|
+
$rootScope.$broadcast('LocalStorageModule.notification.warning','LOCAL_STORAGE_NOT_SUPPORTED');
|
180
|
+
}
|
181
|
+
|
182
|
+
return getFromCookies(key);
|
183
|
+
}
|
184
|
+
|
185
|
+
var item = webStorage ? webStorage.getItem(deriveQualifiedKey(key)) : null;
|
186
|
+
// angular.toJson will convert null to 'null', so a proper conversion is needed
|
187
|
+
// FIXME not a perfect solution, since a valid 'null' string can't be stored
|
188
|
+
if (!item || item === 'null') {
|
189
|
+
return null;
|
190
|
+
}
|
191
|
+
|
192
|
+
if (item.charAt(0) === "{" || item.charAt(0) === "[" || isStringNumber(item)) {
|
193
|
+
return fromJson(item);
|
194
|
+
}
|
195
|
+
|
196
|
+
return item;
|
197
|
+
};
|
198
|
+
|
199
|
+
// Remove an item from local storage
|
200
|
+
// Example use: localStorageService.remove('library'); // removes the key/value pair of library='angular'
|
201
|
+
var removeFromLocalStorage = function (key) {
|
202
|
+
if (!browserSupportsLocalStorage || self.storageType === 'cookie') {
|
203
|
+
if (!browserSupportsLocalStorage) {
|
204
|
+
$rootScope.$broadcast('LocalStorageModule.notification.warning', 'LOCAL_STORAGE_NOT_SUPPORTED');
|
205
|
+
}
|
206
|
+
|
207
|
+
if (notify.removeItem) {
|
208
|
+
$rootScope.$broadcast('LocalStorageModule.notification.removeitem', {key: key, storageType: 'cookie'});
|
209
|
+
}
|
210
|
+
return removeFromCookies(key);
|
211
|
+
}
|
212
|
+
|
213
|
+
try {
|
214
|
+
webStorage.removeItem(deriveQualifiedKey(key));
|
215
|
+
if (notify.removeItem) {
|
216
|
+
$rootScope.$broadcast('LocalStorageModule.notification.removeitem', {key: key, storageType: self.storageType});
|
217
|
+
}
|
218
|
+
} catch (e) {
|
219
|
+
$rootScope.$broadcast('LocalStorageModule.notification.error', e.message);
|
220
|
+
return removeFromCookies(key);
|
221
|
+
}
|
222
|
+
return true;
|
223
|
+
};
|
224
|
+
|
225
|
+
// Return array of keys for local storage
|
226
|
+
// Example use: var keys = localStorageService.keys()
|
227
|
+
var getKeysForLocalStorage = function () {
|
228
|
+
|
229
|
+
if (!browserSupportsLocalStorage) {
|
230
|
+
$rootScope.$broadcast('LocalStorageModule.notification.warning', 'LOCAL_STORAGE_NOT_SUPPORTED');
|
231
|
+
return false;
|
232
|
+
}
|
233
|
+
|
234
|
+
var prefixLength = prefix.length;
|
235
|
+
var keys = [];
|
236
|
+
for (var key in webStorage) {
|
237
|
+
// Only return keys that are for this app
|
238
|
+
if (key.substr(0,prefixLength) === prefix) {
|
239
|
+
try {
|
240
|
+
keys.push(key.substr(prefixLength));
|
241
|
+
} catch (e) {
|
242
|
+
$rootScope.$broadcast('LocalStorageModule.notification.error', e.Description);
|
243
|
+
return [];
|
244
|
+
}
|
245
|
+
}
|
246
|
+
}
|
247
|
+
return keys;
|
248
|
+
};
|
249
|
+
|
250
|
+
// Remove all data for this app from local storage
|
251
|
+
// Also optionally takes a regular expression string and removes the matching key-value pairs
|
252
|
+
// Example use: localStorageService.clearAll();
|
253
|
+
// Should be used mostly for development purposes
|
254
|
+
var clearAllFromLocalStorage = function (regularExpression) {
|
255
|
+
|
256
|
+
regularExpression = regularExpression || "";
|
257
|
+
//accounting for the '.' in the prefix when creating a regex
|
258
|
+
var tempPrefix = prefix.slice(0, -1);
|
259
|
+
var testRegex = new RegExp(tempPrefix + '.' + regularExpression);
|
260
|
+
|
261
|
+
if (!browserSupportsLocalStorage || self.storageType === 'cookie') {
|
262
|
+
if (!browserSupportsLocalStorage) {
|
263
|
+
$rootScope.$broadcast('LocalStorageModule.notification.warning', 'LOCAL_STORAGE_NOT_SUPPORTED');
|
264
|
+
}
|
265
|
+
|
266
|
+
return clearAllFromCookies();
|
267
|
+
}
|
268
|
+
|
269
|
+
var prefixLength = prefix.length;
|
270
|
+
|
271
|
+
for (var key in webStorage) {
|
272
|
+
// Only remove items that are for this app and match the regular expression
|
273
|
+
if (testRegex.test(key)) {
|
274
|
+
try {
|
275
|
+
removeFromLocalStorage(key.substr(prefixLength));
|
276
|
+
} catch (e) {
|
277
|
+
$rootScope.$broadcast('LocalStorageModule.notification.error',e.message);
|
278
|
+
return clearAllFromCookies();
|
279
|
+
}
|
280
|
+
}
|
281
|
+
}
|
282
|
+
return true;
|
283
|
+
};
|
284
|
+
|
285
|
+
// Checks the browser to see if cookies are supported
|
286
|
+
var browserSupportsCookies = (function() {
|
287
|
+
try {
|
288
|
+
return $window.navigator.cookieEnabled ||
|
289
|
+
("cookie" in $document && ($document.cookie.length > 0 ||
|
290
|
+
($document.cookie = "test").indexOf.call($document.cookie, "test") > -1));
|
291
|
+
} catch (e) {
|
292
|
+
$rootScope.$broadcast('LocalStorageModule.notification.error', e.message);
|
293
|
+
return false;
|
294
|
+
}
|
295
|
+
}());
|
296
|
+
|
297
|
+
// Directly adds a value to cookies
|
298
|
+
// Typically used as a fallback is local storage is not available in the browser
|
299
|
+
// Example use: localStorageService.cookie.add('library','angular');
|
300
|
+
var addToCookies = function (key, value) {
|
301
|
+
|
302
|
+
if (isUndefined(value)) {
|
303
|
+
return false;
|
304
|
+
} else if(isArray(value) || isObject(value)) {
|
305
|
+
value = toJson(value);
|
306
|
+
}
|
307
|
+
|
308
|
+
if (!browserSupportsCookies) {
|
309
|
+
$rootScope.$broadcast('LocalStorageModule.notification.error', 'COOKIES_NOT_SUPPORTED');
|
310
|
+
return false;
|
311
|
+
}
|
312
|
+
|
313
|
+
try {
|
314
|
+
var expiry = '',
|
315
|
+
expiryDate = new Date(),
|
316
|
+
cookieDomain = '';
|
317
|
+
|
318
|
+
if (value === null) {
|
319
|
+
// Mark that the cookie has expired one day ago
|
320
|
+
expiryDate.setTime(expiryDate.getTime() + (-1 * 24 * 60 * 60 * 1000));
|
321
|
+
expiry = "; expires=" + expiryDate.toGMTString();
|
322
|
+
value = '';
|
323
|
+
} else if (cookie.expiry !== 0) {
|
324
|
+
expiryDate.setTime(expiryDate.getTime() + (cookie.expiry * 24 * 60 * 60 * 1000));
|
325
|
+
expiry = "; expires=" + expiryDate.toGMTString();
|
326
|
+
}
|
327
|
+
if (!!key) {
|
328
|
+
var cookiePath = "; path=" + cookie.path;
|
329
|
+
if(cookie.domain){
|
330
|
+
cookieDomain = "; domain=" + cookie.domain;
|
331
|
+
}
|
332
|
+
$document.cookie = deriveQualifiedKey(key) + "=" + encodeURIComponent(value) + expiry + cookiePath + cookieDomain;
|
333
|
+
}
|
334
|
+
} catch (e) {
|
335
|
+
$rootScope.$broadcast('LocalStorageModule.notification.error',e.message);
|
336
|
+
return false;
|
337
|
+
}
|
338
|
+
return true;
|
339
|
+
};
|
340
|
+
|
341
|
+
// Directly get a value from a cookie
|
342
|
+
// Example use: localStorageService.cookie.get('library'); // returns 'angular'
|
343
|
+
var getFromCookies = function (key) {
|
344
|
+
if (!browserSupportsCookies) {
|
345
|
+
$rootScope.$broadcast('LocalStorageModule.notification.error', 'COOKIES_NOT_SUPPORTED');
|
346
|
+
return false;
|
347
|
+
}
|
348
|
+
|
349
|
+
var cookies = $document.cookie && $document.cookie.split(';') || [];
|
350
|
+
for(var i=0; i < cookies.length; i++) {
|
351
|
+
var thisCookie = cookies[i];
|
352
|
+
while (thisCookie.charAt(0) === ' ') {
|
353
|
+
thisCookie = thisCookie.substring(1,thisCookie.length);
|
354
|
+
}
|
355
|
+
if (thisCookie.indexOf(deriveQualifiedKey(key) + '=') === 0) {
|
356
|
+
var storedValues = decodeURIComponent(thisCookie.substring(prefix.length + key.length + 1, thisCookie.length))
|
357
|
+
try{
|
358
|
+
var obj = JSON.parse(storedValues);
|
359
|
+
return fromJson(obj)
|
360
|
+
}catch(e){
|
361
|
+
return storedValues
|
362
|
+
}
|
363
|
+
}
|
364
|
+
}
|
365
|
+
return null;
|
366
|
+
};
|
367
|
+
|
368
|
+
var removeFromCookies = function (key) {
|
369
|
+
addToCookies(key,null);
|
370
|
+
};
|
371
|
+
|
372
|
+
var clearAllFromCookies = function () {
|
373
|
+
var thisCookie = null, thisKey = null;
|
374
|
+
var prefixLength = prefix.length;
|
375
|
+
var cookies = $document.cookie.split(';');
|
376
|
+
for(var i = 0; i < cookies.length; i++) {
|
377
|
+
thisCookie = cookies[i];
|
378
|
+
|
379
|
+
while (thisCookie.charAt(0) === ' ') {
|
380
|
+
thisCookie = thisCookie.substring(1, thisCookie.length);
|
381
|
+
}
|
382
|
+
|
383
|
+
var key = thisCookie.substring(prefixLength, thisCookie.indexOf('='));
|
384
|
+
removeFromCookies(key);
|
385
|
+
}
|
386
|
+
};
|
387
|
+
|
388
|
+
var getStorageType = function() {
|
389
|
+
return storageType;
|
390
|
+
};
|
391
|
+
|
392
|
+
// Add a listener on scope variable to save its changes to local storage
|
393
|
+
// Return a function which when called cancels binding
|
394
|
+
var bindToScope = function(scope, key, def, lsKey) {
|
395
|
+
lsKey = lsKey || key;
|
396
|
+
var value = getFromLocalStorage(lsKey);
|
397
|
+
|
398
|
+
if (value === null && isDefined(def)) {
|
399
|
+
value = def;
|
400
|
+
} else if (isObject(value) && isObject(def)) {
|
401
|
+
value = extend(def, value);
|
402
|
+
}
|
403
|
+
|
404
|
+
$parse(key).assign(scope, value);
|
405
|
+
|
406
|
+
return scope.$watch(key, function(newVal) {
|
407
|
+
addToLocalStorage(lsKey, newVal);
|
408
|
+
}, isObject(scope[key]));
|
409
|
+
};
|
410
|
+
|
411
|
+
// Return localStorageService.length
|
412
|
+
// ignore keys that not owned
|
413
|
+
var lengthOfLocalStorage = function() {
|
414
|
+
var count = 0;
|
415
|
+
var storage = $window[storageType];
|
416
|
+
for(var i = 0; i < storage.length; i++) {
|
417
|
+
if(storage.key(i).indexOf(prefix) === 0 ) {
|
418
|
+
count++;
|
419
|
+
}
|
420
|
+
}
|
421
|
+
return count;
|
422
|
+
};
|
423
|
+
|
424
|
+
return {
|
425
|
+
isSupported: browserSupportsLocalStorage,
|
426
|
+
getStorageType: getStorageType,
|
427
|
+
set: addToLocalStorage,
|
428
|
+
add: addToLocalStorage, //DEPRECATED
|
429
|
+
get: getFromLocalStorage,
|
430
|
+
keys: getKeysForLocalStorage,
|
431
|
+
remove: removeFromLocalStorage,
|
432
|
+
clearAll: clearAllFromLocalStorage,
|
433
|
+
bind: bindToScope,
|
434
|
+
deriveKey: deriveQualifiedKey,
|
435
|
+
length: lengthOfLocalStorage,
|
436
|
+
cookie: {
|
437
|
+
isSupported: browserSupportsCookies,
|
438
|
+
set: addToCookies,
|
439
|
+
add: addToCookies, //DEPRECATED
|
440
|
+
get: getFromCookies,
|
441
|
+
remove: removeFromCookies,
|
442
|
+
clearAll: clearAllFromCookies
|
443
|
+
}
|
444
|
+
};
|
445
|
+
}];
|
446
|
+
});
|
@@ -0,0 +1,37 @@
|
|
1
|
+
#= require angular
|
2
|
+
#= require angular-route
|
3
|
+
#= require angular-resource
|
4
|
+
#= require angular-rails-templates
|
5
|
+
#= require_tree ./templates
|
6
|
+
#= require_self
|
7
|
+
#= require_tree ./includes
|
8
|
+
#= require_tree ./directives
|
9
|
+
#= require_tree ./services
|
10
|
+
#= require_tree ./controllers
|
11
|
+
#= require angular-ui-bootstrap
|
12
|
+
|
13
|
+
@APP_NAME_module = angular.module('APP_NAME', [
|
14
|
+
'ngRoute',
|
15
|
+
'ngResource',
|
16
|
+
'templates',
|
17
|
+
'ui.bootstrap',
|
18
|
+
'LocalStorageModule',
|
19
|
+
])
|
20
|
+
|
21
|
+
@APP_NAME_module.config(['$routeProvider', ($routeProvider) ->
|
22
|
+
$routeProvider.
|
23
|
+
#when('/url', {
|
24
|
+
# templateUrl: 'template.html',
|
25
|
+
#}).
|
26
|
+
otherwise({
|
27
|
+
templateUrl: 'home.html',
|
28
|
+
})
|
29
|
+
])
|
30
|
+
|
31
|
+
@APP_NAME_module.config(['localStorageServiceProvider', (localStorageServiceProvider) ->
|
32
|
+
localStorageServiceProvider
|
33
|
+
.setPrefix('APP_NAME')
|
34
|
+
.setStorageType('localStorage')
|
35
|
+
.setStorageCookie(0, '<path>')
|
36
|
+
.setNotify(true, true)
|
37
|
+
])
|
@@ -0,0 +1,21 @@
|
|
1
|
+
/*
|
2
|
+
*= require_self
|
3
|
+
*/
|
4
|
+
@import "bootstrap-sprockets";
|
5
|
+
@import "bootstrap";
|
6
|
+
@import "zwr";
|
7
|
+
@import "rails_bootstrap_forms";
|
8
|
+
|
9
|
+
#search_control, #second_page_title {
|
10
|
+
margin-top: 30px;
|
11
|
+
}
|
12
|
+
|
13
|
+
.search_input {
|
14
|
+
position: relative;
|
15
|
+
}
|
16
|
+
|
17
|
+
.search_input > .glyphicon {
|
18
|
+
position: absolute;
|
19
|
+
right: 0;
|
20
|
+
padding: 8px 14px;
|
21
|
+
}
|
@@ -0,0 +1,90 @@
|
|
1
|
+
!!!
|
2
|
+
%html
|
3
|
+
%head
|
4
|
+
%title #{'APP_NAME'.capitalize}
|
5
|
+
%meta(name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0")
|
6
|
+
-# android stand alone mode
|
7
|
+
%meta(name="mobile-web-app-capable" content="yes")
|
8
|
+
%link(rel="icon" sizes="192x192" href="/assets/icon.png")
|
9
|
+
-# iOS stand alone mode
|
10
|
+
%meta(name="apple-mobile-web-app-capable" content="yes")
|
11
|
+
%meta(name="apple-mobile-web-app-status-bar-style" content="black")
|
12
|
+
%link(rel="apple-touch-icon" href="/assets/icon.png")
|
13
|
+
%link(rel="apple-touch-startup-image" href="/assets/icon.png")
|
14
|
+
-# windows 8.1, maybe mobile, maybe not
|
15
|
+
%meta(name="application-name" content="ID Pickup")
|
16
|
+
%meta(name="msapplication-navbutton-color" content="#FF3300")
|
17
|
+
%meta(name="msapplication-square150x150logo" content="assets/icon.png")
|
18
|
+
%meta(name="msapplication-square310x310logo" content="assets/icon.png")
|
19
|
+
%meta(name="msapplication-square70x70logo" content="assets/icon.png")
|
20
|
+
%meta(name="msapplication-wide310x150logo" content="assets/icon.png")
|
21
|
+
%meta(name="msapplication-TileColor" content="#FF3300")
|
22
|
+
%meta(name="msapplication-TileImage" content="assets/icon.png")
|
23
|
+
%meta(name="msapplication-tooltip" content="ID Pickup")
|
24
|
+
= stylesheet_link_tag 'application', media: 'all'
|
25
|
+
= javascript_include_tag 'application'
|
26
|
+
= csrf_meta_tags
|
27
|
+
%body
|
28
|
+
.container
|
29
|
+
%nav.navbar.navbar-static-top.navbar-inverse(role="navigation")
|
30
|
+
.container-fluid
|
31
|
+
.navbar-header.pull-left
|
32
|
+
%a.navbar-brand(href="#")
|
33
|
+
=image_tag "logo.png", height: '20'
|
34
|
+
#{'APP_NAME'.capitalize}
|
35
|
+
-#
|
36
|
+
-# Sticky menu, on the right
|
37
|
+
#navbar-steady.navbar-header.pull-right
|
38
|
+
%ul.nav.navbar-nav.pull-left
|
39
|
+
-# Static menu items
|
40
|
+
%li.pull-left.hidden-xs
|
41
|
+
%a(href="#") Static 1
|
42
|
+
-# notice that the first to pull right will be right most!
|
43
|
+
%li.pull-right
|
44
|
+
%a(href="#") Static 2
|
45
|
+
-# Static text, like the username
|
46
|
+
%li.navbar-text.pull-right
|
47
|
+
%span.hidden-xs Welcome,
|
48
|
+
%span guest
|
49
|
+
-# following button should ALWAYS be there, unless there is no colapsable items
|
50
|
+
%button.navbar-toggle.collapsed(type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-expanded="false" aria-controls="navbar")
|
51
|
+
%span.sr-only Toggle navigation
|
52
|
+
%span.icon-bar
|
53
|
+
%span.icon-bar
|
54
|
+
%span.icon-bar
|
55
|
+
#navbar.navbar-collapse.collapse
|
56
|
+
%ul.nav.navbar-nav
|
57
|
+
%li.active
|
58
|
+
%a(href="#") Left 1
|
59
|
+
%li
|
60
|
+
%a(href="#") Left 2
|
61
|
+
%li
|
62
|
+
%a.dropdown-toggle(href="#" data-toggle="dropdown")
|
63
|
+
Drop
|
64
|
+
%span.caret
|
65
|
+
%ul.dropdown-menu(role="menu")
|
66
|
+
%li.dropdown-header Header for submenu group
|
67
|
+
%li
|
68
|
+
%a(href="#") Submenu 1
|
69
|
+
%li
|
70
|
+
%a(href="#") Submenu 2
|
71
|
+
%li
|
72
|
+
%a(href="#") Submenu 3
|
73
|
+
%li.divider
|
74
|
+
%li.dropdown-header Header for others
|
75
|
+
%li
|
76
|
+
%a(href="#") Submenu 4
|
77
|
+
%li
|
78
|
+
%a(href="#") Submenu 5
|
79
|
+
%ul.nav.navbar-nav.navbar-right
|
80
|
+
%li
|
81
|
+
%a(href="#") Right 1
|
82
|
+
%li
|
83
|
+
%a(href="#") Right 2
|
84
|
+
-#.alert.alert-success(role="alert")=success_notice
|
85
|
+
-if notice
|
86
|
+
.alert.alert-info(role="alert")=notice
|
87
|
+
-#.alert.alert-warning(role="alert")=alert_warning
|
88
|
+
-if alert
|
89
|
+
.alert.alert-danger(role="alert")=alert
|
90
|
+
= yield
|
@@ -0,0 +1,16 @@
|
|
1
|
+
.container(ng-controller="HomeController")
|
2
|
+
%nav.navbar.navbar-static-top.navbar-inverse(role="navigation")
|
3
|
+
.container-fluid
|
4
|
+
.navbar-header.pull-left
|
5
|
+
%a.navbar-brand(href="#")
|
6
|
+
=image_tag "logo.png", height: '20'
|
7
|
+
Refinder
|
8
|
+
#main
|
9
|
+
.row
|
10
|
+
.col-sm-6
|
11
|
+
.search_input
|
12
|
+
%input#search_control.form-control(type="search" placeholder="Search" ng-change="handle_search_criteria_change()" ng-model="criteria.criteria_text")
|
13
|
+
%span.glyphicon.glyphicon-search(ng-click="handle_search_button_click()")
|
14
|
+
.col-sm-6
|
15
|
+
%h1#second_page_title Result!
|
16
|
+
%p This page should show the results
|
@@ -0,0 +1,9 @@
|
|
1
|
+
@APP_NAME_module.controller 'HomeController', [
|
2
|
+
'$scope', ($scope) ->
|
3
|
+
$scope.criteria =
|
4
|
+
criteria_text: null
|
5
|
+
$scope.handle_search_criteria_change = ->
|
6
|
+
console.log "Text change, now it is #{$scope.criteria.criteria_text}"
|
7
|
+
$scope.handle_search_button_click = ->
|
8
|
+
console.log "Search button clicked"
|
9
|
+
]
|
@@ -0,0 +1,32 @@
|
|
1
|
+
!!!
|
2
|
+
%html(ng-app="APP_NAME")
|
3
|
+
%head
|
4
|
+
%title #{"APP_NAME".capitalize}
|
5
|
+
%meta(name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0")
|
6
|
+
-# android stand alone mode
|
7
|
+
%meta(name="mobile-web-app-capable" content="yes")
|
8
|
+
%link(rel="icon" sizes="192x192" href="/assets/icon.png")
|
9
|
+
-# iOS stand alone mode
|
10
|
+
%meta(name="apple-mobile-web-app-capable" content="yes")
|
11
|
+
%meta(name="apple-mobile-web-app-status-bar-style" content="black")
|
12
|
+
%link(rel="apple-touch-icon" href="/assets/icon.png")
|
13
|
+
%link(rel="apple-touch-startup-image" href="/assets/icon.png")
|
14
|
+
-# windows 8.1, maybe mobile, maybe not
|
15
|
+
%meta(name="application-name" content="ID Pickup")
|
16
|
+
%meta(name="msapplication-navbutton-color" content="#FF3300")
|
17
|
+
%meta(name="msapplication-square150x150logo" content="assets/icon.png")
|
18
|
+
%meta(name="msapplication-square310x310logo" content="assets/icon.png")
|
19
|
+
%meta(name="msapplication-square70x70logo" content="assets/icon.png")
|
20
|
+
%meta(name="msapplication-wide310x150logo" content="assets/icon.png")
|
21
|
+
%meta(name="msapplication-TileColor" content="#FF3300")
|
22
|
+
%meta(name="msapplication-TileImage" content="assets/icon.png")
|
23
|
+
%meta(name="msapplication-tooltip" content="ID Pickup")
|
24
|
+
-#
|
25
|
+
= stylesheet_link_tag 'application', media: 'all'
|
26
|
+
= csrf_meta_tags
|
27
|
+
-# If you need something from the Ruby code, set it up here
|
28
|
+
-# %script
|
29
|
+
%body(role="document")
|
30
|
+
%div.full_height(ng-view)
|
31
|
+
%h1(style="margin-top: 10px;")=t :'Please wait' # Please wait while the application loads!
|
32
|
+
= javascript_include_tag 'app'
|
data/zwr.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zwr
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Zeljko
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-11-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: railties
|
@@ -51,7 +51,17 @@ files:
|
|
51
51
|
- lib/tasks/loc.rake
|
52
52
|
- lib/tasks/zwr.rake
|
53
53
|
- lib/zwr.rb
|
54
|
+
- lib/zwr/app_template.rb
|
54
55
|
- lib/zwr/railtie.rb
|
56
|
+
- lib/zwr/templates/angular-local-storage.js
|
57
|
+
- lib/zwr/templates/app.js.coffee
|
58
|
+
- lib/zwr/templates/application.css.scss
|
59
|
+
- lib/zwr/templates/application.html.haml
|
60
|
+
- lib/zwr/templates/application.js.coffee
|
61
|
+
- lib/zwr/templates/home.html.haml
|
62
|
+
- lib/zwr/templates/home_controller.js.coffee
|
63
|
+
- lib/zwr/templates/home_controller.rb
|
64
|
+
- lib/zwr/templates/index.html.haml
|
55
65
|
- lib/zwr/version.rb
|
56
66
|
- zwr.gemspec
|
57
67
|
homepage: http://rubygems.org/gems/zwr
|