tomify 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
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