spina 0.9.0 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of spina might be problematic. Click here for more details.

Files changed (99) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +6 -2
  3. data/app/assets/javascripts/spina/admin/account.js.coffee +1 -1
  4. data/app/assets/javascripts/spina/admin/pages.js.coffee.erb +1 -1
  5. data/app/assets/javascripts/spina/admin/spina.infinite_scroll.coffee +6 -2
  6. data/app/assets/javascripts/spina/admin/spina.scaffold.coffee +2 -2
  7. data/app/assets/javascripts/spina/admin/{spina.trix.js.coffee → spina.trix.js.coffee.erb} +1 -1
  8. data/app/assets/stylesheets/spina/admin/application.sass +3 -0
  9. data/app/controllers/spina/admin/accounts_controller.rb +0 -2
  10. data/app/controllers/spina/admin/admin_controller.rb +0 -2
  11. data/app/controllers/spina/admin/attachments_controller.rb +5 -3
  12. data/app/controllers/spina/admin/pages_controller.rb +1 -2
  13. data/app/controllers/spina/admin/photos_controller.rb +9 -6
  14. data/app/controllers/spina/admin/users_controller.rb +0 -2
  15. data/app/controllers/spina/pages_controller.rb +17 -6
  16. data/app/helpers/spina/admin/pages_helper.rb +15 -0
  17. data/app/models/spina/account.rb +8 -7
  18. data/app/models/spina/application_record.rb +5 -0
  19. data/app/models/spina/attachment.rb +6 -1
  20. data/app/models/spina/attachment_collection.rb +1 -1
  21. data/app/models/spina/color.rb +1 -1
  22. data/app/models/spina/layout_part.rb +1 -1
  23. data/app/models/spina/line.rb +1 -1
  24. data/app/models/spina/page.rb +10 -2
  25. data/app/models/spina/page_part.rb +1 -1
  26. data/app/models/spina/photo.rb +2 -2
  27. data/app/models/spina/photo_collection.rb +1 -1
  28. data/app/models/spina/photo_collections_photo.rb +1 -1
  29. data/app/models/spina/rewrite_rule.rb +1 -1
  30. data/app/models/spina/structure.rb +1 -1
  31. data/app/models/spina/structure_item.rb +9 -4
  32. data/app/models/spina/structure_part.rb +1 -1
  33. data/app/models/spina/text.rb +1 -1
  34. data/app/models/spina/user.rb +1 -1
  35. data/app/presenters/spina/pages/breadcrumb.rb +102 -0
  36. data/app/presenters/spina/pages/menu_presenter.rb +16 -5
  37. data/app/views/layouts/spina/admin/admin.html.haml +31 -0
  38. data/app/views/layouts/spina/admin/media_library.html.haml +11 -9
  39. data/app/views/spina/admin/accounts/_form.html.haml +29 -23
  40. data/app/views/spina/admin/accounts/analytics.html.haml +19 -15
  41. data/app/views/spina/admin/accounts/social.html.haml +19 -15
  42. data/app/views/spina/admin/accounts/style.html.haml +19 -15
  43. data/app/views/spina/admin/attachments/_select.html.haml +1 -1
  44. data/app/views/spina/admin/attachments/_select_collection.html.haml +1 -1
  45. data/app/views/spina/admin/attachments/insert.js.coffee +5 -0
  46. data/app/views/spina/admin/attachments/insert_collection.js.coffee +7 -0
  47. data/app/views/spina/admin/page_partables/attachment_collections/_form.html.haml +8 -9
  48. data/app/views/spina/admin/page_partables/attachments/_form.html.haml +7 -8
  49. data/app/views/spina/admin/page_partables/photo_collections/_form.html.haml +2 -2
  50. data/app/views/spina/admin/page_partables/photos/_form.html.haml +6 -10
  51. data/app/views/spina/admin/pages/_form.html.haml +25 -6
  52. data/app/views/spina/admin/pages/_form_advanced.html.haml +45 -45
  53. data/app/views/spina/admin/pages/_form_page_content.html.haml +1 -1
  54. data/app/views/spina/admin/pages/_form_page_seo.html.haml +1 -1
  55. data/app/views/spina/admin/pages/edit.html.haml +0 -19
  56. data/app/views/spina/admin/pages/index.html.haml +36 -29
  57. data/app/views/spina/admin/pages/new.html.haml +0 -10
  58. data/app/views/spina/admin/photos/_photo_collection_select.html.haml +4 -4
  59. data/app/views/spina/admin/photos/_photo_multi_picker.html.haml +2 -2
  60. data/app/views/spina/admin/photos/_photo_select.html.haml +4 -1
  61. data/app/views/spina/admin/photos/_photo_single_picker.html.haml +2 -2
  62. data/app/views/spina/admin/photos/index.html.haml +3 -2
  63. data/app/views/spina/admin/photos/insert_photo.js.erb +4 -4
  64. data/app/views/spina/admin/photos/insert_photo_collection.js.erb +6 -3
  65. data/app/views/spina/admin/photos/multi_picker_infinite_scroll.js.erb +1 -1
  66. data/app/views/spina/admin/photos/single_picker_infinite_scroll.js.erb +1 -1
  67. data/app/views/spina/admin/shared/_breadcrumbs.html.haml +1 -0
  68. data/app/views/spina/admin/shared/_notifications.html.haml +23 -12
  69. data/app/views/spina/admin/shared/_primary_navigation.html.haml +43 -3
  70. data/app/views/spina/admin/structure_partables/photos/_form.html.haml +3 -6
  71. data/app/views/spina/admin/users/_form.html.haml +37 -33
  72. data/app/views/spina/admin/users/index.html.haml +27 -23
  73. data/config/initializers/assets.rb +1 -1
  74. data/config/locales/de.yml +4 -0
  75. data/config/locales/en.yml +6 -1
  76. data/config/locales/es.yml +4 -0
  77. data/config/locales/fr.yml +4 -0
  78. data/config/locales/it.yml +4 -0
  79. data/config/locales/nl.yml +8 -0
  80. data/config/locales/pt-BR.yml +4 -0
  81. data/config/locales/ru.yml +16 -4
  82. data/config/locales/tr.yml +4 -0
  83. data/config/locales/zh-CN.yml +4 -0
  84. data/config/routes.rb +3 -3
  85. data/lib/generators/spina/install_generator.rb +31 -11
  86. data/lib/generators/spina/templates/app/views/default/pages/homepage.html.haml +1 -1
  87. data/lib/generators/spina/templates/app/views/default/pages/show.html.haml +1 -1
  88. data/lib/generators/spina/templates/app/views/demo/pages/homepage.html.haml +1 -1
  89. data/lib/generators/spina/templates/app/views/demo/pages/show.html.haml +1 -1
  90. data/lib/generators/spina/templates/config/initializers/spina.rb +1 -0
  91. data/lib/spina.rb +2 -1
  92. data/lib/spina/version.rb +1 -1
  93. data/lib/tasks/spina_tasks.rake +9 -1
  94. metadata +33 -18
  95. data/app/views/layouts/spina/admin/application.html.haml +0 -40
  96. data/app/views/layouts/spina/admin/settings.html.haml +0 -45
  97. data/app/views/layouts/spina/admin/website.html.haml +0 -26
  98. data/app/views/spina/admin/attachments/insert.js.erb +0 -5
  99. data/app/views/spina/admin/attachments/insert_collection.js.erb +0 -7
