fl 0.3.0

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.
Files changed (137) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +44 -0
  3. data/Gemfile +5 -0
  4. data/Gemfile.lock +173 -0
  5. data/README.md +30 -0
  6. data/Rakefile +2 -0
  7. data/app/admin/options.rb +46 -0
  8. data/app/admin/pages.rb +55 -0
  9. data/app/admin/users.rb +34 -0
  10. data/app/assets/javascripts/active_admin.coffee.erb +20 -0
  11. data/app/assets/javascripts/application.coffee.erb +40 -0
  12. data/app/assets/javascripts/ckeditor/basepath.coffee.erb +21 -0
  13. data/app/assets/javascripts/ckeditor/config.coffee.erb +146 -0
  14. data/app/assets/javascripts/ckeditor/plugins/autogrow/plugin.js +232 -0
  15. data/app/assets/javascripts/ckeditor/plugins/autogrow/samples/autogrow.html +102 -0
  16. data/app/assets/javascripts/ckeditor/plugins/stylesheetparser/plugin.js +158 -0
  17. data/app/assets/javascripts/ckeditor/plugins/stylesheetparser/samples/assets/sample.css +70 -0
  18. data/app/assets/javascripts/ckeditor/plugins/stylesheetparser/samples/stylesheetparser.html +85 -0
  19. data/app/assets/javascripts/ckeditor/skins/minimalist/dialog.css +5 -0
  20. data/app/assets/javascripts/ckeditor/skins/minimalist/dialog_ie.css +5 -0
  21. data/app/assets/javascripts/ckeditor/skins/minimalist/dialog_ie7.css +5 -0
  22. data/app/assets/javascripts/ckeditor/skins/minimalist/dialog_ie8.css +5 -0
  23. data/app/assets/javascripts/ckeditor/skins/minimalist/dialog_iequirks.css +5 -0
  24. data/app/assets/javascripts/ckeditor/skins/minimalist/editor.css +5 -0
  25. data/app/assets/javascripts/ckeditor/skins/minimalist/editor_gecko.css +5 -0
  26. data/app/assets/javascripts/ckeditor/skins/minimalist/editor_ie.css +5 -0
  27. data/app/assets/javascripts/ckeditor/skins/minimalist/editor_ie7.css +5 -0
  28. data/app/assets/javascripts/ckeditor/skins/minimalist/editor_ie8.css +5 -0
  29. data/app/assets/javascripts/ckeditor/skins/minimalist/editor_iequirks.css +5 -0
  30. data/app/assets/javascripts/ckeditor/skins/minimalist/icons.png +0 -0
  31. data/app/assets/javascripts/ckeditor/skins/minimalist/icons_hidpi.png +0 -0
  32. data/app/assets/javascripts/ckeditor/skins/minimalist/images/arrow.png +0 -0
  33. data/app/assets/javascripts/ckeditor/skins/minimalist/images/close.png +0 -0
  34. data/app/assets/javascripts/ckeditor/skins/minimalist/images/hidpi/close.png +0 -0
  35. data/app/assets/javascripts/ckeditor/skins/minimalist/images/hidpi/lock-open.png +0 -0
  36. data/app/assets/javascripts/ckeditor/skins/minimalist/images/hidpi/lock.png +0 -0
  37. data/app/assets/javascripts/ckeditor/skins/minimalist/images/hidpi/refresh.png +0 -0
  38. data/app/assets/javascripts/ckeditor/skins/minimalist/images/lock-open.png +0 -0
  39. data/app/assets/javascripts/ckeditor/skins/minimalist/images/lock.png +0 -0
  40. data/app/assets/javascripts/ckeditor/skins/minimalist/images/refresh.png +0 -0
  41. data/app/assets/javascripts/ckeditor/skins/minimalist/readme.md +7 -0
  42. data/app/assets/javascripts/ckeditor/skins/minimalist/skin.js +10 -0
  43. data/app/assets/javascripts/ckeditor/skins/moonocolor/dialog.css +5 -0
  44. data/app/assets/javascripts/ckeditor/skins/moonocolor/dialog_ie.css +5 -0
  45. data/app/assets/javascripts/ckeditor/skins/moonocolor/dialog_ie7.css +5 -0
  46. data/app/assets/javascripts/ckeditor/skins/moonocolor/dialog_ie8.css +5 -0
  47. data/app/assets/javascripts/ckeditor/skins/moonocolor/dialog_iequirks.css +5 -0
  48. data/app/assets/javascripts/ckeditor/skins/moonocolor/editor.css +5 -0
  49. data/app/assets/javascripts/ckeditor/skins/moonocolor/editor_gecko.css +5 -0
  50. data/app/assets/javascripts/ckeditor/skins/moonocolor/editor_ie.css +5 -0
  51. data/app/assets/javascripts/ckeditor/skins/moonocolor/editor_ie7.css +5 -0
  52. data/app/assets/javascripts/ckeditor/skins/moonocolor/editor_ie8.css +5 -0
  53. data/app/assets/javascripts/ckeditor/skins/moonocolor/editor_iequirks.css +5 -0
  54. data/app/assets/javascripts/ckeditor/skins/moonocolor/icons.png +0 -0
  55. data/app/assets/javascripts/ckeditor/skins/moonocolor/icons_hidpi.png +0 -0
  56. data/app/assets/javascripts/ckeditor/skins/moonocolor/images/arrow.png +0 -0
  57. data/app/assets/javascripts/ckeditor/skins/moonocolor/images/close.png +0 -0
  58. data/app/assets/javascripts/ckeditor/skins/moonocolor/images/hidpi/close.png +0 -0
  59. data/app/assets/javascripts/ckeditor/skins/moonocolor/images/hidpi/lock-open.png +0 -0
  60. data/app/assets/javascripts/ckeditor/skins/moonocolor/images/hidpi/lock.png +0 -0
  61. data/app/assets/javascripts/ckeditor/skins/moonocolor/images/hidpi/refresh.png +0 -0
  62. data/app/assets/javascripts/ckeditor/skins/moonocolor/images/lock-open.png +0 -0
  63. data/app/assets/javascripts/ckeditor/skins/moonocolor/images/lock.png +0 -0
  64. data/app/assets/javascripts/ckeditor/skins/moonocolor/images/refresh.png +0 -0
  65. data/app/assets/javascripts/ckeditor/skins/moonocolor/images/spinner.gif +0 -0
  66. data/app/assets/javascripts/ckeditor/skins/moonocolor/readme.md +51 -0
  67. data/app/assets/javascripts/ckeditor/skins/moonocolor/skin.js +10 -0
  68. data/app/assets/javascripts/components/confirm.coffee +51 -0
  69. data/app/assets/javascripts/components/modals.coffee +29 -0
  70. data/app/assets/stylesheets/_defaults.yml +106 -0
  71. data/app/assets/stylesheets/_functions.sass.erb +75 -0
  72. data/app/assets/stylesheets/active_admin.sass +117 -0
  73. data/app/assets/stylesheets/application.sass.erb +46 -0
  74. data/app/assets/stylesheets/styles/reset.sass +139 -0
  75. data/app/assets/stylesheets/styles/structure.sass +69 -0
  76. data/app/assets/stylesheets/styles/ui/flash.sass +128 -0
  77. data/app/assets/stylesheets/styles/ui/fonts.sass +32 -0
  78. data/app/assets/stylesheets/styles/ui/modals.sass +61 -0
  79. data/app/assets/stylesheets/styles/ui/tooltips.sass +139 -0
  80. data/app/controllers/application_controller.rb +87 -0
  81. data/app/helpers/fl/application_helper.rb +53 -0
  82. data/app/helpers/fl/asset_helper.rb +50 -0
  83. data/app/helpers/fl/liquid_helper.rb +29 -0
  84. data/app/helpers/fl/meta_helper.rb +118 -0
  85. data/app/lib/active_record/concerns/base.rb +55 -0
  86. data/app/lib/active_record/concerns/seeds.rb +78 -0
  87. data/app/liquid/filters/meta_filter.rb +6 -0
  88. data/app/liquid/tags/google_analytics_tag.rb +32 -0
  89. data/app/liquid/tags/icon_tag.rb +37 -0
  90. data/app/liquid/tags/meta_tag.rb +120 -0
  91. data/app/mailers/application_mailer.rb +28 -0
  92. data/app/models/application_record.rb +3 -0
  93. data/app/models/asset.rb +95 -0
  94. data/app/models/association.rb +21 -0
  95. data/app/models/meta.rb +27 -0
  96. data/app/models/node.rb +59 -0
  97. data/app/models/profile.rb +49 -0
  98. data/app/models/user.rb +49 -0
  99. data/app/service/flash.rb +8 -0
  100. data/app/views/layouts/_admin.haml +6 -0
  101. data/app/views/layouts/_application.haml +17 -0
  102. data/app/views/layouts/base.haml +26 -0
  103. data/app/views/mailers/layouts/mailer.haml +8 -0
  104. data/app/views/mailers/layouts/mailer.text.erb +1 -0
  105. data/app/views/mailers/new_user.erb +4 -0
  106. data/bin/console +14 -0
  107. data/bin/setup +8 -0
  108. data/config/initializers/active_admin.rb +266 -0
  109. data/config/initializers/ckeditor.rb +63 -0
  110. data/config/initializers/devise.rb +279 -0
  111. data/config/initializers/friendly_id.rb +92 -0
  112. data/config/initializers/inflections.rb +20 -0
  113. data/config/initializers/liquid.rb +87 -0
  114. data/config/initializers/sass.rb +45 -0
  115. data/config/locales/devise.en.yml +62 -0
  116. data/config/locales/en.yml +13 -0
  117. data/config/puma.rb +59 -0
  118. data/config/routes.rb +56 -0
  119. data/db/migrate/20160616060637_create_nodes.rb +26 -0
  120. data/db/migrate/20160707080248_create_users.rb +52 -0
  121. data/db/migrate/20160707094704_create_slugs.rb +33 -0
  122. data/db/migrate/20160710095916_create_associations.rb +20 -0
  123. data/db/migrate/20160713061948_create_profiles.rb +27 -0
  124. data/db/migrate/20161115101221_create_assets.rb +25 -0
  125. data/db/migrate/20170725060408_create_active_admin_comments.rb +22 -0
  126. data/db/seeds.rb +81 -0
  127. data/fl.gemspec +73 -0
  128. data/lib/fl.rb +28 -0
  129. data/lib/fl/constants.rb +52 -0
  130. data/lib/fl/engine.rb +160 -0
  131. data/lib/fl/hash.rb +34 -0
  132. data/lib/generators/fl/sass_vars_generator.rb +16 -0
  133. data/lib/generators/fl/templates/sass.yml +56 -0
  134. data/lib/tasks/ckeditor.rake +37 -0
  135. data/lib/tasks/favicon.rake +37 -0
  136. data/readme/fl.jpg +0 -0
  137. 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,6 @@
1
+ ## Meta Helpers ##
2
+ module MetaFilter
3
+ def textilize(input) # will be available as the "textilize" filter
4
+ "test"
5
+ end
6
+ 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
@@ -0,0 +1,3 @@
1
+ class ApplicationRecord < ActiveRecord::Base
2
+ self.abstract_class = true
3
+ end
@@ -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