cambium 1.2.3 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (114) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +8 -3
  3. data/.ruby-version +1 -0
  4. data/README.md +301 -0
  5. data/Rakefile +20 -1
  6. data/app/assets/javascripts/cambium/admin/application.js.coffee +1 -0
  7. data/app/assets/javascripts/cambium/admin/routers/router.js.coffee +8 -17
  8. data/app/assets/javascripts/cambium/admin/templates/image_cropper.jst.ejs +20 -0
  9. data/app/assets/javascripts/cambium/admin/templates/modal.jst.ejs +3 -0
  10. data/app/assets/javascripts/cambium/admin/views/editor.js.coffee +14 -0
  11. data/app/assets/javascripts/cambium/admin/views/image_cropper.js.coffee +27 -0
  12. data/app/assets/javascripts/cambium/admin/views/keyboard_shortcuts.js.coffee +17 -0
  13. data/app/assets/javascripts/cambium/admin/views/media_picker.js.coffee +38 -0
  14. data/app/assets/stylesheets/cambium/admin/application.scss +4 -0
  15. data/app/assets/stylesheets/cambium/admin/partials/_globals.scss +14 -0
  16. data/app/assets/stylesheets/cambium/admin/partials/components.scss +5 -4
  17. data/app/assets/stylesheets/cambium/admin/partials/forms.scss +95 -2
  18. data/app/assets/stylesheets/cambium/admin/partials/modal.scss +40 -0
  19. data/app/assets/stylesheets/cambium/admin/partials/pagination.scss +28 -0
  20. data/app/assets/stylesheets/cambium/admin/partials/tables.scss +18 -27
  21. data/app/assets/stylesheets/cambium/admin/partials/tiles.scss +57 -0
  22. data/app/controllers/cambium/admin/documents_controller.rb +11 -0
  23. data/app/controllers/cambium/admin/pages_controller.rb +15 -0
  24. data/app/controllers/cambium/admin/settings_controller.rb +32 -0
  25. data/app/controllers/cambium/admin_controller.rb +21 -9
  26. data/app/controllers/cambium/pages_controller.rb +17 -0
  27. data/app/helpers/cambium/cambium_helper.rb +148 -116
  28. data/app/models/cambium/document.rb +59 -0
  29. data/app/models/cambium/page.rb +84 -0
  30. data/app/models/cambium/page_template.rb +85 -0
  31. data/app/models/cambium/setting.rb +40 -0
  32. data/app/models/concerns/publishable.rb +0 -21
  33. data/app/views/cambium/admin/documents/index.html.erb +21 -0
  34. data/app/views/cambium/admin/pages/edit.html.erb +16 -0
  35. data/app/views/cambium/admin/paper_trail/versions/_version.html.erb +1 -1
  36. data/app/views/cambium/admin/search/index.html.erb +2 -1
  37. data/app/views/cambium/admin/settings/index.html.erb +15 -0
  38. data/app/views/cambium/pages/home_missing.html.erb +2 -0
  39. data/app/views/layouts/admin.html.erb +1 -1
  40. data/app/views/pages/default.html.erb +13 -0
  41. data/bin/rails +12 -0
  42. data/cambium.gemspec +9 -3
  43. data/config/routes.rb +12 -0
  44. data/db/migrate/20160107161039_create_cambium_pages.rb +19 -0
  45. data/db/migrate/20160108160638_create_cambium_documents.rb +11 -0
  46. data/db/migrate/20160108185904_create_cambium_settings.rb +10 -0
  47. data/db/migrate/20160111154240_add_is_home_to_pages.rb +5 -0
  48. data/db/migrate/20160125174822_add_page_path_to_pages.rb +5 -0
  49. data/db/migrate/20160205190935_add_upload_gravity_to_documents.rb +5 -0
  50. data/lib/cambium.rb +3 -0
  51. data/lib/cambium/engine.rb +21 -0
  52. data/lib/cambium/version.rb +1 -1
  53. data/lib/generators/cambium/admin_generator.rb +1 -1
  54. data/lib/generators/templates/config/admin/documents.yml +23 -0
  55. data/lib/generators/templates/config/admin/pages.yml +56 -0
  56. data/lib/generators/templates/config/admin/settings.yml +19 -0
  57. data/lib/generators/templates/config/admin/sidebar.yml +15 -0
  58. data/lib/generators/templates/config/initializers/assets.rb +3 -1
  59. data/spec/controllers/cambium/admin/documents_controller_spec.rb +7 -0
  60. data/spec/controllers/cambium/admin/pages_controller_spec.rb +7 -0
  61. data/spec/controllers/cambium/admin/settings_controller_spec.rb +7 -0
  62. data/spec/controllers/cambium/pages_controller_spec.rb +7 -0
  63. data/spec/dummy/README.rdoc +28 -0
  64. data/spec/dummy/Rakefile +6 -0
  65. data/spec/dummy/app/assets/images/.keep +0 -0
  66. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  67. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  68. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  69. data/spec/dummy/app/controllers/concerns/.keep +0 -0
  70. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  71. data/spec/dummy/app/mailers/.keep +0 -0
  72. data/spec/dummy/app/models/.keep +0 -0
  73. data/spec/dummy/app/models/concerns/.keep +0 -0
  74. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  75. data/spec/dummy/bin/bundle +3 -0
  76. data/spec/dummy/bin/rails +4 -0
  77. data/spec/dummy/bin/rake +4 -0
  78. data/spec/dummy/bin/setup +29 -0
  79. data/spec/dummy/config.ru +4 -0
  80. data/spec/dummy/config/application.rb +32 -0
  81. data/spec/dummy/config/boot.rb +5 -0
  82. data/spec/dummy/config/database.yml +25 -0
  83. data/spec/dummy/config/environment.rb +5 -0
  84. data/spec/dummy/config/environments/development.rb +41 -0
  85. data/spec/dummy/config/environments/production.rb +79 -0
  86. data/spec/dummy/config/environments/test.rb +42 -0
  87. data/spec/dummy/config/initializers/assets.rb +11 -0
  88. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  89. data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
  90. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  91. data/spec/dummy/config/initializers/inflections.rb +16 -0
  92. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  93. data/spec/dummy/config/initializers/session_store.rb +3 -0
  94. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  95. data/spec/dummy/config/locales/en.yml +23 -0
  96. data/spec/dummy/config/routes.rb +4 -0
  97. data/spec/dummy/config/secrets.yml +22 -0
  98. data/spec/dummy/lib/assets/.keep +0 -0
  99. data/spec/dummy/log/.keep +0 -0
  100. data/spec/dummy/public/404.html +67 -0
  101. data/spec/dummy/public/422.html +67 -0
  102. data/spec/dummy/public/500.html +66 -0
  103. data/spec/dummy/public/favicon.ico +0 -0
  104. data/spec/factories/cambium_documents.rb +7 -0
  105. data/spec/factories/cambium_pages.rb +6 -0
  106. data/spec/factories/cambium_settings.rb +7 -0
  107. data/spec/models/cambium/document_spec.rb +7 -0
  108. data/spec/models/cambium/page_spec.rb +7 -0
  109. data/spec/models/cambium/setting_spec.rb +7 -0
  110. data/spec/spec_helper.rb +18 -0
  111. metadata +219 -11
  112. data/test/controllers/cambium/admin/dashboard_controller_test.rb +0 -9
  113. data/test/controllers/cambium/admin/users_controller_test.rb +0 -9
  114. data/test/controllers/cambium/admin_controller_test.rb +0 -9
