aerogel-pages 1.4.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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"
|