zwr 0.1.2 → 0.1.3
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/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
|