@@ -0,0 +1,59 @@
1
+ module Cambium
2
+ class Document < ActiveRecord::Base
3
+
4
+ # ------------------------------------------ Plugins
5
+
6
+ include PgSearch
7
+
8
+ multisearchable :against => [:title]
9
+ has_paper_trail
10
+
11
+ dragonfly_accessor :upload
12
+
13
+ # ------------------------------------------ Scopes
14
+
15
+ scope :last_created, -> { order(:created_at => :desc) }
16
+
17
+ # ------------------------------------------ Validations
18
+
19
+ validates :title, :upload, :presence => true
20
+
21
+ # ------------------------------------------ Instance Methods
22
+
23
+ def to_s
24
+ title
25
+ end
26
+
27
+ def image?
28
+ ['jpg','jpeg','gif','png'].include?(upload.ext.downcase)
29
+ end
30
+
31
+ def pdf?
32
+ upload.ext.downcase == 'pdf'
33
+ end
34
+
35
+ def has_thumb?
36
+ thumb_url.present?
37
+ end
38
+
39
+ def thumb_url
40
+ return image_url(300, 300)
41
+ return png_cover_image_url(300, 300) if pdf?
42
+ nil
43
+ end
44
+
45
+ def image_url(width, height)
46
+ upload.thumb("#{width}x#{height}##{upload_gravity}").url
47
+ end
48
+
49
+ def png_cover_image_url(width, height)
50
+ upload.thumb("#{width}x#{height}##{upload_gravity}", :format => 'png',
51
+ :frame => 0).url
52
+ end
53
+
54
+ def ext
55
+ upload.ext
56
+ end
57
+
58
+ end
59
+ end
@@ -0,0 +1,84 @@
1
+ module Cambium
2
+ class Page < ActiveRecord::Base
3
+
4
+ # ------------------------------------------ Plugins
5
+
6
+ include PgSearch, Publishable
7
+
8
+ multisearchable :against => [:title]
9
+ has_paper_trail
10
+ has_superslug
11
+ has_ancestry
12
+
13
+ # ------------------------------------------ Validations
14
+
15
+ validates :title, :presence => true
16
+
17
+ # ------------------------------------------ Scopes
18
+
19
+ scope :alpha, -> { order(:title => :asc) }
20
+
21
+ # ------------------------------------------ Callbacks
22
+
23
+ after_save :cache_page_path
24
+ after_save :reload_routes!
25
+
26
+ # ------------------------------------------ Class Methods
27
+
28
+ def self.home
29
+ where(:is_home => true).published.first
30
+ end
31
+
32
+ # ------------------------------------------ Instance Methods
33
+
34
+ def to_s
35
+ title
36
+ end
37
+
38
+ def template
39
+ PageTemplate.find(template_name)
40
+ end
41
+
42
+ def body
43
+ html.html_safe
44
+ end
45
+
46
+ def path_preview
47
+ "<a href='#{page_path}' target='_blank'>#{page_path}</a>".html_safe
48
+ end
49
+
50
+ def title_path
51
+ path.collect(&:title).join(' : ')
52
+ end
53
+
54
+ def method_missing(method, *arguments, &block)
55
+ if respond_to?(method.to_s)
56
+ if template.fields[method.to_s]['type'] == 'media'
57
+ Cambium::Document.find_by_id(template_data[method.to_s].to_i)
58
+ else
59
+ template_data[method.to_s]
60
+ end
61
+ else
62
+ super
63
+ end
64
+ end
65
+
66
+ def respond_to?(method, include_private = false)
67
+ return true if super
68
+ return false if template.blank?
69
+ return true if template.fields.keys.include?(method.to_s)
70
+ false
71
+ end
72
+
73
+ private
74
+
75
+ def reload_routes!
76
+ Rails.application.reload_routes!
77
+ end
78
+
79
+ def cache_page_path
80
+ update_columns(:page_path => "/#{path.collect(&:slug).join('/')}")
81
+ end
82
+
83
+ end
84
+ end
@@ -0,0 +1,85 @@
1
+ module Cambium
2
+ class PageTemplate
3
+
4
+ def initialize(attrs)
5
+ attributes(attrs)
6
+ self
7
+ end
8
+
9
+ def attributes(attrs = nil)
10
+ @attributes ||= begin
11
+ name = attrs['file_path'].split('/').last.split('.').first
12
+ attrs.merge('name' => name).stringify_keys
13
+ end
14
+ end
15
+
16
+ def has_fields?
17
+ respond_to?('fields')
18
+ end
19
+
20
+ def method_missing(method, *arguments, &block)
21
+ return attributes[method.to_s] if respond_to?(method.to_s)
22
+ return {} if method.to_s == 'fields'
23
+ super
24
+ end
25
+
26
+ def respond_to?(method, include_private = false)
27
+ attributes.keys.include?(method.to_s)
28
+ end
29
+
30
+ def self.all
31
+ (app_templates + cambium_templates).flatten.sort_by(&:name)
32
+ end
33
+
34
+ def self.names
35
+ all.collect(&:name).flatten.uniq.sort
36
+ end
37
+
38
+ def self.find(name)
39
+ all.select { |t| t.name == name }.first
40
+ end
41
+
42
+ private
43
+
44
+ def self.cambium_template_files
45
+ Dir.glob("#{Cambium::Engine.root}/app/views/pages/*.html*")
46
+ end
47
+
48
+ def self.cambium_templates
49
+ templates = []
50
+ cambium_template_files.each do |f|
51
+ templates << create_from_file(f, :cambium)
52
+ end
53
+ templates.reject { |t| app_templates.collect(&:name).include?(t.name) }
54
+ end
55
+
56
+ def self.app_template_files
57
+ Dir.glob("#{Rails.root}/app/views/pages/*.html*")
58
+ end
59
+
60
+ def self.app_templates
61
+ templates = []
62
+ app_template_files.each do |f|
63
+ templates << create_from_file(f, :app)
64
+ end
65
+ templates
66
+ end
67
+
68
+ def self.create_from_file(file, type)
69
+ yaml_regex = /\A(---\s*\n.*?\n?)^(---\s*$\n?)/m
70
+ content = File.read(file)
71
+ if content =~ yaml_regex
72
+ content = content.sub(yaml_regex, "")
73
+ begin
74
+ attrs = YAML.load($1)
75
+ .merge('file_path' => file, 'type' => type, 'content' => content)
76
+ return PageTemplate.new(attrs)
77
+ rescue => e
78
+ Rails.logger.error "YAML Exception: #{e.message}"
79
+ return nil
80
+ end
81
+ end
82
+ end
83
+
84
+ end
85
+ end
@@ -0,0 +1,40 @@
1
+ module Cambium
2
+ class Setting < ActiveRecord::Base
3
+
4
+ # ------------------------------------------ Plugins
5
+
6
+ include PgSearch
7
+
8
+ multisearchable :against => [:key, :value]
9
+ has_paper_trail
10
+
11
+ # ------------------------------------------ Validations
12
+
13
+ validates :key, :presence => true, :uniqueness => true
14
+
15
+ # ------------------------------------------ Scopes
16
+
17
+ scope :alpha, -> { order(:key => :asc) }
18
+
19
+ # ------------------------------------------ Class Methods
20
+
21
+ def self.keys
22
+ all.collect(&:key)
23
+ end
24
+
25
+ def self.method_missing(method, *arguments, &block)
26
+ super
27
+ rescue
28
+ setting = self.find_by_key(method.to_s)
29
+ return setting.value unless setting.nil?
30
+ super
31
+ end
32
+
33
+ # ------------------------------------------ Instance Methods
34
+
35
+ def to_s
36
+ key.humanize.titleize
37
+ end
38
+
39
+ end
40
+ end
@@ -17,10 +17,6 @@ module Publishable
17
17
  (active_at IS ? AND inactive_at IS ?)",