@@ -1,5 +1,5 @@
1
1
  module Spina
2
- class PhotoCollection < ActiveRecord::Base
2
+ class PhotoCollection < ApplicationRecord
3
3
 
4
4
  has_one :page_part, as: :page_partable
5
5
  has_many :photo_collections_photos, autosave: true
@@ -1,5 +1,5 @@
1
1
  module Spina
2
- class PhotoCollectionsPhoto < ActiveRecord::Base
2
+ class PhotoCollectionsPhoto < ApplicationRecord
3
3
  belongs_to :photo
4
4
  belongs_to :photo_collection
5
5
  end
@@ -1,5 +1,5 @@
1
1
  module Spina
2
- class RewriteRule < ActiveRecord::Base
2
+ class RewriteRule < ApplicationRecord
3
3
  validates :old_path, uniqueness: true
4
4
  end
5
5
  end
@@ -1,5 +1,5 @@
1
1
  module Spina
2
- class Structure < ActiveRecord::Base
2
+ class Structure < ApplicationRecord
3
3
  has_one :page_part, as: :page_partable
4
4
  has_many :structure_items
5
5
 
@@ -1,15 +1,20 @@
1
1
  module Spina
2
- class StructureItem < ActiveRecord::Base
2
+ class StructureItem < ApplicationRecord
3
+ before_validation :ensure_position
3
4
  belongs_to :structure
