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
data/db/model/page.rb
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
class Page
|
2
|
+
include Model
|
3
|
+
include Model::Timestamps
|
4
|
+
|
5
|
+
# embedded_in :page
|
6
|
+
belongs_to :page_node, touch: true
|
7
|
+
|
8
|
+
PUBLICATION_STATES = [:published, :hidden, :not_published]
|
9
|
+
|
10
|
+
field :lang, type: Symbol
|
11
|
+
field :published_at, type: Time
|
12
|
+
field :publication_state, type: Symbol, default: :published
|
13
|
+
field :link, type: String
|
14
|
+
field :parent_links, type: Array, default: nil
|
15
|
+
field :title, type: String
|
16
|
+
field :html_description, type: String
|
17
|
+
field :html_keywords, type: String
|
18
|
+
|
19
|
+
before_save :update_links
|
20
|
+
before_update :touch_ancestors
|
21
|
+
before_destroy :touch_ancestors
|
22
|
+
|
23
|
+
embeds_many :page_blocks, class_name: "Pages::Block", order: :position.asc #, cascade_callbacks: true
|
24
|
+
accepts_nested_attributes_for :page_blocks,
|
25
|
+
reject_if: :all_blank,
|
26
|
+
allow_destroy: true
|
27
|
+
|
28
|
+
validates_presence_of :page_node_id, :lang, :title
|
29
|
+
validates_presence_of :link, unless: :root?
|
30
|
+
validates :publication_state, inclusion: { in: PUBLICATION_STATES }
|
31
|
+
validates_uniqueness_of :lang, scope: [:page_node_id]
|
32
|
+
|
33
|
+
# scope :children_of, ->(other_page) { where( :page_id.in => other_page.children.map(&:_id) ) }
|
34
|
+
scope :published, where( :publication_state => :published )
|
35
|
+
scope :published_and_hidden, where( :publication_state.in => [:published, :hidden] )
|
36
|
+
|
37
|
+
# Create a new embedded page block.
|
38
|
+
#
|
39
|
+
def create_page_block( opts )
|
40
|
+
pb = Aerogel::Pages.create_page_block opts[:type], opts
|
41
|
+
pb.page = self
|
42
|
+
pb
|
43
|
+
end
|
44
|
+
|
45
|
+
# Returns url to this page if it is accessible, constructed from the parent links.
|
46
|
+
#
|
47
|
+
def url
|
48
|
+
parts = [parent_links, link].flatten
|
49
|
+
parts.shift # skip root page
|
50
|
+
"/"+parts.join("/")
|
51
|
+
# ( root? ? "/" ) : parts.join("/")
|
52
|
+
end
|
53
|
+
|
54
|
+
# Returns +true+ if this Page is root.
|
55
|
+
#
|
56
|
+
def root?
|
57
|
+
page_node.try(:root?)
|
58
|
+
end
|
59
|
+
|
60
|
+
# Returns root in specified language.
|
61
|
+
#
|
62
|
+
def self.root( lang )
|
63
|
+
PageNode.root.try( :page, lang )
|
64
|
+
end
|
65
|
+
|
66
|
+
# Returns parent page.
|
67
|
+
#
|
68
|
+
def parent
|
69
|
+
page_node.parent.try( :page, lang )
|
70
|
+
end
|
71
|
+
|
72
|
+
# Returns children of this page.
|
73
|
+
#
|
74
|
+
def children
|
75
|
+
Page.where( lang: lang, :page_node_id.in => page_node.children.map(&:_id) )
|
76
|
+
end
|
77
|
+
|
78
|
+
# Returns ancestors of this page.
|
79
|
+
#
|
80
|
+
def ancestors
|
81
|
+
Page.where( lang: lang, :page_node_id.in => page_node.ancestors.map(&:_id) )
|
82
|
+
end
|
83
|
+
|
84
|
+
# Returns list of allowed content block types.
|
85
|
+
#
|
86
|
+
def available_block_types
|
87
|
+
Aerogel::Pages.registered_page_block_types.keys
|
88
|
+
end
|
89
|
+
|
90
|
+
# Returns list of available langs as Symbols
|
91
|
+
#
|
92
|
+
def self.available_langs
|
93
|
+
I18n.available_locales
|
94
|
+
end
|
95
|
+
|
96
|
+
|
97
|
+
# private
|
98
|
+
|
99
|
+
def update_links
|
100
|
+
self.parent_links = default_parent_links if parent_links.nil?
|
101
|
+
update_children_links
|
102
|
+
end
|
103
|
+
|
104
|
+
# Generates default value for parent_links, that is used to populate new Page object.
|
105
|
+
#
|
106
|
+
# NOTE: This is impossible to do as field's default with Proc, because by some reason
|
107
|
+
# Mongoid does not initialize relations at 'assign defaults' stage.
|
108
|
+
#
|
109
|
+
def default_parent_links
|
110
|
+
# puts "** default_parent_links: self.page_node=#{self.page_node.inspect}"
|
111
|
+
# puts "** default_parent_links: self=#{self.inspect}"
|
112
|
+
parent_page = parent
|
113
|
+
if parent_page.present?
|
114
|
+
parent_page.parent_links + [parent_page.link]
|
115
|
+
else
|
116
|
+
[]
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def update_children_links
|
121
|
+
return unless link_changed? || parent_links_changed?
|
122
|
+
# puts "** update children links fired"
|
123
|
+
links = parent_links + [link]
|
124
|
+
children.each do |p|
|
125
|
+
p.update_attributes parent_links: links
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
# Touches parents (if present)
|
130
|
+
#
|
131
|
+
def touch_ancestors
|
132
|
+
ancestors.update_all updated_at: Time.now
|
133
|
+
page_node.ancestors.update_all updated_at: Time.now
|
134
|
+
page_node.touch
|
135
|
+
end
|
136
|
+
|
137
|
+
end # class Page
|
@@ -0,0 +1,43 @@
|
|
1
|
+
class PageNode
|
2
|
+
include Model
|
3
|
+
include Model::OrderedTree
|
4
|
+
include Model::Timestamps
|
5
|
+
|
6
|
+
before_destroy :destroy_children
|
7
|
+
|
8
|
+
belongs_to :page_type
|
9
|
+
has_many :pages, dependent: :destroy
|
10
|
+
# embeds_many :pages, cascade_callbacks: true
|
11
|
+
|
12
|
+
validates_presence_of :page_type
|
13
|
+
|
14
|
+
accepts_nested_attributes_for :pages,
|
15
|
+
reject_if: :all_blank,
|
16
|
+
allow_destroy: true
|
17
|
+
|
18
|
+
before_update :touch_ancestors
|
19
|
+
before_destroy :touch_ancestors
|
20
|
+
|
21
|
+
# scope :with_content, ->(lang) { where( :'pages.lang' => lang ) }
|
22
|
+
# scope :published, ->(lang) { elem_match( pages: { lang: lang, :publication_state => :published } ) }
|
23
|
+
# scope :published_and_hidden, ->(lang) {
|
24
|
+
# elem_match( pages: { lang: lang, :publication_state.in => [:published, :hidden] } )
|
25
|
+
# }
|
26
|
+
|
27
|
+
# Returns content for the specified +lang+.
|
28
|
+
#
|
29
|
+
def page( lang )
|
30
|
+
pages.where( lang: lang.to_sym ).first
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
# Touches parents (if present)
|
36
|
+
#
|
37
|
+
def touch_ancestors
|
38
|
+
ancestors.update_all updated_at: Time.now
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
|
43
|
+
end # class Page
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class PageType
|
2
|
+
include Model
|
3
|
+
|
4
|
+
field :type, type: Symbol
|
5
|
+
field :name, type: String
|
6
|
+
field :allowed_parents, type: Array
|
7
|
+
field :allowed_children, type: Array
|
8
|
+
field :allowed_content_blocks, type: Array
|
9
|
+
field :defaults, type: Hash
|
10
|
+
|
11
|
+
validates_uniqueness_of :type
|
12
|
+
|
13
|
+
has_many :page_nodes
|
14
|
+
|
15
|
+
end # class PageType
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Pages
|
2
|
+
class Block
|
3
|
+
include Model
|
4
|
+
|
5
|
+
embedded_in :page
|
6
|
+
|
7
|
+
field :position, type: Integer
|
8
|
+
|
9
|
+
# Returns symbolized block type, inferred from class name.
|
10
|
+
#
|
11
|
+
def type
|
12
|
+
self.class.name.split("::").last.underscore.to_sym
|
13
|
+
end
|
14
|
+
|
15
|
+
# Returns PageNode of the Page the block belongs to.
|
16
|
+
#
|
17
|
+
def page_node
|
18
|
+
page.page_node
|
19
|
+
end
|
20
|
+
|
21
|
+
# Returns lang of the PageContent the block belongs to.
|
22
|
+
#
|
23
|
+
def lang
|
24
|
+
page.lang
|
25
|
+
end
|
26
|
+
|
27
|
+
# Returns +true+ if block has configurable details.
|
28
|
+
#
|
29
|
+
def has_details?
|
30
|
+
false
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.has_details!
|
34
|
+
define_method(:has_details?) { true }
|
35
|
+
end
|
36
|
+
|
37
|
+
end # class Block
|
38
|
+
end # module Pages
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Pages::Blocks
|
2
|
+
class Image < Pages::Block
|
3
|
+
|
4
|
+
ALIGNMENT_STATES = [:left, :middle, :right]
|
5
|
+
|
6
|
+
field :image, type: Media::Image
|
7
|
+
field :name, type: String
|
8
|
+
field :alignment, type: Symbol, default: :middle
|
9
|
+
field :thumb, type: String
|
10
|
+
|
11
|
+
validates :alignment, inclusion: { in: ALIGNMENT_STATES }
|
12
|
+
|
13
|
+
Aerogel::Pages.register_page_block_type :image, self
|
14
|
+
|
15
|
+
end # class Text
|
16
|
+
end # module Pages
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Pages::Blocks
|
2
|
+
class PagesList < Pages::Block
|
3
|
+
|
4
|
+
Aerogel::Pages.register_page_block_type :pages_list, self
|
5
|
+
|
6
|
+
field :target_page_node_id, type: String
|
7
|
+
field :ordered_by, type: Symbol, default: :position
|
8
|
+
field :ordered_asc, type: Symbol, default: :asc
|
9
|
+
field :limit, type: Integer
|
10
|
+
field :template, type: String
|
11
|
+
field :show_hidden, type: Boolean, default: false
|
12
|
+
|
13
|
+
has_details!
|
14
|
+
|
15
|
+
def listed_pages
|
16
|
+
return @_listed_pages_cache if @_listed_pages_cache
|
17
|
+
target_page_node = target_page_node_id.present? ? PageNode.find( target_page_node_id ) : page_node
|
18
|
+
return [] if target_page_node.nil?
|
19
|
+
listed = target_page_node.page( lang ).children
|
20
|
+
listed = (show_hidden ? listed.published_and_hidden : listed.published )
|
21
|
+
listed = listed.to_a
|
22
|
+
# unless ordered_by == :position
|
23
|
+
# listed = listed.sort_by do |p|
|
24
|
+
# p.content( lang ).try( :send, ordered_by ).try( :to_i ) || 0
|
25
|
+
# end
|
26
|
+
# end
|
27
|
+
# listed = listed.reverse if ordered_asc == :desc
|
28
|
+
# listed = listed.first( limit ) if limit.present? && limit > 0
|
29
|
+
@_listed_pages_cache = listed
|
30
|
+
listed
|
31
|
+
end
|
32
|
+
|
33
|
+
def listed_pages_DISABLED
|
34
|
+
listed = listed_pages.map{|p| p.try :content, lang }.select{|pc| pc.present? }
|
35
|
+
# listed = listed.order_by( ordered_by => (ordered_asc == :asc ? 1 : -1) )
|
36
|
+
# listed = listed.limit( limit ) if limit.present? && limit > 0
|
37
|
+
# listed
|
38
|
+
end
|
39
|
+
|
40
|
+
end # class Text
|
41
|
+
end # module Pages
|
File without changes
|
@@ -0,0 +1,10 @@
|
|
1
|
+
root_page_node = PageNode.root
|
2
|
+
|
3
|
+
model Page
|
4
|
+
|
5
|
+
find_by :page_node_id, :lang
|
6
|
+
|
7
|
+
seeds [
|
8
|
+
{ page_node_id: root_page_node.id, lang: :en, link: '', title: 'Home page' },
|
9
|
+
{ page_node_id: root_page_node.id, lang: :ru, link: '', title: 'Главная страница' }
|
10
|
+
]
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# Sub pages created here only if root has no children
|
2
|
+
#
|
3
|
+
page_type_simple = PageType.where( type: :page ).first
|
4
|
+
page_node_root = PageNode.root
|
5
|
+
|
6
|
+
model PageNode
|
7
|
+
|
8
|
+
find_by :parent_id
|
9
|
+
|
10
|
+
seeds [
|
11
|
+
{
|
12
|
+
parent_id: page_node_root.id, page_type: page_type_simple
|
13
|
+
}
|
14
|
+
]
|
15
|
+
|
@@ -0,0 +1,10 @@
|
|
1
|
+
news_page_node = PageNode.root.children.first
|
2
|
+
|
3
|
+
model Page
|
4
|
+
|
5
|
+
find_by :page_node_id, :lang
|
6
|
+
|
7
|
+
seeds [
|
8
|
+
{ page_node_id: news_page_node.id, lang: :en, link: 'news', title: 'News' },
|
9
|
+
{ page_node_id: news_page_node.id, lang: :ru, link: 'новости', title: 'Новости' }
|
10
|
+
]
|
File without changes
|
@@ -0,0 +1,10 @@
|
|
1
|
+
root_page_node = PageNode.root
|
2
|
+
|
3
|
+
model Page
|
4
|
+
|
5
|
+
find_by :page_node_id, :lang
|
6
|
+
|
7
|
+
seeds [
|
8
|
+
{ page_node_id: root_page_node.id, lang: :en, link: '', title: 'Home page' },
|
9
|
+
{ page_node_id: root_page_node.id, lang: :ru, link: '', title: 'Главная страница' }
|
10
|
+
]
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# A .seed file is a .conf file which stores
|
2
|
+
# database seed data and rules.
|
3
|
+
#
|
4
|
+
|
5
|
+
# Model class to use
|
6
|
+
#
|
7
|
+
# ! required
|
8
|
+
model Setting
|
9
|
+
|
10
|
+
# Attribute name or a list of attribute names to be used as key(s)
|
11
|
+
# when finding objects
|
12
|
+
#
|
13
|
+
# Usage:
|
14
|
+
# find_by :name
|
15
|
+
# or
|
16
|
+
# find_by [:first_name, :last_name]
|
17
|
+
#
|
18
|
+
# ! required
|
19
|
+
find_by :name
|
20
|
+
|
21
|
+
# Values of attributes listed here will be set even
|
22
|
+
# if they exist already in the matching database object.
|
23
|
+
#
|
24
|
+
# Other attributes in the seed data will be treated as a default value,
|
25
|
+
# i.e. they will only be set if the matching database object does not exist
|
26
|
+
# or its corresponding attribute is not set.
|
27
|
+
#
|
28
|
+
# Usage:
|
29
|
+
# force :value
|
30
|
+
# or:
|
31
|
+
# force [:value, :description]
|
32
|
+
#
|
33
|
+
# default is: no fields are forced
|
34
|
+
force :value
|
35
|
+
|
36
|
+
seeds [
|
37
|
+
{ name: 'abc', value: '123' },
|
38
|
+
{ name: 'def', value: '456' },
|
39
|
+
{ name: 'ghi', value: '789' },
|
40
|
+
{ name: 'abcdef', value: '123456' }
|
41
|
+
]
|
42
|
+
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Aerogel::Pages
|
2
|
+
|
3
|
+
def self.registered(app)
|
4
|
+
setup_reloader(app) if Aerogel.config.aerogel.reloader?
|
5
|
+
|
6
|
+
# module initialization
|
7
|
+
Aerogel::Pages.reset!
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.setup_reloader(app)
|
11
|
+
app.use Aerogel::Reloader, :'db/model', before: true do
|
12
|
+
Aerogel::Pages.reset!
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.reset!
|
17
|
+
@registered_page_block_types ||= {}
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.registered_page_block_types
|
21
|
+
@registered_page_block_types ||= {}
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.register_page_block_type( type, model )
|
25
|
+
registered_page_block_types[type] = model
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.create_page_block( type, *args )
|
29
|
+
type = type.to_sym
|
30
|
+
if registered_page_block_types[type].nil?
|
31
|
+
raise ArgumentError.new( "Invalid page block type: '#{type}'")
|
32
|
+
end
|
33
|
+
registered_page_block_types[type].new( *args )
|
34
|
+
end
|
35
|
+
|
36
|
+
end # module Aerogel::Pages
|
37
|
+
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Aerogel::Pages
|
2
|
+
module Traversal
|
3
|
+
|
4
|
+
def self.page( id, lang )
|
5
|
+
PageNode.find( id ).try( :page, lang )
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.root( lang )
|
9
|
+
Page.root(lang)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.find( url, lang )
|
13
|
+
page = root(lang)
|
14
|
+
traverse page, url.dup, lang
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.traverse( page, url, lang )
|
18
|
+
return page if page.nil? || url.blank?
|
19
|
+
link = url.shift
|
20
|
+
page = page.children.where( link: link ).first
|
21
|
+
traverse page, url, lang
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.find_closest_in_other_lang( page, lang )
|
25
|
+
return page.page_node.page(lang) if page.page_node.page(lang).present?
|
26
|
+
return root(lang) if page.root?
|
27
|
+
find_closest_in_other_lang( page.parent, lang )
|
28
|
+
end
|
29
|
+
end # module Traversal
|
30
|
+
end # module Aerogel::Pages
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'aerogel/core'
|
2
|
+
require 'aerogel/admin'
|
3
|
+
require "aerogel/pages/version"
|
4
|
+
require "aerogel/pages/core"
|
5
|
+
require "aerogel/pages/traversal"
|
6
|
+
|
7
|
+
module Aerogel
|
8
|
+
|
9
|
+
# Finally, register module's root folder
|
10
|
+
register_path File.join( File.dirname(__FILE__), '..', '..' )
|
11
|
+
|
12
|
+
|
13
|
+
# configure module
|
14
|
+
on_load do |app|
|
15
|
+
app.register Aerogel::Pages
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
en:
|
2
|
+
mongoid:
|
3
|
+
models:
|
4
|
+
page: Page
|
5
|
+
page_node: Page (tree node)
|
6
|
+
|
7
|
+
attributes:
|
8
|
+
page_node:
|
9
|
+
title: Title
|
10
|
+
type: Type
|
11
|
+
|
12
|
+
page:
|
13
|
+
title: Title
|
14
|
+
published_at: Published at
|
15
|
+
publication_state: Publication state
|
16
|
+
link: Link
|
17
|
+
html_description: "<HTML/> meta description"
|
18
|
+
html_keywords: "<HTML/> meta keywords"
|
@@ -0,0 +1,19 @@
|
|
1
|
+
ru:
|
2
|
+
mongoid:
|
3
|
+
models:
|
4
|
+
page: Страница
|
5
|
+
page_node: Страница (узел дерева)
|
6
|
+
|
7
|
+
attributes:
|
8
|
+
|
9
|
+
page_node:
|
10
|
+
title: Заголовок
|
11
|
+
type: Тип
|
12
|
+
|
13
|
+
page:
|
14
|
+
title: Заголовок
|
15
|
+
published_at: Дата публикации
|
16
|
+
publication_state: Состояние публикации
|
17
|
+
link: Ссылка
|
18
|
+
html_description: "<HTML/> meta description"
|
19
|
+
html_keywords: "<HTML/> meta keywords"
|
@@ -0,0 +1,38 @@
|
|
1
|
+
en:
|
2
|
+
aerogel:
|
3
|
+
admin:
|
4
|
+
pages:
|
5
|
+
views:
|
6
|
+
index:
|
7
|
+
no_page_selected: No page is selected
|
8
|
+
|
9
|
+
delete:
|
10
|
+
title: Delete page?
|
11
|
+
text_no_subpages: |
|
12
|
+
<p>
|
13
|
+
Do you really want to delete page <b>%{title}</b>?
|
14
|
+
</p>
|
15
|
+
|
16
|
+
text_with_subpages: |
|
17
|
+
<p>
|
18
|
+
Do you really want to delete page <b>%{title}</b> and <b>%{count}</b>
|
19
|
+
of its subpages?
|
20
|
+
</p>
|
21
|
+
|
22
|
+
preview:
|
23
|
+
no_content_in_this_language: Page has no content in this language
|
24
|
+
|
25
|
+
edit:
|
26
|
+
clear_page_content: Clear page content
|
27
|
+
no_content: No content
|
28
|
+
add_content: Add content
|
29
|
+
page_details: Page details
|
30
|
+
no_publication_date: No publication date
|
31
|
+
add_block: Add block
|
32
|
+
block:
|
33
|
+
details: Details
|
34
|
+
text: Text
|
35
|
+
image: Image
|
36
|
+
hr: HR
|
37
|
+
pages_list: "Pages: List"
|
38
|
+
|