fl 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +44 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +173 -0
- data/README.md +30 -0
- data/Rakefile +2 -0
- data/app/admin/options.rb +46 -0
- data/app/admin/pages.rb +55 -0
- data/app/admin/users.rb +34 -0
- data/app/assets/javascripts/active_admin.coffee.erb +20 -0
- data/app/assets/javascripts/application.coffee.erb +40 -0
- data/app/assets/javascripts/ckeditor/basepath.coffee.erb +21 -0
- data/app/assets/javascripts/ckeditor/config.coffee.erb +146 -0
- data/app/assets/javascripts/ckeditor/plugins/autogrow/plugin.js +232 -0
- data/app/assets/javascripts/ckeditor/plugins/autogrow/samples/autogrow.html +102 -0
- data/app/assets/javascripts/ckeditor/plugins/stylesheetparser/plugin.js +158 -0
- data/app/assets/javascripts/ckeditor/plugins/stylesheetparser/samples/assets/sample.css +70 -0
- data/app/assets/javascripts/ckeditor/plugins/stylesheetparser/samples/stylesheetparser.html +85 -0
- data/app/assets/javascripts/ckeditor/skins/minimalist/dialog.css +5 -0
- data/app/assets/javascripts/ckeditor/skins/minimalist/dialog_ie.css +5 -0
- data/app/assets/javascripts/ckeditor/skins/minimalist/dialog_ie7.css +5 -0
- data/app/assets/javascripts/ckeditor/skins/minimalist/dialog_ie8.css +5 -0
- data/app/assets/javascripts/ckeditor/skins/minimalist/dialog_iequirks.css +5 -0
- data/app/assets/javascripts/ckeditor/skins/minimalist/editor.css +5 -0
- data/app/assets/javascripts/ckeditor/skins/minimalist/editor_gecko.css +5 -0
- data/app/assets/javascripts/ckeditor/skins/minimalist/editor_ie.css +5 -0
- data/app/assets/javascripts/ckeditor/skins/minimalist/editor_ie7.css +5 -0
- data/app/assets/javascripts/ckeditor/skins/minimalist/editor_ie8.css +5 -0
- data/app/assets/javascripts/ckeditor/skins/minimalist/editor_iequirks.css +5 -0
- data/app/assets/javascripts/ckeditor/skins/minimalist/icons.png +0 -0
- data/app/assets/javascripts/ckeditor/skins/minimalist/icons_hidpi.png +0 -0
- data/app/assets/javascripts/ckeditor/skins/minimalist/images/arrow.png +0 -0
- data/app/assets/javascripts/ckeditor/skins/minimalist/images/close.png +0 -0
- data/app/assets/javascripts/ckeditor/skins/minimalist/images/hidpi/close.png +0 -0
- data/app/assets/javascripts/ckeditor/skins/minimalist/images/hidpi/lock-open.png +0 -0
- data/app/assets/javascripts/ckeditor/skins/minimalist/images/hidpi/lock.png +0 -0
- data/app/assets/javascripts/ckeditor/skins/minimalist/images/hidpi/refresh.png +0 -0
- data/app/assets/javascripts/ckeditor/skins/minimalist/images/lock-open.png +0 -0
- data/app/assets/javascripts/ckeditor/skins/minimalist/images/lock.png +0 -0
- data/app/assets/javascripts/ckeditor/skins/minimalist/images/refresh.png +0 -0
- data/app/assets/javascripts/ckeditor/skins/minimalist/readme.md +7 -0
- data/app/assets/javascripts/ckeditor/skins/minimalist/skin.js +10 -0
- data/app/assets/javascripts/ckeditor/skins/moonocolor/dialog.css +5 -0
- data/app/assets/javascripts/ckeditor/skins/moonocolor/dialog_ie.css +5 -0
- data/app/assets/javascripts/ckeditor/skins/moonocolor/dialog_ie7.css +5 -0
- data/app/assets/javascripts/ckeditor/skins/moonocolor/dialog_ie8.css +5 -0
- data/app/assets/javascripts/ckeditor/skins/moonocolor/dialog_iequirks.css +5 -0
- data/app/assets/javascripts/ckeditor/skins/moonocolor/editor.css +5 -0
- data/app/assets/javascripts/ckeditor/skins/moonocolor/editor_gecko.css +5 -0
- data/app/assets/javascripts/ckeditor/skins/moonocolor/editor_ie.css +5 -0
- data/app/assets/javascripts/ckeditor/skins/moonocolor/editor_ie7.css +5 -0
- data/app/assets/javascripts/ckeditor/skins/moonocolor/editor_ie8.css +5 -0
- data/app/assets/javascripts/ckeditor/skins/moonocolor/editor_iequirks.css +5 -0
- data/app/assets/javascripts/ckeditor/skins/moonocolor/icons.png +0 -0
- data/app/assets/javascripts/ckeditor/skins/moonocolor/icons_hidpi.png +0 -0
- data/app/assets/javascripts/ckeditor/skins/moonocolor/images/arrow.png +0 -0
- data/app/assets/javascripts/ckeditor/skins/moonocolor/images/close.png +0 -0
- data/app/assets/javascripts/ckeditor/skins/moonocolor/images/hidpi/close.png +0 -0
- data/app/assets/javascripts/ckeditor/skins/moonocolor/images/hidpi/lock-open.png +0 -0
- data/app/assets/javascripts/ckeditor/skins/moonocolor/images/hidpi/lock.png +0 -0
- data/app/assets/javascripts/ckeditor/skins/moonocolor/images/hidpi/refresh.png +0 -0
- data/app/assets/javascripts/ckeditor/skins/moonocolor/images/lock-open.png +0 -0
- data/app/assets/javascripts/ckeditor/skins/moonocolor/images/lock.png +0 -0
- data/app/assets/javascripts/ckeditor/skins/moonocolor/images/refresh.png +0 -0
- data/app/assets/javascripts/ckeditor/skins/moonocolor/images/spinner.gif +0 -0
- data/app/assets/javascripts/ckeditor/skins/moonocolor/readme.md +51 -0
- data/app/assets/javascripts/ckeditor/skins/moonocolor/skin.js +10 -0
- data/app/assets/javascripts/components/confirm.coffee +51 -0
- data/app/assets/javascripts/components/modals.coffee +29 -0
- data/app/assets/stylesheets/_defaults.yml +106 -0
- data/app/assets/stylesheets/_functions.sass.erb +75 -0
- data/app/assets/stylesheets/active_admin.sass +117 -0
- data/app/assets/stylesheets/application.sass.erb +46 -0
- data/app/assets/stylesheets/styles/reset.sass +139 -0
- data/app/assets/stylesheets/styles/structure.sass +69 -0
- data/app/assets/stylesheets/styles/ui/flash.sass +128 -0
- data/app/assets/stylesheets/styles/ui/fonts.sass +32 -0
- data/app/assets/stylesheets/styles/ui/modals.sass +61 -0
- data/app/assets/stylesheets/styles/ui/tooltips.sass +139 -0
- data/app/controllers/application_controller.rb +87 -0
- data/app/helpers/fl/application_helper.rb +53 -0
- data/app/helpers/fl/asset_helper.rb +50 -0
- data/app/helpers/fl/liquid_helper.rb +29 -0
- data/app/helpers/fl/meta_helper.rb +118 -0
- data/app/lib/active_record/concerns/base.rb +55 -0
- data/app/lib/active_record/concerns/seeds.rb +78 -0
- data/app/liquid/filters/meta_filter.rb +6 -0
- data/app/liquid/tags/google_analytics_tag.rb +32 -0
- data/app/liquid/tags/icon_tag.rb +37 -0
- data/app/liquid/tags/meta_tag.rb +120 -0
- data/app/mailers/application_mailer.rb +28 -0
- data/app/models/application_record.rb +3 -0
- data/app/models/asset.rb +95 -0
- data/app/models/association.rb +21 -0
- data/app/models/meta.rb +27 -0
- data/app/models/node.rb +59 -0
- data/app/models/profile.rb +49 -0
- data/app/models/user.rb +49 -0
- data/app/service/flash.rb +8 -0
- data/app/views/layouts/_admin.haml +6 -0
- data/app/views/layouts/_application.haml +17 -0
- data/app/views/layouts/base.haml +26 -0
- data/app/views/mailers/layouts/mailer.haml +8 -0
- data/app/views/mailers/layouts/mailer.text.erb +1 -0
- data/app/views/mailers/new_user.erb +4 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/config/initializers/active_admin.rb +266 -0
- data/config/initializers/ckeditor.rb +63 -0
- data/config/initializers/devise.rb +279 -0
- data/config/initializers/friendly_id.rb +92 -0
- data/config/initializers/inflections.rb +20 -0
- data/config/initializers/liquid.rb +87 -0
- data/config/initializers/sass.rb +45 -0
- data/config/locales/devise.en.yml +62 -0
- data/config/locales/en.yml +13 -0
- data/config/puma.rb +59 -0
- data/config/routes.rb +56 -0
- data/db/migrate/20160616060637_create_nodes.rb +26 -0
- data/db/migrate/20160707080248_create_users.rb +52 -0
- data/db/migrate/20160707094704_create_slugs.rb +33 -0
- data/db/migrate/20160710095916_create_associations.rb +20 -0
- data/db/migrate/20160713061948_create_profiles.rb +27 -0
- data/db/migrate/20161115101221_create_assets.rb +25 -0
- data/db/migrate/20170725060408_create_active_admin_comments.rb +22 -0
- data/db/seeds.rb +81 -0
- data/fl.gemspec +73 -0
- data/lib/fl.rb +28 -0
- data/lib/fl/constants.rb +52 -0
- data/lib/fl/engine.rb +160 -0
- data/lib/fl/hash.rb +34 -0
- data/lib/generators/fl/sass_vars_generator.rb +16 -0
- data/lib/generators/fl/templates/sass.yml +56 -0
- data/lib/tasks/ckeditor.rake +37 -0
- data/lib/tasks/favicon.rake +37 -0
- data/readme/fl.jpg +0 -0
- metadata +416 -0
@@ -0,0 +1,55 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module Concerns
|
3
|
+
module Base
|
4
|
+
|
5
|
+
## This is used to provide base functionality to migrations
|
6
|
+
#########################################
|
7
|
+
#########################################
|
8
|
+
|
9
|
+
# Adapter
|
10
|
+
def adapter
|
11
|
+
ENV["DATABASE_ADAPTER"]
|
12
|
+
end
|
13
|
+
|
14
|
+
# Down
|
15
|
+
def down
|
16
|
+
drop_table table, if_exists: true
|
17
|
+
end
|
18
|
+
|
19
|
+
# UUID
|
20
|
+
def uuid(key=:id)
|
21
|
+
adapter == "sqlite3" ? {} : { key => :uuid }
|
22
|
+
end
|
23
|
+
|
24
|
+
# Table
|
25
|
+
def table
|
26
|
+
self.class.name.gsub!("Create", "").underscore
|
27
|
+
end
|
28
|
+
|
29
|
+
#########################################
|
30
|
+
#########################################
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
# http://stackoverflow.com/a/5665974/1143732
|
35
|
+
# Set "plugin" for UUID BEFORE using it
|
36
|
+
def setup_uuid
|
37
|
+
case adapter
|
38
|
+
when "mysql2"
|
39
|
+
execute("DROP TRIGGER IF EXISTS before_insert_#{table};") #http://stackoverflow.com/a/5945220/1143732
|
40
|
+
execute("CREATE TRIGGER before_insert_#{table} BEFORE INSERT ON associations FOR EACH ROW SET new.uuid = uuid();")
|
41
|
+
when "sqlite3"
|
42
|
+
# Nothing to do
|
43
|
+
when "postgresql"
|
44
|
+
enable_extension 'uuid-ossp' # => http://theworkaround.com/2015/06/12/using-uuids-in-rails.html#postgresql
|
45
|
+
else
|
46
|
+
raise NotImplementedError, "Unknown adapter type '#{adapter}'"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
#########################################
|
51
|
+
#########################################
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module Concerns
|
3
|
+
module Seeds
|
4
|
+
|
5
|
+
## This is used to provide base functionality during seeding
|
6
|
+
#########################################
|
7
|
+
#########################################
|
8
|
+
|
9
|
+
# => first_or_initialize
|
10
|
+
# => https://snippets.aktagon.com/snippets/620-rails-find-or-initialize-and-find-or-create-methods-are-deprecated
|
11
|
+
def create model, attrs, vals=nil
|
12
|
+
|
13
|
+
# => Model
|
14
|
+
# => http://stackoverflow.com/a/32869926/1143732
|
15
|
+
model = model.to_s.titleize.gsub(" ","::")
|
16
|
+
model = model.constantize rescue nil
|
17
|
+
|
18
|
+
# => Model exists
|
19
|
+
unless model.nil?
|
20
|
+
|
21
|
+
# => Setup
|
22
|
+
payload = model.where(attrs).first_or_initialize
|
23
|
+
is_new = payload.new_record?
|
24
|
+
|
25
|
+
# => Action
|
26
|
+
payload.update vals || attrs
|
27
|
+
|
28
|
+
# => Output
|
29
|
+
if payload.valid?
|
30
|
+
puts "#{payload.class.name} #{is_new ? 'Created' : 'Updated'} - #{payload.ref}" + (payload.has_attribute?(:val) ? " → #{payload.val}" : nil)
|
31
|
+
else
|
32
|
+
puts "#{payload.class.name} Error - #{payload.errors.full_messages}"
|
33
|
+
end
|
34
|
+
|
35
|
+
else
|
36
|
+
puts "Model Not Initialized"
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
########################################
|
42
|
+
########################################
|
43
|
+
|
44
|
+
# => Iterate over hash or array
|
45
|
+
# => http://stackoverflow.com/a/16413593/1143732
|
46
|
+
def iterate model, h, ref=nil
|
47
|
+
return h unless h.is_a?(Hash) || h.is_a?(Array) # => Return if not hash
|
48
|
+
|
49
|
+
# => Linebreak
|
50
|
+
puts "\n"
|
51
|
+
|
52
|
+
# => Proceed if hash/array
|
53
|
+
h.each do |k,v|
|
54
|
+
|
55
|
+
# If v is nil, an array is being iterated and the value is k.
|
56
|
+
# If v is not nil, a hash is being iterated and the value is v.
|
57
|
+
value = v || k
|
58
|
+
|
59
|
+
# Ref
|
60
|
+
# If exists, need to prepend ref_
|
61
|
+
reference = v ? "#{ref}#{'_' if ref}#{k}" : ref
|
62
|
+
|
63
|
+
# => Iterate or continue
|
64
|
+
if value.is_a?(Hash) || value.is_a?(Array)
|
65
|
+
iterate model, value, k
|
66
|
+
else
|
67
|
+
create model, { ref: reference, val: value }, { seed: true }
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
#########################################
|
74
|
+
#########################################
|
75
|
+
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# Returns a Google Analytics tag.
|
2
|
+
#
|
3
|
+
# Usage:
|
4
|
+
#
|
5
|
+
# {% ga 'UA-XXXXX-X' %}
|
6
|
+
|
7
|
+
class Tags::GoogleAnalyticsTag < ::Liquid::Tag
|
8
|
+
Syntax = /(#{::Liquid::QuotedFragment}+)?/
|
9
|
+
|
10
|
+
def initialize(tag_name, markup, tokens)
|
11
|
+
if markup =~ Syntax
|
12
|
+
@account_id = $1.gsub('\'', '')
|
13
|
+
else
|
14
|
+
raise ::Liquid::SyntaxError.new("Syntax Error in 'Google Analytics Tag' - Valid syntax: {% ga <account_id> %}")
|
15
|
+
end
|
16
|
+
|
17
|
+
super
|
18
|
+
end
|
19
|
+
|
20
|
+
def render(context)
|
21
|
+
%{
|
22
|
+
<script>
|
23
|
+
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
24
|
+
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
25
|
+
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
26
|
+
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
|
27
|
+
ga('create', '#{@account_id}', 'auto');
|
28
|
+
ga('send', 'pageview');
|
29
|
+
</script>
|
30
|
+
}
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
class Tags::IconTag < Liquid::Tag
|
2
|
+
Syntax = /(#{::Liquid::QuotedFragment}+)?/
|
3
|
+
|
4
|
+
#################################
|
5
|
+
|
6
|
+
## Init ##
|
7
|
+
def initialize tag_name, markup, tokens
|
8
|
+
if markup =~ Syntax
|
9
|
+
@icon = $1.gsub('\'', '')
|
10
|
+
else
|
11
|
+
raise ::Liquid::SyntaxError.new("Syntax Error in 'Icon Tag' - Valid syntax: {% i <args> %}")
|
12
|
+
end
|
13
|
+
|
14
|
+
super
|
15
|
+
end
|
16
|
+
|
17
|
+
#################################
|
18
|
+
|
19
|
+
## Helpers ##
|
20
|
+
def helpers
|
21
|
+
@helpers ||= ApplicationController.helpers
|
22
|
+
end
|
23
|
+
|
24
|
+
#################################
|
25
|
+
|
26
|
+
## Output ##
|
27
|
+
def render context
|
28
|
+
gem_name = 'font-awesome-rails'
|
29
|
+
gdep = Gem::Dependency.new gem_name
|
30
|
+
|
31
|
+
# Invoke
|
32
|
+
helpers.send (gdep.matching_specs.max_by(&:version) ? :fa_icon : :ion_icon), @icon
|
33
|
+
end
|
34
|
+
|
35
|
+
#################################
|
36
|
+
|
37
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
###################################################
|
2
|
+
###################################################
|
3
|
+
## ___ ___ _ ##
|
4
|
+
## | \/ | | | ##
|
5
|
+
## | . . | ___| |_ __ _ ##
|
6
|
+
## | |\/| |/ _ \ __/ _` | ##
|
7
|
+
## | | | | __/ || (_| | ##
|
8
|
+
## \_| |_/\___|\__\__,_| ##
|
9
|
+
###################################################
|
10
|
+
###################################################
|
11
|
+
|
12
|
+
class Tags::MetaTag < Liquid::Tag
|
13
|
+
Syntax = /(#{::Liquid::QuotedFragment}+)?/
|
14
|
+
|
15
|
+
########################################
|
16
|
+
########################################
|
17
|
+
|
18
|
+
## Parse Arguments ##
|
19
|
+
## Define args here and pass to renderer as @variables ##
|
20
|
+
def initialize tag_name, markup, tokens
|
21
|
+
@tag = tag_name
|
22
|
+
@markup = markup.split(", ")
|
23
|
+
super
|
24
|
+
end
|
25
|
+
|
26
|
+
## Output
|
27
|
+
def render context
|
28
|
+
meta @tag, @markup
|
29
|
+
end
|
30
|
+
|
31
|
+
########################################
|
32
|
+
########################################
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
# Helpers
|
37
|
+
def helpers
|
38
|
+
@helpers ||= ApplicationController.helpers
|
39
|
+
end
|
40
|
+
|
41
|
+
# Meta
|
42
|
+
# => Main meta method
|
43
|
+
# => tag is for self-enclosed tags (<meta> etc)
|
44
|
+
def meta type, *args
|
45
|
+
options = args.join(', ')
|
46
|
+
|
47
|
+
# Return Values
|
48
|
+
case type.to_sym
|
49
|
+
when :js, :javascript, :javascripts, :script, :scripts
|
50
|
+
helpers.javascript_include_tag *args
|
51
|
+
when :css, :stylesheet, :stylesheets
|
52
|
+
helpers.stylesheet_link_tag *args
|
53
|
+
when :title
|
54
|
+
helpers.content_tag :title, options
|
55
|
+
when :favicon
|
56
|
+
helpers.favicon_link_tag "icons/favicon.ico"
|
57
|
+
when :csrf
|
58
|
+
#helpers.csrf_meta_tags
|
59
|
+
else
|
60
|
+
helpers.tag :meta, name: type, content: options
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
########################################
|
65
|
+
########################################
|
66
|
+
|
67
|
+
# Robots
|
68
|
+
# => http://noarchive.net/meta/
|
69
|
+
def robots *args
|
70
|
+
|
71
|
+
# => Inputs
|
72
|
+
# => No input = all
|
73
|
+
# => If true and false are present, only true is passed
|
74
|
+
options = args.extract_options! # => Don't need defaults
|
75
|
+
|
76
|
+
# => Results
|
77
|
+
results = Array.new(2)
|
78
|
+
# No options / args = "index, follow"
|
79
|
+
# First check for one of the following :index, index: true, noindex: false == "index"
|
80
|
+
# Second check for one of the following :follow, follow: true, nofollow: false == "follow"
|
81
|
+
# Third check for one of the following :noindex, noindex: true == "noindex"
|
82
|
+
# Forth check for one of the following :nofollow, nofollow: true == "nofollow"
|
83
|
+
results[0] = "index" if options[:index] || args.include?(:index) || options[:noindex] == false || (options.empty? && args.empty?)
|
84
|
+
results[1] = "follow" if options[:follow] || args.include?(:follow) || options[:nofollow] == false || (options.empty? && args.empty?)
|
85
|
+
results[0] = "noindex" if (options[:noindex] || args.include?(:noindex) || options[:index] == false) && (!args.include?(:index))
|
86
|
+
results[1] = "nofollow" if (options[:nofollow] || args.include?(:nofollow) || options[:follow] == false) && (!args.include?(:follow))
|
87
|
+
|
88
|
+
results.delete_at(0) if (options[:index] == false) && (options[:index] != true || !args.include?(:index))
|
89
|
+
results.delete_at(1) if (options[:follow] == false) && (options[:follow] != true || !args.include?(:follow))
|
90
|
+
|
91
|
+
# => Return
|
92
|
+
# => Options only accepts actual content (array)
|
93
|
+
meta :robots, results.compact.join(",") if results.any?
|
94
|
+
end
|
95
|
+
|
96
|
+
# Favicon
|
97
|
+
# => https://github.com/audreyr/favicon-cheat-sheet
|
98
|
+
# => http://iconhandbook.co.uk/reference/chart/favicons/
|
99
|
+
def favicon img="icons/favicon.ico", *args
|
100
|
+
|
101
|
+
# => Accepts all styles of icon
|
102
|
+
defaults = { "apple-touch-icon" => [57,60,72,76,114,120,144,152,167,180], "icon" => [16,32] }
|
103
|
+
options = args.extract_options!.merge!(defaults) { |key, v1, v2| v1 }
|
104
|
+
|
105
|
+
case options
|
106
|
+
when :all
|
107
|
+
|
108
|
+
when true
|
109
|
+
else
|
110
|
+
meta :favicon, "https://www.frontlineutilities.co.uk/favicon.ico"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
########################################
|
115
|
+
########################################
|
116
|
+
|
117
|
+
end
|
118
|
+
|
119
|
+
###################################################
|
120
|
+
###################################################
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class ApplicationMailer < ActionMailer::Base
|
2
|
+
|
3
|
+
# => Address
|
4
|
+
# => http://stackoverflow.com/a/8106387/1143732
|
5
|
+
@@address = Mail::Address.new Rails.application.secrets.app[:email]
|
6
|
+
@@address.display_name = Rails.application.secrets.app[:domain]
|
7
|
+
|
8
|
+
# => Default
|
9
|
+
# => http://stackoverflow.com/a/18579046/1143732
|
10
|
+
default from: @@address.format, template_path: "mailers"
|
11
|
+
|
12
|
+
# Layout (app/views/layouts)
|
13
|
+
layout "mailers/layouts/mailer"
|
14
|
+
|
15
|
+
##########################################################
|
16
|
+
##########################################################
|
17
|
+
|
18
|
+
# For Admin "seeds" notification
|
19
|
+
def new_user user
|
20
|
+
@user = user
|
21
|
+
mail to: @@address
|
22
|
+
puts "User details sent to → #{@@address}"
|
23
|
+
end
|
24
|
+
|
25
|
+
##########################################################
|
26
|
+
##########################################################
|
27
|
+
|
28
|
+
end
|
data/app/models/asset.rb
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
class Asset < ApplicationRecord
|
2
|
+
|
3
|
+
####################################################################
|
4
|
+
####################################################################
|
5
|
+
|
6
|
+
# Source - http://rails-bestpractices.com/posts/2010/08/18/use-sti-and-polymorphic-model-for-multiple-uploads/
|
7
|
+
# Need to find a way to remove the model name from the mix (IE "current_user.avatar.attachment.url" should be "current_user.avatar.url")
|
8
|
+
##########################################
|
9
|
+
##########################################
|
10
|
+
|
11
|
+
# => Associations
|
12
|
+
##################
|
13
|
+
belongs_to :assetable, polymorphic: true
|
14
|
+
|
15
|
+
# => CkEditor
|
16
|
+
##################
|
17
|
+
if defined? Ckeditor
|
18
|
+
include Ckeditor::Orm::ActiveRecord::AssetBase
|
19
|
+
include Ckeditor::Backend::Paperclip
|
20
|
+
end
|
21
|
+
|
22
|
+
# => Table
|
23
|
+
# => Required for CKEditor
|
24
|
+
##################
|
25
|
+
self.table_name = "assets"
|
26
|
+
|
27
|
+
# => Paperclip
|
28
|
+
##################
|
29
|
+
has_attached_file FL::FILE
|
30
|
+
validates_attachment FL::FILE, presence: true, content_type: { content_type: /\Aimage\/.*\z/, message: "%{value}" }, size: { in: 0..3.megabytes }
|
31
|
+
|
32
|
+
# => Alias
|
33
|
+
##################
|
34
|
+
alias_attribute :ref, :id
|
35
|
+
|
36
|
+
##########################################
|
37
|
+
##########################################
|
38
|
+
|
39
|
+
###################
|
40
|
+
# Methods #
|
41
|
+
###################
|
42
|
+
|
43
|
+
# => Before Create
|
44
|
+
# => https://github.com/thoughtbot/paperclip/wiki/Extracting-image-dimensions
|
45
|
+
# => https://github.com/galetahub/ckeditor/blob/master/lib/ckeditor/backend/paperclip.rb#L38 (implemented in CKEditor)
|
46
|
+
before_create -> { %i(width height).each {|style| self[style] = geometry.send(style)} }, if: Proc.new { |i| i.image? and i.has_dimensions? }
|
47
|
+
|
48
|
+
# => Errors Fix
|
49
|
+
# => https://github.com/thoughtbot/paperclip/pull/1554#issuecomment-200666161
|
50
|
+
after_validation {|a| a.errors.delete(FL::FILE)}
|
51
|
+
|
52
|
+
##########################################
|
53
|
+
##########################################
|
54
|
+
|
55
|
+
# => URL
|
56
|
+
##################
|
57
|
+
def url *args
|
58
|
+
data.url *args
|
59
|
+
end
|
60
|
+
|
61
|
+
# => CKEditor
|
62
|
+
##################
|
63
|
+
def url_content
|
64
|
+
url(:medium)
|
65
|
+
end
|
66
|
+
|
67
|
+
# => Image?
|
68
|
+
##################
|
69
|
+
def image?
|
70
|
+
%r(\Aimage\/.*\Z) =~ data_content_type
|
71
|
+
end
|
72
|
+
|
73
|
+
# => Dimensions
|
74
|
+
##################
|
75
|
+
def has_dimensions?
|
76
|
+
respond_to?(:width) && respond_to?(:height)
|
77
|
+
end
|
78
|
+
|
79
|
+
##########################################
|
80
|
+
##########################################
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
# => Geometry
|
85
|
+
# => https://github.com/galetahub/ckeditor/blob/master/lib/ckeditor/backend/paperclip.rb#L23
|
86
|
+
def geometry
|
87
|
+
@geometry ||= begin
|
88
|
+
file = data.respond_to?(:queued_for_write) ? data.queued_for_write[:original] : data.to_file
|
89
|
+
::Paperclip::Geometry.from_file(file)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
####################################################################
|
94
|
+
|
95
|
+
end
|