spina 0.10.0 → 0.11.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 +16 -4
- data/app/assets/fonts/spina/ics_spina.eot +0 -0
- data/app/assets/fonts/spina/ics_spina.svg +356 -0
- 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/barchart.svg +10 -0
- data/app/assets/icons/spina/bars.svg +1 -0
- data/app/assets/icons/spina/bold.svg +1 -0
- data/app/assets/icons/spina/brush.svg +10 -0
- data/app/assets/icons/spina/camera.svg +10 -0
- data/app/assets/icons/spina/caret-down.svg +1 -0
- data/app/assets/icons/spina/caret-left.svg +1 -0
- data/app/assets/icons/spina/caret-right.svg +1 -0
- data/app/assets/icons/spina/caret-up.svg +1 -0
- data/app/assets/icons/spina/cart.svg +10 -0
- data/app/assets/icons/spina/chart-outline.svg +10 -0
- data/app/assets/icons/spina/check.svg +10 -0
- data/app/assets/icons/spina/chevron-down.svg +1 -0
- data/app/assets/icons/spina/chevron-left.svg +1 -0
- data/app/assets/icons/spina/chevron-right.svg +1 -0
- data/app/assets/icons/spina/chevron-up.svg +1 -0
- data/app/assets/icons/spina/code.svg +1 -0
- data/app/assets/icons/spina/cog-outline.svg +10 -0
- data/app/assets/icons/spina/cog.svg +10 -0
- data/app/assets/icons/spina/comment.svg +1 -0
- data/app/assets/icons/spina/cross.svg +10 -0
- data/app/assets/icons/spina/customer-outline.svg +10 -0
- data/app/assets/icons/spina/document.svg +10 -0
- data/app/assets/icons/spina/dots.svg +10 -0
- data/app/assets/icons/spina/exclamation.svg +13 -0
- data/app/assets/icons/spina/eye.svg +1 -0
- data/app/assets/icons/spina/filter.svg +10 -0
- data/app/assets/icons/spina/home.svg +1 -0
- data/app/assets/icons/spina/image.svg +10 -0
- data/app/assets/icons/spina/inbox-outline.svg +10 -0
- data/app/assets/icons/spina/info.svg +13 -0
- data/app/assets/icons/spina/italic.svg +1 -0
- data/app/assets/icons/spina/large-check.svg +10 -0
- data/app/assets/icons/spina/link.svg +1 -0
- data/app/assets/icons/spina/list-ul.svg +1 -0
- data/app/assets/icons/spina/mail-outline.svg +10 -0
- data/app/assets/icons/spina/mail.svg +10 -0
- data/app/assets/icons/spina/media-library.svg +10 -0
- data/app/assets/icons/spina/megaphone.svg +10 -0
- data/app/assets/icons/spina/min.svg +14 -0
- data/app/assets/icons/spina/pages.svg +10 -0
- data/app/assets/icons/spina/pencil-outline.svg +10 -0
- data/app/assets/icons/spina/pencil.svg +16 -0
- data/app/assets/icons/spina/picture-o.svg +1 -0
- data/app/assets/icons/spina/plus.svg +10 -0
- data/app/assets/icons/spina/power-off.svg +10 -0
- data/app/assets/icons/spina/preview/icons_spina-preview.html +1043 -0
- data/app/assets/icons/spina/preview/ics_spina-preview.html +1043 -0
- data/app/assets/icons/spina/preview.svg +10 -0
- data/app/assets/icons/spina/product-outline.svg +10 -0
- data/app/assets/icons/spina/random.svg +10 -0
- data/app/assets/icons/spina/refresh.svg +13 -0
- data/app/assets/icons/spina/search.svg +10 -0
- data/app/assets/icons/spina/shop.svg +12 -0
- data/app/assets/icons/spina/social-outline.svg +10 -0
- data/app/assets/icons/spina/trash.svg +10 -0
- data/app/assets/icons/spina/upload-outline.svg +14 -0
- data/app/assets/icons/spina/users-outline.svg +10 -0
- data/app/assets/images/spina/arrow-left.png +0 -0
- data/app/assets/images/spina/arrow-right.png +0 -0
- data/app/assets/images/spina/danger-zone-ribbon.png +0 -0
- data/app/assets/images/spina/datepicker.png +0 -0
- data/app/assets/images/spina/divider.png +0 -0
- data/app/assets/images/spina/marker.png +0 -0
- data/app/assets/images/spina/mask.png +0 -0
- data/app/assets/images/spina/spina.png +0 -0
- data/app/assets/images/spina/spina_small.png +0 -0
- data/app/assets/images/spina/wheel.png +0 -0
- data/app/assets/javascripts/spina/admin/{account.js.coffee → account.coffee} +0 -0
- data/app/assets/javascripts/spina/admin/application.coffee.erb +152 -0
- data/app/assets/javascripts/spina/admin/{confirm_delete.js.coffee.erb → confirm_delete.coffee.erb} +0 -0
- data/app/assets/javascripts/spina/admin/dropdown.coffee +75 -0
- data/app/assets/javascripts/spina/admin/forms.coffee +7 -0
- data/app/assets/javascripts/spina/admin/galleryselect.coffee +20 -0
- data/app/assets/javascripts/spina/admin/{spina.infinite_scroll.coffee → infinite_scroll.coffee} +1 -0
- data/app/assets/javascripts/spina/admin/modal.coffee +54 -0
- data/app/assets/javascripts/spina/admin/navigation.coffee +38 -0
- data/app/assets/javascripts/spina/admin/notifications.coffee +7 -0
- data/app/assets/javascripts/spina/admin/{pages.js.coffee.erb → pages.coffee.erb} +11 -2
- data/app/assets/javascripts/spina/admin/switch.coffee +43 -0
- data/app/assets/javascripts/spina/admin/tabs.coffee +13 -0
- data/app/assets/javascripts/spina/admin/{spina.trix.js.coffee.erb → trix.coffee.erb} +26 -25
- data/app/assets/javascripts/spina/admin/uploads.coffee +35 -0
- data/app/assets/stylesheets/spina/_admin_editing.sass +25 -0
- data/app/assets/stylesheets/spina/_buttons.sass +367 -0
- data/app/assets/stylesheets/spina/_cards.sass +54 -0
- data/app/assets/stylesheets/spina/_configuration.sass +15 -0
- data/app/assets/stylesheets/spina/_custom_animations.sass +61 -0
- data/app/assets/stylesheets/spina/_farbtastic.sass +37 -0
- data/app/assets/stylesheets/spina/_fonts.sass +18 -0
- data/app/assets/stylesheets/spina/_forms.sass +806 -0
- data/app/assets/stylesheets/spina/_gallery.sass +249 -0
- data/app/assets/stylesheets/spina/_ics_spina.scss +60 -0
- data/app/assets/stylesheets/spina/_labels.sass +30 -0
- data/app/assets/stylesheets/spina/_login.sass +46 -0
- data/app/assets/stylesheets/spina/_modal.sass +162 -0
- data/app/assets/stylesheets/spina/_notifications.sass +62 -0
- data/app/assets/stylesheets/spina/_sortable_lists.sass +177 -0
- data/app/assets/stylesheets/spina/_tables.sass +301 -0
- data/app/assets/stylesheets/spina/_trix.sass +99 -0
- data/app/assets/stylesheets/spina/_wizard.sass +122 -0
- data/app/assets/stylesheets/spina/_wysihtml5.sass +79 -0
- data/app/assets/stylesheets/spina/application.sass +0 -1
- data/app/assets/stylesheets/spina/wysihtml5_textarea.sass +14 -0
- data/app/assets/stylesheets/spina.sass +564 -0
- data/app/controllers/concerns/spina/frontend.rb +59 -0
- data/app/controllers/spina/admin/navigations_controller.rb +60 -0
- data/app/controllers/spina/admin/pages_controller.rb +7 -6
- data/app/controllers/spina/admin/photos_controller.rb +18 -7
- data/app/controllers/spina/application_controller.rb +2 -2
- data/app/controllers/spina/pages_controller.rb +4 -49
- data/app/helpers/spina/admin/pages_helper.rb +12 -7
- data/app/helpers/spina/application_helper.rb +0 -29
- data/app/models/concerns/spina/part.rb +1 -1
- data/app/models/spina/navigation.rb +11 -0
- data/app/models/spina/navigation_item.rb +17 -0
- data/app/models/spina/page.rb +11 -0
- data/app/models/spina/page_part.rb +1 -1
- data/app/models/spina/photo_collection.rb +6 -1
- data/app/models/spina/structure.rb +4 -0
- data/app/models/spina/structure_item.rb +5 -1
- data/app/models/spina/structure_part.rb +16 -3
- data/app/views/layouts/spina/admin/admin.html.haml +8 -1
- data/app/views/layouts/spina/admin/pages.html.haml +30 -0
- data/app/views/spina/admin/accounts/_form.html.haml +1 -1
- data/app/views/spina/admin/accounts/analytics.html.haml +1 -1
- data/app/views/spina/admin/accounts/social.html.haml +1 -1
- data/app/views/spina/admin/accounts/style.html.haml +1 -1
- data/app/views/spina/admin/navigations/_navigation_item_nested_list.html.haml +7 -0
- data/app/views/spina/admin/navigations/_page.html.haml +8 -0
- data/app/views/spina/admin/navigations/edit.html.haml +22 -0
- data/app/views/spina/admin/navigations/show.html.haml +7 -0
- data/app/views/spina/admin/page_partables/attachment_collections/_form.html.haml +1 -1
- data/app/views/spina/admin/page_partables/attachments/_form.html.haml +1 -1
- data/app/views/spina/admin/page_partables/photo_collections/_form.html.haml +1 -1
- data/app/views/spina/admin/page_partables/photos/_form.html.haml +1 -1
- data/app/views/spina/admin/page_partables/structures/_form.html.haml +1 -1
- data/app/views/spina/admin/pages/_form.html.haml +12 -5
- data/app/views/spina/admin/pages/_page.html.haml +12 -18
- data/app/views/spina/admin/pages/_page_nested_list.html.haml +7 -0
- data/app/views/spina/admin/pages/create.js.coffee +0 -0
- data/app/views/spina/admin/pages/index.html.haml +24 -42
- data/app/views/spina/admin/pages/update.js.coffee +1 -3
- data/app/views/spina/admin/photos/_photo.html.haml +2 -0
- data/app/views/spina/admin/photos/_photo_collection_select.html.haml +1 -1
- data/app/views/spina/admin/photos/_photo_select.html.haml +2 -2
- data/app/views/spina/admin/photos/_wysihtml5_select.html.haml +1 -1
- data/app/views/spina/admin/photos/create_multiple.js.erb +4 -0
- data/app/views/spina/admin/photos/index.html.haml +1 -1
- data/app/views/spina/admin/photos/single_picker_infinite_scroll.js.erb +1 -1
- data/app/views/spina/admin/sessions/new.html.haml +8 -5
- data/app/views/spina/admin/shared/_notifications.html.haml +3 -1
- data/app/views/spina/admin/shared/_primary_navigation.html.haml +4 -3
- data/app/views/spina/admin/shared/_rich_text_field.html.haml +16 -16
- data/app/views/spina/admin/structure_items/_fields.html.haml +7 -8
- data/app/views/spina/admin/structure_partables/photo_collections/_form.html.haml +14 -0
- data/app/views/spina/admin/structure_partables/photos/_form.html.haml +1 -1
- data/app/views/spina/shared/_google_site_verification.html.haml +1 -0
- data/config/fontcustom.yml +95 -0
- data/config/locales/en.yml +11 -0
- data/config/locales/nl.yml +13 -3
- data/config/locales/pt-BR.yml +11 -1
- data/config/routes.rb +14 -8
- data/db/migrate/1_create_spina_tables.rb +0 -7
- data/db/migrate/2_create_spina_translation_tables.rb +26 -7
- data/db/migrate/3_create_spina_navigations.rb +21 -0
- data/lib/generators/spina/templates/config/initializers/carrierwave.rb +1 -1
- data/lib/spina/engine.rb +1 -2
- data/lib/spina/fontcustom/_ics_spina.scss +5 -0
- data/lib/spina/version.rb +1 -1
- data/lib/spina.rb +3 -1
- metadata +146 -45
- data/app/assets/images/spina/admin/logo@2x.png +0 -0
- data/app/assets/javascripts/spina/admin/application.js +0 -10
- data/app/assets/javascripts/spina/admin/spina.scaffold.coffee +0 -15
- data/app/assets/javascripts/spina/application.js +0 -15
- data/app/assets/stylesheets/spina/_mixins.scss +0 -34
@@ -0,0 +1,60 @@
|
|
1
|
+
module Spina
|
2
|
+
module Admin
|
3
|
+
class NavigationsController < AdminController
|
4
|
+
layout 'spina/admin/pages'
|
5
|
+
|
6
|
+
before_action :set_breadcrumb, except: [:show]
|
7
|
+
|
8
|
+
load_and_authorize_resource class: Navigation
|
9
|
+
|
10
|
+
def show
|
11
|
+
add_breadcrumb t('spina.website.pages')
|
12
|
+
end
|
13
|
+
|
14
|
+
def edit
|
15
|
+
add_breadcrumb @navigation.label, spina.admin_navigation_path(@navigation)
|
16
|
+
add_breadcrumb t('spina.edit')
|
17
|
+
render layout: 'spina/admin/admin'
|
18
|
+
end
|
19
|
+
|
20
|
+
def update
|
21
|
+
if @navigation.update_attributes(navigation_params)
|
22
|
+
redirect_to spina.admin_navigation_path(@navigation)
|
23
|
+
else
|
24
|
+
render :edit
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def sort
|
29
|
+
params[:list].each_pair do |parent_pos, parent_node|
|
30
|
+
update_child_pages_position(parent_node)
|
31
|
+
update_navigation_item_position(parent_node[:id], parent_pos, nil)
|
32
|
+
end
|
33
|
+
render nothing: true
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def update_navigation_item_position(navigation_item_id, position, parent_id = nil)
|
39
|
+
Spina::NavigationItem.update(navigation_item_id, position: position.to_i + 1, parent_id: parent_id )
|
40
|
+
end
|
41
|
+
|
42
|
+
def update_child_pages_position(node)
|
43
|
+
if node[:children].present?
|
44
|
+
node[:children].each_pair do |child_pos, child_node|
|
45
|
+
update_child_pages_position(child_node) if child_node[:children].present?
|
46
|
+
update_navigation_item_position(child_node[:id], child_pos, node[:id])
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def set_breadcrumb
|
52
|
+
add_breadcrumb t('spina.website.pages'), spina.admin_pages_path
|
53
|
+
end
|
54
|
+
|
55
|
+
def navigation_params
|
56
|
+
params.require(:navigation).permit(:auto_add_pages, page_ids: [])
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
module Spina
|
2
2
|
module Admin
|
3
3
|
class PagesController < AdminController
|
4
|
-
|
5
4
|
before_action :set_breadcrumb
|
6
5
|
before_action :set_tabs, only: [:new, :create, :edit, :update]
|
7
6
|
before_action :set_locale
|
@@ -19,7 +18,8 @@ module Spina
|
|
19
18
|
@page.view_template = params[:view_template]
|
20
19
|
end
|
21
20
|
add_breadcrumb I18n.t('spina.pages.new')
|
22
|
-
@page_parts = current_theme.
|
21
|
+
@page_parts = @page.view_template_page_parts(current_theme).map { |part| @page.page_part(part) }
|
22
|
+
render layout: 'spina/admin/admin'
|
23
23
|
end
|
24
24
|
|
25
25
|
def create
|
@@ -29,22 +29,23 @@ module Spina
|
|
29
29
|
redirect_to spina.edit_admin_page_url(@page)
|
30
30
|
else
|
31
31
|
@page_parts = @page.page_parts
|
32
|
-
render :new
|
32
|
+
render :new, layout: 'spina/admin/admin'
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
36
|
def edit
|
37
37
|
@page = Page.find(params[:id])
|
38
38
|
add_breadcrumb @page.title
|
39
|
-
@page_parts = current_theme.
|
39
|
+
@page_parts = @page.view_template_page_parts(current_theme).map { |part| @page.page_part(part) }
|
40
|
+
render layout: 'spina/admin/admin'
|
40
41
|
end
|
41
42
|
|
42
43
|
def update
|
43
44
|
I18n.locale = params[:locale] || I18n.default_locale
|
44
45
|
@page = Page.find(params[:id])
|
45
|
-
add_breadcrumb @page.title
|
46
46
|
respond_to do |format|
|
47
47
|
if @page.update_attributes(page_params)
|
48
|
+
add_breadcrumb @page.title
|
48
49
|
@page.touch
|
49
50
|
I18n.locale = I18n.default_locale
|
50
51
|
format.html { redirect_to spina.edit_admin_page_url(@page, params: {locale: @locale}) }
|
@@ -52,7 +53,7 @@ module Spina
|
|
52
53
|
else
|
53
54
|
format.html do
|
54
55
|
@page_parts = @page.page_parts
|
55
|
-
render :edit
|
56
|
+
render :edit, layout: 'spina/admin/admin'
|
56
57
|
end
|
57
58
|
end
|
58
59
|
end
|
@@ -18,13 +18,24 @@ module Spina
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def create
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
render params[:media_library] ? :create : :create_and_select
|
21
|
+
if photo_params[:files].present?
|
22
|
+
@photos = photo_params[:files].map do |file|
|
23
|
+
Photo.create!(file: file)
|
25
24
|
end
|
26
|
-
|
27
|
-
|
25
|
+
respond_to do |format|
|
26
|
+
format.js do
|
27
|
+
render :create_multiple
|
28
|
+
end
|
29
|
+
end
|
30
|
+
else
|
31
|
+
@photo = Photo.create!(photo_params)
|
32
|
+
respond_to do |format|
|
33
|
+
format.js do
|
34
|
+
render params[:media_library] ? :create : :create_and_select
|
35
|
+
end
|
36
|
+
format.json do
|
37
|
+
render json: { file_url: @photo.file_url }
|
38
|
+
end
|
28
39
|
end
|
29
40
|
end
|
30
41
|
end
|
@@ -100,7 +111,7 @@ module Spina
|
|
100
111
|
end
|
101
112
|
|
102
113
|
def photo_params
|
103
|
-
params.require(:photo).permit(:file)
|
114
|
+
params.require(:photo).permit(:file, files: [])
|
104
115
|
end
|
105
116
|
|
106
117
|
end
|
@@ -17,12 +17,12 @@ module Spina
|
|
17
17
|
helper_method :current_theme
|
18
18
|
|
19
19
|
def current_user
|
20
|
-
@current_user ||= Spina::User.where(id: session[:user_id]).first if session[:user_id]
|
20
|
+
@current_user ||= ::Spina::User.where(id: session[:user_id]).first if session[:user_id]
|
21
21
|
end
|
22
22
|
helper_method :current_user
|
23
23
|
|
24
24
|
def current_account
|
25
|
-
@current_account ||= Account.first
|
25
|
+
@current_account ||= ::Spina::Account.first
|
26
26
|
end
|
27
27
|
helper_method :current_account
|
28
28
|
|
@@ -1,70 +1,25 @@
|
|
1
1
|
module Spina
|
2
2
|
class PagesController < Spina::ApplicationController
|
3
|
+
include Spina::Frontend
|
4
|
+
|
3
5
|
rescue_from ActiveRecord::RecordNotFound, with: :render_404
|
4
6
|
|
5
|
-
before_action :set_locale
|
6
|
-
before_action :rewrite_page, only: [:show]
|
7
7
|
before_action :current_user_can_view_page?, except: [:robots]
|
8
8
|
|
9
|
-
|
10
|
-
render_with_template(page)
|
11
|
-
end
|
12
|
-
|
13
|
-
def show
|
14
|
-
if should_skip_to_first_child?
|
15
|
-
redirect_to first_live_child.try(:materialized_path) and return
|
16
|
-
elsif page.link_url.present?
|
17
|
-
redirect_to page.link_url and return
|
18
|
-
end
|
9
|
+
helper_method :page
|
19
10
|
|
11
|
+
def homepage
|
20
12
|
render_with_template(page)
|
21
13
|
end
|
22
14
|
|
23
15
|
private
|
24
16
|
|
25
|
-
def set_locale
|
26
|
-
I18n.locale = params[:locale] || I18n.default_locale
|
27
|
-
end
|
28
|
-
|
29
|
-
def rewrite_page
|
30
|
-
if page.nil? && rule = RewriteRule.find_by(old_path: "/" + params[:id])
|
31
|
-
redirect_to rule.new_path, status: :moved_permanently
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
def page_by_locale(locale)
|
36
|
-
Page.with_translations(locale).find_by(materialized_path: spina_request_path)
|
37
|
-
end
|
38
|
-
|
39
|
-
def page
|
40
|
-
current_page = page_by_locale(I18n.locale) || page_by_locale(I18n.default_locale)
|
41
|
-
@page ||= (action_name == 'homepage') ? Page.find_by!(name: 'homepage') : current_page
|
42
|
-
end
|
43
|
-
helper_method :page
|
44
|
-
|
45
|
-
def spina_request_path
|
46
|
-
segments = ['/', params[:locale], params[:id]].compact
|
47
|
-
File.join(*segments)
|
48
|
-
end
|
49
|
-
|
50
17
|
def current_user_can_view_page?
|
51
18
|
raise ActiveRecord::RecordNotFound if page.nil? || !page.live?
|
52
19
|
|
53
20
|
current_user.present?
|
54
21
|
end
|
55
22
|
|
56
|
-
def should_skip_to_first_child?
|
57
|
-
page.skip_to_first_child && first_live_child
|
58
|
-
end
|
59
|
-
|
60
|
-
def first_live_child
|
61
|
-
page.children.sorted.live.first
|
62
|
-
end
|
63
|
-
|
64
|
-
def render_with_template(page)
|
65
|
-
render layout: "#{current_theme.name.parameterize.underscore}/#{page.layout_template || 'application'}", template: "#{current_theme.name.parameterize.underscore}/pages/#{page.view_template || 'show'}"
|
66
|
-
end
|
67
|
-
|
68
23
|
def render_404
|
69
24
|
render file: "#{Rails.root}/public/404.html", status: 404
|
70
25
|
end
|
@@ -1,20 +1,20 @@
|
|
1
1
|
module Spina
|
2
2
|
module Admin
|
3
3
|
module PagesHelper
|
4
|
-
def
|
4
|
+
def link_to_add_structure_item_fields(f, association, &block)
|
5
5
|
new_object = f.object.send(association).klass.new
|
6
6
|
id = new_object.object_id
|
7
7
|
fields = f.fields_for(association, new_object, child_index: id) do |builder|
|
8
8
|
build_structure_parts(f.object.page_part.name, new_object) if structure_item?(new_object)
|
9
9
|
render("spina/admin/#{ partable_partial_namespace(new_object) }/fields", f: builder)
|
10
10
|
end
|
11
|
-
link_to '#', class: "#{
|
11
|
+
link_to '#', class: "#{add_structure_item_fields_class(new_object)} button button-link", data: {id: id, fields: fields.gsub("\n", "")} do
|
12
12
|
block.yield
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
-
def
|
17
|
-
structure_item?(object) ? 'add_structure' : '
|
16
|
+
def add_structure_item_fields_class(object)
|
17
|
+
structure_item?(object) ? 'add_structure' : 'add_structure_item_fields'
|
18
18
|
end
|
19
19
|
|
20
20
|
def structure_item?(object)
|
@@ -23,9 +23,14 @@ module Spina
|
|
23
23
|
|
24
24
|
def build_structure_parts(name, item)
|
25
25
|
structure = current_theme.structures.find { |structure| structure[:name] == name }
|
26
|
-
|
27
|
-
|
28
|
-
part
|
26
|
+
return item.structure_parts unless structure.present?
|
27
|
+
structure[:structure_parts].map do |structure_part|
|
28
|
+
part = item.structure_parts.where(name: structure_part[:name]).first
|
29
|
+
if part.nil?
|
30
|
+
part = item.structure_parts.build(structure_part)
|
31
|
+
part.structure_partable = structure_part[:partable_type].constantize.new
|
32
|
+
end
|
33
|
+
part
|
29
34
|
end
|
30
35
|
end
|
31
36
|
|
@@ -1,35 +1,6 @@
|
|
1
1
|
module Spina
|
2
2
|
module ApplicationHelper
|
3
3
|
|
4
|
-
def markdown(text)
|
5
|
-
sha = Digest::SHA1.hexdigest(text.to_s)
|
6
|
-
Rails.cache.fetch sha do
|
7
|
-
renderer = Redcarpet::Render::HTML.new(hard_wrap: true, filter_html: false)
|
8
|
-
options = {
|
9
|
-
autolink: true,
|
10
|
-
no_intra_emphasis: true,
|
11
|
-
fenced_code_blocks: true,
|
12
|
-
lax_spacing: true,
|
13
|
-
strikethrough: true,
|
14
|
-
superscript: true
|
15
|
-
}
|
16
|
-
html = Redcarpet::Markdown.new(renderer, options).render(text.to_s)
|
17
|
-
|
18
|
-
html.gsub!(/\[vimeo\s+(\d*)\]/, '<figure class="video"><iframe src="http://player.vimeo.com/video/\1?portrait=0&title=0&byline=0" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe></figure>')
|
19
|
-
html.gsub!(/\[button\s+(.*)\](.*)\[\/button\]/, '<a href="\1" class="button">\2</a>')
|
20
|
-
html.html_safe
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def link_to_add_fields(name, f, association)
|
25
|
-
new_object = f.object.send(association).klass.new
|
26
|
-
id = new_object.object_id
|
27
|
-
fields = f.fields_for(association, new_object, child_index: id) do |builder|
|
28
|
-
render(association.to_s.singularize + "_fields", f: builder)
|
29
|
-
end
|
30
|
-
link_to(name, '#', class: "add_fields button button-primary button-link", data: {id: id, fields: fields.gsub("\n", ""), icon: '&'})
|
31
|
-
end
|
32
|
-
|
33
4
|
def current_account
|
34
5
|
@current_account ||= Account.first
|
35
6
|
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Spina
|
2
|
+
class Navigation < ApplicationRecord
|
3
|
+
has_many :navigation_items, dependent: :destroy
|
4
|
+
has_many :pages, through: :navigation_items
|
5
|
+
|
6
|
+
scope :sorted, -> { order(:position) }
|
7
|
+
|
8
|
+
validates :name, :label, presence: true
|
9
|
+
validates :name, uniqueness: true
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Spina
|
2
|
+
class NavigationItem < ApplicationRecord
|
3
|
+
belongs_to :navigation
|
4
|
+
belongs_to :page
|
5
|
+
|
6
|
+
has_ancestry orphan_strategy: :adopt
|
7
|
+
|
8
|
+
scope :sorted, -> { order('spina_navigation_items.position') }
|
9
|
+
scope :live, -> { joins(:page).where(spina_pages: {draft: false, active: true}) }
|
10
|
+
scope :in_menu, -> { joins(:page).where(spina_pages: {show_in_menu: true}) }
|
11
|
+
scope :active, -> { joins(:page).where(spina_pages: {active: true}) }
|
12
|
+
|
13
|
+
validates :page, uniqueness: {scope: :navigation}
|
14
|
+
|
15
|
+
delegate :menu_title, :materialized_path, to: :page
|
16
|
+
end
|
17
|
+
end
|
data/app/models/spina/page.rb
CHANGED
@@ -9,12 +9,15 @@ module Spina
|
|
9
9
|
has_ancestry orphan_strategy: :adopt # i.e. added to the parent of deleted node
|
10
10
|
|
11
11
|
has_many :page_parts, dependent: :destroy, inverse_of: :page
|
12
|
+
has_many :navigation_items, dependent: :destroy
|
13
|
+
has_many :navigations, through: :navigation_items
|
12
14
|
|
13
15
|
before_validation :ensure_title
|
14
16
|
before_validation :ancestry_is_nil
|
15
17
|
before_validation :set_materialized_path
|
16
18
|
after_save :save_children
|
17
19
|
after_save :rewrite_rule
|
20
|
+
after_create :add_to_navigation
|
18
21
|
|
19
22
|
accepts_nested_attributes_for :page_parts, allow_destroy: true
|
20
23
|
validates_presence_of :title
|
@@ -94,6 +97,10 @@ module Spina
|
|
94
97
|
theme.view_templates.find { |template| template[:name] == view_template_name }
|
95
98
|
end
|
96
99
|
|
100
|
+
def view_template_page_parts(theme)
|
101
|
+
theme.page_parts.select { |page_part| page_part[:name].in? view_template_config(theme)[:page_parts] }
|
102
|
+
end
|
103
|
+
|
97
104
|
def full_materialized_path
|
98
105
|
File.join(Spina::Engine.routes.url_helpers.root_path, materialized_path)
|
99
106
|
end
|
@@ -128,5 +135,9 @@ module Spina
|
|
128
135
|
self.title = self.name.capitalize if self.title.blank? && self.name.present?
|
129
136
|
end
|
130
137
|
|
138
|
+
def add_to_navigation
|
139
|
+
navigations << Spina::Navigation.where(auto_add_pages: true)
|
140
|
+
end
|
141
|
+
|
131
142
|
end
|
132
143
|
end
|
@@ -1,13 +1,18 @@
|
|
1
1
|
module Spina
|
2
2
|
class PhotoCollection < ApplicationRecord
|
3
|
-
|
3
|
+
|
4
4
|
has_one :page_part, as: :page_partable
|
5
5
|
has_many :photo_collections_photos, autosave: true
|
6
6
|
has_many :photos, through: :photo_collections_photos
|
7
|
+
has_many :structure_parts, as: :structure_partable
|
7
8
|
|
8
9
|
attr_reader :photo_tokens, :photo_positions
|
9
10
|
accepts_nested_attributes_for :photos, allow_destroy: true
|
10
11
|
|
12
|
+
def content
|
13
|
+
self
|
14
|
+
end
|
15
|
+
|
11
16
|
def photo_tokens=(ids)
|
12
17
|
self.photo_ids = ids.split(",")
|
13
18
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Spina
|
2
2
|
class StructureItem < ApplicationRecord
|
3
3
|
before_validation :ensure_position
|
4
|
-
belongs_to :structure
|
4
|
+
belongs_to :structure, optional: true
|
5
5
|
has_many :structure_parts, dependent: :destroy
|
6
6
|
|
7
7
|
scope :sorted_by_structure, -> { order('position') }
|
@@ -9,6 +9,10 @@ module Spina
|
|
9
9
|
validates_presence_of :position
|
10
10
|
accepts_nested_attributes_for :structure_parts, allow_destroy: true
|
11
11
|
|
12
|
+
def has_content?(structure_part)
|
13
|
+
content(structure_part).present?
|
14
|
+
end
|
15
|
+
|
12
16
|
def content(structure_part)
|
13
17
|
structure_parts.find_by(name: structure_part).try(:content)
|
14
18
|
end
|
@@ -2,8 +2,8 @@ module Spina
|
|
2
2
|
class StructurePart < ApplicationRecord
|
3
3
|
include Part
|
4
4
|
|
5
|
-
belongs_to :structure_item
|
6
|
-
belongs_to :structure_partable, polymorphic: true
|
5
|
+
belongs_to :structure_item, optional: true
|
6
|
+
belongs_to :structure_partable, polymorphic: true, optional: true
|
7
7
|
|
8
8
|
accepts_nested_attributes_for :structure_partable, allow_destroy: true
|
9
9
|
|
@@ -13,5 +13,18 @@ module Spina
|
|
13
13
|
alias_attribute :partable, :structure_partable
|
14
14
|
alias_attribute :partable_type, :structure_partable_type
|
15
15
|
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
|
16
29
|
end
|
17
|
-
end
|
30
|
+
end
|
@@ -2,8 +2,9 @@
|
|
2
2
|
%html{lang: I18n.locale}
|
3
3
|
%head
|
4
4
|
%meta{charset: 'utf-8'}
|
5
|
-
%meta{name: 'viewport', content: 'initial-scale=1.0
|
5
|
+
%meta{name: 'viewport', content: 'initial-scale=1.0'}
|
6
6
|
= csrf_meta_tags
|
7
|
+
%meta{name: 'turbolinks-cache-control', content: 'no-preview'}
|
7
8
|
|
8
9
|
%title Spina
|
9
10
|
|
@@ -17,6 +18,12 @@
|
|
17
18
|
= javascript_include_tag 'spina/admin/application', data: {turbolinks_track: true}
|
18
19
|
= yield(:plugin_stylesheets)
|
19
20
|
|
21
|
+
/ Plugins
|
22
|
+
- Spina::Plugin.all.each do |plugin|
|
23
|
+
- if current_theme.plugins.include? plugin.name
|
24
|
+
- if lookup_context.exists? "spina/admin/hooks/#{ plugin.namespace }/_head"
|
25
|
+
= render "spina/admin/hooks/#{ plugin.namespace }/head"
|
26
|
+
|
20
27
|
%body
|
21
28
|
= render 'spina/admin/shared/primary_navigation'
|
22
29
|
|
@@ -0,0 +1,30 @@
|
|
1
|
+
- content_for(:permanent_notice) do
|
2
|
+
- unless current_account.robots_allowed?
|
3
|
+
.permanent-notice.permanent-notice-info
|
4
|
+
= icon('search')
|
5
|
+
%p
|
6
|
+
=t 'spina.pages.invisible_to_search_engines'
|
7
|
+
%small=t 'spina.pages.invisible_to_search_engines_description'
|
8
|
+
|
9
|
+
- content_for :application do
|
10
|
+
%header#header
|
11
|
+
#header_actions
|
12
|
+
= link_to '#pages_list', class: 'button sort-switch', data: {change_order: t('spina.pages.change_order'), done_changing_order: t('spina.pages.done_changing_order')} do
|
13
|
+
= icon('random')
|
14
|
+
= t('spina.pages.change_order')
|
15
|
+
|
16
|
+
= yield(:header_actions) if content_for?(:header_actions)
|
17
|
+
|
18
|
+
.breadcrumbs= render_breadcrumbs separator: '<div class="divider"></div>'
|
19
|
+
|
20
|
+
%nav#secondary.tabs
|
21
|
+
%ul
|
22
|
+
%li{class: ('active' if controller_name == 'pages')}
|
23
|
+
= link_to t('spina.website.all_pages'), spina.admin_pages_path
|
24
|
+
|
25
|
+
- Spina::Navigation.sorted.each do |navigation|
|
26
|
+
%li{class: ('active' if controller_name == 'navigations' && @navigation == navigation)}= link_to navigation.label, spina.admin_navigation_path(navigation)
|
27
|
+
|
28
|
+
= yield
|
29
|
+
|
30
|
+
= render template: "layouts/spina/admin/admin"
|
@@ -0,0 +1,7 @@
|
|
1
|
+
%li.dd-item{data: {id: navigation_item_nested_list.id}}
|
2
|
+
%div.dd-item-inner
|
3
|
+
= render partial: 'spina/admin/pages/page', object: navigation_item_nested_list.page
|
4
|
+
|
5
|
+
- if navigation_item_nested_list.children.present?
|
6
|
+
%ol.dd-list
|
7
|
+
= render partial: 'navigation_item_nested_list', collection: navigation_item_nested_list.children.sorted
|
@@ -0,0 +1,8 @@
|
|
1
|
+
%tr
|
2
|
+
%td{style: "padding-left: #{20 * page.depth + 16}px"}
|
3
|
+
.form-checkbox
|
4
|
+
= check_box_tag 'navigation[page_ids][]', page.id, @navigation.page_ids.include?(page.id)
|
5
|
+
= label_tag page.title
|
6
|
+
|
7
|
+
- if page.children.any?
|
8
|
+
= render partial: 'page', collection: page.children.sorted
|
@@ -0,0 +1,22 @@
|
|
1
|
+
= form_for [:admin, @navigation] do |f|
|
2
|
+
= hidden_field_tag 'navigation[page_ids][]', nil
|
3
|
+
|
4
|
+
%header#header
|
5
|
+
#header_actions
|
6
|
+
= button_tag t('spina.save'), class: 'button button-primary'
|
7
|
+
.breadcrumbs= render_breadcrumbs separator: '<div class="divider"></div>'
|
8
|
+
|
9
|
+
|
10
|
+
.well
|
11
|
+
.table-container
|
12
|
+
%table.table.table-clickable
|
13
|
+
%tbody= render partial: 'page', collection: Spina::Page.sorted.roots
|
14
|
+
|
15
|
+
.well
|
16
|
+
.horizontal-form
|
17
|
+
.horizontal-form-group
|
18
|
+
.horizontal-form-label
|
19
|
+
= Spina::Navigation.human_attribute_name :auto_add_pages
|
20
|
+
%small= Spina::Navigation.human_attribute_name :auto_add_pages_description
|
21
|
+
.horizontal-form-content
|
22
|
+
= f.check_box :auto_add_pages, data: {switch: true}
|
@@ -0,0 +1,7 @@
|
|
1
|
+
- content_for(:header_actions) do
|
2
|
+
= link_to t('spina.edit', label: @navigation.label), spina.edit_admin_navigation_path(@navigation), class: 'button'
|
3
|
+
|
4
|
+
.well
|
5
|
+
.dd#pages_list{data: {:"sort-url" => spina.sort_admin_navigation_url(@navigation) }}
|
6
|
+
%ol.dd-list
|
7
|
+
= render partial: 'navigation_item_nested_list', collection: @navigation.navigation_items.roots
|
@@ -3,7 +3,7 @@
|
|
3
3
|
.horizontal-form-content
|
4
4
|
= f.fields_for :page_partable, f.object.page_partable do |ff|
|
5
5
|
= link_to select_collection_admin_attachments_path(ff.object_name, selected_attachment_ids: ff.object.attachment_ids), remote: true, class: 'media_picker clearfix' do
|
6
|
-
.placeholder
|
6
|
+
.placeholder
|
7
7
|
%span.button.button-small.button-round
|
8
8
|
%i.icon.icon-dots
|
9
9
|
= t('spina.choose_from_library')
|
@@ -2,7 +2,7 @@
|
|
2
2
|
= f.object.title
|
3
3
|
.horizontal-form-content
|
4
4
|
= link_to select_admin_attachments_path(f.object_name, selected_attachment_id: f.object.page_partable.try(:id)), remote: true, class: 'media_picker clearfix' do
|
5
|
-
.placeholder
|
5
|
+
.placeholder
|
6
6
|
%span.button.button-small.button-round
|
7
7
|
%i.icon.icon-dots
|
8
8
|
= t('spina.choose_from_library')
|
@@ -3,7 +3,7 @@
|
|
3
3
|
.horizontal-form-content
|
4
4
|
= f.fields_for :page_partable, f.object.page_partable do |ff|
|
5
5
|
= link_to spina.photo_collection_select_admin_photos_path(ff.object_name, selected_photo_ids: ff.object.photo_ids), remote: true, class: 'media_picker clearfix' do
|
6
|
-
.placeholder
|
6
|
+
.placeholder
|
7
7
|
%span.button.button-small.button-round
|
8
8
|
%i.icon.icon-dots
|
9
9
|
=t 'spina.pages.photos_picker'
|