4
5
  has_many :structure_parts, dependent: :destroy
5
6
 
6
7
  scope :sorted_by_structure, -> { order('position') }
7
8
 
9
+ validates_presence_of :position
8
10
  accepts_nested_attributes_for :structure_parts, allow_destroy: true
9
11
 
10
12
  def content(structure_part)
11
- structure_part = structure_parts.where(name: structure_part).first
12
- structure_part.try(:content)
13
+ structure_parts.find_by(name: structure_part).try(:content)
14
+ end
15
+
16
+ def ensure_position
17
+ self.position ||= Time.now.to_i
13
18
  end
14
19
  end
15
- end
20
+ end
@@ -1,5 +1,5 @@
1
1
  module Spina
2
- class StructurePart < ActiveRecord::Base
2
+ class StructurePart < ApplicationRecord
3
3
  include Part
4
4
 
5
5
  belongs_to :structure_item
@@ -1,5 +1,5 @@
1
1
  module Spina
2
- class Text < ActiveRecord::Base
2
+ class Text < ApplicationRecord
3
3
  translates :content
4
4
 
5
5
  has_many :page_parts, as: :page_partable
@@ -1,5 +1,5 @@
1
1
  module Spina
2
- class User < ActiveRecord::Base
2
+ class User < ApplicationRecord
3
3
  has_secure_password
4
4
 
5
5
  validates_presence_of :name, :email
@@ -0,0 +1,102 @@
1
+ # require 'active_support/core_ext/string'
2
+ require 'active_support/configurable'
3
+ require 'action_view/helpers/tag_helper'
4
+ require 'action_view/helpers/url_helper'
5
+
6
+ module Spina
7
+ module Pages
8
+ class Breadcrumb
9
+ include ActionView::Helpers::TagHelper
10
+ include ActionView::Helpers::UrlHelper
11
+ include ActiveSupport::Configurable
12
+
13
+ config_accessor :list_tag, :list_class, :li, :list_wrapper, :list_item_tag, :list_item_css, :last_item_css
14
+
15
+ self.list_tag = :ul
16
+ self.list_class = 'breadcrumb'
17
+ self.list_item_tag = :li
18
+ self.list_item_css = nil
19
+ self.last_item_css = 'active'
20
+ self.list_wrapper = false
21
+
22
+ attr_accessor :context, :current_page, :include_homepage, :breadcrumb_items, :homepage
23
+ delegate :output_buffer, :output_buffer=, to: :context
24
+
25
+ def initialize(page, context, include_homepage = true)
26
+ @current_page = page
27
+ @include_homepage = include_homepage
28
+ @context = context
29
+ @breadcrumb_items = Array.new()
30
+ @homepage = Page.find_by(name: :homepage)
31
+
32
+ build_breadcrumb(page) unless @homepage.id == @current_page.id
33
+ end
34
+
35
+ def to_html
36
+ render_breadcrumb_wrapper(@breadcrumb_items)
37
+ end
38
+
39
+ private
40
+
41
+ def build_breadcrumb(page)
42
+ if !page.nil?
43
+ @breadcrumb_items.push(page)
44
+
45
+ build_breadcrumb(page.parent)
46
+ else
47
+ # Manually insert homepage and reverse the breadcrumb items once you hit the latest parent
48
+ @breadcrumb_items.push(homepage) if @include_homepage
49
+ @breadcrumb_items = @breadcrumb_items.reverse unless @breadcrumb_items.empty?
50
+ end
51
+ end
52
+
53
+ def render_breadcrumb_wrapper(items)
54
+ if items.any?
55
+ if list_wrapper
56
+ content_tag(:div) do
57
+ render_breadcrumb_items(items)
58
+ end
59
+ else
60
+ render_breadcrumb_items(items)
61
+ end
62
+ end
63
+ end
64
+
65
+ def render_breadcrumb_items(items)
66
+ content_tag(list_tag, class: breadcrumb_list_css) do
67
+ items.each_with_index.inject(ActiveSupport::SafeBuffer.new) do |buffer, (item, index)|
68
+ buffer << render_breadcrumb_item(item, index, items.length)
69
+ end
70
+ end
71
+ end
72
+
73
+ def render_breadcrumb_item(item, index, items_length)
74
+ content_tag(list_item_tag, class: breadcrumb_item_css(item, index, items_length)) do
75
+ buffer = ActiveSupport::SafeBuffer.new
76
+ if index + 1 == items_length
77
+ buffer << item.title
78
+ else
79
+ buffer << link_to(item.title, item.full_materialized_path)
80
+ end
81
+ buffer
82
+ end
83
+ end
84
+
85
+ def breadcrumb_list_css
86
+ css = []
87
+ css << list_class
88
+
89
+ css.reject(&:blank?).presence
90
+ end
91
+
92
+ def breadcrumb_item_css(item, index, items_length)
93
+ css = []
94
+ css << list_item_css
95
+ css << last_item_css if index + 1 == items_length
96
+
97
+ css.reject(&:blank?).presence
98
+ end
99
+
100
+ end
101
+ end
102
+ end
@@ -10,7 +10,7 @@ module Spina
10
10
  include ActionView::Helpers::UrlHelper
