conjoin 0.0.1 → 0.0.2
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/conjoin.gemspec +20 -0
- data/lib/conjoin.rb +27 -1
- data/lib/conjoin/active_record.rb +374 -0
- data/lib/conjoin/assets.rb +205 -0
- data/lib/conjoin/auth.rb +92 -0
- data/lib/conjoin/class_methods.rb +15 -0
- data/lib/conjoin/csrf.rb +26 -0
- data/lib/conjoin/cuba.rb +72 -0
- data/lib/conjoin/env_string.rb +17 -0
- data/lib/conjoin/form_builder.rb +334 -0
- data/lib/conjoin/i18n.rb +97 -0
- data/lib/conjoin/inputs/boolean.rb +8 -0
- data/lib/conjoin/inputs/checkbox.rb +14 -0
- data/lib/conjoin/inputs/date.rb +11 -0
- data/lib/conjoin/inputs/decimal.rb +9 -0
- data/lib/conjoin/inputs/file.rb +17 -0
- data/lib/conjoin/inputs/hidden.rb +10 -0
- data/lib/conjoin/inputs/integer.rb +9 -0
- data/lib/conjoin/inputs/password.rb +10 -0
- data/lib/conjoin/inputs/radio.rb +35 -0
- data/lib/conjoin/inputs/select.rb +67 -0
- data/lib/conjoin/inputs/state.rb +68 -0
- data/lib/conjoin/inputs/string.rb +9 -0
- data/lib/conjoin/inputs/time.rb +11 -0
- data/lib/conjoin/middleware.rb +40 -0
- data/lib/conjoin/recursive_ostruct.rb +117 -0
- data/lib/conjoin/tasks.rb +4 -0
- data/lib/conjoin/tasks/migrate.rake +70 -0
- data/lib/conjoin/tasks/migrate.rb +142 -0
- data/lib/conjoin/version.rb +1 -1
- data/lib/conjoin/widgets.rb +323 -0
- metadata +296 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4c454413ab5c7c375c051e3ced92551be1712d05
|
4
|
+
data.tar.gz: db8a9ed9f764770c4ff4d82b3d3c3a4593c9ba6c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e428284a01f0dd42f77beafb36e214f2e4e4cff749257cca9680ae72565a8fa063927255bd8452fe50f75cc44640ef544e3779131114aba55e5348bbfab843bd
|
7
|
+
data.tar.gz: 9578582ec7152be92f90d4d6a6e2d26c300332729ad24504c949030acc92e20ffe54ea40ceb016375e9fee00cf8e64f5bfa61d8e5c358903c903ba4d4551cbf3
|
data/conjoin.gemspec
CHANGED
@@ -18,6 +18,26 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
+
spec.add_dependency "cuba", "~> 3.1.1"
|
22
|
+
spec.add_dependency "cuba-sugar"
|
23
|
+
spec.add_dependency "rack_csrf", "~> 2.4.0"
|
24
|
+
spec.add_dependency "rack-protection", "~> 1.5.2"
|
25
|
+
spec.add_dependency "r18n-core"
|
26
|
+
spec.add_dependency 'highline', '~> 1.6.11'
|
27
|
+
spec.add_dependency "mab"
|
28
|
+
spec.add_dependency "tilt"
|
29
|
+
spec.add_dependency "sass"
|
30
|
+
spec.add_dependency "coffee-script"
|
31
|
+
spec.add_dependency "slim"
|
32
|
+
spec.add_dependency "mimemagic"
|
33
|
+
spec.add_dependency "rake"
|
34
|
+
spec.add_dependency "hashie"
|
35
|
+
spec.add_dependency "chronic"
|
36
|
+
spec.add_dependency "unicorn"
|
37
|
+
spec.add_dependency "clap"
|
38
|
+
spec.add_dependency "shield"
|
39
|
+
spec.add_dependency "better_errors"
|
40
|
+
|
21
41
|
spec.add_development_dependency "bundler", "~> 1.3"
|
22
42
|
spec.add_development_dependency "rake"
|
23
43
|
end
|
data/lib/conjoin.rb
CHANGED
@@ -1,5 +1,31 @@
|
|
1
1
|
require "conjoin/version"
|
2
|
+
require "conjoin/recursive_ostruct"
|
3
|
+
require "conjoin/middleware"
|
4
|
+
require "conjoin/env_string"
|
5
|
+
require "conjoin/class_methods"
|
6
|
+
require "conjoin/cuba"
|
2
7
|
|
3
8
|
module Conjoin
|
4
|
-
|
9
|
+
extend ClassMethods
|
10
|
+
|
11
|
+
if not env.mounted?
|
12
|
+
require 'active_record'
|
13
|
+
require 'action_mailer'
|
14
|
+
require 'slim'
|
15
|
+
require "tilt/coffee"
|
16
|
+
require "tilt/sass"
|
17
|
+
end
|
18
|
+
|
19
|
+
autoload :ActiveRecord, "conjoin/active_record"
|
20
|
+
autoload :Assets , "conjoin/assets"
|
21
|
+
autoload :Auth , "conjoin/auth"
|
22
|
+
autoload :Environment , "conjoin/environment"
|
23
|
+
autoload :FormBuilder , "conjoin/form_builder"
|
24
|
+
autoload :I18N , "conjoin/i18n"
|
25
|
+
autoload :Widgets , "conjoin/widgets"
|
26
|
+
autoload :Csrf , "conjoin/csrf"
|
27
|
+
# ActionMailer
|
28
|
+
# https://gist.github.com/acwright/1944639
|
29
|
+
# DelayedJob
|
30
|
+
# https://gist.github.com/robhurring/732327
|
5
31
|
end
|
@@ -0,0 +1,374 @@
|
|
1
|
+
module Conjoin
|
2
|
+
module ActiveRecord
|
3
|
+
include ::ActiveRecord
|
4
|
+
|
5
|
+
class << self
|
6
|
+
attr_accessor :app
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.setup app
|
10
|
+
require 'mini_record'
|
11
|
+
self.app = app
|
12
|
+
ActiveRecord::Base.send :include, Form
|
13
|
+
|
14
|
+
if not Conjoin.env.mounted?
|
15
|
+
require 'enumerize'
|
16
|
+
require 'protector'
|
17
|
+
Protector::Adapters::ActiveRecord.activate!
|
18
|
+
start_active_record
|
19
|
+
else
|
20
|
+
ActiveRecord::Base.default_timezone = Time.zone
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def self.start_active_record
|
27
|
+
if not Conjoin.env.test?
|
28
|
+
return if ActiveRecord::Base.connected?
|
29
|
+
else
|
30
|
+
if ActiveRecord::Base.connected?
|
31
|
+
ActiveRecord::Base.connection.disconnect!
|
32
|
+
end
|
33
|
+
end
|
34
|
+
# ActiveRecord::Base.logger = Logger.new(STDERR) unless @app.test?
|
35
|
+
|
36
|
+
db = URI.parse ENV['DATABASE_URL']
|
37
|
+
|
38
|
+
ActiveRecord::Base.establish_connection(
|
39
|
+
adapter: db.scheme == 'postgres' ? 'postgresql' : db.scheme,
|
40
|
+
encoding: 'utf8',
|
41
|
+
reconnect: true,
|
42
|
+
database: db.path[1..-1],
|
43
|
+
host: db.host,
|
44
|
+
port: db.port,
|
45
|
+
pool: ENV['DATABASE_POOL'] || 5,
|
46
|
+
username: db.user,
|
47
|
+
password: db.password,
|
48
|
+
wait_timeout: 2147483
|
49
|
+
)
|
50
|
+
end
|
51
|
+
|
52
|
+
module Form
|
53
|
+
extend ActiveSupport::Concern
|
54
|
+
|
55
|
+
attr_accessor :req_params
|
56
|
+
|
57
|
+
included do
|
58
|
+
define_model_callbacks :validates, :save_as
|
59
|
+
before_save :save_unrestricted_attributes
|
60
|
+
end
|
61
|
+
|
62
|
+
def is_form?
|
63
|
+
self.class.model_name.to_s[/Form$/]
|
64
|
+
end
|
65
|
+
|
66
|
+
def validate
|
67
|
+
end
|
68
|
+
|
69
|
+
def validates req_params
|
70
|
+
req_params = req_params.is_a?(OpenStruct) ? req_params.to_hash : HashIndifferent.new(req_params)
|
71
|
+
@req_params = req_params
|
72
|
+
|
73
|
+
run_callbacks :validates do
|
74
|
+
self.attributes = req_params
|
75
|
+
valid?
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def save_as current_user
|
80
|
+
run_callbacks :save_as do
|
81
|
+
add_creator_and_updater_for self, current_user, req_params
|
82
|
+
save!
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def save_unrestricted_attributes
|
87
|
+
if @unrestricted_attributes and @unrestricted_attributes.any?
|
88
|
+
@unrestricted_attributes.each do |field, value|
|
89
|
+
self.send "#{field}=", value
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def set_unrestricted_attribute field, value
|
95
|
+
@unrestricted_attributes ||= {}
|
96
|
+
@unrestricted_attributes[field] = value
|
97
|
+
end
|
98
|
+
|
99
|
+
def set_unrestricted_attributes *fields
|
100
|
+
fields.extract_options!.each do |field, value|
|
101
|
+
set_unrestricted_attribute field, value
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def add_creator_and_updater_for(model, current_user = nil, current_params)
|
106
|
+
# set the creator and updater
|
107
|
+
id = current_user.try(:id) || ENV["SYSTEM_USER_ID"]
|
108
|
+
|
109
|
+
# Save creator
|
110
|
+
if model.respond_to? :creator_id and model.new_record?
|
111
|
+
model.set_unrestricted_attribute 'creator_id', id
|
112
|
+
end
|
113
|
+
|
114
|
+
# Save updater
|
115
|
+
if model.respond_to? :updater_id
|
116
|
+
model.set_unrestricted_attribute 'updater_id', id
|
117
|
+
end
|
118
|
+
|
119
|
+
return unless current_params
|
120
|
+
# loop through associated records
|
121
|
+
current_params.each do |name, value|
|
122
|
+
if name.end_with?("_attributes")
|
123
|
+
associated_name = name.gsub(/_attributes$/, '')
|
124
|
+
associated_model = model.try associated_name
|
125
|
+
|
126
|
+
if associated_model.kind_of? ::ActiveRecord::Base
|
127
|
+
new_current_params = current_params[name]
|
128
|
+
if new_current_params.kind_of? Hash
|
129
|
+
add_creator_and_updater_for associated_model, current_user, new_current_params
|
130
|
+
end
|
131
|
+
elsif associated_model.kind_of? ActiveRecord::Associations::CollectionProxy
|
132
|
+
new_current_params = current_params[name]
|
133
|
+
associated_model.each_with_index do |current_model, i|
|
134
|
+
add_creator_and_updater_for current_model, current_user, new_current_params[i]
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def remove_error!(attribute, message = :invalid, options = {})
|
142
|
+
# -- Same code as private method ActiveModel::Errors.normalize_message(attribute, message, options).
|
143
|
+
callbacks_options = [:if, :unless, :on, :allow_nil, :allow_blank, :strict]
|
144
|
+
case message
|
145
|
+
when Symbol
|
146
|
+
message = self.errors.generate_message(attribute, message, options.except(*callbacks_options))
|
147
|
+
when Proc
|
148
|
+
message = message.call
|
149
|
+
else
|
150
|
+
message = message
|
151
|
+
end
|
152
|
+
# -- end block
|
153
|
+
|
154
|
+
# -- Delete message - based on ActiveModel::Errors.added?(attribute, message = :invalid, options = {}).
|
155
|
+
message = self.errors[attribute].delete(message) rescue nil
|
156
|
+
# -- Delete attribute from errors if message array is empty.
|
157
|
+
self.errors.messages.delete(attribute) if !self.errors.messages[attribute].present?
|
158
|
+
return message
|
159
|
+
end
|
160
|
+
|
161
|
+
def valid_except?(except={})
|
162
|
+
self.valid?
|
163
|
+
# -- Use this to call valid? for superclass if self.valid? is overridden.
|
164
|
+
# self.class.superclass.instance_method(:valid?).bind(self).call
|
165
|
+
except.each do |attribute, message|
|
166
|
+
if message.present?
|
167
|
+
remove_error!(attribute, message)
|
168
|
+
else
|
169
|
+
self.errors.delete(attribute)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
!self.errors.present?
|
173
|
+
end
|
174
|
+
|
175
|
+
def valid_only? *columns
|
176
|
+
self.valid?
|
177
|
+
self.errors.messages.each do |field, message|
|
178
|
+
self.errors.delete(field) unless columns.include? field
|
179
|
+
end
|
180
|
+
!self.errors.present?
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
# https://github.com/rails/rails/blob/4-1-stable/activerecord/lib/active_record/associations/association_scope.rb#L63
|
187
|
+
# module ActiveRecord
|
188
|
+
# module Associations
|
189
|
+
# class AssociationScope #:nodoc:
|
190
|
+
# def add_constraints(scope, owner, assoc_klass, refl, tracker)
|
191
|
+
# chain = refl.chain
|
192
|
+
# scope_chain = refl.scope_chain
|
193
|
+
#
|
194
|
+
# tables = construct_tables(chain, assoc_klass, refl, tracker)
|
195
|
+
#
|
196
|
+
# chain.each_with_index do |reflection, i|
|
197
|
+
# table, foreign_table = tables.shift, tables.first
|
198
|
+
#
|
199
|
+
# if reflection.source_macro == :belongs_to
|
200
|
+
# if reflection.options[:polymorphic]
|
201
|
+
# key = reflection.association_primary_key(assoc_klass)
|
202
|
+
# else
|
203
|
+
# key = reflection.association_primary_key
|
204
|
+
# end
|
205
|
+
#
|
206
|
+
# foreign_key = reflection.foreign_key
|
207
|
+
# else
|
208
|
+
# key = reflection.foreign_key
|
209
|
+
# foreign_key = reflection.active_record_primary_key
|
210
|
+
# end
|
211
|
+
#
|
212
|
+
# if reflection == chain.last
|
213
|
+
# bind_val = bind scope, table.table_name, key.to_s, owner[foreign_key], tracker
|
214
|
+
# scope = scope.where(table[key].eq(bind_val))
|
215
|
+
#
|
216
|
+
# if reflection.type
|
217
|
+
# #############################################
|
218
|
+
# #############################################
|
219
|
+
# #############################################
|
220
|
+
# #############################################
|
221
|
+
# #############################################
|
222
|
+
# #############################################
|
223
|
+
# # .gsub(/\w+::/, '')
|
224
|
+
# # is a fix for polymorphic associations like
|
225
|
+
# # VendorWizard::VendorGroup so it can work
|
226
|
+
# # with the _type VendorGroup instead of
|
227
|
+
# # VendorWizard::VendorGroup
|
228
|
+
# #############################################
|
229
|
+
# #############################################
|
230
|
+
# #############################################
|
231
|
+
# #############################################
|
232
|
+
# #############################################
|
233
|
+
# value = owner.class.base_class.name.gsub(/\w+::/, '')
|
234
|
+
# #############################################
|
235
|
+
# bind_val = bind scope, table.table_name, reflection.type.to_s, value, tracker
|
236
|
+
# scope = scope.where(table[reflection.type].eq(bind_val))
|
237
|
+
# end
|
238
|
+
# else
|
239
|
+
# constraint = table[key].eq(foreign_table[foreign_key])
|
240
|
+
#
|
241
|
+
# if reflection.type
|
242
|
+
# value = chain[i + 1].klass.base_class.name
|
243
|
+
# bind_val = bind scope, table.table_name, reflection.type.to_s, value, tracker
|
244
|
+
# scope = scope.where(table[reflection.type].eq(bind_val))
|
245
|
+
# end
|
246
|
+
#
|
247
|
+
# scope = scope.joins(join(foreign_table, constraint))
|
248
|
+
# end
|
249
|
+
#
|
250
|
+
# is_first_chain = i == 0
|
251
|
+
# klass = is_first_chain ? assoc_klass : reflection.klass
|
252
|
+
#
|
253
|
+
# # Exclude the scope of the association itself, because that
|
254
|
+
# # was already merged in the #scope method.
|
255
|
+
# scope_chain[i].each do |scope_chain_item|
|
256
|
+
# item = eval_scope(klass, scope_chain_item, owner)
|
257
|
+
#
|
258
|
+
# if scope_chain_item == refl.scope
|
259
|
+
# scope.merge! item.except(:where, :includes, :bind)
|
260
|
+
# end
|
261
|
+
#
|
262
|
+
# if is_first_chain
|
263
|
+
# scope.includes! item.includes_values
|
264
|
+
# end
|
265
|
+
#
|
266
|
+
# scope.where_values += item.where_values
|
267
|
+
# scope.order_values |= item.order_values
|
268
|
+
# end
|
269
|
+
# end
|
270
|
+
#
|
271
|
+
# scope
|
272
|
+
# end
|
273
|
+
# end
|
274
|
+
# end
|
275
|
+
# end
|
276
|
+
# ACTIVERECORD 4.0.3
|
277
|
+
module ActiveRecord
|
278
|
+
module Associations
|
279
|
+
class AssociationScope #:nodoc:
|
280
|
+
def add_constraints(scope)
|
281
|
+
tables = construct_tables
|
282
|
+
|
283
|
+
chain.each_with_index do |reflection, i|
|
284
|
+
table, foreign_table = tables.shift, tables.first
|
285
|
+
|
286
|
+
if reflection.source_macro == :has_and_belongs_to_many
|
287
|
+
join_table = tables.shift
|
288
|
+
|
289
|
+
scope = scope.joins(join(
|
290
|
+
join_table,
|
291
|
+
table[reflection.association_primary_key].
|
292
|
+
eq(join_table[reflection.association_foreign_key])
|
293
|
+
))
|
294
|
+
|
295
|
+
table, foreign_table = join_table, tables.first
|
296
|
+
end
|
297
|
+
|
298
|
+
if reflection.source_macro == :belongs_to
|
299
|
+
if reflection.options[:polymorphic]
|
300
|
+
key = reflection.association_primary_key(self.klass)
|
301
|
+
else
|
302
|
+
key = reflection.association_primary_key
|
303
|
+
end
|
304
|
+
|
305
|
+
foreign_key = reflection.foreign_key
|
306
|
+
else
|
307
|
+
key = reflection.foreign_key
|
308
|
+
foreign_key = reflection.active_record_primary_key
|
309
|
+
end
|
310
|
+
|
311
|
+
if reflection == chain.last
|
312
|
+
bind_val = bind scope, table.table_name, key.to_s, owner[foreign_key]
|
313
|
+
scope = scope.where(table[key].eq(bind_val))
|
314
|
+
|
315
|
+
if reflection.type
|
316
|
+
#############################################
|
317
|
+
#############################################
|
318
|
+
#############################################
|
319
|
+
#############################################
|
320
|
+
#############################################
|
321
|
+
#############################################
|
322
|
+
# .gsub(/\w+::/, '')
|
323
|
+
# is a fix for polymorphic associations like
|
324
|
+
# VendorWizard::VendorGroup so it can work
|
325
|
+
# with the _type VendorGroup instead of
|
326
|
+
# VendorWizard::VendorGroup
|
327
|
+
#############################################
|
328
|
+
#############################################
|
329
|
+
#############################################
|
330
|
+
#############################################
|
331
|
+
#############################################
|
332
|
+
value = owner.class.base_class.name.gsub(/\w+::/, '')
|
333
|
+
#############################################
|
334
|
+
bind_val = bind scope, table.table_name, reflection.type.to_s, value
|
335
|
+
scope = scope.where(table[reflection.type].eq(bind_val))
|
336
|
+
end
|
337
|
+
|
338
|
+
else
|
339
|
+
constraint = table[key].eq(foreign_table[foreign_key])
|
340
|
+
|
341
|
+
if reflection.type
|
342
|
+
type = chain[i + 1].klass.base_class.name
|
343
|
+
constraint = constraint.and(table[reflection.type].eq(type))
|
344
|
+
end
|
345
|
+
|
346
|
+
scope = scope.joins(join(foreign_table, constraint))
|
347
|
+
end
|
348
|
+
|
349
|
+
is_first_chain = i == 0
|
350
|
+
klass = is_first_chain ? self.klass : reflection.klass
|
351
|
+
|
352
|
+
# Exclude the scope of the association itself, because that
|
353
|
+
# was already merged in the #scope method.
|
354
|
+
scope_chain[i].each do |scope_chain_item|
|
355
|
+
item = eval_scope(klass, scope_chain_item)
|
356
|
+
|
357
|
+
if scope_chain_item == self.reflection.scope
|
358
|
+
scope.merge! item.except(:where, :includes)
|
359
|
+
end
|
360
|
+
|
361
|
+
if is_first_chain
|
362
|
+
scope.includes! item.includes_values
|
363
|
+
end
|
364
|
+
|
365
|
+
scope.where_values += item.where_values
|
366
|
+
scope.order_values |= item.order_values
|
367
|
+
end
|
368
|
+
end
|
369
|
+
|
370
|
+
scope
|
371
|
+
end
|
372
|
+
end
|
373
|
+
end
|
374
|
+
end
|
@@ -0,0 +1,205 @@
|
|
1
|
+
module Conjoin
|
2
|
+
module Assets
|
3
|
+
class << self
|
4
|
+
attr_accessor :app
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.setup app
|
8
|
+
self.app = app
|
9
|
+
|
10
|
+
require 'mimemagic'
|
11
|
+
require 'base64'
|
12
|
+
require 'slim'
|
13
|
+
require 'sass'
|
14
|
+
require 'ostruct'
|
15
|
+
|
16
|
+
# if ENV['RACK_ENV'] != 'production'
|
17
|
+
# require 'rugged'
|
18
|
+
# end
|
19
|
+
|
20
|
+
Slim::Engine.set_default_options \
|
21
|
+
disable_escape: true,
|
22
|
+
use_html_safe: true,
|
23
|
+
disable_capture: false,
|
24
|
+
pretty: (Conjoin.env.production? or Conjoin.env.staging?) ? false : true
|
25
|
+
|
26
|
+
app.settings[:assets] ||= OpenStruct.new({
|
27
|
+
settings: {},
|
28
|
+
stylesheet: [],
|
29
|
+
images: [],
|
30
|
+
javascript_head: [],
|
31
|
+
javascript: []
|
32
|
+
})
|
33
|
+
end
|
34
|
+
|
35
|
+
%w(stylesheet javascript javascript_head).each do |type|
|
36
|
+
define_method "#{type}_assets" do
|
37
|
+
plugin[:"#{type}"]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def asset_path file
|
42
|
+
case file[/(\.[^.]+)$/]
|
43
|
+
when '.css', '.js'
|
44
|
+
path = "#{plugin.settings[:path] || '/'}#{cache_string}assets/#{file}"
|
45
|
+
else
|
46
|
+
path = "#{plugin.settings[:path] || '/'}#{cache_string}assets/images/#{file}"
|
47
|
+
end
|
48
|
+
"http#{req.env['SERVER_PORT'] == '443' ? 's' : ''}://#{req.env['HTTP_HOST']}#{path}"
|
49
|
+
end
|
50
|
+
|
51
|
+
def image_tag file, options = {}
|
52
|
+
options[:src] = asset_path(file)
|
53
|
+
mab do
|
54
|
+
img options
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def fa_icon icon, options = {}
|
59
|
+
options[:class] ||= ''
|
60
|
+
options[:class] += " fa fa-#{icon}"
|
61
|
+
|
62
|
+
mab do
|
63
|
+
i options
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def accepted_assets
|
68
|
+
"(.*)\.(js|css|eot|svg|ttf|woff|png|gif|jpg|jpeg)$"
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def cache_string
|
74
|
+
if Conjoin.env.mounted?
|
75
|
+
# @cache_string ||= (File.read "#{Assets.app.root}/sha") + "/"
|
76
|
+
"/"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def plugin
|
81
|
+
Assets.app.settings[:assets]
|
82
|
+
end
|
83
|
+
|
84
|
+
def links_for type, opts = {}
|
85
|
+
method = :link
|
86
|
+
path = :href
|
87
|
+
extention = :css
|
88
|
+
|
89
|
+
options = {
|
90
|
+
'data-turbolinks-track' => true
|
91
|
+
}
|
92
|
+
|
93
|
+
case type
|
94
|
+
when :stylesheet_assets
|
95
|
+
options.merge!({
|
96
|
+
rel: 'stylesheet',
|
97
|
+
type: 'text/css',
|
98
|
+
media: 'all'
|
99
|
+
})
|
100
|
+
when :javascript_assets, :javascript_head_assets
|
101
|
+
method = :script
|
102
|
+
path = :src
|
103
|
+
extention = :js
|
104
|
+
else
|
105
|
+
raise 'Please choose a type: stylesheet_assets, javascript_head_assets or javascript_assets'
|
106
|
+
end
|
107
|
+
|
108
|
+
# merge in the user options allowing them to override
|
109
|
+
options.merge! opts
|
110
|
+
|
111
|
+
app = self
|
112
|
+
|
113
|
+
mab do
|
114
|
+
if Conjoin.env.production? or Conjoin.env.staging?
|
115
|
+
options[path] = asset_path "#{type}.#{extention}"
|
116
|
+
send(method, options)
|
117
|
+
else
|
118
|
+
app.send(type).each do |asset|
|
119
|
+
options[path] = asset_path asset.gsub(/\.coffee/, '.js').gsub(/\.scss/, '.css')
|
120
|
+
send(method, options)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
module ClassMethods
|
127
|
+
%w(stylesheet javascript javascript_head).each do |type|
|
128
|
+
define_method "#{type}_assets" do |files|
|
129
|
+
files.each do |path|
|
130
|
+
settings[:assets][:"#{type}"] << path
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def all_assets
|
136
|
+
settings[:assets]
|
137
|
+
end
|
138
|
+
|
139
|
+
def assets_settings as
|
140
|
+
settings[:assets].settings.merge! as
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
class Helpers
|
145
|
+
def asset_path path
|
146
|
+
app.root + '/app/assets/' + path
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
class Routes < Struct.new(:settings)
|
151
|
+
def app
|
152
|
+
App.settings = settings
|
153
|
+
App.root = Conjoin::Assets.app.root
|
154
|
+
App.plugin Conjoin::Cuba::Render
|
155
|
+
App.plugin Assets
|
156
|
+
App
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
# erb = Tilt::ERBTemplate.new "#{Assets.app.root}/app/assets/#{file}.scss"
|
161
|
+
# scss = Tilt::ScssTemplate.new{ erb.render(Helpers.new) }
|
162
|
+
|
163
|
+
# scss.render
|
164
|
+
class App < Conjoin::Cuba
|
165
|
+
def add_asset file, ext
|
166
|
+
dir = ''
|
167
|
+
new_ext = false
|
168
|
+
|
169
|
+
case ext
|
170
|
+
when 'css'
|
171
|
+
dir = !file[/^bower/] ? 'stylesheets/' : ''
|
172
|
+
new_ext = 'scss' if stylesheet_assets.include? file + '.scss'
|
173
|
+
when 'js'
|
174
|
+
dir = !file[/^bower/] ? 'javascripts/' : ''
|
175
|
+
new_ext = 'coffee' if javascript_assets.include? file + '.coffee' \
|
176
|
+
or javascript_head_assets.include? file + '.coffee'
|
177
|
+
end
|
178
|
+
|
179
|
+
if new_ext
|
180
|
+
render "#{Assets.app.root}/app/assets/#{dir}#{file}.#{new_ext}"
|
181
|
+
else
|
182
|
+
File.read "#{Assets.app.root}/app/assets/#{dir}#{file}.#{ext}"
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
define do
|
187
|
+
on get, accepted_assets do |file, ext|
|
188
|
+
res.headers["Content-Type"] = "#{MimeMagic.by_extension(ext).to_s}; charset=utf-8"
|
189
|
+
|
190
|
+
if %w(stylesheet_assets javascript_head_assets javascript_assets).include? file
|
191
|
+
content = ''
|
192
|
+
|
193
|
+
send(file).each do |asset|
|
194
|
+
content += add_asset asset.sub(/(\.)(?!.*\.).+/, ""), ext
|
195
|
+
end
|
196
|
+
|
197
|
+
res.write content
|
198
|
+
else
|
199
|
+
res.write add_asset file, ext
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|