18
18
  Time.now, Time.now, nil, nil) }
19
19
 
20
- # --------------------------------- Callbacks
21
-
22
- before_save :convert_dates
23
-
24
20
  end
25
21
 
26
22
  # --------------------------------- Instance Methods
@@ -54,23 +50,6 @@ module Publishable
54
50
  inactive_at.strftime("%l:%M %p")
55
51
  end
56
52
 
57
- def convert_dates
58
- self.active_time = Time.now.strftime("%l:%M %p") if self.active_time.blank?
59
- self.inactive_time = '12:00 AM' if self.inactive_time.blank?
60
- if self.active_date.blank?
61
- self.active_at = nil
62
- else
63
- self.active_at = DateTime.strptime("#{self.active_date}
64
- #{self.active_time}", "%d %B, %Y %l:%M %p")
65
- end
66
- if self.inactive_date.blank?
67
- self.inactive_at = nil
68
- else
69
- self.inactive_at = DateTime.strptime("#{self.inactive_date}
70
- #{self.inactive_time}", "%d %B, %Y %l:%M %p")
71
- end
72
- end
73
-
74
53
  def publish!
75
54
  update_column :active_at, Time.now
76
55
  end
@@ -0,0 +1,21 @@
1
+ <%= cambium_page_title(admin_table.title) %>
2
+
3
+ <div id="page-content" class="tiles">
4
+ <% @collection.each do |obj| %>
5
+ <article class="tile <%= obj.ext %>" data-id="<%= obj.id %>"
6
+ data-filename="<%= obj.upload.name %>"
7
+ data-image="<%= obj.image? %>"
8
+ data-thumb="<%= obj.upload.thumb('400x400#').url %>"
9
+ data-url="<%= obj.upload.url %>">
10
+ <%= link_to(cambium.edit_admin_document_path(obj)) do %>
11
+ <%= image_tag(obj.thumb_url) if obj.has_thumb? %>
12
+ <h3><%= obj.title %></h3>
13
+ <% end %>
14
+ </article>
15
+ <% end %>
16
+
17
+
18
+ <div class="pagination">
19
+ <%= paginate @collection %>
20
+ </div>
21
+ </div>
@@ -0,0 +1,16 @@
1
+ <%= cambium_page_title(admin_form.title) %>
2
+
3
+ <div id="page-content"
4
+ data-library="<%= cambium.admin_documents_path(:no_layout => true) %>">
5
+ <%= cambium_form(@object, admin_form.fields) do |f| %>
6
+ <% if @object.template.present? && @object.template.has_fields? %>
7
+ <h2>Custom Template Fields</h2>
8
+ <%= f.simple_fields_for :template_data,
9
+ OpenStruct.new(f.object.template_data) do |td| %>
10
+ <% @object.template.fields.each do |field| %>
11
+ <%= cambium_field(td, @object, field) %>
12
+ <% end %>
13
+ <% end %>
14
+ <% end %>
15
+ <% end %>
16
+ </div>
@@ -10,7 +10,7 @@
10
10
  <p class="action">
11
11
  <%= content_tag(:strong, user.name.present? ? user.name : user.email) %>
12
12
  <%= "#{version.event}d" %>
13
- <%= version.item_type.downcase %>
13
+ <%= version.item_type.downcase.gsub(/cambium::/, '') %>
14
14
  <% if cambium_route(:edit, version.item).nil? %>
15
15
  <%= content_tag(:strong, version.item.to_s) %>
16
16
  <% else %>
@@ -16,7 +16,8 @@
16
16
  <% if @collection.size > 0 %>
17
17
  <% @collection.each do |item| %>
18
18
  <tr>
19
- <%= content_tag(:td, item.searchable_type, :class => 'search-type') %>
19
+ <%= content_tag(:td, item.searchable_type.gsub(/Cambium::/, ''),
20
+ :class => 'search-type') %>
20
21
  <%= content_tag(:td, item.searchable.to_s) %>
21
22
  <%= content_tag(
22
23
  :td,
@@ -0,0 +1,15 @@
1
+ <%= cambium_page_title(admin_table.title) %>
2
+
3
+ <div id="page-content">
4
+ <section class="form settings">
5
+ <% @collection.each do |obj| %>
6
+ <%= simple_form_for [:admin, obj] do |f| %>
7
+ <%= f.input :value,
8
+ :as => admin_view.form.edit.fields.send(obj.key).type,
9
+ :label => admin_view.form.edit.fields.send(obj.key).label,
10
+ :input_html => { :id => obj.key } %>
11
+ <%= f.submit "Save #{admin_view.form.edit.fields.send(obj.key).label}" %>
12
+ <% end %>
13
+ <% end %>
14
+ </section>
15
+ </div>
@@ -0,0 +1,2 @@
1
+ <h1>Home Missing!</h1>
2
+ <p>You need to designate a page as your home page.</p>
@@ -12,7 +12,7 @@
12
12
  <%= javascript_include_tag "modernizr" %>
13
13
  <%= csrf_meta_tags %>
14
14
  </head>
15
- <body class="cambium admin <%= 'dashboard' if controller_name == 'dashboard' %>">
15
+ <body class="cambium admin <%= controller_name %>">
16
16
 
17
17
  <%= render 'cambium/admin/status' %>
18
18
  <%= render 'cambium/admin/header' %>
@@ -0,0 +1,13 @@
1
+ ---
2
+ title: Default
3
+ fields:
4
+ feature_image:
5
+ type: media
6
+ label: Featured Image
7
+ ---
8
+
9
+ <h1><%= @page.title %></h1>
10
+ <%= image_tag @page.feature_image.upload.url if @page.feature_image %>
11
+ <div class="body">
12
+ <%= @page.body %>
13
+ </div>
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+ # This command will automatically be run when you run "rails" with Rails 4 gems installed from the root of your application.
3
+
4
+ ENGINE_ROOT = File.expand_path('../..', __FILE__)
5
+ ENGINE_PATH = File.expand_path('../../lib/cambium/engine', __FILE__)
6
+
7
+ # Set up gems listed in the Gemfile.
8
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
9
+ require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
10
+
11
+ require 'rails/all'
12
+ require 'rails/engine/commands'
@@ -14,12 +14,17 @@ Gem::Specification.new do |spec|
14
14
  spec.license = "MIT"
15
15
 
16
16
  spec.files = `git ls-files -z`.split("\x0")
17
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
17
+ spec.test_files = Dir["spec/**/*"]
18
18
  spec.require_paths = ["lib"]
19
19
 
20
- spec.add_development_dependency "bundler", "~> 1.6"
20
+ spec.add_development_dependency 'bundler', '~> 1.10'
21
+ spec.add_development_dependency 'rspec-rails'
22
+ spec.add_development_dependency 'capybara'
23
+ spec.add_development_dependency 'factory_girl_rails'
21
24
 
25
+ spec.add_dependency 'ancestry'
22
26
  spec.add_dependency 'bones-rails', '>= 1.1.3'
27
+ spec.add_dependency 'dragonfly'
23
28
  spec.add_dependency 'kaminari'
24
29
  spec.add_dependency 'mark_it_zero', '~> 0.3.0'
25
30
  spec.add_dependency 'paper_trail'
@@ -27,6 +32,7 @@ Gem::Specification.new do |spec|
27
32
  spec.add_dependency 'pickadate-rails'
28
33
  spec.add_dependency 'rails'
29
34
  spec.add_dependency 'rake'
30
- spec.add_dependency 'superslug'
35
+ spec.add_dependency 'superslug', '~> 1.3.0'
36
+ spec.add_dependency 'trumbowyg_rails'
31
37
 
32
38
  end