11
11
  include ActiveSupport::Configurable
12
12
 
13
- config_accessor :list_tag, :list_class, :li, :list_wrapper, :list_item_tag, :list_item_css, :selected_css, :current_css, :first_css, :last_css
13
+ config_accessor :list_tag, :list_class, :li, :list_wrapper, :list_item_tag, :list_item_css, :selected_css, :current_css, :first_css, :last_css, :list_tag_with_child_css, :list_item_with_child_css
14
14
 
15
15
  self.list_tag = :ul
16
16
  self.list_class = 'nav'
@@ -21,6 +21,8 @@ module Spina
21
21
  self.current_css = 'current'
22
22
  self.first_css = 'first'
23
23
  self.last_css = 'last'
24
+ self.list_tag_with_child_css = 'dropdown-menu'
25
+ self.list_item_with_child_css = 'dropdown'
24
26
 
25
27
  attr_accessor :context, :collection, :current_menu_item
26
28
  delegate :output_buffer, :output_buffer=, to: :context
@@ -51,7 +53,7 @@ module Spina
51
53
  end
52
54
 
53
55
  def render_menu_items(menu_items)
54
- content_tag(list_tag, class: list_class) do
56
+ content_tag(list_tag, class: menu_items_css(menu_items)) do
55
57
  menu_items.each_with_index.inject(ActiveSupport::SafeBuffer.new) do |buffer, (item, index)|
56
58
  buffer << render_menu_item(item, index, menu_items.length)
57
59
  end
@@ -59,21 +61,30 @@ module Spina
59
61
  end
60
62
 
61
63
  def render_menu_item(menu_item, index, menu_items_length)
62
- content_tag(list_item_tag, class: menu_item_css(menu_item[0], index, menu_items_length)) do
64
+ content_tag(list_item_tag, class: menu_item_css(menu_item[0], index, menu_items_length, !menu_item[1].empty?)) do
63
65
  buffer = ActiveSupport::SafeBuffer.new
64
- buffer << link_to(menu_item[0].menu_title, menu_item[0].materialized_path)
66
+ buffer << link_to(menu_item[0].menu_title, menu_item[0].full_materialized_path)
65
67
  buffer << render_list_wrapper(menu_item[1])
66
68
  buffer
67
69
  end
68
70
  end
69
71
 
70
- def menu_item_css(menu_item, index, menu_items_length)
72
+ def menu_items_css(menu_items)
73
+ css = []
74
+ css << list_class
75
+ css << list_tag_with_child_css if !menu_items.first[0].ancestry.nil?
76
+
77
+ css.reject(&:blank?).presence
78
+ end
79
+
80
+ def menu_item_css(menu_item, index, menu_items_length, has_child)
71
81
  css = []
72
82
  css << list_item_css
73
83
  css << selected_css if (@selected_menu_items.present? && @selected_menu_items.include?(menu_item) )
74
84
  css << current_css if @current_menu_item == menu_item
75
85
  css << first_css if index == 0
