blueberry_cms 0.1.0 → 0.1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +34 -0
- data/app/assets/javascripts/blueberry_cms/multilingual-tabs.coffee +0 -0
- data/app/assets/javascripts/blueberry_cms/sortable-page-blocks.coffee +14 -0
- data/app/assets/javascripts/blueberry_cms/sortable-pages.coffee +17 -0
- data/app/assets/javascripts/blueberry_cms.coffee +3 -0
- data/app/assets/stylesheets/blueberry_cms/components.sass +39 -0
- data/app/assets/stylesheets/blueberry_cms/multilingual-tabs.sass +44 -0
- data/app/assets/stylesheets/blueberry_cms.sass +1 -0
- data/app/controllers/blueberry_cms/admin/menus_controller.rb +50 -0
- data/app/controllers/blueberry_cms/admin/pages_controller.rb +22 -16
- data/app/controllers/blueberry_cms/root_controller.rb +2 -1
- data/app/decorators/block_decorator.rb +13 -0
- data/app/decorators/blueberry_cms/link_decorator.rb +15 -0
- data/app/decorators/blueberry_cms/page_block_decorator.rb +46 -0
- data/app/decorators/blueberry_cms/page_decorator.rb +7 -0
- data/app/helpers/blueberry_cms/menus_helper.rb +27 -0
- data/app/helpers/blueberry_cms/pages_helper.rb +11 -0
- data/app/models/blueberry_cms/image.rb +19 -0
- data/app/models/blueberry_cms/link.rb +28 -0
- data/app/models/blueberry_cms/menu.rb +19 -0
- data/app/models/blueberry_cms/menu_link.rb +36 -0
- data/app/models/blueberry_cms/page.rb +62 -11
- data/app/models/blueberry_cms/page_block.rb +29 -8
- data/app/models/blueberry_cms/page_blocks/faq.rb +19 -0
- data/app/models/blueberry_cms/page_blocks/gallery.rb +12 -12
- data/app/models/blueberry_cms/page_blocks/links.rb +15 -0
- data/app/models/blueberry_cms/page_blocks/rich_text.rb +4 -15
- data/app/models/blueberry_cms/page_blocks/shared.rb +25 -0
- data/app/models/blueberry_cms/page_blocks/tabs.rb +17 -0
- data/app/models/blueberry_cms/page_blocks/video_gallery.rb +13 -0
- data/app/models/blueberry_cms/question.rb +11 -0
- data/app/models/blueberry_cms/tab.rb +13 -0
- data/app/models/blueberry_cms/video.rb +70 -0
- data/app/models/concerns/blueberry_cms/sortable.rb +25 -0
- data/app/models/custom_render.rb +3 -3
- data/app/views/blueberry_cms/admin/menus/_empty.html.slim +2 -0
- data/app/views/blueberry_cms/admin/menus/_form.html.slim +6 -0
- data/app/views/blueberry_cms/admin/menus/_link_fields.html.slim +30 -0
- data/app/views/blueberry_cms/admin/menus/_menu.html.slim +18 -0
- data/app/views/blueberry_cms/admin/menus/edit.html.slim +15 -0
- data/app/views/blueberry_cms/admin/menus/index.html.slim +26 -0
- data/app/views/blueberry_cms/admin/menus/new.html.slim +15 -0
- data/app/views/blueberry_cms/admin/page_blocks/_faq.html.slim +15 -0
- data/app/views/blueberry_cms/admin/page_blocks/_faq_questions_fields.slim +24 -0
- data/app/views/blueberry_cms/admin/page_blocks/_form.html.slim +18 -0
- data/app/views/blueberry_cms/admin/page_blocks/_gallery.html.slim +16 -0
- data/app/views/blueberry_cms/admin/page_blocks/_gallery_images_fields.html.slim +14 -0
- data/app/views/blueberry_cms/admin/page_blocks/_links.html.slim +25 -0
- data/app/views/blueberry_cms/admin/page_blocks/_links_links_fields.slim +23 -0
- data/app/views/blueberry_cms/admin/page_blocks/_richtext.html.slim +30 -0
- data/app/views/blueberry_cms/admin/page_blocks/_shared.html.slim +8 -0
- data/app/views/blueberry_cms/admin/page_blocks/_tabs.html.slim +11 -0
- data/app/views/blueberry_cms/admin/page_blocks/_tabs_tabs_fields.html.slim +24 -0
- data/app/views/blueberry_cms/admin/page_blocks/_videogallery.html.slim +15 -0
- data/app/views/blueberry_cms/admin/page_blocks/_videos_fields.slim +17 -0
- data/app/views/blueberry_cms/admin/pages/_block_fields.html.slim +53 -3
- data/app/views/blueberry_cms/admin/pages/_custom_fields.html.slim +0 -0
- data/app/views/blueberry_cms/admin/pages/_empty.html.slim +2 -0
- data/app/views/blueberry_cms/admin/pages/_form.html.slim +47 -11
- data/app/views/blueberry_cms/admin/pages/_page.html.slim +33 -0
- data/app/views/blueberry_cms/admin/pages/edit.html.slim +12 -3
- data/app/views/blueberry_cms/admin/pages/index.html.slim +6 -27
- data/app/views/blueberry_cms/admin/pages/new.html.slim +9 -1
- data/app/views/blueberry_cms/admin/partials/_form_errors.html.slim +5 -0
- data/app/views/blueberry_cms/page_blocks/_faq.html.slim +19 -0
- data/app/views/blueberry_cms/page_blocks/_form.html.slim +19 -0
- data/app/views/blueberry_cms/page_blocks/_gallery.html.slim +22 -0
- data/app/views/blueberry_cms/page_blocks/_links.html.slim +52 -0
- data/app/views/blueberry_cms/page_blocks/_richtext.html.slim +10 -0
- data/app/views/blueberry_cms/page_blocks/_tabs.html.slim +8 -0
- data/app/views/blueberry_cms/page_blocks/_videogallery.html.slim +27 -0
- data/app/views/blueberry_cms/pages/_blocks.html.slim +5 -0
- data/app/views/blueberry_cms/pages/show.html.slim +9 -8
- data/config/locales/cs.enum.yml +10 -0
- data/config/locales/cs.mongoid.yml +49 -0
- data/config/locales/cs.yml +79 -13
- data/config/routes.rb +6 -2
- data/lib/blueberry_cms/engine.rb +12 -0
- data/lib/blueberry_cms/liquid_tags/page_link.rb +3 -1
- data/lib/blueberry_cms/liquid_tags/page_url.rb +18 -0
- data/lib/blueberry_cms/version.rb +1 -1
- data/lib/blueberry_cms.rb +9 -3
- data/lib/generators/blueberry/templates/image_uploader.rb +31 -0
- data/lib/generators/blueberry/uploader_generator.rb +9 -0
- metadata +184 -10
- data/app/assets/javascripts/blueberry_cms.js +0 -1
- data/app/assets/stylesheets/blueberry_cms/application.css +0 -15
- data/app/models/blueberry_cms/page_blocks/text.rb +0 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e91d2118e7044a75f384a362dc3276491ec99c78
|
4
|
+
data.tar.gz: 9bb48bd2b149ce3b97ab6d1d4ac3c49e4fe9adca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4a2ecd4ba705b32796d8ac2dd78fc68ed8efe6b20e45eed6a6399840948c87a2953fbc7e74cba79964362255d530acf51a5edf40fa33d07bfc4f4a9ebf6734c5
|
7
|
+
data.tar.gz: 42600c8ab70c5fbb54d346f952929fb952a27f4c6c7be534baf18dea7d483e946598699056f51b5efb896686d87539577bd7f1d15f0c77d989d295da03ddae60
|
data/README.md
CHANGED
@@ -11,6 +11,18 @@ Add this line to your application's Gemfile:
|
|
11
11
|
gem 'blueberry_cms'
|
12
12
|
```
|
13
13
|
|
14
|
+
Add this line to your application's sass:
|
15
|
+
|
16
|
+
```sass
|
17
|
+
@import blueberry_cms
|
18
|
+
```
|
19
|
+
|
20
|
+
Add this line to your application's coffeescript:
|
21
|
+
|
22
|
+
```coffee
|
23
|
+
#= require blueberry_cms
|
24
|
+
```
|
25
|
+
|
14
26
|
And then execute:
|
15
27
|
```bash
|
16
28
|
$ bundle
|
@@ -20,6 +32,28 @@ Or install it yourself as:
|
|
20
32
|
```bash
|
21
33
|
$ gem install blueberry_cms
|
22
34
|
```
|
35
|
+
## BlueberryCMS::Page custom fields
|
36
|
+
```ruby
|
37
|
+
# config/initializers/blueberry_cms.rb
|
38
|
+
|
39
|
+
module BreadcrumbLeft
|
40
|
+
extend ActiveSupport::Concern
|
41
|
+
|
42
|
+
included do
|
43
|
+
field :breadcrumb_left, type: Boolean, default: false
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
ActiveSupport::Reloader.to_prepare do
|
48
|
+
BlueberryCMS::Page.send(:include, BreadcrumbLeft)
|
49
|
+
end
|
50
|
+
```
|
51
|
+
|
52
|
+
```slim
|
53
|
+
# app/views/blueberry_cms/admin/pages/_custom_fields.html.slim
|
54
|
+
|
55
|
+
= f.input :breadcrumb_left
|
56
|
+
```
|
23
57
|
|
24
58
|
## Contributing
|
25
59
|
Contribution directions go here.
|
File without changes
|
@@ -0,0 +1,14 @@
|
|
1
|
+
initSortable = ->
|
2
|
+
sortable(
|
3
|
+
'#blocks',
|
4
|
+
handle: 'i.glyphicon-resize-vertical',
|
5
|
+
forcePlaceholderSize: true
|
6
|
+
)
|
7
|
+
|
8
|
+
initSortable()
|
9
|
+
$('#blocks').on 'cocoon:after-insert', ->
|
10
|
+
initSortable()
|
11
|
+
|
12
|
+
$('#blocks').on 'sortupdate', (e) ->
|
13
|
+
$('> .nested-fields', this).map (position) ->
|
14
|
+
$(this).find('input[id$=_position]').val(position)
|
@@ -0,0 +1,17 @@
|
|
1
|
+
$ ->
|
2
|
+
action = $('.pages-tree').data('url')
|
3
|
+
|
4
|
+
sortable(
|
5
|
+
'ul.pages',
|
6
|
+
handle: 'i.glyphicon-resize-vertical',
|
7
|
+
forcePlaceholderSize: true
|
8
|
+
)
|
9
|
+
|
10
|
+
$('ul.pages').on 'sortupdate', (e) ->
|
11
|
+
item = $(e.detail.item)
|
12
|
+
|
13
|
+
$.ajax
|
14
|
+
url: action + "/#{item.data('id')}",
|
15
|
+
dataType: 'json'
|
16
|
+
method: 'PUT',
|
17
|
+
data: { page: { position: item.index() } }
|
@@ -0,0 +1,39 @@
|
|
1
|
+
.form-layout
|
2
|
+
.form-group
|
3
|
+
display: flex
|
4
|
+
align-items: flex-start
|
5
|
+
+render-to(xs, ms)
|
6
|
+
display: block
|
7
|
+
|
8
|
+
label
|
9
|
+
min-width: rem(220)
|
10
|
+
margin-top: rem(13)
|
11
|
+
text-align: right
|
12
|
+
+render-to(xs, ms)
|
13
|
+
width: 100%
|
14
|
+
min-width: auto
|
15
|
+
text-align: left
|
16
|
+
|
17
|
+
.form-control-wrapper
|
18
|
+
margin-left: rem(15)
|
19
|
+
margin-right: 25%
|
20
|
+
flex-grow: 2
|
21
|
+
+render-to(xs, ms, sm, md)
|
22
|
+
margin-right: 0
|
23
|
+
|
24
|
+
+render-to(xs, ms)
|
25
|
+
margin-left: 0
|
26
|
+
|
27
|
+
.form-control-wrapper
|
28
|
+
margin-right: 0
|
29
|
+
margin-left: 0
|
30
|
+
|
31
|
+
.box-footer
|
32
|
+
text-align: right
|
33
|
+
|
34
|
+
.for-horizontal-form
|
35
|
+
padding-left: 0
|
36
|
+
|
37
|
+
.pages-tree__row
|
38
|
+
&:hover
|
39
|
+
background-color: #F4F6FA
|
@@ -0,0 +1,44 @@
|
|
1
|
+
.multilingual-tabs-section
|
2
|
+
.tab-content,
|
3
|
+
input[type="radio"]
|
4
|
+
display: none
|
5
|
+
|
6
|
+
.tab-label
|
7
|
+
position: relative
|
8
|
+
padding: 10px 15px
|
9
|
+
margin-bottom: -1px
|
10
|
+
margin-right: 2px
|
11
|
+
text-transform: uppercase
|
12
|
+
font-weight: normal
|
13
|
+
line-height: 20px
|
14
|
+
display: inline-block
|
15
|
+
color: #1aabd5
|
16
|
+
cursor: pointer
|
17
|
+
border-radius: rem(4) rem(4) 0 0
|
18
|
+
border: 1px solid transparent;
|
19
|
+
|
20
|
+
&:hover
|
21
|
+
border-color: #dcdcdc #dcdcdc #ddd;
|
22
|
+
color: #444;
|
23
|
+
background: #f7f7f7;
|
24
|
+
border: 1px solid #ddd;
|
25
|
+
border-bottom-color: transparent;
|
26
|
+
|
27
|
+
.tab-content
|
28
|
+
border-top: 1px solid #ddd;
|
29
|
+
padding-top: rem(25)
|
30
|
+
|
31
|
+
//all available languages
|
32
|
+
#cs-tab:checked ~ .multilingual-tabs-labels #cs-tab,
|
33
|
+
#en-tab:checked ~ .multilingual-tabs-labels #en-tab,
|
34
|
+
#ru-tab:checked ~ .multilingual-tabs-labels #ru-tab
|
35
|
+
color: #d2d6de;
|
36
|
+
background-color: #f4f6fa;
|
37
|
+
border: 1px solid #ddd;
|
38
|
+
border-bottom-color: transparent;
|
39
|
+
cursor: default;
|
40
|
+
|
41
|
+
#cs-tab:checked ~ .multilingual-content-section .cs-content,
|
42
|
+
#en-tab:checked ~ .multilingual-content-section .en-content,
|
43
|
+
#ru-tab:checked ~ .multilingual-content-section .ru-content
|
44
|
+
display: block;
|
@@ -0,0 +1 @@
|
|
1
|
+
@import 'blueberry_cms/*'
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module BlueberryCMS
|
2
|
+
module Admin
|
3
|
+
class MenusController < BlueberryCMS.page_admin_controller.constantize
|
4
|
+
helper BlueberryCMS::PagesHelper
|
5
|
+
before_action :find_menu, only: %i(edit update destroy)
|
6
|
+
|
7
|
+
def index
|
8
|
+
@menus = Menu.ordered
|
9
|
+
end
|
10
|
+
|
11
|
+
def new
|
12
|
+
@menu = Menu.new
|
13
|
+
end
|
14
|
+
|
15
|
+
def create
|
16
|
+
@menu = Menu.new(menu_params)
|
17
|
+
if @menu.save
|
18
|
+
redirect_to(params[:continue] ? [:edit, :admin, @menu] : [:admin, :menus])
|
19
|
+
else
|
20
|
+
render :new
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def edit; end
|
25
|
+
|
26
|
+
def update
|
27
|
+
if @menu.update(menu_params)
|
28
|
+
redirect_to(params[:continue] ? [:edit, :admin, @menu] : [:admin, :menus])
|
29
|
+
else
|
30
|
+
render :edit
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def destroy
|
35
|
+
@menu.destroy
|
36
|
+
redirect_to [:admin, :menus]
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def menu_params
|
42
|
+
params.require(:menu).permit!
|
43
|
+
end
|
44
|
+
|
45
|
+
def find_menu
|
46
|
+
@menu = Menu.find(params[:id])
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -1,8 +1,13 @@
|
|
1
1
|
module BlueberryCMS
|
2
2
|
module Admin
|
3
3
|
class PagesController < BlueberryCMS.page_admin_controller.constantize
|
4
|
+
include Wisper::Publisher
|
5
|
+
helper BlueberryCMS::PagesHelper
|
6
|
+
|
7
|
+
after_action :refresh_sitemap, only: %i(update create destroy)
|
8
|
+
|
4
9
|
def index
|
5
|
-
@pages = Page.
|
10
|
+
@pages = Page.roots
|
6
11
|
end
|
7
12
|
|
8
13
|
def new
|
@@ -13,7 +18,7 @@ module BlueberryCMS
|
|
13
18
|
def create
|
14
19
|
@page = Page.new(page_params)
|
15
20
|
if @page.save
|
16
|
-
redirect_to [:admin, :pages]
|
21
|
+
redirect_to(params[:continue] ? [:edit, :admin, @page] : [:admin, :pages])
|
17
22
|
else
|
18
23
|
render :new
|
19
24
|
end
|
@@ -25,11 +30,18 @@ module BlueberryCMS
|
|
25
30
|
|
26
31
|
def update
|
27
32
|
@page = Page.find(params[:id])
|
28
|
-
p page_params.to_hash
|
29
33
|
if @page.update_attributes(page_params)
|
30
|
-
|
34
|
+
respond_to do |format|
|
35
|
+
format.html {
|
36
|
+
redirect_to(params[:continue] ? [:edit, :admin, @page] : [:admin, :pages])
|
37
|
+
}
|
38
|
+
format.js { head :ok }
|
39
|
+
end
|
31
40
|
else
|
32
|
-
|
41
|
+
respond_to do |format|
|
42
|
+
format.html { render :edit }
|
43
|
+
format.js { head :unprocessable_entity }
|
44
|
+
end
|
33
45
|
end
|
34
46
|
end
|
35
47
|
|
@@ -45,17 +57,11 @@ module BlueberryCMS
|
|
45
57
|
private
|
46
58
|
|
47
59
|
def page_params
|
48
|
-
params.
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
blocks_attributes: [
|
54
|
-
:_destroy, :id, :_type, :urls,
|
55
|
-
page_ids: [],
|
56
|
-
content_translations: [:cs, :en],
|
57
|
-
]
|
58
|
-
)
|
60
|
+
params.require(:page).permit!
|
61
|
+
end
|
62
|
+
|
63
|
+
def refresh_sitemap
|
64
|
+
broadcast(:refresh_sitemap)
|
59
65
|
end
|
60
66
|
end
|
61
67
|
end
|
@@ -1,7 +1,8 @@
|
|
1
1
|
module BlueberryCMS
|
2
2
|
class RootController < ApplicationController
|
3
3
|
def index
|
4
|
-
|
4
|
+
page = BlueberryCMS::Page.find_by!(path: "/#{params[:path]}")
|
5
|
+
redirect_to I18n.with_locale(I18n.default_locale) { page.to_path }
|
5
6
|
end
|
6
7
|
end
|
7
8
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class BlockDecorator < Draper::Decorator
|
2
|
+
delegate_all
|
3
|
+
|
4
|
+
def css_class
|
5
|
+
array = [object.css_class]
|
6
|
+
array << 'block--centered-reverse' if right?
|
7
|
+
array.join(' ')
|
8
|
+
end
|
9
|
+
|
10
|
+
def process_markdown(string)
|
11
|
+
h.sanitize Markdown.new(string).to_html, tags: %w(strong em)
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module BlueberryCMS
|
2
|
+
class LinkDecorator < BaseDecorator
|
3
|
+
def link_background
|
4
|
+
"background-image: url(#{image.url(:content)})" if image?
|
5
|
+
end
|
6
|
+
|
7
|
+
def link_url
|
8
|
+
page ? page.to_path : url
|
9
|
+
end
|
10
|
+
|
11
|
+
def link_title
|
12
|
+
page ? page.name : title
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module BlueberryCMS
|
2
|
+
class PageBlockDecorator < BaseDecorator
|
3
|
+
def block_object
|
4
|
+
is_a?(BlueberryCMS::PageBlocks::Shared) ? block.decorate : self
|
5
|
+
end
|
6
|
+
|
7
|
+
def computed_classes
|
8
|
+
array = [css_class]
|
9
|
+
array << "block--mt-#{top_margin}" if top_margin?
|
10
|
+
array << "block--mt-#{top_margin_xs}-mobile" if top_margin_xs?
|
11
|
+
|
12
|
+
array << "block--mb-#{bottom_margin}" if bottom_margin?
|
13
|
+
array << "block--mb-#{bottom_margin_xs}-mobile" if bottom_margin_xs?
|
14
|
+
array << "block--gallery-text-#{orientation}" if respond_to?(:orientation)
|
15
|
+
array << 'block--bg-fractals white' if try(:red_background)
|
16
|
+
|
17
|
+
if object.is_a?(BlueberryCMS::PageBlocks::VideoGallery)
|
18
|
+
array << 'block--bg-fractals white block--videogallery'
|
19
|
+
end
|
20
|
+
|
21
|
+
array.join(' ')
|
22
|
+
end
|
23
|
+
|
24
|
+
def label
|
25
|
+
text = if object.respond_to?(:name)
|
26
|
+
object.name
|
27
|
+
elsif object.respond_to?(:title)
|
28
|
+
object.title
|
29
|
+
elsif object.respond_to?(:content)
|
30
|
+
h.strip_tags(object.content)
|
31
|
+
elsif object.is_a?(BlueberryCMS::PageBlocks::Shared)
|
32
|
+
[object.block&.page&.name, object.block&.decorate&.label].compact.join(' | ')
|
33
|
+
end
|
34
|
+
|
35
|
+
[object.model_name.human, h.truncate(text, length: 90)].compact.join(' - ')
|
36
|
+
end
|
37
|
+
|
38
|
+
def name
|
39
|
+
process_markdown(object.name) if object.name.present?
|
40
|
+
end
|
41
|
+
|
42
|
+
def title
|
43
|
+
process_markdown(object.title) if object.title.present?
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module BlueberryCMS
|
2
|
+
module MenusHelper
|
3
|
+
def render_menu(slug)
|
4
|
+
menu = BlueberryCMS::Menu.find_by(slugs: slug)
|
5
|
+
safe_join(menu_links(menu.links)) if menu.links.any?
|
6
|
+
end
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def link(link)
|
11
|
+
name = link.name.presence || link.page.name
|
12
|
+
url = link.page&.to_path || link.url
|
13
|
+
|
14
|
+
active_link_to name, anchored_link(url, link.anchor.presence), class: link.css_class.presence, active: :exclusive, target: link.new_window ? '_blank' : '_self'
|
15
|
+
end
|
16
|
+
|
17
|
+
def menu_links(links)
|
18
|
+
links.map do |link|
|
19
|
+
content_tag(:li, link(link))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def anchored_link(link, anchor)
|
24
|
+
[link, anchor.presence].compact.join('#')
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module BlueberryCMS
|
2
|
+
module PagesHelper
|
3
|
+
def nested_set_options(klass, current_page = nil)
|
4
|
+
@cache ||= {}
|
5
|
+
@cache[klass] ||= klass.traverse(:depth_first)
|
6
|
+
@cache[klass].map do |page|
|
7
|
+
["#{'–' * page.depth} #{page.name}", page.id, disabled: page == current_page ]
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module BlueberryCMS
|
2
|
+
class Image
|
3
|
+
include Mongoid::Document
|
4
|
+
|
5
|
+
field :href, type: String
|
6
|
+
field :name, localize: true
|
7
|
+
|
8
|
+
mount_uploader :image, ImageUploader
|
9
|
+
|
10
|
+
def self.find(id)
|
11
|
+
_id = BSON::ObjectId.from_string(id)
|
12
|
+
page = BlueberryCMS::Page.find_by('blocks.images._id' => _id)
|
13
|
+
gallery = page.blocks.find_by('images._id' => _id)
|
14
|
+
gallery.images.find_by('_id' => _id)
|
15
|
+
end
|
16
|
+
|
17
|
+
embedded_in :attachable, polymorphic: true
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module BlueberryCMS
|
2
|
+
class Link
|
3
|
+
include Mongoid::Document
|
4
|
+
|
5
|
+
field :css_class, type: String
|
6
|
+
field :title, type: String
|
7
|
+
field :description, type: String
|
8
|
+
field :url, type: String
|
9
|
+
field :page_id, type: BSON::ObjectId
|
10
|
+
field :image_tmp, type: String
|
11
|
+
field :percentage, type: String
|
12
|
+
|
13
|
+
embedded_in :links, class_name: 'BlueberryCMS::PageBlocks::Links'
|
14
|
+
|
15
|
+
mount_uploader :image, ImageUploader
|
16
|
+
|
17
|
+
def self.find(id)
|
18
|
+
_id = BSON::ObjectId.from_string(id)
|
19
|
+
page = BlueberryCMS::Page.find_by('blocks.links._id' => _id)
|
20
|
+
links = page.blocks.find_by('links._id' => _id)
|
21
|
+
links.links.find_by('_id' => _id)
|
22
|
+
end
|
23
|
+
|
24
|
+
def page
|
25
|
+
Page.find(page_id) if page_id
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module BlueberryCMS
|
2
|
+
class Menu
|
3
|
+
include Mongoid::Document
|
4
|
+
include Mongoid::Slug
|
5
|
+
|
6
|
+
field :name, type: String
|
7
|
+
validates :name, presence: true
|
8
|
+
|
9
|
+
slug :name
|
10
|
+
|
11
|
+
embeds_many :links, class_name: 'BlueberryCMS::MenuLink',
|
12
|
+
cascade_callbacks: true,
|
13
|
+
order: :position.asc
|
14
|
+
|
15
|
+
accepts_nested_attributes_for :links, allow_destroy: true
|
16
|
+
|
17
|
+
scope :ordered, -> { order(name: :asc) }
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module BlueberryCMS
|
2
|
+
class MenuLink
|
3
|
+
include Mongoid::Document
|
4
|
+
|
5
|
+
field :anchor, localize: true
|
6
|
+
field :css_class
|
7
|
+
field :name, localize: true
|
8
|
+
field :page_id, type: BSON::ObjectId
|
9
|
+
field :position, type: Integer
|
10
|
+
field :new_window, type: Boolean
|
11
|
+
field :url, type: String, localize: true
|
12
|
+
|
13
|
+
embedded_in :menu, class_name: 'BlueberryCMS::Menu'
|
14
|
+
|
15
|
+
before_save :assign_default_position, if: :assign_default_position?
|
16
|
+
|
17
|
+
def page
|
18
|
+
Page.find(page_id) if page_id
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def assign_default_position
|
24
|
+
links = menu.links
|
25
|
+
self.position = if links.where(:position.ne => nil).any?
|
26
|
+
links.where(:position.ne => nil).last.position + 1
|
27
|
+
else
|
28
|
+
0
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def assign_default_position?
|
33
|
+
position.nil?
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -2,42 +2,93 @@ module BlueberryCMS
|
|
2
2
|
class Page
|
3
3
|
include Mongoid::Document
|
4
4
|
include Mongoid::Tree
|
5
|
+
include Mongoid::Tree::Traversal
|
5
6
|
include Mongoid::Tree::Ordering
|
7
|
+
include Mongoid::Slug
|
8
|
+
include BlueberryCMS::Sortable
|
6
9
|
|
7
|
-
field :
|
8
|
-
field :
|
9
|
-
field :meta_title, localize: true
|
10
|
+
field :active, localize: true, type: Boolean
|
11
|
+
field :custom_slug, localize: true
|
10
12
|
field :meta_description, localize: true
|
11
|
-
field :
|
12
|
-
field :
|
13
|
+
field :meta_keywords, localize: true, type: Array
|
14
|
+
field :meta_title, localize: true
|
15
|
+
field :name, localize: true
|
13
16
|
field :path, localize: true
|
17
|
+
field :published_at, type: DateTime
|
18
|
+
field :show_in_footer, type: Boolean
|
19
|
+
field :show_in_menu, type: Boolean
|
20
|
+
field :slug, localize: true
|
21
|
+
|
22
|
+
embeds_many :blocks, class_name: 'BlueberryCMS::PageBlock',
|
23
|
+
cascade_callbacks: true,
|
24
|
+
order: :position.asc
|
25
|
+
|
26
|
+
slug :slug_source, localize: true
|
14
27
|
|
15
|
-
embeds_many :blocks, class_name: 'BlueberryCMS::PageBlock'
|
16
28
|
accepts_nested_attributes_for :blocks, allow_destroy: true
|
17
29
|
|
18
30
|
validates :path, uniqueness: true
|
31
|
+
validates :name, presence: true
|
32
|
+
|
33
|
+
after_save :rebuild_children_paths
|
19
34
|
|
35
|
+
before_destroy :ensure_root, :move_children_to_parent
|
20
36
|
after_rearrange :rebuild_path
|
21
37
|
|
22
|
-
|
38
|
+
scope :active, -> { where(active: true) }
|
39
|
+
scope :in_menu, -> { where(show_in_menu: true) }
|
40
|
+
scope :in_footer, -> { where(show_in_footer: true) }
|
41
|
+
scope :ordered, lambda {
|
42
|
+
order(name: :asc).collation(locale: 'cs', strength: 1)
|
43
|
+
}
|
23
44
|
|
24
|
-
def
|
25
|
-
|
45
|
+
def slug_source
|
46
|
+
custom_slug.presence || name
|
47
|
+
end
|
48
|
+
|
49
|
+
def rebuild_children_paths
|
50
|
+
if %i[custom_slug name].any? { |f| attribute_changed? f.to_s }
|
51
|
+
children.each(&:save)
|
52
|
+
end
|
26
53
|
end
|
27
54
|
|
28
55
|
def to_path
|
29
56
|
"/#{I18n.locale}#{path}"
|
30
57
|
end
|
31
58
|
|
59
|
+
def name_translations=(attributes)
|
60
|
+
attributes.stringify_keys!
|
61
|
+
primary_locale_name = attributes[I18n.default_locale.to_s]
|
62
|
+
empty_locale_keys = attributes.select { |_, v| v.blank? || v.empty? }.keys
|
63
|
+
|
64
|
+
empty_locale_keys.each do |locale|
|
65
|
+
attributes[locale] = primary_locale_name
|
66
|
+
end
|
67
|
+
|
68
|
+
super
|
69
|
+
end
|
70
|
+
|
32
71
|
private
|
33
72
|
|
73
|
+
def ensure_root
|
74
|
+
if root?
|
75
|
+
errors.add(:base, :invalid)
|
76
|
+
throw :abort
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
34
80
|
def rebuild_path
|
35
81
|
self.path_translations = I18n.available_locales.each_with_object({}) do |locale, translations|
|
36
82
|
I18n.with_locale(locale) do
|
37
|
-
|
38
|
-
translations[locale] = '/' + pages.join('/')
|
83
|
+
translations[locale] = generate_path
|
39
84
|
end
|
40
85
|
end
|
41
86
|
end
|
87
|
+
|
88
|
+
def generate_path
|
89
|
+
return '/' if root?
|
90
|
+
|
91
|
+
[parent.path, slug_builder.to_url].join('/').gsub('//', '/')
|
92
|
+
end
|
42
93
|
end
|
43
94
|
end
|