aerogel-pages 1.4.12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +14 -0
- data/Rakefile +1 -0
- data/aerogel-pages.gemspec +26 -0
- data/app/helpers/README.md +7 -0
- data/app/helpers/decorators.rb +74 -0
- data/app/helpers/pages.rb +32 -0
- data/app/routes/admin-pages.rb +150 -0
- data/app/routes/pages.rb +16 -0
- data/assets/javascripts/admin-pages/pages-widget.js.coffee +83 -0
- data/assets/javascripts/admin-pages/pane-preview.js.coffee +37 -0
- data/assets/javascripts/admin-pages/pane-tree.js.coffee +105 -0
- data/assets/javascripts/admin-pages-edit/admin-modal-select.js.coffee +63 -0
- data/assets/javascripts/admin-pages-edit/datetime-picker-field.js.coffee +36 -0
- data/assets/javascripts/admin-pages-edit/page-blocks.js.coffee +71 -0
- data/assets/javascripts/admin-pages-edit/page-content-tabs.js.coffee +40 -0
- data/assets/javascripts/admin-pages-utils/attached-footer.js.coffee +62 -0
- data/assets/javascripts/admin-pages-utils/autofixed-height.js.coffee +15 -0
- data/assets/javascripts/admin-pages-utils/two-pane-widget.js.coffee +78 -0
- data/assets/javascripts/aerogel-pages.js.coffee +3 -0
- data/assets/javascripts/controllers/admin-pages-edit.js.coffee +33 -0
- data/assets/javascripts/controllers/admin-pages.js.coffee +17 -0
- data/assets/stylesheets/admin-pages/_admin-pages-alert.css.scss +14 -0
- data/assets/stylesheets/admin-pages/_pages-widget.css.scss +113 -0
- data/assets/stylesheets/admin-pages/_pane-tree.css.scss +15 -0
- data/assets/stylesheets/admin-pages/_preview.css.scss +35 -0
- data/assets/stylesheets/admin-pages/_two-pane-widget.css.scss +103 -0
- data/assets/stylesheets/admin-pages-common/_admin-modals-select.css.scss +34 -0
- data/assets/stylesheets/admin-pages-common/_form-details.css.scss +11 -0
- data/assets/stylesheets/admin-pages-common/_nav-tabs.css.scss +6 -0
- data/assets/stylesheets/admin-pages-common/_page-blocks.css.scss +18 -0
- data/assets/stylesheets/admin-pages-common/_panels.css.scss +11 -0
- data/assets/stylesheets/admin-pages-common/_publication-states.css.scss +11 -0
- data/assets/stylesheets/admin-pages-common/_smart-links.css.scss +9 -0
- data/assets/stylesheets/admin-pages-common/_smart-tree-table-icons.css.scss +42 -0
- data/assets/stylesheets/admin-pages-edit/breadcrumbs.css.scss +11 -0
- data/assets/stylesheets/admin-pages-edit/form.css.scss +23 -0
- data/assets/stylesheets/admin-pages-edit/page-blocks.css.scss +88 -0
- data/assets/stylesheets/admin-pages-edit/page-footer.css.scss +21 -0
- data/assets/stylesheets/admin-pages-edit/page-header.css.scss +15 -0
- data/assets/stylesheets/admin-pages-edit/page.css.scss +30 -0
- data/assets/stylesheets/admin-pages-edit/tabs.css.scss +20 -0
- data/assets/stylesheets/aerogel-pages.css.scss +20 -0
- data/assets/stylesheets/controllers/admin-pages-edit.css.scss +7 -0
- data/assets/stylesheets/controllers/admin-pages.css.scss +5 -0
- data/assets/stylesheets/pages/_body.css.scss +3 -0
- data/assets/stylesheets/pages/_footer.css.scss +13 -0
- data/assets/stylesheets/pages/_header.css.scss +5 -0
- data/assets/stylesheets/pages/_image.css.scss +18 -0
- data/assets/stylesheets/pages/_layout-sticky-footer.css.scss +27 -0
- data/assets/stylesheets/pages/_menu.css.scss +45 -0
- data/assets/stylesheets/pages/_page-content.css.scss +3 -0
- data/assets/vendor/jquery.history.js +1 -0
- data/assets/vendor/smart-links.js.coffee +42 -0
- data/config/README.md +3 -0
- data/config/development/.keep +0 -0
- data/config/production/.keep +0 -0
- data/db/model/page.rb +137 -0
- data/db/model/page_node.rb +43 -0
- data/db/model/page_type.rb +15 -0
- data/db/model/pages/block.rb +38 -0
- data/db/model/pages/blocks/hr.rb +9 -0
- data/db/model/pages/blocks/image.rb +16 -0
- data/db/model/pages/blocks/pages_list.rb +41 -0
- data/db/model/pages/blocks/text.rb +9 -0
- data/db/seed/development/.keep +0 -0
- data/db/seed/development/01_page_types.seed +8 -0
- data/db/seed/development/02_root_page_node.seed +8 -0
- data/db/seed/development/03_root_pages.seed +10 -0
- data/db/seed/development/04_news_page_node.seed +15 -0
- data/db/seed/development/05_news_pages.seed +10 -0
- data/db/seed/production/.keep +0 -0
- data/db/seed/production/01_page_types.seed +8 -0
- data/db/seed/production/02_root_page_node.seed +8 -0
- data/db/seed/production/03_root_pages.seed +10 -0
- data/db/seed/seed.template +42 -0
- data/lib/aerogel/pages/core.rb +37 -0
- data/lib/aerogel/pages/traversal.rb +30 -0
- data/lib/aerogel/pages/version.rb +5 -0
- data/lib/aerogel/pages.rb +19 -0
- data/locales/actions.en.yml +11 -0
- data/locales/actions.ru.yml +11 -0
- data/locales/admin.en.yml +11 -0
- data/locales/admin.ru.yml +11 -0
- data/locales/models.en.yml +18 -0
- data/locales/models.ru.yml +19 -0
- data/locales/views.en.yml +38 -0
- data/locales/views.ru.yml +39 -0
- data/public/README.md +1 -0
- data/rake/README.md +3 -0
- data/views/admin/pages/_edit_form.html.erb +23 -0
- data/views/admin/pages/_page-DISABLED.html.erb +5 -0
- data/views/admin/pages/append.html.erb +4 -0
- data/views/admin/pages/delete.html.erb +28 -0
- data/views/admin/pages/edit/_block.html.erb +16 -0
- data/views/admin/pages/edit/_block_header.html.erb +66 -0
- data/views/admin/pages/edit/_breadcrumbs.html.erb +13 -0
- data/views/admin/pages/edit/_page.html.erb +63 -0
- data/views/admin/pages/edit/_page_footer.html.erb +55 -0
- data/views/admin/pages/edit/_page_header.html.erb +65 -0
- data/views/admin/pages/edit/_page_node.html.erb +79 -0
- data/views/admin/pages/edit/block/_default.html.erb +3 -0
- data/views/admin/pages/edit/block/_hr.html.erb +5 -0
- data/views/admin/pages/edit/block/_image.html.erb +20 -0
- data/views/admin/pages/edit/block/_pages_list.html.erb +53 -0
- data/views/admin/pages/edit/block/_text.html.erb +3 -0
- data/views/admin/pages/edit/select_page.html.erb +59 -0
- data/views/admin/pages/edit/select_template.html.erb +50 -0
- data/views/admin/pages/edit.html.erb +4 -0
- data/views/admin/pages/index/_pane_preview.html.erb +23 -0
- data/views/admin/pages/index/_pane_tree.html.erb +50 -0
- data/views/admin/pages/index/_pane_tree_tabs.html.erb +26 -0
- data/views/admin/pages/index.html.erb +26 -0
- data/views/admin/pages/insert.html.erb +4 -0
- data/views/admin/pages/preview/_block.html.erb +7 -0
- data/views/admin/pages/preview/_breadcrumbs.html.erb +11 -0
- data/views/admin/pages/preview/block/_default.html.erb +5 -0
- data/views/admin/pages/preview/block/_hr.html.erb +1 -0
- data/views/admin/pages/preview/block/_image.html.erb +8 -0
- data/views/admin/pages/preview/block/_pages_list.html.erb +14 -0
- data/views/admin/pages/preview/block/_text.html.erb +1 -0
- data/views/admin/pages/preview.html.erb +30 -0
- data/views/admin/table_builder/smart-list-table/_table_column.html.erb +3 -0
- data/views/admin/table_builder/smart-list-table/_table_row.html.erb +9 -0
- data/views/admin/table_builder/smart-list-table/table.html.erb +10 -0
- data/views/admin/table_builder/smart-tree-table/_table_column.html.erb +3 -0
- data/views/admin/table_builder/smart-tree-table/_table_row.html.erb +14 -0
- data/views/admin/table_builder/smart-tree-table/table.html.erb +10 -0
- data/views/admin/tabs_builder/pages-tree-tabs/_tab.html.erb +5 -0
- data/views/admin/tabs_builder/pages-tree-tabs/tabs.html.erb +3 -0
- data/views/form_builder/admin-pages-edit/field.erb +31 -0
- data/views/form_builder/admin-pages-edit/field_datetime.erb +19 -0
- data/views/form_builder/admin-pages-edit/field_default.erb +5 -0
- data/views/form_builder/admin-pages-edit/field_radio_buttons.erb +22 -0
- data/views/form_builder/admin-pages-edit/field_text_addon.erb +17 -0
- data/views/form_builder/admin-pages-edit/field_textarea.erb +28 -0
- data/views/form_builder/admin-pages-edit/field_title.erb +5 -0
- data/views/form_builder/admin-pages-edit/fieldset.erb +4 -0
- data/views/form_builder/admin-pages-edit-block/field.erb +31 -0
- data/views/form_builder/admin-pages-edit-block/field_default.erb +5 -0
- data/views/form_builder/admin-pages-edit-block/field_media-file.erb +60 -0
- data/views/form_builder/admin-pages-edit-block/field_media-image.erb +67 -0
- data/views/form_builder/admin-pages-edit-block/field_radio_buttons.erb +22 -0
- data/views/form_builder/admin-pages-edit-block/field_select_page.erb +34 -0
- data/views/form_builder/admin-pages-edit-block/field_select_template.erb +32 -0
- data/views/form_builder/admin-pages-edit-block/field_text_inline.erb +5 -0
- data/views/form_builder/admin-pages-edit-block/field_textarea.erb +2 -0
- data/views/form_builder/admin-pages-edit-block/fieldset.erb +4 -0
- data/views/layouts/admin/pages/preview.html.erb +9 -0
- data/views/layouts/application.html.erb +62 -0
- data/views/layouts/pages/_breadcrumbs.html.erb +20 -0
- data/views/layouts/pages/_flashes.html.erb +9 -0
- data/views/layouts/pages/_menu.html.erb +37 -0
- data/views/layouts/pages/_menu_item.html.erb +15 -0
- data/views/layouts/pages/_menu_user.html.erb +8 -0
- data/views/pages/_block.html.erb +7 -0
- data/views/pages/block/_default.html.erb +5 -0
- data/views/pages/block/_hr.html.erb +1 -0
- data/views/pages/block/_image.html.erb +8 -0
- data/views/pages/block/_pages_list.html.erb +13 -0
- data/views/pages/block/_text.html.erb +1 -0
- data/views/pages/list/_default.html.erb +7 -0
- data/views/pages/list/_table.html.erb +12 -0
- data/views/pages/list/_ul.html.erb +7 -0
- data/views/pages/view.html.erb +4 -0
- metadata +267 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8e26c560b6efb0c21e672cdec8a7ff2ebf041c1b
|
4
|
+
data.tar.gz: eb661e738d4d57d2d5808c7ae1b16f7f7d53ab1d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7877fad07008c646599daff5ad77adc06d5e6f589e3dc2911c06f3bf7cd6789f61cad45d58907bc61f8553cf95abd51a1ea8ffba700c712b1e5378c4d721d83d
|
7
|
+
data.tar.gz: 076ff583a35fabd307a3edf87cad5a1956875f20919998d00af042c14c2b7788f7f7a61f9926e56581527d577c7876a025a52ce120bc9a50e6b323602243a2c3
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Alex Kukushkin
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'aerogel/pages/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "aerogel-pages"
|
8
|
+
spec.version = Aerogel::Pages::VERSION
|
9
|
+
spec.authors = ["Alex Kukushkin"]
|
10
|
+
spec.email = ["alex@kukushk.in"]
|
11
|
+
spec.description = %q{Page editing/publishing module for aerogel CMS}
|
12
|
+
spec.summary = %q{Page editing/publishing module for aerogel CMS}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "aerogel-core", "~> 1.4"
|
22
|
+
spec.add_dependency "aerogel-admin", "~> 1.4"
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
25
|
+
spec.add_development_dependency "rake"
|
26
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# Returns publication state as icon,
|
2
|
+
# unless it is :published, in which case nothing is rendered.
|
3
|
+
#
|
4
|
+
def admin_pages_publication_state_as_icon( page_node, lang )
|
5
|
+
page = page_node.page( lang )
|
6
|
+
state = page.try(:publication_state) || :not_published
|
7
|
+
case state.to_sym
|
8
|
+
when :published then '' # icon 'fa-check'
|
9
|
+
when :hidden then icon 'fa-eye', title: 'hidden'
|
10
|
+
else
|
11
|
+
icon 'fa-times', title: 'not published'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# Returns page title for given +lang+, with respect to publication state.
|
16
|
+
#
|
17
|
+
def admin_pages_title_as_text( page_node, lang )
|
18
|
+
page = page_node.page( lang )
|
19
|
+
if page.nil?
|
20
|
+
publication_state = :not_published
|
21
|
+
other_page = page_node.pages.first
|
22
|
+
if other_page.nil?
|
23
|
+
return "<span class='nodata'>no translation</span>"
|
24
|
+
end
|
25
|
+
return "<span class='nodata'>#{other_page.lang}: #{h other_page.title}</span>"
|
26
|
+
end
|
27
|
+
case page.publication_state.to_sym
|
28
|
+
when :published then h page.title
|
29
|
+
when :hidden then "<span class='state-hidden'>#{h page.title}</span>"
|
30
|
+
else
|
31
|
+
"<span class='state-not-published'>#{h page.title}</span>"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Returns title and publication state as icon and text.
|
36
|
+
#
|
37
|
+
def admin_pages_title_as_icon_and_text( page_node, lang )
|
38
|
+
admin_pages_publication_state_as_icon( page_node, lang )+" "+admin_pages_title_as_text( page_node, lang )
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
# Returns link to a page for given +lang+, with respect to publication state.
|
43
|
+
#
|
44
|
+
def admin_pages_link_as_text( page_node, lang )
|
45
|
+
page = page_node.page( lang )
|
46
|
+
return "<span class='nodata'>no content</span>" if page.blank?
|
47
|
+
case page.publication_state.to_sym
|
48
|
+
when :published then h( page.link )
|
49
|
+
when :hidden then "<span class='state-hidden'>#{h page.link}</span>"
|
50
|
+
else
|
51
|
+
"<span class='state-not-published'>#{h page.link}</span>"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Returns link and publication state as icon and text.
|
56
|
+
#
|
57
|
+
def admin_pages_link_as_icon_and_text( page_node, lang )
|
58
|
+
admin_pages_publication_state_as_icon( page_node, lang )+" "+admin_pages_link_as_text( page_node, lang )
|
59
|
+
end
|
60
|
+
|
61
|
+
# Returns full path to current page in given +lang+,
|
62
|
+
# links are generated as icon and text
|
63
|
+
#
|
64
|
+
def admin_pages_url_as_text( page_node, lang )
|
65
|
+
return '' if page_node.nil?
|
66
|
+
page_node.ancestors_and_self.sort_by(&:depth).map do |pn|
|
67
|
+
if pn.root?
|
68
|
+
icon 'fa-home'
|
69
|
+
else
|
70
|
+
admin_pages_link_as_icon_and_text pn, lang
|
71
|
+
end
|
72
|
+
end.join(" / ")
|
73
|
+
end
|
74
|
+
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# Returns root page in current lang
|
2
|
+
#
|
3
|
+
def page_root
|
4
|
+
@current_page_root ||= Page.root( current_locale )
|
5
|
+
end
|
6
|
+
|
7
|
+
# Returns or sets current Page object being served.
|
8
|
+
#
|
9
|
+
def current_page( page = nil )
|
10
|
+
@current_page = page if page.present?
|
11
|
+
@current_page
|
12
|
+
end
|
13
|
+
|
14
|
+
# Returns current page url, if Page is served,
|
15
|
+
# plain ULR otherwise.
|
16
|
+
#
|
17
|
+
# If opts[:locale] is specified, tries to find closest page in other lang.
|
18
|
+
#
|
19
|
+
def current_page_url( opts = {} )
|
20
|
+
if current_page.present?
|
21
|
+
if !opts.key?(:locale) || opts[:locale] == current_page.lang
|
22
|
+
current_page.url
|
23
|
+
else
|
24
|
+
# find this page in other lang
|
25
|
+
other_page = Aerogel::Pages::Traversal.find_closest_in_other_lang( current_page, opts[:locale] )
|
26
|
+
return nil unless other_page.present?
|
27
|
+
url_to( other_page.url, opts )
|
28
|
+
end
|
29
|
+
else
|
30
|
+
current_url opts
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,150 @@
|
|
1
|
+
namespace "/admin/pages" do
|
2
|
+
|
3
|
+
admin_menu "/admin/pages/", icon: 'fa-file', label: :'aerogel.admin.panes.pages', priority: 10
|
4
|
+
|
5
|
+
get "/", "/:lang-" do
|
6
|
+
@page_nodes = PageNode.traverse
|
7
|
+
@lang = params[:lang] || I18n.default_locale
|
8
|
+
pass
|
9
|
+
end
|
10
|
+
|
11
|
+
namespace "/:lang-:id" do
|
12
|
+
before do
|
13
|
+
@lang = params[:lang]
|
14
|
+
@selected_page_node = PageNode.find( params[:id] ) or halt 404
|
15
|
+
end
|
16
|
+
|
17
|
+
get do
|
18
|
+
@page_nodes = PageNode.traverse
|
19
|
+
pass
|
20
|
+
end
|
21
|
+
|
22
|
+
get "/preview" do
|
23
|
+
layout "admin/pages/preview"
|
24
|
+
@page_node = @selected_page_node
|
25
|
+
pass
|
26
|
+
end
|
27
|
+
|
28
|
+
get "/append" do
|
29
|
+
@page_node = PageNode.new( parent_id: @selected_page_node.parent_id )
|
30
|
+
@page_node.page_type = PageType.where( type: :page ).first
|
31
|
+
pass
|
32
|
+
end
|
33
|
+
|
34
|
+
post "/append" do
|
35
|
+
@page_node = PageNode.new( params[:page_node] )
|
36
|
+
@page_node.parent_id = @selected_page_node.parent_id
|
37
|
+
pass unless @page_node.save
|
38
|
+
@page_node.move_below @selected_page_node
|
39
|
+
redirect "/admin/pages/#{@lang}-#{@page_node.id}"
|
40
|
+
end
|
41
|
+
|
42
|
+
get "/insert" do
|
43
|
+
@page_node = PageNode.new( parent_id: @selected_page_node.id )
|
44
|
+
@page_node.page_type = PageType.where( type: :page ).first
|
45
|
+
pass
|
46
|
+
end
|
47
|
+
|
48
|
+
post "/insert" do
|
49
|
+
@page_node = PageNode.new( params[:page_node] )
|
50
|
+
@page_node.parent_id = @selected_page_node.id
|
51
|
+
if @page_node.save
|
52
|
+
redirect "/admin/pages/#{@lang}-#{@page_node.id}"
|
53
|
+
end
|
54
|
+
# flash.now[:error] = t.aerogel.db.errors.failed_to_save( name: h( @page.id ),
|
55
|
+
# errors: @page.errors.full_messages.join(", ")
|
56
|
+
# )
|
57
|
+
pass
|
58
|
+
end
|
59
|
+
|
60
|
+
get "/delete" do
|
61
|
+
@page_node = @selected_page_node
|
62
|
+
pass
|
63
|
+
end
|
64
|
+
|
65
|
+
post "/delete" do
|
66
|
+
@page_node = @selected_page_node
|
67
|
+
# pass unless @page.save
|
68
|
+
parent_id = @page_node.parent_id
|
69
|
+
@page_node.destroy
|
70
|
+
redirect "/admin/pages/#{@lang}-#{parent_id}",
|
71
|
+
notice: "Page \"#{admin_pages_title_as_text @page_node, @lang}\" deleted."
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
get "/edit" do
|
76
|
+
@page_node = @selected_page_node
|
77
|
+
pass
|
78
|
+
end
|
79
|
+
|
80
|
+
post "/edit" do
|
81
|
+
# flash.now[:debug] = "params: #{params.inspect}"
|
82
|
+
@page_node = @selected_page_node
|
83
|
+
if @page_node.update_attributes params[:page_node].except( :page_type )
|
84
|
+
redirect "/admin/pages/#{@lang}-#{@page_node.id}" #, notice: "Page updated"
|
85
|
+
end
|
86
|
+
# flash.now[:error] = t.aerogel.db.errors.failed_to_save( name: h( @page.id ),
|
87
|
+
# errors: @page.errors.full_messages.join(", ")
|
88
|
+
#)
|
89
|
+
pass
|
90
|
+
end
|
91
|
+
|
92
|
+
get "/edit/page_block" do
|
93
|
+
# Find or Create page and page content with given ids
|
94
|
+
# and place the new block inside
|
95
|
+
#
|
96
|
+
page_node = PageNode.find( params[:page_block][:page_node_id] )
|
97
|
+
unless page_node.present?
|
98
|
+
page_node = PageNode.new
|
99
|
+
page_node._id = params[:page_block][:page_node_id]
|
100
|
+
end
|
101
|
+
page = page_node.pages.find params[:page_block][:page_id]
|
102
|
+
unless page.present?
|
103
|
+
page = page_node.pages.new lang: params[:page_block][:lang]
|
104
|
+
page._id = params[:page_block][:page_id]
|
105
|
+
end
|
106
|
+
page_block = page.create_page_block params[:page_block]
|
107
|
+
field_prefix = "page_node[pages_attributes][#{page.lang}][page_blocks_attributes][#{page_block.id}]"
|
108
|
+
opts = {
|
109
|
+
field_prefix: field_prefix,
|
110
|
+
style: 'admin-pages-edit-block'
|
111
|
+
}
|
112
|
+
fields = Aerogel::Forms::Fieldset.new page_block, nil, nil, opts do
|
113
|
+
partial "admin/pages/edit/block", scope: self, locals: { type: params[:page_block][:type] }
|
114
|
+
end
|
115
|
+
fields.render
|
116
|
+
end
|
117
|
+
|
118
|
+
get "/edit/select_page" do
|
119
|
+
@page_nodes = PageNode.traverse
|
120
|
+
@select_lang = params[:select_lang] || @lang
|
121
|
+
@select_page_node_id = params[:select_page_node_id] || nil
|
122
|
+
view "admin/pages/edit/select_page"
|
123
|
+
end
|
124
|
+
|
125
|
+
get "/edit/select_template" do
|
126
|
+
@select_template_name = params[:select_template_name] || nil
|
127
|
+
@select_template_prefix = params[:select_template_prefix] || nil
|
128
|
+
@templates = []
|
129
|
+
templates_wildcard = File.join( @select_template_prefix, '**/*.erb' )
|
130
|
+
template_entry = Struct.new :id, :module, :filename
|
131
|
+
Aerogel.get_resource_list( :views, templates_wildcard ) do |f, rf, path, base_path|
|
132
|
+
id = rf
|
133
|
+
filename = rf.sub(/^#{@select_template_prefix}/, '')
|
134
|
+
module_name = base_path[:module_name]
|
135
|
+
@templates << template_entry.new( id, module_name, filename )
|
136
|
+
end
|
137
|
+
|
138
|
+
view "admin/pages/edit/select_template"
|
139
|
+
end
|
140
|
+
|
141
|
+
end # namespace ":lang\::id"
|
142
|
+
#
|
143
|
+
# Common Pages controller routes
|
144
|
+
#
|
145
|
+
route :get, :post, ['/', '/:id', '/:id/:action'] do
|
146
|
+
action = params[:action] || 'index'
|
147
|
+
view "admin/pages/#{action}"
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
data/app/routes/pages.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
|
2
|
+
# Locate page by URL
|
3
|
+
#
|
4
|
+
get "/*" do
|
5
|
+
path = params[:splat].first.split "/" # .join "/"
|
6
|
+
@page = Aerogel::Pages::Traversal.find path, current_locale
|
7
|
+
pass if @page.nil?
|
8
|
+
|
9
|
+
current_page @page
|
10
|
+
page_title @page.try( :title )
|
11
|
+
view "pages/view"
|
12
|
+
end
|
13
|
+
|
14
|
+
error do
|
15
|
+
"Internal server error: #{h env['sinatra.error'].inspect}"
|
16
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
#
|
2
|
+
#
|
3
|
+
log = (msg) ->
|
4
|
+
console?.log "** admin/pages: #{msg}"
|
5
|
+
|
6
|
+
|
7
|
+
class @PagesWidget
|
8
|
+
two_pane_widget: null
|
9
|
+
current_state: {
|
10
|
+
lang: 'en'
|
11
|
+
}
|
12
|
+
|
13
|
+
constructor: ( @element, @pane_left, @pane_right ) ->
|
14
|
+
@two_pane_widget = new TwoPaneWidget @element, @pane_left, @pane_right
|
15
|
+
top_h = $("#top-menu").outerHeight()
|
16
|
+
foot_h = $("#footer").outerHeight()
|
17
|
+
@height_fixer = new AutofixedHeight @element, top_h+foot_h #, top_h+ foot_h
|
18
|
+
@current_title = document.title
|
19
|
+
History.Adapter.bind window, 'statechange', =>
|
20
|
+
@set_state History.getState().data
|
21
|
+
|
22
|
+
@element.on 'changed.two-pane', (e, left_middle_right) =>
|
23
|
+
@on_pane_open left_middle_right
|
24
|
+
log "initialized"
|
25
|
+
|
26
|
+
# Callback invoked by tree 'selected' event
|
27
|
+
on_page_selected: ( id, object ) =>
|
28
|
+
@current_state.page_node_id = id
|
29
|
+
# @current_state.page_attributes = object.attributes
|
30
|
+
@push_state()
|
31
|
+
log "on_page_selected: id:#{@current_state.page_node_id}"
|
32
|
+
|
33
|
+
|
34
|
+
# Callback invoked on pane open/close events
|
35
|
+
on_pane_open: ( left_middle_right ) =>
|
36
|
+
@current_state.open_pane = left_middle_right
|
37
|
+
@push_state()
|
38
|
+
|
39
|
+
# Go to page
|
40
|
+
goto_page: (id) ->
|
41
|
+
@current_state.page_node_id = id
|
42
|
+
@push_state()
|
43
|
+
|
44
|
+
push_state: ->
|
45
|
+
# push current state to history,
|
46
|
+
url = ''
|
47
|
+
if @current_state.page_node_id?
|
48
|
+
url = "#{@current_state.lang}-#{@current_state.page_node_id}"
|
49
|
+
log "setting url to '#{url}'"
|
50
|
+
log "setting lang '#{@current_state.lang}'"
|
51
|
+
History.pushState( @current_state, @current_title, url )
|
52
|
+
|
53
|
+
|
54
|
+
set_state: ( state ) ->
|
55
|
+
log "set_state: id:#{state.page_node_id}"
|
56
|
+
# console?.log state
|
57
|
+
@current_state = state
|
58
|
+
if state.page_node_id?
|
59
|
+
row = pane_tree.find_row_by_id state.page_node_id
|
60
|
+
@current_state.page_attributes = row.attributes
|
61
|
+
@update @current_state
|
62
|
+
|
63
|
+
update: ( state ) ->
|
64
|
+
log "calling update(): id=#{state.page_node_id}"
|
65
|
+
pane_tree.update state
|
66
|
+
pane_preview.update state
|
67
|
+
if state.open_pane == 'left'
|
68
|
+
@two_pane_widget.open_left( false )
|
69
|
+
else if state.open_pane == 'right'
|
70
|
+
@two_pane_widget.open_right( false )
|
71
|
+
else
|
72
|
+
@two_pane_widget.open_middle( false )
|
73
|
+
|
74
|
+
# Constructs url to +action+ on page specified by +lang+ and +id+
|
75
|
+
#
|
76
|
+
url_to: ( lang, id = '', action = null ) ->
|
77
|
+
if action? then "#{lang}-#{id}/#{action}" else "#{lang}-#{id}"
|
78
|
+
|
79
|
+
|
80
|
+
# Constructs url to +action+ on page specified by current state.
|
81
|
+
#
|
82
|
+
url_to_action: ( action ) ->
|
83
|
+
@url_to( @current_state.lang, @current_state.page_node_id, action )
|
@@ -0,0 +1,37 @@
|
|
1
|
+
log = (msg) ->
|
2
|
+
console?.log "** admin/pages:preview: #{msg}"
|
3
|
+
|
4
|
+
class @PanePreview
|
5
|
+
constructor: (@element) ->
|
6
|
+
@content = @element.find('.content').first()
|
7
|
+
@preview = @element.find('#preview').first()
|
8
|
+
@preview_empty = @element.find('#preview-empty').first()
|
9
|
+
@toolbar = @element.find('.bottom-toolbar').first()
|
10
|
+
@attached_footer = new AttachedFooter
|
11
|
+
target: @preview
|
12
|
+
footer: @toolbar
|
13
|
+
observe: @content
|
14
|
+
@current_page_node_id = null
|
15
|
+
log "initialized"
|
16
|
+
# ...
|
17
|
+
#
|
18
|
+
update: (state) ->
|
19
|
+
if state.page_node_id?
|
20
|
+
url_preview = pages_widget.url_to_action 'preview'
|
21
|
+
url_edit = pages_widget.url_to_action 'edit'
|
22
|
+
if @current_page_node_id != state.page_node_id
|
23
|
+
$.get url_preview, (data) =>
|
24
|
+
@preview.html data
|
25
|
+
@preview.show()
|
26
|
+
@preview_empty.hide()
|
27
|
+
@content.animate {scrollTop: 0} #, 'slow'
|
28
|
+
@toolbar.show()
|
29
|
+
@toolbar.find('.page-edit-link').attr 'href', url_edit
|
30
|
+
@attached_footer.update_footer()
|
31
|
+
else
|
32
|
+
@preview.hide()
|
33
|
+
@toolbar.hide()
|
34
|
+
@preview_empty.show()
|
35
|
+
@current_page_node_id = state.page_node_id
|
36
|
+
|
37
|
+
|
@@ -0,0 +1,105 @@
|
|
1
|
+
# Left pane (tree) widget
|
2
|
+
#
|
3
|
+
tree_selector = "#tree"
|
4
|
+
tree_column = 3
|
5
|
+
|
6
|
+
log = (msg) ->
|
7
|
+
console?.log "** admin/pages:tree: #{msg}"
|
8
|
+
|
9
|
+
class @PaneTree
|
10
|
+
constructor: (@element) ->
|
11
|
+
@tree_table = new SmartTreeTable @element.find( tree_selector ).first(),
|
12
|
+
column: tree_column
|
13
|
+
on_select: @on_tree_item_selected
|
14
|
+
prefix:
|
15
|
+
branch:
|
16
|
+
expanded: '<i class="prefix-expanded fa fa-caret-down"></i>'
|
17
|
+
collapsed: '<i class="prefix-collapsed fa fa-caret-right"></i>'
|
18
|
+
dragAndDrop:
|
19
|
+
enabled: false
|
20
|
+
dropTarget:
|
21
|
+
overlay:
|
22
|
+
before: '<i class="fa fa-long-arrow-up"></i>'
|
23
|
+
into: '<i class="fa fa-long-arrow-right"></i>'
|
24
|
+
after: '<i class="fa fa-long-arrow-down"></i>'
|
25
|
+
|
26
|
+
@select null
|
27
|
+
|
28
|
+
@attached_footer = new AttachedFooter
|
29
|
+
target: $(tree_selector)
|
30
|
+
footer: @bottom_toolbar()
|
31
|
+
observe: $('.pane-tree .content')
|
32
|
+
|
33
|
+
log "initialized"
|
34
|
+
|
35
|
+
# Updates pane tree widget
|
36
|
+
#
|
37
|
+
update: (state) ->
|
38
|
+
@tree_table.select state.page_node_id, false
|
39
|
+
@scroll_to_view state.page_node_id
|
40
|
+
@update_bottom_toolbar state
|
41
|
+
@update_top_toolbar state
|
42
|
+
|
43
|
+
select: (id) ->
|
44
|
+
@tree_table.select id, false
|
45
|
+
|
46
|
+
expand: (id) ->
|
47
|
+
@tree_table.expand id
|
48
|
+
|
49
|
+
scroll_to_view: (id) ->
|
50
|
+
return unless id?
|
51
|
+
row = @tree_table.rows[id]
|
52
|
+
return unless row?
|
53
|
+
el = row.el
|
54
|
+
el_t = el.position().top
|
55
|
+
el_b = el_t + el.height()
|
56
|
+
if el_t < 0 || $('.pane-tree .content').height() < el_b
|
57
|
+
origin_to = @tree_table.table.position().top
|
58
|
+
scroll_to = el.position().top
|
59
|
+
# console?.log "** pane-tree: scrolling to selected: #{scroll_to}: #{origin_to}"
|
60
|
+
@element.find('.content').animate { scrollTop: scroll_to - origin_to } #, 'slow'
|
61
|
+
|
62
|
+
|
63
|
+
# Callback to be invoked when page (tree item) is selected
|
64
|
+
#
|
65
|
+
on_tree_item_selected: (id, object, el) =>
|
66
|
+
pages_widget.on_page_selected id, object
|
67
|
+
|
68
|
+
|
69
|
+
# Returns row object specified by given +id+
|
70
|
+
#
|
71
|
+
find_row_by_id: (id) ->
|
72
|
+
@tree_table.rows[id]
|
73
|
+
|
74
|
+
# Returns action buttons elements, or elements within buttons specified by +selector+
|
75
|
+
#
|
76
|
+
bottom_toolbar: (selector = '') ->
|
77
|
+
@element.find(".bottom-toolbar #{selector}")
|
78
|
+
|
79
|
+
# Updates action buttons state and labels
|
80
|
+
#
|
81
|
+
update_bottom_toolbar: (state) ->
|
82
|
+
unless state.page_node_id?
|
83
|
+
@bottom_toolbar().hide()
|
84
|
+
return
|
85
|
+
object = @find_row_by_id state.page_node_id
|
86
|
+
@bottom_toolbar().show()
|
87
|
+
@bottom_toolbar('.page-append-link').attr 'href', pages_widget.url_to_action 'append'
|
88
|
+
@bottom_toolbar('.page-insert-link').attr 'href', pages_widget.url_to_action 'insert'
|
89
|
+
@bottom_toolbar('.page-delete-link').attr 'href', pages_widget.url_to_action 'delete'
|
90
|
+
@bottom_toolbar(' .page-name').text object.contents
|
91
|
+
@attached_footer.update_footer()
|
92
|
+
|
93
|
+
# Returns top toolbar element, or elements within buttons specified by +selector+
|
94
|
+
#
|
95
|
+
top_toolbar: (selector = '') ->
|
96
|
+
@element.find(".top-toolbar #{selector}")
|
97
|
+
|
98
|
+
# Updates top toolbar buttons and links
|
99
|
+
#
|
100
|
+
update_top_toolbar: (state) ->
|
101
|
+
@top_toolbar('.lang-select-link').each ->
|
102
|
+
lang = $(@).attr 'data-lang-id'
|
103
|
+
$(@).attr 'href', pages_widget.url_to( lang, state.page_node_id )
|
104
|
+
|
105
|
+
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# Modal dialogs for page and template/layout selection.
|
2
|
+
#
|
3
|
+
|
4
|
+
modal_result = null
|
5
|
+
|
6
|
+
@admin_modal_select_and_close = ( result ) ->
|
7
|
+
console?.log "** amdin modal select and close: #{result}"
|
8
|
+
modal_result = result
|
9
|
+
$("#adminModal").modal 'hide'
|
10
|
+
|
11
|
+
@admin_modal_select_page_clear = (e) ->
|
12
|
+
field = $(e.currentTarget).closest('.field-select-page')
|
13
|
+
field.find('.page-node-id').val ''
|
14
|
+
field.find('.page-label').val ''
|
15
|
+
|
16
|
+
@admin_modal_select_page_select = (e) ->
|
17
|
+
field = $(e.currentTarget).closest('.field-select-page')
|
18
|
+
modal_result = null
|
19
|
+
select_lang = field.data 'lang'
|
20
|
+
select_page_node_id = field.find(".page-node-id").val()
|
21
|
+
$("#adminModal").modal
|
22
|
+
remote: "edit/select_page?select_lang=#{select_lang}&select_page_node_id=#{select_page_node_id}"
|
23
|
+
$("#adminModal").on 'hidden.bs.modal', ->
|
24
|
+
if modal_result?
|
25
|
+
console?.log "** select page: selected result: #{modal_result.page_id}, #{modal_result.page_label}"
|
26
|
+
field.find('.page-node-id').val modal_result.page_node_id
|
27
|
+
html_result = $.parseHTML(modal_result.page_label)
|
28
|
+
text_result = $(html_result).text().replace(/^\s+|\s+$/g, '')
|
29
|
+
field.find('.page-label').val text_result
|
30
|
+
# on_select()
|
31
|
+
$("#adminModal").off 'hidden.bs.modal'
|
32
|
+
|
33
|
+
@admin_modal_select_template_clear = (e) ->
|
34
|
+
field = $(e.currentTarget).closest('.field-select-template')
|
35
|
+
field.find('.template-id').val ''
|
36
|
+
field.find('.template-label').val ''
|
37
|
+
|
38
|
+
@admin_modal_select_template_select = (e) ->
|
39
|
+
field = $(e.currentTarget).closest('.field-select-template')
|
40
|
+
modal_result = null
|
41
|
+
select_template_prefix = field.data 'prefix'
|
42
|
+
select_template_id = field.find(".template-id").val()
|
43
|
+
$("#adminModal").modal
|
44
|
+
remote: "edit/select_template?select_template_prefix=#{select_template_prefix}&select_template_name=#{select_template_id}"
|
45
|
+
$("#adminModal").on 'hidden.bs.modal', ->
|
46
|
+
if modal_result?
|
47
|
+
console?.log "** select template: selected result: #{modal_result.template_id}"
|
48
|
+
field.find('.template-id').val modal_result.template_id
|
49
|
+
html_result = $.parseHTML(modal_result.template_label)
|
50
|
+
text_result = $(html_result).text().replace(/^\s+|\s+$/g, '')
|
51
|
+
field.find('.template-label').val text_result
|
52
|
+
# on_select()
|
53
|
+
$("#adminModal").off 'hidden.bs.modal'
|
54
|
+
|
55
|
+
|
56
|
+
# Install event handlers on select-page fields
|
57
|
+
$ ->
|
58
|
+
$("body").on 'click', '.field-select-page .btn-clear', admin_modal_select_page_clear
|
59
|
+
$("body").on 'click', '.field-select-page .btn-select', admin_modal_select_page_select
|
60
|
+
$("body").on 'click', '.field-select-template .btn-clear', admin_modal_select_template_clear
|
61
|
+
$("body").on 'click', '.field-select-template .btn-select', admin_modal_select_template_select
|
62
|
+
|
63
|
+
console?.log "** select page fields installed"
|