76
86
  css << last_css if index + 1 == menu_items_length
87
+ css << list_item_with_child_css if has_child
77
88
 
78
89
  css.reject(&:blank?).presence
79
90
  end
@@ -0,0 +1,31 @@
1
+ !!!
2
+ %html{lang: I18n.locale}
3
+ %head
4
+ %meta{charset: 'utf-8'}
5
+ %meta{name: 'viewport', content: 'initial-scale=1.0, user-scalable=no'}
6
+ = csrf_meta_tags
7
+
8
+ %title Spina
9
+
10
+ / Stylesheet
11
+ = stylesheet_link_tag 'spina/admin/application', data: {turbolinks_track: true}
12
+
13
+ /[if lt IE 9]
14
+ = javascript_include_tag '//html5shiv.googlecode.com/svn/trunk/html5.js', data: {turbolinks_track: true}
15
+
16
+ / JavaScript
17
+ = javascript_include_tag 'spina/admin/application', data: {turbolinks_track: true}
18
+ = yield(:plugin_stylesheets)
19
+
20
+ %body
21
+ = render 'spina/admin/shared/primary_navigation'
22
+
23
+ %section#main
24
+ = yield(:permanent_notice)
25
+
26
+ = render 'spina/admin/shared/notifications'
27
+
28
+ = content_for?(:application) ? yield(:application) : yield
29
+
30
+ = link_to 'http://www.spinacms.com', class: 'spina-logo', target: :blank do
31
+ = image_tag('spina/spina.png')
@@ -1,12 +1,14 @@
1
- - content_for(:tertiary_navigation) do
2
- %nav.tabs
3
- %ul
4
- %li{class: ('active' if controller_name == 'photos')}
5
- = link_to Spina::Photo.model_name.human(count: 2), spina.admin_photos_path
6
- %li{class: ('active' if controller_name == 'attachments')}
7
- = link_to Spina::Attachment.model_name.human(count: 2), spina.admin_attachments_path
1
+ - content_for :application do
2
+ %header#header
3
+ = render partial: 'spina/admin/shared/breadcrumbs'
4
+
5
+ %nav#secondary.tabs
6
+ %ul
7
+ %li{class: ('active' if controller_name == 'photos')}
8
+ = link_to t('spina.media_library.photos'), spina.admin_photos_path
9
+ %li{class: ('active' if controller_name == 'attachments')}
10
+ = link_to t('spina.media_library.attachments'), spina.admin_attachments_path
8
11
 
9
- - content_for :website do
10
12
  = yield
11
13
 
12
- = render template: 'layouts/spina/admin/website'
14
+ = render template: "layouts/spina/admin/admin"
@@ -1,42 +1,48 @@
1
1
  = form_for [spina, :admin, current_account] do |f|
2
- .table-container
3
- %table.table.table-form
4
- %tr
5
- %td
2
+ %header#header
3
+ = render partial: 'spina/admin/shared/breadcrumbs'
4
+
5
+ #header_actions
6
+ %button.button.button-primary{type: 'submit'}
7
+ = icon('check')
8
+ = t('spina.preferences.account_save')
9
+
10
+ .well
11
+ .horizontal-form
12
+ .horizontal-form-group
13
+ .horizontal-form-label
6
14
  = Spina::Account.human_attribute_name(:name)
7
- %td
15
+ .horizontal-form-content
8
16
  = f.text_field :name, placeholder: Spina::Account.human_attribute_name(:name)
9
17
 
10
- %tr
11
- %td
18
+ .horizontal-form-group
19
+ .horizontal-form-label
12
20
  = Spina::Account.human_attribute_name(:address)
13
- %td
21
+ .horizontal-form-content
14
22
  = f.text_field :address, placeholder: Spina::Account.human_attribute_name(:address)
15
23
 
16
- %tr
17
- %td
24
+ .horizontal-form-group
25
+ .horizontal-form-label
18
26
  = Spina::Account.human_attribute_name(:postal_code)
19
- %td
27
+ .horizontal-form-content
20
28
  = f.text_field :postal_code, placeholder: Spina::Account.human_attribute_name(:postal_code)
21
29
 
22
- %tr
23
- %td
30
+ .horizontal-form-group
31
+ .horizontal-form-label
24
32
  = Spina::Account.human_attribute_name(:city)
