spina 0.11.1 → 0.12.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.
- checksums.yaml +4 -4
- data/README.md +41 -12
- data/Rakefile +1 -0
- data/app/assets/fonts/spina/ics_spina.eot +0 -0
- data/app/assets/fonts/spina/ics_spina.svg +5 -3
- data/app/assets/fonts/spina/ics_spina.ttf +0 -0
- data/app/assets/fonts/spina/ics_spina.woff +0 -0
- data/app/assets/icons/spina/lock.svg +3 -0
- data/app/assets/icons/spina/preview/ics_spina-preview.html +16 -1
- data/app/assets/javascripts/spina/admin/application.coffee.erb +3 -25
- data/app/assets/javascripts/spina/admin/navigation.coffee +7 -0
- data/app/assets/javascripts/spina/admin/pages.coffee.erb +1 -13
- data/app/assets/javascripts/spina/admin/trix.coffee.erb +2 -1
- data/app/assets/stylesheets/spina/_admin_editing.sass +0 -4
- data/app/assets/stylesheets/spina/_buttons.sass +8 -8
- data/app/assets/stylesheets/spina/_configuration.sass +5 -1
- data/app/assets/stylesheets/spina/_custom_animations.sass +26 -26
- data/app/assets/stylesheets/spina/_fonts.sass +5 -1
- data/app/assets/stylesheets/spina/_forms.sass +66 -33
- data/app/assets/stylesheets/spina/_gallery.sass +32 -15
- data/app/assets/stylesheets/spina/_ics_spina.scss +1 -0
- data/app/assets/stylesheets/spina/_login.sass +10 -4
- data/app/assets/stylesheets/spina/_mixins.sass +5 -0
- data/app/assets/stylesheets/spina/_modal.sass +4 -4
- data/app/assets/stylesheets/spina/_notifications.sass +5 -5
- data/app/assets/stylesheets/spina/_sortable_lists.sass +9 -9
- data/app/assets/stylesheets/spina/_tables.sass +9 -9
- data/app/assets/stylesheets/spina/_wizard.sass +5 -5
- data/app/assets/stylesheets/spina/admin/application.sass +4 -1
- data/app/assets/stylesheets/spina/application.sass +0 -1
- data/app/assets/stylesheets/spina.sass +23 -27
- data/app/controllers/spina/admin/accounts_controller.rb +2 -7
- data/app/controllers/spina/admin/admin_controller.rb +8 -3
- data/app/controllers/spina/admin/attachments_controller.rb +0 -2
- data/app/controllers/spina/admin/navigations_controller.rb +3 -2
- data/app/controllers/spina/admin/pages_controller.rb +7 -8
- data/app/controllers/spina/admin/password_resets_controller.rb +49 -0
- data/app/controllers/spina/admin/photos_controller.rb +15 -34
- data/app/controllers/spina/admin/sessions_controller.rb +1 -1
- data/app/controllers/spina/admin/users_controller.rb +8 -9
- data/app/controllers/spina/application_controller.rb +3 -9
- data/app/controllers/spina/pages_controller.rb +3 -3
- data/app/helpers/spina/admin/pages_helper.rb +16 -23
- data/app/mailers/spina/user_mailer.rb +21 -0
- data/app/models/concerns/spina/optionable.rb +12 -0
- data/app/models/concerns/spina/part.rb +5 -1
- data/app/models/concerns/spina/partable.rb +20 -5
- data/app/models/concerns/spina/photo_collectable.rb +24 -0
- data/app/models/spina/account.rb +16 -6
- data/app/models/spina/layout_part.rb +1 -0
- data/app/models/spina/option.rb +17 -0
- data/app/models/spina/page.rb +36 -63
- data/app/models/spina/page_part.rb +1 -0
- data/app/models/spina/photo_collection.rb +1 -13
- data/app/models/spina/structure_item.rb +4 -8
- data/app/models/spina/structure_part.rb +2 -13
- data/app/models/spina/user.rb +1 -0
- data/app/presenters/spina/pages/menu_presenter.rb +18 -49
- data/app/views/layouts/spina/mail.html.erb +1 -0
- data/app/views/spina/admin/page_partables/{colors → options}/_form.html.haml +2 -3
- data/app/views/spina/admin/page_partables/photo_collections/_form.html.haml +7 -7
- data/app/views/spina/admin/page_partables/structures/_form.html.haml +7 -8
- data/app/views/spina/admin/pages/_form.html.haml +2 -2
- data/app/views/spina/admin/pages/_form_advanced.html.haml +2 -2
- data/app/views/spina/admin/password_resets/edit.html.haml +13 -0
- data/app/views/spina/admin/password_resets/new.html.haml +13 -0
- data/app/views/spina/admin/photos/_photo.html.haml +2 -1
- data/app/views/spina/admin/photos/{_wysihtml5_select.html.haml → _trix_select.html.haml} +2 -4
- data/app/views/spina/admin/photos/create.js.erb +3 -5
- data/app/views/spina/admin/photos/{wysihtml5_infinite_scroll.js.erb → trix_infinite_scroll.js.erb} +0 -2
- data/app/views/spina/admin/photos/{wysihtml5_insert.js.coffee → trix_insert.js.erb} +2 -2
- data/app/views/spina/admin/photos/trix_select.js.erb +3 -0
- data/app/views/spina/admin/sessions/new.html.haml +3 -1
- data/app/views/spina/admin/shared/_primary_navigation.html.haml +1 -1
- data/app/views/spina/admin/shared/_rich_text_field.html.haml +2 -1
- data/app/views/spina/admin/structure_items/_fields.html.haml +3 -3
- data/app/views/spina/admin/structure_partables/lines/_form.html.haml +5 -2
- data/app/views/spina/admin/structure_partables/options/_form.html.haml +7 -0
- data/app/views/spina/admin/structure_partables/photo_collections/_form.html.haml +12 -9
- data/app/views/spina/admin/structure_partables/photos/_form.html.haml +10 -7
- data/app/views/spina/admin/structure_partables/texts/_form.html.haml +5 -2
- data/app/views/spina/admin/users/_form.html.haml +1 -1
- data/app/views/spina/shared/_admin_bar.html.haml +1 -1
- data/app/views/spina/shared/_navigation.html.haml +1 -1
- data/app/views/spina/user_mailer/forgot_password.html.erb +1 -0
- data/app/views/spina/user_mailer/forgot_password.txt.erb +1 -0
- data/config/locales/en.yml +10 -0
- data/config/locales/nl.yml +2 -0
- data/config/routes.rb +5 -9
- data/db/migrate/1_create_spina_tables.rb +8 -7
- data/db/migrate/2_create_spina_translation_tables.rb +7 -26
- data/db/migrate/3_create_spina_navigations.rb +1 -1
- data/db/migrate/4_add_password_reset_token_to_spina_users.rb +6 -0
- data/db/migrate/5_remove_translated_columns.rb +11 -0
- data/db/migrate/6_create_spina_options.rb +8 -0
- data/lib/generators/spina/install_generator.rb +0 -22
- data/lib/generators/spina/templates/app/views/default/shared/_navigation.html.haml +1 -1
- data/lib/generators/spina/templates/app/views/demo/shared/_navigation.html.haml +1 -1
- data/lib/generators/spina/templates/config/initializers/themes/default.rb +9 -0
- data/lib/generators/spina/templates/config/initializers/themes/demo.rb +1 -9
- data/lib/spina/engine.rb +4 -3
- data/lib/spina/theme.rb +2 -1
- data/lib/spina/version.rb +1 -1
- data/lib/spina.rb +0 -23
- metadata +32 -69
- data/app/assets/images/spina/marker.png +0 -0
- data/app/assets/images/spina/mask.png +0 -0
- data/app/assets/images/spina/wheel.png +0 -0
- data/app/assets/stylesheets/spina/_cards.sass +0 -54
- data/app/assets/stylesheets/spina/_farbtastic.sass +0 -37
- data/app/assets/stylesheets/spina/_wysihtml5.sass +0 -79
- data/app/assets/stylesheets/spina/wysihtml5_textarea.sass +0 -14
- data/app/controllers/spina/admin/page_parts_controller.rb +0 -11
- data/app/helpers/spina/application_helper.rb +0 -30
- data/app/models/spina/ability.rb +0 -20
- data/app/models/spina/color.rb +0 -7
- data/app/presenters/spina/pages/breadcrumb.rb +0 -102
- data/app/views/layouts/spina/email.html.erb +0 -124
- data/app/views/spina/admin/layout_partables/colors/_form.html.haml +0 -4
- data/app/views/spina/admin/page_parts/_wysihtml5_link.html.haml +0 -12
- data/app/views/spina/admin/page_parts/insert_wysihtml5_link.js +0 -5
- data/app/views/spina/admin/page_parts/wysihtml5_link.js +0 -2
- data/app/views/spina/admin/photos/create_and_select.js.erb +0 -7
- data/app/views/spina/admin/photos/create_multiple.js.erb +0 -4
- data/app/views/spina/admin/photos/wysihtml5_select.js.erb +0 -3
- data/vendor/assets/javascripts/spina/jquery.farbtastic.js +0 -345
- data/vendor/assets/javascripts/spina/morris.js +0 -1767
- data/vendor/assets/javascripts/spina/raphael.js +0 -8111
- data/vendor/assets/javascripts/spina/wysihtml5.js +0 -269
- data/vendor/assets/javascripts/spina/wysihtml5_parser_rules.js +0 -551
- data/vendor/assets/stylesheets/spina/_morris.scss +0 -2
@@ -1,9 +1,24 @@
|
|
1
1
|
module Spina
|
2
2
|
module Partable
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
part
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
def part(attributes)
|
7
|
+
part = parts.where(name: attributes[:name]).first_or_initialize(attributes)
|
8
|
+
part.partable = part.partable_type.constantize.new if part.partable.blank?
|
9
|
+
part.options = attributes[:options]
|
10
|
+
part
|
11
|
+
end
|
12
|
+
|
13
|
+
def has_content?(name)
|
14
|
+
content(name).present?
|
15
|
+
end
|
16
|
+
|
17
|
+
def content(name)
|
18
|
+
part = parts.find_by(name: name)
|
19
|
+
part.try(:content)
|
20
|
+
end
|
21
|
+
|
7
22
|
end
|
8
23
|
end
|
9
|
-
end
|
24
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
3
|
+
module Spina
|
4
|
+
module PhotoCollectable
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
attr_reader :photo_tokens, :photo_positions
|
9
|
+
end
|
10
|
+
|
11
|
+
def photo_tokens=(ids)
|
12
|
+
self.photo_ids = ids.split(",")
|
13
|
+
end
|
14
|
+
|
15
|
+
def photo_positions=(positions)
|
16
|
+
positions = positions.split(",")
|
17
|
+
self.photo_collections_photos.each do |photo|
|
18
|
+
photo.position = positions.index(photo.photo.try(:id).try(:to_s))
|
19
|
+
end
|
20
|
+
logger.info self.photo_collections_photos.inspect
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
data/app/models/spina/account.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
module Spina
|
2
2
|
class Account < ApplicationRecord
|
3
|
+
include Partable
|
4
|
+
|
3
5
|
serialize :preferences
|
4
|
-
include Spina::Partable
|
5
6
|
|
6
7
|
mount_uploader :logo, LogoUploader
|
7
8
|
|
@@ -42,7 +43,10 @@ module Spina
|
|
42
43
|
|
43
44
|
def bootstrap_website
|
44
45
|
theme_config = ::Spina::Theme.find_by_name(theme)
|
45
|
-
|
46
|
+
if theme_config
|
47
|
+
bootstrap_pages(theme_config)
|
48
|
+
bootstrap_navigations(theme_config)
|
49
|
+
end
|
46
50
|
end
|
47
51
|
|
48
52
|
def bootstrap_pages(theme)
|
@@ -51,20 +55,26 @@ module Spina
|
|
51
55
|
activate_used_view_templates(theme)
|
52
56
|
end
|
53
57
|
|
58
|
+
def bootstrap_navigations(theme)
|
59
|
+
theme.navigations.each_with_index do |navigation, index|
|
60
|
+
Navigation.where(name: navigation[:name]).first_or_create.update_attributes(navigation.merge(position: index))
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
54
64
|
def find_or_create_custom_pages(theme)
|
55
65
|
theme.custom_pages.each do |page|
|
56
|
-
Page.
|
66
|
+
Page.where(name: page[:name])
|
57
67
|
.first_or_create(title: page[:title])
|
58
|
-
.
|
68
|
+
.update_attributes(view_template: page[:view_template], deletable: page[:deletable])
|
59
69
|
end
|
60
70
|
end
|
61
71
|
|
62
72
|
def deactivate_unused_view_templates(theme)
|
63
|
-
Page.active.
|
73
|
+
Page.active.where.not(view_template: theme.view_templates.map{|h|h[:name]}).update_all(active: false)
|
64
74
|
end
|
65
75
|
|
66
76
|
def activate_used_view_templates(theme)
|
67
|
-
Page.
|
77
|
+
Page.where(active: false, view_template: theme.view_templates.map{|h|h[:name]}).update_all(active: true)
|
68
78
|
end
|
69
79
|
|
70
80
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Spina
|
2
|
+
class Option < ApplicationRecord
|
3
|
+
has_one :page_part, as: :page_partable
|
4
|
+
has_one :layout_part, as: :layout_partable
|
5
|
+
has_one :structure_part, as: :structure_partable
|
6
|
+
|
7
|
+
def content
|
8
|
+
I18n.t(['options',part.name,value].compact.join('.'))
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def part
|
14
|
+
page_part || layout_part || structure_part
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/app/models/spina/page.rb
CHANGED
@@ -1,40 +1,38 @@
|
|
1
1
|
module Spina
|
2
2
|
class Page < ApplicationRecord
|
3
|
-
include
|
4
|
-
|
5
|
-
translates :title, :menu_title, :seo_title, :description, :materialized_path
|
3
|
+
include Partable
|
6
4
|
|
5
|
+
# Stores the old path when generating a new materialized_path
|
7
6
|
attr_accessor :old_path
|
8
7
|
|
9
|
-
|
10
|
-
|
8
|
+
# Page contains multiple parts called PageParts
|
11
9
|
has_many :page_parts, dependent: :destroy, inverse_of: :page
|
10
|
+
alias_attribute :parts, :page_parts
|
11
|
+
accepts_nested_attributes_for :page_parts, allow_destroy: true
|
12
|
+
|
13
|
+
# Orphaned pages are adopted by parent pages if available, otherwise become root
|
14
|
+
has_ancestry orphan_strategy: :adopt
|
15
|
+
|
16
|
+
# Pages can belong to navigations (optional)
|
12
17
|
has_many :navigation_items, dependent: :destroy
|
13
18
|
has_many :navigations, through: :navigation_items
|
14
19
|
|
15
|
-
|
16
|
-
|
17
|
-
|
20
|
+
scope :active, -> { where(active: true) }
|
21
|
+
scope :sorted, -> { order(:position) }
|
22
|
+
scope :live, -> { active.where(draft: false) }
|
23
|
+
scope :in_menu, -> { where(show_in_menu: true) }
|
24
|
+
|
25
|
+
# Save children to update all materialized_paths
|
18
26
|
after_save :save_children
|
27
|
+
|
28
|
+
# Create a 301 redirect if materialized_path changed
|
19
29
|
after_save :rewrite_rule
|
20
|
-
after_create :add_to_navigation
|
21
30
|
|
22
|
-
|
23
|
-
|
31
|
+
before_validation :set_materialized_path
|
32
|
+
validates :title, presence: true
|
24
33
|
validates :materialized_path, uniqueness: true
|
25
34
|
|
26
|
-
|
27
|
-
scope :custom_pages, -> { where(deletable: false) }
|
28
|
-
scope :live, -> { where(draft: false, active: true) }
|
29
|
-
scope :in_menu, -> { where(show_in_menu: true) }
|
30
|
-
scope :active, -> { where(active: true) }
|
31
|
-
scope :not_active, -> { where(active: false) }
|
32
|
-
scope :by_name, ->(name) { where(name: name) }
|
33
|
-
scope :not_by_config_theme, ->(theme) { where.not(view_template: theme.view_templates.map { |h| h[:name] }) }
|
34
|
-
scope :by_config_theme, ->(theme) { where(view_template: theme.view_templates.map { |h| h[:name] }) }
|
35
|
-
|
36
|
-
alias_attribute :page_part, :part
|
37
|
-
alias_attribute :parts, :page_parts
|
35
|
+
translates :title, :menu_title, :seo_title, :description, :materialized_path
|
38
36
|
|
39
37
|
def to_s
|
40
38
|
name
|
@@ -60,15 +58,6 @@ module Spina
|
|
60
58
|
read_attribute(:seo_title).blank? ? title : read_attribute(:seo_title)
|
61
59
|
end
|
62
60
|
|
63
|
-
def has_content?(page_part)
|
64
|
-
content(page_part).present?
|
65
|
-
end
|
66
|
-
|
67
|
-
def content(page_part)
|
68
|
-
page_part = page_parts.where(name: page_part).first
|
69
|
-
page_part.try(:content)
|
70
|
-
end
|
71
|
-
|
72
61
|
def live?
|
73
62
|
!draft? && active?
|
74
63
|
end
|
@@ -101,43 +90,27 @@ module Spina
|
|
101
90
|
theme.page_parts.select { |page_part| page_part[:name].in? view_template_config(theme)[:page_parts] }
|
102
91
|
end
|
103
92
|
|
104
|
-
def full_materialized_path
|
105
|
-
File.join(Spina::Engine.routes.url_helpers.root_path, materialized_path)
|
106
|
-
end
|
107
|
-
|
108
93
|
private
|
109
94
|
|
110
|
-
|
111
|
-
|
112
|
-
end
|
113
|
-
|
114
|
-
def localized_materialized_path
|
115
|
-
if I18n.locale == I18n.default_locale
|
116
|
-
generate_materialized_path.prepend('/')
|
117
|
-
else
|
118
|
-
generate_materialized_path.prepend("/#{I18n.locale}/")
|
95
|
+
def rewrite_rule
|
96
|
+
RewriteRule.create(old_path: old_path, new_path: materialized_path) if old_path != materialized_path
|
119
97
|
end
|
120
|
-
end
|
121
98
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
99
|
+
def localized_materialized_path
|
100
|
+
if I18n.locale == I18n.default_locale
|
101
|
+
generate_materialized_path.prepend('/')
|
102
|
+
else
|
103
|
+
generate_materialized_path.prepend("/#{I18n.locale}/").gsub(/\/\z/, "")
|
104
|
+
end
|
127
105
|
end
|
128
|
-
end
|
129
|
-
|
130
|
-
def ancestry_is_nil
|
131
|
-
self.ancestry = self.ancestry.presence
|
132
|
-
end
|
133
106
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
107
|
+
def generate_materialized_path
|
108
|
+
if root?
|
109
|
+
name == 'homepage' ? '' : "#{url_title}"
|
110
|
+
else
|
111
|
+
ancestors.collect(&:url_title).append(url_title).join('/')
|
112
|
+
end
|
113
|
+
end
|
141
114
|
|
142
115
|
end
|
143
116
|
end
|
@@ -1,30 +1,18 @@
|
|
1
1
|
module Spina
|
2
2
|
class PhotoCollection < ApplicationRecord
|
3
|
+
include PhotoCollectable
|
3
4
|
|
4
5
|
has_one :page_part, as: :page_partable
|
5
6
|
has_many :photo_collections_photos, autosave: true
|
6
7
|
has_many :photos, through: :photo_collections_photos
|
7
8
|
has_many :structure_parts, as: :structure_partable
|
8
9
|
|
9
|
-
attr_reader :photo_tokens, :photo_positions
|
10
10
|
accepts_nested_attributes_for :photos, allow_destroy: true
|
11
11
|
|
12
12
|
def content
|
13
13
|
self
|
14
14
|
end
|
15
15
|
|
16
|
-
def photo_tokens=(ids)
|
17
|
-
self.photo_ids = ids.split(",")
|
18
|
-
end
|
19
|
-
|
20
|
-
def photo_positions=(positions)
|
21
|
-
positions = positions.split(",")
|
22
|
-
self.photo_collections_photos.each do |photo|
|
23
|
-
photo.position = positions.index(photo.photo.try(:id).try(:to_s))
|
24
|
-
end
|
25
|
-
logger.info self.photo_collections_photos.inspect
|
26
|
-
end
|
27
|
-
|
28
16
|
alias_method :old_update_attributes, :update_attributes
|
29
17
|
def update_attributes(attributes)
|
30
18
|
self.photos.clear if attributes.reject{|key,value| key == "id" }.blank?
|
@@ -1,21 +1,17 @@
|
|
1
1
|
module Spina
|
2
2
|
class StructureItem < ApplicationRecord
|
3
|
+
include Partable
|
4
|
+
|
3
5
|
before_validation :ensure_position
|
4
6
|
belongs_to :structure, optional: true
|
5
7
|
has_many :structure_parts, dependent: :destroy
|
6
8
|
|
7
|
-
scope :sorted_by_structure, -> { order(
|
9
|
+
scope :sorted_by_structure, -> { order(:position) }
|
8
10
|
|
9
11
|
validates_presence_of :position
|
10
12
|
accepts_nested_attributes_for :structure_parts, allow_destroy: true
|
11
13
|
|
12
|
-
|
13
|
-
content(structure_part).present?
|
14
|
-
end
|
15
|
-
|
16
|
-
def content(structure_part)
|
17
|
-
structure_parts.find_by(name: structure_part).try(:content)
|
18
|
-
end
|
14
|
+
alias_attribute :parts, :structure_parts
|
19
15
|
|
20
16
|
def ensure_position
|
21
17
|
self.position ||= Time.now.to_i
|
@@ -1,6 +1,8 @@
|
|
1
1
|
module Spina
|
2
2
|
class StructurePart < ApplicationRecord
|
3
3
|
include Part
|
4
|
+
include PhotoCollectable
|
5
|
+
include Optionable
|
4
6
|
|
5
7
|
belongs_to :structure_item, optional: true
|
6
8
|
belongs_to :structure_partable, polymorphic: true, optional: true
|
@@ -13,18 +15,5 @@ module Spina
|
|
13
15
|
alias_attribute :partable, :structure_partable
|
14
16
|
alias_attribute :partable_type, :structure_partable_type
|
15
17
|
alias_method :structure_partable_attributes=, :partable_attributes=
|
16
|
-
|
17
|
-
attr_reader :photo_tokens, :photo_positions
|
18
|
-
def photo_tokens=(ids)
|
19
|
-
self.photo_ids = ids.split(",")
|
20
|
-
end
|
21
|
-
|
22
|
-
def photo_positions=(positions)
|
23
|
-
positions = positions.split(",")
|
24
|
-
self.photo_collections_photos.each do |photo|
|
25
|
-
photo.position = positions.index(photo.photo.try(:id).try(:to_s))
|
26
|
-
end
|
27
|
-
logger.info self.photo_collections_photos.inspect
|
28
|
-
end
|
29
18
|
end
|
30
19
|
end
|
data/app/models/spina/user.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
# require 'active_support/core_ext/string'
|
2
1
|
require 'active_support/configurable'
|
3
2
|
require 'action_view/helpers/tag_helper'
|
4
3
|
require 'action_view/helpers/url_helper'
|
@@ -10,24 +9,19 @@ module Spina
|
|
10
9
|
include ActionView::Helpers::UrlHelper
|
11
10
|
include ActiveSupport::Configurable
|
12
11
|
|
13
|
-
config_accessor :list_tag, :list_class, :
|
12
|
+
config_accessor :list_tag, :list_class, :list_item_tag, :list_item_css, :selected_css, :current_css
|
14
13
|
|
15
14
|
self.list_tag = :ul
|
16
15
|
self.list_class = 'nav'
|
17
16
|
self.list_item_tag = :li
|
18
17
|
self.list_item_css = nil
|
19
|
-
self.list_wrapper = false
|
20
18
|
self.selected_css = 'active'
|
21
19
|
self.current_css = 'current'
|
22
|
-
self.first_css = 'first'
|
23
|
-
self.last_css = 'last'
|
24
|
-
self.list_tag_with_child_css = 'dropdown-menu'
|
25
|
-
self.list_item_with_child_css = 'dropdown'
|
26
20
|
|
27
21
|
attr_accessor :context, :collection, :current_menu_item
|
28
22
|
delegate :output_buffer, :output_buffer=, to: :context
|
29
23
|
|
30
|
-
def initialize(collection, context, current_menu_item=nil)
|
24
|
+
def initialize(collection, context, current_menu_item = nil)
|
31
25
|
@collection = collection
|
32
26
|
@context = context
|
33
27
|
@current_menu_item = current_menu_item
|
@@ -35,59 +29,34 @@ module Spina
|
|
35
29
|
end
|
36
30
|
|
37
31
|
def to_html
|
38
|
-
|
32
|
+
render_menu_items(collection) if collection.present?
|
39
33
|
end
|
40
34
|
|
41
35
|
private
|
42
36
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
render_menu_items(menu_items)
|
37
|
+
def render_menu_items(menu_items)
|
38
|
+
content_tag(list_tag, class: list_class) do
|
39
|
+
menu_items.each.inject(ActiveSupport::SafeBuffer.new) do |buffer, item|
|
40
|
+
buffer << render_menu_item(item)
|
48
41
|
end
|
49
|
-
else
|
50
|
-
render_menu_items(menu_items)
|
51
42
|
end
|
52
43
|
end
|
53
|
-
end
|
54
44
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
buffer <<
|
45
|
+
def render_menu_item(menu_item)
|
46
|
+
content_tag(list_item_tag, class: menu_item_css(menu_item[0])) do
|
47
|
+
buffer = ActiveSupport::SafeBuffer.new
|
48
|
+
buffer << link_to(menu_item[0].menu_title, menu_item[0].materialized_path)
|
49
|
+
buffer << render_menu_items(menu_item[1]) if menu_item[1].present?
|
50
|
+
buffer
|
59
51
|
end
|
60
52
|
end
|
61
|
-
end
|
62
53
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
buffer
|
54
|
+
def menu_item_css(menu_item)
|
55
|
+
css = [list_item_css]
|
56
|
+
css << selected_css if (@selected_menu_items.present? && @selected_menu_items.include?(menu_item) )
|
57
|
+
css << current_css if @current_menu_item == menu_item
|
58
|
+
css
|
69
59
|
end
|
70
|
-
end
|
71
|
-
|
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)
|
81
|
-
css = []
|
82
|
-
css << list_item_css
|
83
|
-
css << selected_css if (@selected_menu_items.present? && @selected_menu_items.include?(menu_item) )
|
84
|
-
css << current_css if @current_menu_item == menu_item
|
85
|
-
css << first_css if index == 0
|
86
|
-
css << last_css if index + 1 == menu_items_length
|
87
|
-
css << list_item_with_child_css if has_child
|
88
|
-
|
89
|
-
css.reject(&:blank?).presence
|
90
|
-
end
|
91
60
|
|
92
61
|
end
|
93
62
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= yield %>
|
@@ -2,6 +2,5 @@
|
|
2
2
|
= f.object.title
|
3
3
|
.horizontal-form-content
|
4
4
|
= f.fields_for :page_partable, f.object.page_partable do |ff|
|
5
|
-
.
|
6
|
-
= ff.
|
7
|
-
.colorpicker-container
|
5
|
+
.select-dropdown
|
6
|
+
= ff.select :value, f.object.options[:values].map{|o| [option_label(f.object, o), o]}, prompt: true
|
@@ -8,10 +8,10 @@
|
|
8
8
|
%i.icon.icon-dots
|
9
9
|
=t 'spina.pages.photos_picker'
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
11
|
+
.photo-collection
|
12
|
+
- if ff.object.photos.sorted_by_photo_collection.any?
|
13
|
+
= render 'spina/admin/photos/photo_collection', photos: ff.object.photos.sorted_by_photo_collection
|
14
|
+
- elsif ff.object.photos.any?
|
15
|
+
= render 'spina/admin/photos/photo_collection', photos: ff.object.photos
|
16
|
+
= ff.hidden_field :photo_tokens, value: ff.object.photo_ids.join(",")
|
17
|
+
= ff.hidden_field :photo_positions, value: ff.object.photos.sorted_by_photo_collection.pluck(:photo_id).join(","), class: 'photo-positions'
|
@@ -4,19 +4,18 @@
|
|
4
4
|
%label= f.object.title
|
5
5
|
|
6
6
|
%ul
|
7
|
-
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
= structure_item.structure_parts.first.try(:structure_partable).try(:content)
|
7
|
+
- f.object.page_partable.structure_items.sort_by(&:position).each_with_index do |structure_item, index|
|
8
|
+
%li{class: ('active' if index == 0), data: {structure_item_id: structure_item.object_id}}
|
9
|
+
= link_to "#structure_form_pane_#{structure_item.object_id}" do
|
10
|
+
%i.icon.icon-bars.sortable-handle
|
11
|
+
= structure_item.structure_parts.first.try(:structure_partable).try(:content)
|
13
12
|
|
14
13
|
= f.fields_for :page_partable do |ff|
|
15
14
|
- ff.object.page_part = f.object
|
16
|
-
= link_to_add_structure_item_fields ff
|
15
|
+
= link_to_add_structure_item_fields ff do
|
17
16
|
= icon('plus')
|
18
17
|
|
19
18
|
.structure-form-content
|
20
19
|
= f.fields_for :page_partable do |ff|
|
21
|
-
= ff.fields_for :structure_items, ff.object.structure_items.
|
20
|
+
= ff.fields_for :structure_items, ff.object.structure_items.sort_by(&:position) do |fff|
|
22
21
|
= render 'spina/admin/structure_items/fields', f: fff
|
@@ -8,12 +8,12 @@
|
|
8
8
|
= link_to '#', data: {close_notification: true} do
|
9
9
|
= icon('cross')
|
10
10
|
|
11
|
-
= form_for [spina, :admin, @page], html: {id: 'page_form', autocomplete: "off"
|
11
|
+
= form_for [spina, :admin, @page], html: {id: 'page_form', autocomplete: "off"} do |f|
|
12
12
|
%header#header
|
13
13
|
.breadcrumbs= render_breadcrumbs separator: '<div class="divider"></div>'
|
14
14
|
- unless @page.new_record?
|
15
15
|
- if Spina.config.locales.size > 1
|
16
|
-
%div{style: 'display: inline-block; margin-left: 12px;
|
16
|
+
%div{style: 'display: inline-block; margin-left: 12px; position: absolute', data: {dropdown: true}}
|
17
17
|
= link_to '#', class: 'button button-link button-round button-small', data: {trigger: 'dropdown', target: '#locales'} do
|
18
18
|
= icon('comment')
|
19
19
|
= @locale.upcase
|
@@ -39,9 +39,9 @@
|
|
39
39
|
- options = options_for_select(current_theme.view_templates.map { |template| [template[:title], template[:name], {'data-page-parts' => template[:page_parts]}] }, @page.view_template)
|
40
40
|
= f.select :view_template, options
|
41
41
|
|
42
|
-
.horizontal-form-group
|
42
|
+
.horizontal-form-group
|
43
43
|
.horizontal-form-label
|
44
44
|
= Spina::Page.human_attribute_name :ancestry
|
45
45
|
.horizontal-form-content
|
46
46
|
.select-dropdown.ancestry
|
47
|
-
= f.select :parent_id, page_ancestry_options(f.object), include_blank: Spina::Page.human_attribute_name(:no_parent)
|
47
|
+
= f.select :parent_id, page_ancestry_options(f.object), include_blank: Spina::Page.human_attribute_name(:no_parent)
|
@@ -0,0 +1,13 @@
|
|
1
|
+
= form_for @user, url: spina.admin_password_reset_path(params[:id]), html: {id: "login_wrapper"} do |f|
|
2
|
+
= image_tag 'spina/admin/spina.png', class: 'animated fadeInDown'
|
3
|
+
- if @user.errors.any?
|
4
|
+
.failed-to-login.animated.fadeInDown
|
5
|
+
.icon.icon-cross
|
6
|
+
= @user.errors.full_messages.join('<br />').html_safe
|
7
|
+
|
8
|
+
.login-fields
|
9
|
+
= f.text_field :password, placeholder: Spina::User.human_attribute_name(:password), autofocus: true, class: "animated fadeInDown"
|
10
|
+
|
11
|
+
= f.text_field :password_confirmation, placeholder: Spina::User.human_attribute_name(:password_confirmation), class: "animated fadeInDown"
|
12
|
+
|
13
|
+
= f.button t('spina.forgot_password.save'), class: 'button button-primary animated fadeInDown'
|
@@ -0,0 +1,13 @@
|
|
1
|
+
= form_tag spina.admin_password_resets_path, method: :post, id: "login_wrapper" do
|
2
|
+
= image_tag 'spina/admin/spina.png'
|
3
|
+
- if flash[:alert].present?
|
4
|
+
.failed-to-login.animated.fadeInDown
|
5
|
+
.icon.icon-cross
|
6
|
+
= flash[:alert]
|
7
|
+
|
8
|
+
.login-fields
|
9
|
+
= text_field_tag :email, params[:email], placeholder: Spina::User.human_attribute_name(:email), autofocus: true
|
10
|
+
|
11
|
+
= button_tag t('spina.forgot_password.request'), class: 'button button-primary'
|
12
|
+
|
13
|
+
.login-extra-links= link_to t('spina.login'), spina.admin_login_path, class: 'button button-hollow button-block'
|
@@ -1,7 +1,8 @@
|
|
1
1
|
.item
|
2
2
|
.overlay
|
3
3
|
= link_to spina.admin_photo_path(photo), method: :delete, class: 'icon-only delete-photo-link', data: {confirm: t('spina.photos.delete_confirmation')} do
|
4
|
-
=t('spina.photos.delete')
|
4
|
+
= t('spina.photos.delete')
|
5
|
+
%span.photo-name= truncate(photo.name, length: 125)
|
5
6
|
= radio_button_tag :photo_id, photo.id
|
6
7
|
= check_box_tag 'photo_ids[]', photo.id
|
7
8
|
= image_tag photo.file.thumb.url, id: "photo_#{photo.id}"
|
@@ -5,9 +5,7 @@
|
|
5
5
|
= form_for [spina, :admin, @photo], html: {multipart: true} do |f|
|
6
6
|
= f.label :file, t('spina.photos.upload_image')
|
7
7
|
= f.file_field :files, multiple: true, data: {customfileinput: true}
|
8
|
-
|
9
|
-
= form_tag spina.wysihtml5_insert_admin_photos_path(params[:object_id]), remote: true, class: 'gallery-prepend-image' do
|
8
|
+
= form_tag spina.trix_insert_admin_photos_path(params[:object_id]), remote: true, class: 'gallery-prepend-image' do
|
10
9
|
.infinite-scroll
|
11
10
|
= render partial: 'spina/admin/photos/photo_single_picker', collection: @photos
|
12
|
-
|
13
|
-
.infinite-pagination= link_to_next_page @photos, 'Next', remote: true
|
11
|
+
.infinite-pagination= link_to_next_page @photos, 'Next', remote: true
|
@@ -1,6 +1,4 @@
|
|
1
|
-
<%
|
2
|
-
|
3
|
-
<% else %>
|
4
|
-
$item = $("<%=j render partial: 'spina/admin/photos/photo', object: @photo %>");
|
1
|
+
<% @photos.each do |photo| %>
|
2
|
+
$item = $("<%=j render partial: 'spina/admin/photos/photo', object: photo %>");
|
5
3
|
$(".gallery-prepend-image .infinite-scroll").prepend($item);
|
6
|
-
<% end %>
|
4
|
+
<% end %>
|
data/app/views/spina/admin/photos/{wysihtml5_infinite_scroll.js.erb → trix_infinite_scroll.js.erb}
RENAMED
@@ -1,6 +1,4 @@
|
|
1
1
|
// Append new data
|
2
2
|
$("<%=j render partial: 'spina/admin/photos/photo_single_picker', collection: @photos %>").appendTo($(".infinite-scroll"));
|
3
|
-
|
4
3
|
// Update pagination link
|
5
4
|
$('.infinite-pagination').html("<%= j link_to_next_page @photos, 'Next', remote: true %>").infiniteScroll()
|
6
|
-
|
@@ -1,2 +1,2 @@
|
|
1
|
-
$('#<%= params[:object_id] %>').trigger('photo-insert', '<%= @photo.file.url %>')
|
2
|
-
$.hideModal()
|
1
|
+
$('#<%= params[:object_id] %>').trigger('photo-insert', '<%= @photo.file.url %>')
|
2
|
+
$.hideModal()
|