tomify 0.0.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 (157) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +19 -0
  4. data/Rakefile +6 -0
  5. data/app/assets/images/tomify/gifs/basketball.gif +0 -0
  6. data/app/assets/images/tomify/gifs/laughing.gif +0 -0
  7. data/app/assets/images/tomify/gifs/sneer.gif +0 -0
  8. data/app/assets/images/tomify/gifs/wind.gif +0 -0
  9. data/app/assets/images/tomify/gifs/woods.gif +0 -0
  10. data/app/assets/javascripts/tomify/default/array.coffee +4 -0
  11. data/app/assets/javascripts/tomify/default/jquery.patch.coffee +9 -0
  12. data/app/assets/javascripts/tomify/default/object.coffee +4 -0
  13. data/app/assets/javascripts/tomify/default/string.coffee +40 -0
  14. data/app/assets/javascripts/tomify/dynamic/classes/component.coffee +7 -0
  15. data/app/assets/javascripts/tomify/dynamic/classes/field.coffee +24 -0
  16. data/app/assets/javascripts/tomify/dynamic/classes/form.coffee +72 -0
  17. data/app/assets/javascripts/tomify/dynamic/classes/model.coffee +41 -0
  18. data/app/assets/javascripts/tomify/dynamic/classes/namespace.coffee +24 -0
  19. data/app/assets/javascripts/tomify/dynamic/classes/observer.coffee +22 -0
  20. data/app/assets/javascripts/tomify/dynamic/classes/request.coffee +26 -0
  21. data/app/assets/javascripts/tomify/dynamic/classes/store.coffee +37 -0
  22. data/app/assets/javascripts/tomify/dynamic/global.coffee +16 -0
  23. data/app/assets/javascripts/tomify/dynamic/react/components/admin/pages.coffee.erb +30 -0
  24. data/app/assets/javascripts/tomify/dynamic/react/components/admin/settings.coffee +27 -0
  25. data/app/assets/javascripts/tomify/dynamic/react/components/admin/sidebars.coffee +16 -0
  26. data/app/assets/javascripts/tomify/dynamic/react/components/admin/uploads.coffee +13 -0
  27. data/app/assets/javascripts/tomify/dynamic/react/components/admin/users.coffee +18 -0
  28. data/app/assets/javascripts/tomify/dynamic/react/components/edit.coffee +51 -0
  29. data/app/assets/javascripts/tomify/dynamic/react/components/fields/checkbox.coffee +8 -0
  30. data/app/assets/javascripts/tomify/dynamic/react/components/fields/default.coffee +3 -0
  31. data/app/assets/javascripts/tomify/dynamic/react/components/fields/file.coffee +3 -0
  32. data/app/assets/javascripts/tomify/dynamic/react/components/fields/markdown.coffee +9 -0
  33. data/app/assets/javascripts/tomify/dynamic/react/components/fields/select.coffee +8 -0
  34. data/app/assets/javascripts/tomify/dynamic/react/components/fields/textarea.coffee +3 -0
  35. data/app/assets/javascripts/tomify/dynamic/react/components/index.coffee +87 -0
  36. data/app/assets/javascripts/tomify/dynamic/react/components/layout/admin_navbar.coffee +29 -0
  37. data/app/assets/javascripts/tomify/dynamic/react/components/layout/analytics.coffee +34 -0
  38. data/app/assets/javascripts/tomify/dynamic/react/components/layout/footer.coffee +11 -0
  39. data/app/assets/javascripts/tomify/dynamic/react/components/layout/header.coffee +28 -0
  40. data/app/assets/javascripts/tomify/dynamic/react/components/layout/messages.coffee +18 -0
  41. data/app/assets/javascripts/tomify/dynamic/react/components/layout/navbar.coffee +6 -0
  42. data/app/assets/javascripts/tomify/dynamic/react/components/layout/public_navbar.coffee +56 -0
  43. data/app/assets/javascripts/tomify/dynamic/react/components/new.coffee +48 -0
  44. data/app/assets/javascripts/tomify/dynamic/react/components/pagination.coffee +29 -0
  45. data/app/assets/javascripts/tomify/dynamic/react/components/public/passwords/new.coffee +38 -0
  46. data/app/assets/javascripts/tomify/dynamic/react/components/public/sessions/new.coffee +40 -0
  47. data/app/assets/javascripts/tomify/dynamic/react/components/public/sessions/show.coffee +35 -0
  48. data/app/assets/javascripts/tomify/dynamic/react/components/public/users/edit.coffee +42 -0
  49. data/app/assets/javascripts/tomify/dynamic/react/components/public/users/new.coffee +35 -0
  50. data/app/assets/javascripts/tomify/dynamic/react/mixins/follow.coffee +51 -0
  51. data/app/assets/javascripts/tomify/dynamic/react/mixins/will-initialize.coffee +7 -0
  52. data/app/assets/javascripts/tomify/dynamic/react/mount.coffee +9 -0
  53. data/app/assets/javascripts/tomify/turbolinks/compatibility.coffee +29 -0
  54. data/app/assets/javascripts/tomify/turbolinks/react.coffee +5 -0
  55. data/app/assets/javascripts/tomify-dynamic.js +8 -0
  56. data/app/assets/javascripts/tomify.js +1 -0
  57. data/app/assets/stylesheets/_tomify.scss +1 -0
  58. data/app/assets/stylesheets/tomify/_default.scss +26 -0
  59. data/app/assets/stylesheets/tomify/_footer.scss +1 -0
  60. data/app/assets/stylesheets/tomify/_navbar.scss +43 -0
  61. data/app/assets/stylesheets/tomify/_page.scss +31 -0
  62. data/app/assets/stylesheets/tomify/_pagination.scss +5 -0
  63. data/app/assets/stylesheets/tomify/_variables.scss +10 -0
  64. data/app/controllers/tomify/admin/controller.rb +7 -0
  65. data/app/controllers/tomify/admin/pages_controller.rb +2 -0
  66. data/app/controllers/tomify/admin/settings_controller.rb +2 -0
  67. data/app/controllers/tomify/admin/sidebars_controller.rb +2 -0
  68. data/app/controllers/tomify/admin/uploads_controller.rb +2 -0
  69. data/app/controllers/tomify/admin/users_controller.rb +2 -0
  70. data/app/controllers/tomify/api/admin/controller.rb +3 -0
  71. data/app/controllers/tomify/api/admin/pages_controller.rb +2 -0
  72. data/app/controllers/tomify/api/admin/settings_controller.rb +2 -0
  73. data/app/controllers/tomify/api/admin/sidebars_controller.rb +2 -0
  74. data/app/controllers/tomify/api/admin/uploads_controller.rb +2 -0
  75. data/app/controllers/tomify/api/admin/users_controller.rb +7 -0
  76. data/app/controllers/tomify/api/public/controller.rb +3 -0
  77. data/app/controllers/tomify/api/public/passwords_controller.rb +10 -0
  78. data/app/controllers/tomify/api/public/sessions_controller.rb +19 -0
  79. data/app/controllers/tomify/api/public/users_controller.rb +25 -0
  80. data/app/controllers/tomify/concerns/api/admin.rb +9 -0
  81. data/app/controllers/tomify/concerns/api/helpers.rb +57 -0
  82. data/app/controllers/tomify/concerns/api/json.rb +46 -0
  83. data/app/controllers/tomify/concerns/api/public.rb +9 -0
  84. data/app/controllers/tomify/concerns/default/auth_helper.rb +22 -0
  85. data/app/controllers/tomify/concerns/default/env_helper.rb +34 -0
  86. data/app/controllers/tomify/concerns/default/helper.rb +13 -0
  87. data/app/controllers/tomify/concerns/default/react_helper.rb +7 -0
  88. data/app/controllers/tomify/concerns/default.rb +17 -0
  89. data/app/controllers/tomify/public/controller.rb +2 -0
  90. data/app/controllers/tomify/public/pages_controller.rb +22 -0
  91. data/app/controllers/tomify/public/sessions_controller.rb +5 -0
  92. data/app/controllers/tomify/public/users_controller.rb +7 -0
  93. data/app/controllers/tomify_controller.rb +3 -0
  94. data/app/helpers/tomify/carrierwave_helper.rb +17 -0
  95. data/app/helpers/tomify/email_helper.rb +19 -0
  96. data/app/helpers/tomify/render_helper.rb +13 -0
  97. data/app/helpers/tomify/timezone_helper.rb +5 -0
  98. data/app/mailers/tomify/user_mailer.rb +13 -0
  99. data/app/mailers/tomify_mailer.rb +14 -0
  100. data/app/models/tomify/concerns/page.rb +74 -0
  101. data/app/models/tomify/concerns/sidebar.rb +18 -0
  102. data/app/models/tomify/concerns/token.rb +18 -0
  103. data/app/models/tomify/concerns/upload.rb +36 -0
  104. data/app/models/tomify/concerns/user.rb +52 -0
  105. data/app/models/tomify/page.rb +3 -0
  106. data/app/models/tomify/setting/boolean.rb +11 -0
  107. data/app/models/tomify/setting/json.rb +11 -0
  108. data/app/models/tomify/setting/text.rb +3 -0
  109. data/app/models/tomify/setting/uploader.rb +6 -0
  110. data/app/models/tomify/setting.rb +48 -0
  111. data/app/models/tomify/sidebar.rb +3 -0
  112. data/app/models/tomify/token.rb +3 -0
  113. data/app/models/tomify/upload.rb +3 -0
  114. data/app/models/tomify/user.rb +3 -0
  115. data/app/models/tomify_record.rb +33 -0
  116. data/app/uploaders/tomify/file_uploader.rb +5 -0
  117. data/app/uploaders/tomify/setting_uploader.rb +7 -0
  118. data/app/uploaders/tomify_uploader.rb +20 -0
  119. data/app/views/templates/contact.haml +24 -0
  120. data/app/views/templates/default.haml +4 -0
  121. data/app/views/tomify/defaults/_body.haml +8 -0
  122. data/app/views/tomify/defaults/_container.haml +3 -0
  123. data/app/views/tomify/defaults/_env.haml +2 -0
  124. data/app/views/tomify/defaults/_head.haml +14 -0
  125. data/app/views/tomify/defaults/_meta.haml +17 -0
  126. data/app/views/tomify/defaults/_sharing.haml +23 -0
  127. data/app/views/tomify/layouts/application.haml +4 -0
  128. data/app/views/tomify/layouts/mailer.haml +7 -0
  129. data/app/views/tomify/mailers/user_mailer/invite.haml +13 -0
  130. data/app/views/tomify/mailers/user_mailer/reset_password.haml +17 -0
  131. data/config/initializers/assets.rb +7 -0
  132. data/config/initializers/database.rb +3 -0
  133. data/config/initializers/flash_patch.rb +15 -0
  134. data/config/initializers/mailer.rb +4 -0
  135. data/config/initializers/renderers.rb +4 -0
  136. data/config/initializers/settings.rb +5 -0
  137. data/config/routes.rb +38 -0
  138. data/db/migrate/19900000000000_create_users.rb +13 -0
  139. data/db/migrate/19900000000001_create_tokens.rb +10 -0
  140. data/db/migrate/19900000000002_create_settings.rb +13 -0
  141. data/db/migrate/19900000000003_create_uploads.rb +13 -0
  142. data/db/migrate/19900000000004_create_pages.rb +22 -0
  143. data/db/migrate/19900000000005_create_sidebars.rb +12 -0
  144. data/db/seeds.rb +43 -0
  145. data/lib/generators/tomify/bundle/bundle_generator.rb +12 -0
  146. data/lib/generators/tomify/bundle/templates/default.js +2 -0
  147. data/lib/generators/tomify/bundle/templates/react.js +3 -0
  148. data/lib/previews/tomify/user_preview.rb +9 -0
  149. data/lib/previews/tomify_preview.rb +6 -0
  150. data/lib/tasks/package.rake +40 -0
  151. data/lib/tomify/constantly.rb +12 -0
  152. data/lib/tomify/engine.rb +11 -0
  153. data/lib/tomify/version.rb +3 -0
  154. data/lib/tomify.rb +40 -0
  155. data/vendor/tomify/development/react.js +20494 -0
  156. data/vendor/tomify/production/react.js +20352 -0
  157. metadata +219 -0