25
- %td
33
+ .horizontal-form-content
26
34
  = f.text_field :city, placeholder: Spina::Account.human_attribute_name(:city)
27
35
 
28
- %tr
29
- %td
36
+ .horizontal-form-group
37
+ .horizontal-form-label
30
38
  = Spina::Account.human_attribute_name(:phone)
31
- %td
39
+ .horizontal-form-content
32
40
  = f.text_field :phone, placeholder: Spina::Account.human_attribute_name(:phone)
33
41
 
34
- %tr
35
- %td
42
+ .horizontal-form-group
43
+ .horizontal-form-label
36
44
  = Spina::Account.human_attribute_name(:email)
37
- %td
45
+ .horizontal-form-content
38
46
  = f.text_field :email, placeholder: Spina::Account.human_attribute_name(:email)
39
47
 
40
- %button.button.button-primary{type: 'submit'}
41
- = icon('check')
42
- = t('spina.preferences.account_save')
48
+
@@ -1,22 +1,26 @@
1
1
  = form_for [spina, :admin, current_account] do |f|
2
- .table-container
3
- %table.table.table-form
4
- %tr
5
- %td
2
+ %header#header
3
+ = render partial: 'spina/admin/shared/breadcrumbs'
4
+
5
+ #header_actions
6
+ %button.button.button-primary{type: 'submit'}
7
+ = icon('check')
8
+ = t('spina.preferences.analytics_save')
9
+
10
+ .well
11
+ .horizontal-form
12
+ .horizontal-form-group
13
+ .horizontal-form-label
6
14
  = Spina::Account.human_attribute_name(:robots_allowed)
7
- %td
15
+ .horizontal-form-content
8
16
  = f.check_box :robots_allowed, data: {switch: true}
9
- %tr
10
- %td
17
+ .horizontal-form-group
18
+ .horizontal-form-label
11
19
  = Spina::Account.human_attribute_name(:google_analytics)
12
- %td
20
+ .horizontal-form-content
13
21
  = f.text_field :google_analytics, placeholder: Spina::Account.human_attribute_name(:google_analytics)
14
- %tr
15
- %td
22
+ .horizontal-form-group
23
+ .horizontal-form-label
16
24
  = Spina::Account.human_attribute_name(:google_site_verification)
17
- %td
25
+ .horizontal-form-content
18
26
  = f.text_field :google_site_verification, placeholder: Spina::Account.human_attribute_name(:google_site_verification)
19
-
20
- %button.button.button-primary{type: 'submit'}
21
- = icon('check')
22
- = t('spina.preferences.analytics_save')
@@ -1,24 +1,28 @@
1
1
  = form_for [spina, :admin, current_account] do |f|
2
- .table-container
3
- %table.table.table-form
4
- %tr
5
- %td
2
+ %header#header
3
+ = render partial: 'spina/admin/shared/breadcrumbs'
4
+
5
+ #header_actions
6
+ %button.button.button-primary{type: 'submit'}
7
+ = icon('check')
8
+ = t('spina.preferences.social_media_save')
9
+
10
+ .well
11
+ .horizontal-form
12
+ .horizontal-form-group
13
+ .horizontal-form-label
6
14
  = Spina::Account.human_attribute_name(:facebook)
7
- %td
15
+ .horizontal-form-content
8
16
  = f.text_field :facebook, placeholder: Spina::Account.human_attribute_name(:facebook)
9
17
 
10
- %tr
11
- %td
18
+ .horizontal-form-group
19
+ .horizontal-form-label
12
20
  = Spina::Account.human_attribute_name(:twitter)
13
- %td
21
+ .horizontal-form-content
14
22
  = f.text_field :twitter, placeholder: Spina::Account.human_attribute_name(:twitter)
15
23
 
16
- %tr
17
- %td
24
+ .horizontal-form-group
25
+ .horizontal-form-label
18
26
  = Spina::Account.human_attribute_name(:google_plus)
19
- %td
27
+ .horizontal-form-content
20
28
  = f.text_field :google_plus, placeholder: Spina::Account.human_attribute_name(:google_plus)
21
-
22
- %button.button.button-primary{type: 'submit'}
23
- = icon('check')
24
- = t('spina.preferences.social_media_save')