@@ -0,0 +1,74 @@
1
+ module Tomify::Concerns::Page
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ mount_uploader :cover_image, CoverImageUploader
6
+ mount_uploader :share_image, ShareImageUploader
7
+
8
+ belongs_to :sidebar
9
+ belongs_to :parent, class_name: self
10
+ has_many :children, class_name: self, foreign_key: :parent_id
11
+
12
+ before_validation :format_path
13
+ before_validation :require_root, if: :root_changed?
14
+ before_save :set_root, if: :root_changed?
15
+ before_destroy { |page| page.root.blank? }
16
+
17
+ validates_presence_of :rank, :path, :name, :template
18
+ validates_uniqueness_of :path
19
+ validate :parent_valid?
20
+
21
+ default_scope { order(:rank, :name) }
22
+ scope :active, -> { where(active: true) }
23
+
24
+ to_html :text
25
+ end
26
+
27
+ class_methods do
28
+ def root
29
+ find_by(root: true) || new(root: true, name: "Home", path: "", template: "default")
30
+ end
31
+
32
+ def templates
33
+ return @files if @files
34
+ @files = Dir.glob("#{Tomify.root}/app/views/templates/*")
35
+ @files.concat Dir.glob("#{Rails.root}/app/views/templates/*")
36
+ @files.compact!
37
+ @files.collect! { |file| file.split("/").last.split(".").first }
38
+ @files.sort_by! { |f| f == "default" ? "" : f } # Default First
39
+ end
40
+
41
+ def admin_params
42
+ [
43
+ :parent_id, :sidebar_id,
44
+ :active, :root, :rank,
45
+ :path, :name, :template,
46
+ :title, :description,
47
+ :cover_image, :share_image,
48
+ :text
49
+ ]
50
+ end
51
+ end
52
+
53
+ def serializable_hash(options = nil)
54
+ options = { include: [:parent, :sidebar] } if options.blank?
55
+ super(options)
56
+ end
57
+
58
+ private
59
+ def parent_valid?
60
+ errors.add(:parent_id) if parent && parent.id == id
61
+ end
62
+
63
+ def format_path
64
+ self.path = path.try(:strip).try(:downcase)
65
+ end
66
+
67
+ def require_root
68
+ errors.add(:root, "is required") unless root || self.class.where.not(id: id).root.present?
69
+ end
70
+
71
+ def set_root
72
+ self.class.where.not(id: id).where(root: true).update_all(root: false) if root
73
+ end
74
+ end
@@ -0,0 +1,18 @@
1
+ module Tomify::Concerns::Sidebar
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ has_many :pages
6
+ validates_presence_of :name
7
+
8
+ scope :active, -> { where(active: true) }
9
+
10
+ to_html :text
11
+ end
12
+
13
+ class_methods do
14
+ def admin_params
15
+ [:active, :name, :heading, :text]
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ module Tomify::Concerns::Token
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ belongs_to :user
6
+
7
+ before_create :create_uuid
8
+ end
9
+
10
+ def to_param
11
+ uuid
12
+ end
13
+
14
+ private
15
+ def create_uuid
16
+ self.uuid ||= SecureRandom.uuid
17
+ end
18
+ end
@@ -0,0 +1,36 @@
1
+ module Tomify::Concerns::Upload
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ mount_uploader :file, Tomify::FileUploader
6
+
7
+ before_validation :set_model
8
+ before_validation :validate_content_type, on: :update, if: :content_type_changed?
9
+
10
+ validates_presence_of :uuid, :name, :file, :size, :content_type
11
+ validates_uniqueness_of :uuid, :name
12
+
13
+ default_scope { order(:name) }
14
+ end
15
+
16
+ def to_param
17
+ uuid
18
+ end
19
+
20
+ class_methods do
21
+ def admin_params
22
+ [:uuid, :name, :file, :size, :content_type]
23
+ end
24
+ end
25
+
26
+ private
27
+ def set_model
28
+ self.uuid ||= SecureRandom.uuid
29
+ self.size = file.size
30
+ self.content_type = file.content_type
31
+ end
32
+
33
+ def validate_content_type
34
+ errors.add(:content_type, "cannot change")
35
+ end
36
+ end
@@ -0,0 +1,52 @@
1
+ module Tomify::Concerns::User
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ has_secure_password validations: false
6
+ has_many :tokens, dependent: :destroy
7
+
8
+ before_validation :format_email
9
+ after_create :send_invite, unless: :password_digest
10
+
11
+ validates_presence_of :email, :first_name, :last_name
12
+ validates_uniqueness_of :email, allow_blank: true
13
+ validates_format_of :email, with: /@/i, allow_blank: true
14
+ validates_length_of :password, minimum: 8, allow_blank: true
15
+ validates_confirmation_of :password, allow_blank: true
16
+
17
+ default_scope { order(:created_at) }
18
+ scope :admin, -> { where(admin: true) }
19
+ end
20
+
21
+ class_methods do
22
+ def admin_params
23
+ [:admin, :email, :first_name, :last_name]
24
+ end
25
+
26
+ def public_params
27
+ [:email, :first_name, :last_name, :password, :password_confirmation]
28
+ end
29
+ end
30
+
31
+ def name
32
+ "#{first_name} #{last_name}"
33
+ end
34
+
35
+ def token
36
+ tokens.first_or_create
37
+ end
38
+
39
+ def serializable_hash(options = nil)
40
+ options = { methods: [:name] } if options.blank?
41
+ super options
42
+ end
43
+
44
+ private
45
+ def format_email
46
+ self.email = email.try(:strip).try(:downcase)
47
+ end
48
+
49
+ def send_invite
50
+ Tomify::UserMailer.invite(self).deliver_now
51
+ end
52
+ end
@@ -0,0 +1,3 @@
1
+ class Tomify::Page < Tomify.models.base
2
+ include Tomify::Concerns::Page
3
+ end
@@ -0,0 +1,11 @@
1
+ class Tomify::Setting::Boolean < Tomify::Setting
2
+ validates_inclusion_of :value, in: [true, false]
3
+
4
+ def value
5
+ super == "true"
6
+ end
7
+
8
+ def value=(v)
9
+ super(v.to_s)
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ class Tomify::Setting::Json < Tomify::Setting
2
+ validates_presence_of :json
3
+
4
+ def value
5
+ json
6
+ end
7
+
8
+ def value=(value)
9
+ self.json = value
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ class Tomify::Setting::Text < Tomify::Setting
2
+ validates_presence_of :value
3
+ end
@@ -0,0 +1,6 @@
1
+ class Tomify::UploaderSetting < Tomify::Setting
2
+ mount_uploader :value, Tomify::SettingUploader
3
+
4
+ validates_presence_of :json
5
+ validate :metadata
6
+ end
@@ -0,0 +1,48 @@
1
+ class Tomify::Setting < Tomify.models.base
2
+ validates_presence_of :type, :name
3
+ validates_uniqueness_of :name
4
+ validates_format_of :name, with: /\A[a-z_]+\z/, message: "can only contain lowercase letters and underscores"
5
+ validate :type_valid?, on: :update
6
+ validate :name_valid?, on: :update
7
+
8
+ after_commit :update_config
9
+ before_destroy { |record| !record.name.in? self.class.required_settings }
10
+
11
+ def self.public
12
+ where(public: true)
13
+ end
14
+
15
+ def self.required_settings
16
+ ["allow_signup", "name", "email", "timezone"]
17
+ end
18
+
19
+ def self.admin_params
20
+ [:type, :name, :value, :json]
21
+ end
22
+
23
+ def serializable_hash(options = nil)
24
+ options ||= {}
25
+ super({ methods: [:type] }.update(options))
26
+ end
27
+
28
+ private
29
+ def type_valid?
30
+ errors.add(:type, "cannot change") if type_changed?
31
+ end
32
+
33
+ def name_valid?
34
+ return true unless name_was.in? self.class.required_settings
35
+ errors.add(:name, "cannot change if required") if name_changed?
36
+ end
37
+
38
+ def update_config
39
+ case name
40
+ when "aws"
41
+ Tomify::CarrierwaveHelper.load_config
42
+ when "email"
43
+ Tomify::EmailHelper.load_config
44
+ when "timezone"
45
+ Tomify::TimezoneHelper.load_config
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,3 @@
1
+ class Tomify::Sidebar < Tomify.models.base
2
+ include Tomify::Concerns::Sidebar
3
+ end
@@ -0,0 +1,3 @@
1
+ class Tomify::Token < Tomify.models.base
2
+ include Tomify::Concerns::Token
3
+ end
@@ -0,0 +1,3 @@
1
+ class Tomify::Upload < Tomify.models.base
2
+ include Tomify::Concerns::Upload
3
+ end
@@ -0,0 +1,3 @@
1
+ class Tomify::User < Tomify.models.base
2
+ include Tomify::Concerns::User
3
+ end
@@ -0,0 +1,33 @@
1
+ class TomifyRecord < ActiveRecord::Base
2
+ self.abstract_class = true
3
+
4
+ def self.to_html(*attrs)
5
+ attrs.each do |attr|
6
+ define_method("#{attr}_to_html") do
7
+ Rails.cache.fetch("#{self.class.name.downcase}-#{id}-#{attr}") do
8
+ markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML, autolink: true, tables: true)
9
+ markdown.render(self[attr] || "").html_safe
10
+ end
11
+ end
12
+ end
13
+
14
+ define_method("bust_html_cache") do
15
+ attrs.each do |attr|
16
+ Rails.cache.delete("#{self.class.name.downcase}-#{id}-#{attr}")
17
+ end
18
+ end
19
+
20
+ after_save :bust_html_cache
21
+ end
22
+
23
+ def self.date_from(*attrs)
24
+ attrs.each do |attr|
25
+ define_method("#{attr}_date") do
26
+ value = read_attribute attr
27
+ value && value.strftime("%m/%d/%y %I:%M %p")
28
+ end
29
+ end
30
+ end
31
+
32
+ date_from :created_at, :updated_at
33
+ end
@@ -0,0 +1,5 @@
1
+ class Tomify::FileUploader < Tomify.uploaders.base
2
+ def filename
3
+ "#{model.uuid}.#{file.extension}" if original_filename.present?
4
+ end
5
+ end
@@ -0,0 +1,7 @@
1
+ class Tomify::SettingUploader < Tomify.uploaders.base
2
+ # in uploader
3
+ # if image
4
+ # width ||= 1000000000
5
+ # height ||= -1
6
+ # resize_to_fill width, height
7
+ end
@@ -0,0 +1,20 @@
1
+ class TomifyUploader < CarrierWave::Uploader::Base
2
+ include CarrierWave::MiniMagick
3
+
4
+ def store_dir
5
+ self.class.name.downcase.chomp("uploader").chomp("image")
6
+ end
7
+
8
+ def filename
9
+ "#{secure_token}.#{file.extension}" if original_filename.present?
10
+ end
11
+
12
+ def secure_token
13
+ var = :"@#{mounted_as}_secure_token"
14
+ model.instance_variable_get(var) || model.instance_variable_set(var, SecureRandom.uuid)
15
+ end
16
+
17
+ def image?(new_file)
18
+ new_file.content_type.downcase.include? "image" rescue false
19
+ end
20
+ end
@@ -0,0 +1,24 @@
1
+ .container-fluid
2
+ .row.text-center
3
+ .col-md-8.col-md-offset-2
4
+ .page= @page.text_to_html
5
+ - if contact_email = setting(:contact_email)
6
+ %p
7
+ = link_to "mailto:#{contact_email}", target: :_blank do
8
+ = fa_icon :send
9
+ = contact_email
10
+ - if twitter = setting(:twitter)
11
+ %p
12
+ = link_to "https://twitter.com/#{twitter}", target: :_blank do
13
+ = fa_icon :twitter
14
+ = twitter
15
+ - if facebook = setting(:facebook)
16
+ %p
17
+ = link_to "https://www.facebook.com/#{facebook}", target: :_blank do
18
+ = fa_icon :facebook
19
+ = facebook
20
+ - if instagram = setting(:instagram)
21
+ %p
22
+ = link_to "https://instagram.com/#{instagram}", target: :_blank do
23
+ = fa_icon :instagram
24
+ = instagram
@@ -0,0 +1,4 @@
1
+ .container-fluid
2
+ .row.text-center
3
+ .col-md-8.col-md-offset-2
4
+ .page= @page.text_to_html
@@ -0,0 +1,8 @@
1
+ %body(class="#{action_name} #{controller_name} #{controller_name}-#{action_name}")
2
+ = tomify_render_for :header, :layout
3
+ = tomify_render_for :navbar, :layout
4
+ = tomify_render_for :messages, :layout
5
+ = tomify_render_for :container, :layout
6
+ = tomify_render_for :footer, :layout
7
+ = tomify_render_for :env, :layout
8
+ = tomify_render_for :analytics, :layout
@@ -0,0 +1,3 @@
1
+ .container-fluid
2
+ .row
3
+ .col-md-12= yield
@@ -0,0 +1,2 @@
1
+ :javascript
2
+ window.env = #{js_env.to_json}
@@ -0,0 +1,14 @@
1
+ %head
2
+ %meta(charset="utf-8")
3
+ %meta(http-equiv="X-UA-Compatible" content="IE=edge")
4
+ %meta(name="viewport" content="width=device-width, initial-scale=1")
5
+ = tomify_render_for :sharing
6
+ = tomify_render_for :meta
7
+ - assets = content_for?(:assets) ? yield(:assets) : "application"
8
+ = stylesheet_link_tag assets, media: "all", "data-turbolinks-track" => true
9
+ = javascript_include_tag assets, "data-turbolinks-track" => true
10
+ = content_for :head
11
+ /[if lt IE 9]
12
+ = javascript_include_tag "https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"
13
+ = javascript_include_tag "https://oss.maxcdn.com/respond/1.4.2/respond.min.js"
14
+ = csrf_meta_tags
@@ -0,0 +1,17 @@
1
+ %link(rel="apple-touch-icon" sizes="57x57" href="/apple-icon-57x57.png")
2
+ %link(rel="apple-touch-icon" sizes="60x60" href="/apple-icon-60x60.png")
3
+ %link(rel="apple-touch-icon" sizes="72x72" href="/apple-icon-72x72.png")
4
+ %link(rel="apple-touch-icon" sizes="76x76" href="/apple-icon-76x76.png")
5
+ %link(rel="apple-touch-icon" sizes="114x114" href="/apple-icon-114x114.png")
6
+ %link(rel="apple-touch-icon" sizes="120x120" href="/apple-icon-120x120.png")
7
+ %link(rel="apple-touch-icon" sizes="144x144" href="/apple-icon-144x144.png")
8
+ %link(rel="apple-touch-icon" sizes="152x152" href="/apple-icon-152x152.png")
9
+ %link(rel="apple-touch-icon" sizes="180x180" href="/apple-icon-180x180.png")
10
+ %link(rel="icon" type="image/png" sizes="192x192" href="/android-icon-192x192.png")
11
+ %link(rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png")
12
+ %link(rel="icon" type="image/png" sizes="96x96" href="/favicon-96x96.png")
13
+ %link(rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png")
14
+ %link(rel="manifest" href="/manifest.json")
15
+ %meta(name="msapplication-TileColor" content="#ffffff")
16
+ %meta(name="msapplication-TileImage" content="/ms-icon-144x144.png")
17
+ %meta(name="theme-color" content="#ffffff")
@@ -0,0 +1,23 @@
1
+ - title = content_for(:meta_title) || page.title
2
+ - description = content_for(:meta_description) || page.description
3
+ - image = content_for(:meta_image)
4
+ - image ||= page.share_image.file.url if page.share_image.present?
5
+ - image ||= root_page.share_image.file.url if root_page.share_image.present?
6
+ - url = request.original_url
7
+
8
+ %title= title
9
+ %meta(name="description" content="#{description}")
10
+ %link(rel="canonical" href="#{url}")
11
+
12
+ %meta(property="og:type" content="website")
13
+ %meta(property="og:title" content="#{title}")
14
+ %meta(property="og:description" content="#{description}")
15
+ %meta(property="og:image" content="#{image}")
16
+ %meta(property="og:url" content="#{url}")
17
+ %meta(name="twitter:card" content="summary")
18
+ - if twitter = setting(:twitter)
19
+ %meta(name="twitter:site" content="@#{twitter}")
20
+ %meta(name="twitter:title" content="#{title}")
21
+ %meta(name="twitter:description" content="#{description}")
22
+ %meta(name="twitter:image" content="#{image}")
23
+ %meta(name="twitter:url" content="#{url}")
@@ -0,0 +1,4 @@
1
+ <!DOCTYPE html>
2
+ %html
3
+ = tomify_render_for :head
4
+ = tomify_render_for :body
@@ -0,0 +1,7 @@
1
+ <!DOCTYPE html>
2
+ %html
3
+ %head
4
+ %meta(charset="utf-8")
5
+ %meta(http-equiv="X-UA-Compatible" content="IE=edge")
6
+ %meta(name="viewport" content="width=device-width, initial-scale=1")
7
+ %body= yield
@@ -0,0 +1,13 @@
1
+ %div(style="text-align: center;")
2
+ %p Dear #{@user.first_name},
3
+ %p You've been invited to join #{setting(:name)}!
4
+ = image_tag "gifs/woods.gif"
5
+ %p
6
+ Click
7
+ = link_to "here", root_url(token: @user.token)
8
+ to join!
9
+ = image_tag "gifs/wind.gif"
10
+ %p
11
+ Thanks,
12
+ %br
13
+ = setting(:name)
@@ -0,0 +1,17 @@
1
+ %div(style="text-align: center;")
2
+ %p Dear #{@user.first_name},
3
+ %p Looks like you forgot your password...
4
+ = image_tag "gifs/laughing.gif"
5
+ = image_tag "gifs/sneer.gif"
6
+ %p Sounds like a rough day
7
+ = image_tag "gifs/woods.gif"
8
+ = image_tag "gifs/basketball.gif"
9
+ %p You'll do better next time
10
+ = image_tag "gifs/wind.gif"
11
+ %p
12
+ Guess you can update it
13
+ = link_to "here", root_url(token: @user.token)
14
+ %p
15
+ Thanks,
16
+ %br
17
+ = setting(:name)
@@ -0,0 +1,7 @@
1
+ Rails.application.config.assets.paths << "#{Tomify.root}/app/assets/images/tomify"
2
+ Rails.application.config.assets.paths << "#{Tomify.root}/vendor/tomify/#{Rails.env}"
3
+
4
+ Dir.glob("#{Tomify.root.join("app", "assets", "images")}/**/*").each do |path|
5
+ next if File.directory? path
6
+ Rails.application.config.assets.precompile << path.split("app/assets/images/")[1]
7
+ end
@@ -0,0 +1,3 @@
1
+ Tomify::Engine.config.paths["db/migrate"].expanded.each do |path|
2
+ Rails.application.config.paths["db/migrate"] << path
3
+ end
@@ -0,0 +1,15 @@
1
+ module ActionController
2
+ module Flash
3
+ def render(*args)
4
+ options = args.last.is_a?(Hash) ? args.last : {}
5
+
6
+ self.class._flash_types.each do |type|
7
+ if message = options.delete(type)
8
+ flash[type] = message
9
+ end
10
+ end
11
+
12
+ super(*args)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,4 @@
1
+ if Rails.env.development?
2
+ Rails.application.config.action_mailer.delivery_method = :test
3
+ Rails.application.config.action_mailer.preview_path = "#{Tomify.root}/lib/previews"
4
+ end
@@ -0,0 +1,4 @@
1
+ ActionController::Renderers.add :component do |name, options|
2
+ component = react_component name, options.delete(:props)
3
+ render options.merge(inline: component)
4
+ end
@@ -0,0 +1,5 @@
1
+ if TomifyRecord.connection.table_exists? :settings
2
+ Tomify::CarrierwaveHelper.load_config
3
+ Tomify::EmailHelper.load_config
4
+ Tomify::TimezoneHelper.load_config
5
+ end
data/config/routes.rb ADDED
@@ -0,0 +1,38 @@
1
+ Rails.application.routes.draw do
2
+ scope module: :tomify do
3
+ root "public/pages#root"
4
+
5
+ scope module: :public do
6
+ resource :user, only: :edit
7
+ resource :session, only: :show
8
+ end
9
+
10
+ namespace :admin do
11
+ root "settings#index"
12
+
13
+ resources :pages, only: :index
14
+ resources :settings, only: :index
15
+ resources :sidebars, only: :index
16
+ resources :uploads, only: :index
17
+ resources :users, only: :index
18
+ end
19
+
20
+ namespace :api do
21
+ namespace :admin do
22
+ resources :pages, only: [:index, :create, :show, :update, :destroy]
23
+ resources :settings, only: [:index, :create, :show, :update, :destroy]
24
+ resources :sidebars, only: [:index, :create, :show, :update, :destroy]
25
+ resources :uploads, only: [:index, :create, :show, :update, :destroy]
26
+ resources :users, only: [:index, :create, :show, :update, :destroy]
27
+ end
28
+
29
+ namespace :public do
30
+ resource :user, only: [:create, :show, :update]
31
+ resource :session, only: [:create, :destroy]
32
+ resource :password, only: :create
33
+ end
34
+ end
35
+
36
+ get ":path", to: "public/pages#show", as: :page
37
+ end
38
+ end
@@ -0,0 +1,13 @@
1
+ class CreateUsers < ActiveRecord::Migration[5.0]
2
+ def change
3
+ create_table :users do |t|
4
+ t.boolean :admin, default: false, null: false, index: true
5
+ t.string :email, null: false, index: true
6
+ t.string :first_name, null: false
7
+ t.string :last_name, null: false
8
+ t.string :password_digest
9
+
10
+ t.timestamps null: false
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,10 @@
1
+ class CreateTokens < ActiveRecord::Migration[5.0]
2
+ def change
3
+ create_table :tokens do |t|
4
+ t.integer :user_id, null: false
5
+ t.uuid :uuid, null: false
6
+
7
+ t.timestamps null: false
8
+ end
9
+ end
10
+ end