gaco_cms 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +48 -0
- data/Rakefile +10 -0
- data/app/assets/builds/gaco_cms.css +18257 -0
- data/app/assets/builds/gaco_cms.js +43235 -0
- data/app/assets/builds/gaco_cms.js.map +7 -0
- data/app/assets/builds/gaco_cms_front.css +18237 -0
- data/app/assets/builds/gaco_cms_front.js +10722 -0
- data/app/assets/builds/gaco_cms_front.js.map +7 -0
- data/app/assets/javascripts/gaco_cms/base.js +24 -0
- data/app/assets/javascripts/gaco_cms/controllers/confirm_controller.ts +20 -0
- data/app/assets/javascripts/gaco_cms/controllers/deletable_row_controller.ts +46 -0
- data/app/assets/javascripts/gaco_cms/controllers/editor_controller.ts +58 -0
- data/app/assets/javascripts/gaco_cms/controllers/file_input_controller.ts +82 -0
- data/app/assets/javascripts/gaco_cms/controllers/modal_controller.ts +73 -0
- data/app/assets/javascripts/gaco_cms/controllers/remote_content_controller.ts +27 -0
- data/app/assets/javascripts/gaco_cms/controllers/repeatable_field_controller.ts +26 -0
- data/app/assets/javascripts/gaco_cms/controllers/sortable_controller.ts +27 -0
- data/app/assets/javascripts/gaco_cms/controllers/toggle_field_controller.ts +37 -0
- data/app/assets/javascripts/gaco_cms/controllers/translatable_controller.ts +86 -0
- data/app/assets/javascripts/gaco_cms/lib/progress_bar.ts +7 -0
- data/app/assets/javascripts/gaco_cms/lib/request.ts +21 -0
- data/app/assets/javascripts/gaco_cms/lib/turbo_request.ts +61 -0
- data/app/assets/javascripts/gaco_cms/stimulus.ts +9 -0
- data/app/assets/javascripts/gaco_cms.js +7 -0
- data/app/assets/javascripts/gaco_cms_front.js +3 -0
- data/app/assets/stylesheets/gaco_cms/bootstrap_custom.scss +15 -0
- data/app/assets/stylesheets/gaco_cms/shared.scss +22 -0
- data/app/assets/stylesheets/gaco_cms.css.scss +8 -0
- data/app/assets/stylesheets/gaco_cms_front.css.scss +6 -0
- data/app/controllers/concerns/gaco_cms/turbo_concern.rb +52 -0
- data/app/controllers/gaco_cms/admin/base_controller.rb +20 -0
- data/app/controllers/gaco_cms/admin/field_groups_controller.rb +87 -0
- data/app/controllers/gaco_cms/admin/field_groups_manager_controller.rb +66 -0
- data/app/controllers/gaco_cms/admin/field_groups_renderer_controller.rb +33 -0
- data/app/controllers/gaco_cms/admin/fields_controller.rb +20 -0
- data/app/controllers/gaco_cms/admin/page_types_controller.rb +56 -0
- data/app/controllers/gaco_cms/admin/pages_controller.rb +70 -0
- data/app/controllers/gaco_cms/admin/themes_controller.rb +55 -0
- data/app/controllers/gaco_cms/admin_controller.rb +47 -0
- data/app/controllers/gaco_cms/front_controller.rb +39 -0
- data/app/helpers/gaco_cms/application_helper.rb +26 -0
- data/app/jobs/gaco_cms/application_job.rb +6 -0
- data/app/mailers/gaco_cms/application_mailer.rb +8 -0
- data/app/models/concerns/gaco_cms/fields_assignable.rb +40 -0
- data/app/models/concerns/gaco_cms/union_scope.rb +14 -0
- data/app/models/gaco_cms/application_record.rb +25 -0
- data/app/models/gaco_cms/draft_record.rb +16 -0
- data/app/models/gaco_cms/field.rb +78 -0
- data/app/models/gaco_cms/field_group.rb +55 -0
- data/app/models/gaco_cms/field_value.rb +77 -0
- data/app/models/gaco_cms/media_file.rb +22 -0
- data/app/models/gaco_cms/page.rb +57 -0
- data/app/models/gaco_cms/page_type.rb +38 -0
- data/app/models/gaco_cms/theme.rb +28 -0
- data/app/services/gaco_cms/application_service.rb +33 -0
- data/app/services/gaco_cms/shortcode_parser.rb +217 -0
- data/app/services/gaco_cms/theme_content_generator.rb +55 -0
- data/app/views/gaco_cms/admin/base/index.html.haml +4 -0
- data/app/views/gaco_cms/admin/field_groups_manager/_field.html.haml +53 -0
- data/app/views/gaco_cms/admin/field_groups_manager/_group.html.haml +54 -0
- data/app/views/gaco_cms/admin/field_groups_manager/index.html.haml +14 -0
- data/app/views/gaco_cms/admin/field_groups_renderer/_field.html.haml +31 -0
- data/app/views/gaco_cms/admin/field_groups_renderer/_fields_frame.html.haml +16 -0
- data/app/views/gaco_cms/admin/field_groups_renderer/_group.html.haml +24 -0
- data/app/views/gaco_cms/admin/field_groups_renderer/default_value/_page.html.haml +3 -0
- data/app/views/gaco_cms/admin/field_groups_renderer/fields/_editor.html.haml +3 -0
- data/app/views/gaco_cms/admin/field_groups_renderer/fields/_file.html.haml +4 -0
- data/app/views/gaco_cms/admin/field_groups_renderer/fields/_page.html.haml +3 -0
- data/app/views/gaco_cms/admin/field_groups_renderer/fields/_text_area.html.haml +3 -0
- data/app/views/gaco_cms/admin/field_groups_renderer/fields/_text_field.html.haml +3 -0
- data/app/views/gaco_cms/admin/field_groups_renderer/index.html.haml +20 -0
- data/app/views/gaco_cms/admin/page_types/form.html.haml +27 -0
- data/app/views/gaco_cms/admin/page_types/index.html.haml +27 -0
- data/app/views/gaco_cms/admin/pages/edit.html.haml +57 -0
- data/app/views/gaco_cms/admin/pages/index.html.haml +23 -0
- data/app/views/gaco_cms/admin/pages/new.html.haml +16 -0
- data/app/views/gaco_cms/admin/themes/edit.html.haml +36 -0
- data/app/views/gaco_cms/admin/themes/index.html.haml +24 -0
- data/app/views/gaco_cms/admin/themes/new.html.haml +21 -0
- data/app/views/layouts/gaco_cms/_breadcrumb.html.haml +7 -0
- data/app/views/layouts/gaco_cms/_flash_messages.html.haml +13 -0
- data/app/views/layouts/gaco_cms/admin.haml +55 -0
- data/config/routes.rb +26 -0
- data/db/migrate/20230202133738_create_cms_pages.rb +16 -0
- data/db/migrate/20230202134840_create_cms_field_groups.rb +17 -0
- data/db/migrate/20230202135314_create_cms_fields.rb +21 -0
- data/db/migrate/20230202135739_create_cms_field_values.rb +16 -0
- data/db/migrate/20230202181744_create_cms_media_files.rb +10 -0
- data/db/migrate/20230206231547_create_cms_page_types.rb +23 -0
- data/db/migrate/20230209090008_create_cms_themes.rb +19 -0
- data/lib/gaco_cms/config.rb +19 -0
- data/lib/gaco_cms/engine.rb +31 -0
- data/lib/gaco_cms/version.rb +5 -0
- data/lib/gaco_cms.rb +18 -0
- data/lib/generators/gaco_cms/install_generator.rb +16 -0
- data/lib/generators/gaco_cms/install_template/gaco_cms.rb +11 -0
- data/lib/generators/gaco_cms/install_template/themes/default/index.html.haml +2 -0
- data/lib/generators/gaco_cms/install_template/themes/default/layouts/application.html.haml +34 -0
- data/lib/generators/gaco_cms/install_template/themes/default/page.html.haml +2 -0
- data/lib/tasks/auto_annotate_models.rake +59 -0
- data/lib/tasks/gaco_cms_tasks.rake +5 -0
- metadata +174 -0
@@ -0,0 +1,8 @@
|
|
1
|
+
@import './gaco_cms/bootstrap_custom';
|
2
|
+
@import 'bootstrap/scss/bootstrap';
|
3
|
+
|
4
|
+
$fa-font-path: 'assets/gaco_cms/fontawesome/webfonts';
|
5
|
+
@import '@fortawesome/fontawesome-free/scss/fontawesome';
|
6
|
+
@import "@fortawesome/fontawesome-free/scss/solid.scss";
|
7
|
+
|
8
|
+
@import './gaco_cms/shared';
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module GacoCms
|
2
|
+
module TurboConcern
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
included do
|
5
|
+
around_action :parse_turbo_frame, if: -> { turbo_frame_id && request.get? }
|
6
|
+
end
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def turbo_frame_id
|
11
|
+
request.headers['Turbo-Frame']
|
12
|
+
end
|
13
|
+
|
14
|
+
# fix: automatically render content turbo frame caller tag
|
15
|
+
def parse_turbo_frame
|
16
|
+
begin
|
17
|
+
yield
|
18
|
+
render_turbo_content(turbo_frame_id) { response.body }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def render_turbo_content(target, &block)
|
23
|
+
response.content_type = 'text/vnd.turbo-stream.html'
|
24
|
+
content = "#{block.call}#{turbo_flash_messages}"
|
25
|
+
response.body = turbo_stream_with(:update, content, target: target)
|
26
|
+
end
|
27
|
+
|
28
|
+
# @param e (Exception)
|
29
|
+
def print_turbo_error(e)
|
30
|
+
Rails.logger.error e.message
|
31
|
+
Rails.logger.error e.backtrace.join("\n")
|
32
|
+
dev_msg = Rails.env.production? ? '' : " ==> #{e.message}"
|
33
|
+
flash[:error] = "#{t('common.internal_error')}. #{dev_msg}"
|
34
|
+
end
|
35
|
+
|
36
|
+
# @return [String]
|
37
|
+
def turbo_flash_messages
|
38
|
+
flash_messages = render_to_string(partial: '/layouts/gaco_cms/flash_messages')
|
39
|
+
return '' unless flash_messages.present?
|
40
|
+
|
41
|
+
content = turbo_stream_with(:update, flash_messages, target: :toasts)
|
42
|
+
flash.clear # clear streamed flash messages
|
43
|
+
content
|
44
|
+
end
|
45
|
+
|
46
|
+
def turbo_stream_with(action, content, target: nil, targets: nil)
|
47
|
+
"<turbo-stream action='#{action}' #{"target='#{target}'" if target} #{"targets='#{targets}'" if targets}>
|
48
|
+
<template>#{content}</template>
|
49
|
+
</turbo-stream>"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GacoCms
|
4
|
+
module Admin
|
5
|
+
class BaseController < GacoCms::AdminController
|
6
|
+
skip_before_action :verify_authenticity_token, only: :upload_file
|
7
|
+
|
8
|
+
def upload_file
|
9
|
+
file = GacoCms::MediaFile.new(file: params[:file])
|
10
|
+
if file.save
|
11
|
+
render json: { location: file.url }
|
12
|
+
else
|
13
|
+
render json: { error: file.errors.full_message.join(', ') }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def index; end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GacoCms
|
4
|
+
module Admin
|
5
|
+
class FieldGroupsController < BaseController
|
6
|
+
before_action :set_group, except: %i[index new create new_field]
|
7
|
+
before_action { add_breadcrumb(FieldGroup.human_name(count: 2), url_for(action: :index)) }
|
8
|
+
|
9
|
+
def index
|
10
|
+
@groups = FieldGroup.ordered.all
|
11
|
+
end
|
12
|
+
|
13
|
+
def new
|
14
|
+
@group = FieldGroup.new
|
15
|
+
render :form
|
16
|
+
end
|
17
|
+
|
18
|
+
def create
|
19
|
+
group = FieldGroup.new(group_params)
|
20
|
+
if group.save
|
21
|
+
redirect_to url_for(action: :index), notice: 'Group saved'
|
22
|
+
else
|
23
|
+
render inline: group.errors.full_messages.join(', ')
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def edit
|
28
|
+
render :form
|
29
|
+
end
|
30
|
+
|
31
|
+
def update
|
32
|
+
if @group.update(group_params)
|
33
|
+
redirect_to url_for(action: :index), notice: 'Group updated'
|
34
|
+
else
|
35
|
+
render inline: @group.errors.full_messages.join(', ')
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def destroy
|
40
|
+
@group.destroy!
|
41
|
+
redirect_to url_for(action: :index), notice: 'Group destroyed'
|
42
|
+
end
|
43
|
+
|
44
|
+
def tpl
|
45
|
+
locals = { group: @group, field_values: FieldValue.none, group_no: Time.current.to_i }
|
46
|
+
render partial: '/gaco_cms/admin/fields/render/group', locals: locals
|
47
|
+
end
|
48
|
+
|
49
|
+
def new_field
|
50
|
+
field = Field.new(kind: params[:kind])
|
51
|
+
render partial: 'field', locals: { field: field }
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def group_params
|
57
|
+
fix_record_param
|
58
|
+
fix_fields_params
|
59
|
+
params.require(:gaco_cms_field_group)
|
60
|
+
.permit(:key, :record_id, :record_type, :repeat, :position,
|
61
|
+
title: permitted_locales, description: permitted_locales,
|
62
|
+
fields_attributes: [:id, :kind, :key, :repeat, :required,
|
63
|
+
:translatable, :position, :_destroy,
|
64
|
+
{ title: permitted_locales, def_value: permitted_locales,
|
65
|
+
description: permitted_locales }])
|
66
|
+
end
|
67
|
+
|
68
|
+
def set_group
|
69
|
+
@group = FieldGroup.find(params[:id])
|
70
|
+
end
|
71
|
+
|
72
|
+
def fix_record_param
|
73
|
+
record = params[:gaco_cms_field_group].delete(:record).to_s
|
74
|
+
params[:gaco_cms_field_group][:record_type], params[:gaco_cms_field_group][:record_id] = record.split('/')
|
75
|
+
end
|
76
|
+
|
77
|
+
def fix_fields_params
|
78
|
+
items = (params[:fields_attributes] || {}).values
|
79
|
+
items.each do |item|
|
80
|
+
def_val = item[:def_value]
|
81
|
+
item[:def_value] = { en: def_val } if def_val && !def_val.is_a?(Hash)
|
82
|
+
end
|
83
|
+
params[:gaco_cms_field_group][:fields_attributes] = items
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GacoCms
|
4
|
+
module Admin
|
5
|
+
class FieldGroupsManagerController < BaseController
|
6
|
+
before_action :set_record, only: %i[index update]
|
7
|
+
|
8
|
+
# @option record_type [String]
|
9
|
+
# @option record_id [Integer]
|
10
|
+
# @option reload_frame [String]
|
11
|
+
def index
|
12
|
+
@groups = @record.field_groups
|
13
|
+
end
|
14
|
+
|
15
|
+
def group_tpl
|
16
|
+
@group = FieldGroup.new
|
17
|
+
render partial: 'group', locals: { group: @group }
|
18
|
+
end
|
19
|
+
|
20
|
+
# @option kind [String]
|
21
|
+
def field_tpl
|
22
|
+
field = Field.new(kind: params[:kind])
|
23
|
+
render partial: 'field', locals: { field: field, parent_name: params[:parent_name] }
|
24
|
+
end
|
25
|
+
|
26
|
+
def update
|
27
|
+
if @record.update(groups_params)
|
28
|
+
render inline: ''
|
29
|
+
else
|
30
|
+
render inline: @record.errors.full_messages.join(', ')
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
# TODO: whitelist record_types
|
37
|
+
def set_record
|
38
|
+
@record = params[:record_type].constantize.find(params[:record_id])
|
39
|
+
end
|
40
|
+
|
41
|
+
def groups_params
|
42
|
+
fix_groups_fields
|
43
|
+
fix_fields_params
|
44
|
+
fields_attrs = [:id, :kind, :key, :repeat, :required, :translatable, :position, :_destroy,
|
45
|
+
:title, :description, { def_value: permitted_locales }]
|
46
|
+
params.require(:groups_manager)
|
47
|
+
.permit(field_groups_attributes: [:id, :key, :record_id, :record_type, :repeat, :position, :_destroy, :template,
|
48
|
+
:title, :description, fields_attributes: fields_attrs])
|
49
|
+
end
|
50
|
+
|
51
|
+
def fix_groups_fields
|
52
|
+
params[:groups_manager][:field_groups_attributes] = params[:groups_manager][:field_groups_attributes].values
|
53
|
+
end
|
54
|
+
|
55
|
+
def fix_fields_params
|
56
|
+
params[:groups_manager][:field_groups_attributes].each do |group_attrs|
|
57
|
+
group_attrs[:fields_attributes] = (group_attrs[:fields_attributes] || {}).values
|
58
|
+
group_attrs[:fields_attributes].each do |field_attr|
|
59
|
+
def_val = field_attr[:def_value]
|
60
|
+
field_attr[:def_value] = { en: def_val } if def_val && !def_val.is_a?(Hash)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GacoCms
|
4
|
+
module Admin
|
5
|
+
class FieldGroupsRendererController < BaseController
|
6
|
+
before_action :set_record, only: %i[index update]
|
7
|
+
|
8
|
+
def index
|
9
|
+
@groups = @record.field_groups
|
10
|
+
@groups = @record.page_type.field_groups if params[:parent] && @record.is_a?(Page)
|
11
|
+
end
|
12
|
+
|
13
|
+
def render_group
|
14
|
+
group = FieldGroup.find(params[:group_id])
|
15
|
+
locals = { group: group, field_values: FieldValue.none, group_no: Time.current.to_i }
|
16
|
+
render partial: 'group', locals: locals
|
17
|
+
end
|
18
|
+
|
19
|
+
def render_field
|
20
|
+
field = Field.find(params[:field_id])
|
21
|
+
value = field.field_values.new(group_no: params[:group_no])
|
22
|
+
render partial: 'field', locals: { value: value }
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
# TODO: whitelist record_types
|
28
|
+
def set_record
|
29
|
+
@record = params[:record_type].constantize.find(params[:record_id])
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GacoCms
|
4
|
+
module Admin
|
5
|
+
class FieldsController < BaseController
|
6
|
+
before_action :set_field
|
7
|
+
|
8
|
+
def tpl
|
9
|
+
value = @field.field_values.new(group_no: params[:group_no])
|
10
|
+
render partial: '/gaco_cms/admin/fields/render/field', locals: { value: value }
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def set_field
|
16
|
+
@field = Field.find(params[:id])
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GacoCms
|
4
|
+
module Admin
|
5
|
+
class PageTypesController < BaseController
|
6
|
+
before_action :set_page_type, only: %i[edit update destroy]
|
7
|
+
before_action { add_breadcrumb(PageType.human_name(count: 2), url_for(action: :index)) }
|
8
|
+
|
9
|
+
def index
|
10
|
+
@page_types = PageType.all.title_ordered
|
11
|
+
end
|
12
|
+
|
13
|
+
def new
|
14
|
+
@page_type = PageType.new
|
15
|
+
render :form
|
16
|
+
end
|
17
|
+
|
18
|
+
def create
|
19
|
+
page_type = PageType.new(page_type_params)
|
20
|
+
if page_type.save
|
21
|
+
redirect_to url_for(action: :index), notice: 'PageType saved'
|
22
|
+
else
|
23
|
+
render inline: page_type.errors.full_message.join(', ')
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def edit
|
28
|
+
render :form
|
29
|
+
end
|
30
|
+
|
31
|
+
def update
|
32
|
+
if @page_type.update(page_type_params)
|
33
|
+
redirect_to url_for(action: :index), notice: 'PageType saved'
|
34
|
+
else
|
35
|
+
render inline: @page_type.errors.full_message.join(', ')
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def destroy
|
40
|
+
@page_type.destroy!
|
41
|
+
redirect_to url_for(action: :index), notice: 'PageType destroyed'
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def page_type_params
|
47
|
+
params.require(:gaco_cms_page_type)
|
48
|
+
.permit(:key, :template, title: permitted_locales)
|
49
|
+
end
|
50
|
+
|
51
|
+
def set_page_type
|
52
|
+
@page_type = PageType.find(params[:id])
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GacoCms
|
4
|
+
module Admin
|
5
|
+
class PagesController < BaseController
|
6
|
+
before_action :set_page_type
|
7
|
+
before_action :set_page, only: %i[edit update destroy]
|
8
|
+
before_action :set_breadcrumb
|
9
|
+
|
10
|
+
def index
|
11
|
+
@pages = @page_type.pages.title_ordered
|
12
|
+
end
|
13
|
+
|
14
|
+
def new
|
15
|
+
@page = @page_type.pages.new
|
16
|
+
end
|
17
|
+
|
18
|
+
def create
|
19
|
+
page = @page_type.pages.new(page_params)
|
20
|
+
if page.save
|
21
|
+
redirect_to url_for(action: :edit, id: page), notice: 'Page created'
|
22
|
+
else
|
23
|
+
render inline: page.errors.full_messages.join(', ')
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def edit; end
|
28
|
+
|
29
|
+
def update
|
30
|
+
if @page.update(page_params)
|
31
|
+
render inline: ''
|
32
|
+
else
|
33
|
+
render inline: @page.errors.full_messages.join(', ')
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def destroy
|
38
|
+
@page.destroy!
|
39
|
+
redirect_to url_for(action: :index), notice: 'Page destroyed'
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def page_params
|
45
|
+
fix_fields_values_param(:gaco_cms_page)
|
46
|
+
params.require(:gaco_cms_page)
|
47
|
+
.permit(:key, :template, :photo_url,
|
48
|
+
content: permitted_locales, summary: permitted_locales, title: permitted_locales,
|
49
|
+
field_values_attributes: permitted_field_values_params)
|
50
|
+
end
|
51
|
+
|
52
|
+
def set_page
|
53
|
+
@page = @page_type.pages.find(params[:id])
|
54
|
+
end
|
55
|
+
|
56
|
+
def set_page_type
|
57
|
+
@page_type = PageType.find(params[:page_type_id])
|
58
|
+
end
|
59
|
+
|
60
|
+
def set_breadcrumb
|
61
|
+
type_id = @page_type ? @page_type.id : @page.page_type_id
|
62
|
+
name = @page_type ? @page_type.title : @page.page_type.title
|
63
|
+
add_breadcrumb(name, edit_gaco_cms_admin_page_type_path(type_id))
|
64
|
+
|
65
|
+
url = gaco_cms_admin_page_type_pages_path(page_type_id: @page_type ? @page_type.id : @page.page_type_id)
|
66
|
+
add_breadcrumb(Page.human_name(count: 2), url)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GacoCms
|
4
|
+
module Admin
|
5
|
+
class ThemesController < BaseController
|
6
|
+
before_action :set_theme, except: %i[index new create]
|
7
|
+
before_action { add_breadcrumb(Theme.human_name(count: 2), url_for(action: :index)) }
|
8
|
+
|
9
|
+
def index
|
10
|
+
@themes = Theme.ordered.all
|
11
|
+
end
|
12
|
+
|
13
|
+
def new
|
14
|
+
@theme = Theme.new
|
15
|
+
end
|
16
|
+
|
17
|
+
def create
|
18
|
+
theme = Theme.new(theme_params)
|
19
|
+
if theme.save
|
20
|
+
redirect_to url_for(action: :edit, id: theme), notice: 'Theme created'
|
21
|
+
else
|
22
|
+
render inline: theme.errors.full_messages.join(', ')
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def edit; end
|
27
|
+
|
28
|
+
def update
|
29
|
+
if @theme.update(theme_params)
|
30
|
+
render inline: ''
|
31
|
+
else
|
32
|
+
render inline: @theme.errors.full_messages.join(', ')
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def destroy
|
37
|
+
@theme.destroy!
|
38
|
+
redirect_to url_for(action: :index), notice: 'Theme destroyed'
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def theme_params
|
44
|
+
fix_fields_values_param(:gaco_cms_theme)
|
45
|
+
params.require(:gaco_cms_theme)
|
46
|
+
.permit(:key, :title, :active,
|
47
|
+
field_values_attributes: permitted_field_values_params)
|
48
|
+
end
|
49
|
+
|
50
|
+
def set_theme
|
51
|
+
@theme = Theme.find(params[:id])
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GacoCms
|
4
|
+
class AdminController < GacoCms::Config.parent_backend_controller.constantize
|
5
|
+
include GacoCms::TurboConcern
|
6
|
+
before_action :gaco_check_authentication
|
7
|
+
before_action { add_breadcrumb(:home, gaco_cms_admin_path) }
|
8
|
+
layout :gaco_set_layout
|
9
|
+
helper_method :ajax_request?
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
layout :gaco_set_layout
|
14
|
+
def gaco_set_layout
|
15
|
+
ajax_request? ? false : 'gaco_cms/admin'
|
16
|
+
end
|
17
|
+
|
18
|
+
def ajax_request?
|
19
|
+
request.headers[:xhr].present? || request.headers['Turbo-Frame']
|
20
|
+
end
|
21
|
+
|
22
|
+
def add_breadcrumb(label, url = nil)
|
23
|
+
@breadcrumbs ||= []
|
24
|
+
@breadcrumbs << [label, url]
|
25
|
+
end
|
26
|
+
|
27
|
+
def permitted_locales
|
28
|
+
I18n.available_locales
|
29
|
+
end
|
30
|
+
|
31
|
+
def permitted_field_values_params
|
32
|
+
[:id, :field_id, :group_no, :position, :_destroy, { value: permitted_locales }]
|
33
|
+
end
|
34
|
+
|
35
|
+
def fix_fields_values_param(param_key)
|
36
|
+
values = params[:field_values_attributes]&.values || []
|
37
|
+
values.each do |v|
|
38
|
+
v[:value] = { I18n.locale => v[:value] } unless v[:value].is_a?(Hash)
|
39
|
+
end
|
40
|
+
params[param_key][:field_values_attributes] = values
|
41
|
+
end
|
42
|
+
|
43
|
+
def gaco_check_authentication
|
44
|
+
# TODO: check admin authentication
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GacoCms
|
4
|
+
class FrontController < GacoCms::Config.parent_front_controller.constantize
|
5
|
+
layout :gaco_set_layout
|
6
|
+
before_action :gaco_set_locale
|
7
|
+
helper_method :theme_path_for
|
8
|
+
helper_method :current_theme
|
9
|
+
|
10
|
+
def index
|
11
|
+
render theme_path_for(:index)
|
12
|
+
end
|
13
|
+
|
14
|
+
def page
|
15
|
+
key = params[:page_id]
|
16
|
+
@page = Page.by_key(key) || Page.find(key)
|
17
|
+
render theme_path_for(:page)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def gaco_set_layout
|
23
|
+
instance_eval(&Config.front_layout)
|
24
|
+
end
|
25
|
+
|
26
|
+
def gaco_set_locale
|
27
|
+
session[:gaco_locale] = params[:locale] if params[:locale].present?
|
28
|
+
I18n.locale = session[:gaco_locale] if session[:gaco_locale]
|
29
|
+
end
|
30
|
+
|
31
|
+
def theme_path_for(tpl = params[:action])
|
32
|
+
"themes/#{current_theme.key}/#{tpl}"
|
33
|
+
end
|
34
|
+
|
35
|
+
def current_theme
|
36
|
+
@current_theme ||= Theme.current
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GacoCms
|
4
|
+
module ApplicationHelper
|
5
|
+
def form_title(model)
|
6
|
+
model.id ? "Edit #{model.class.human_name}" : "New #{model.class.human_name}"
|
7
|
+
end
|
8
|
+
|
9
|
+
def page_url_for(id)
|
10
|
+
Rails.application.routes.url_helpers.gaco_cms_page_path(page_id: id)
|
11
|
+
end
|
12
|
+
module_function :page_url_for
|
13
|
+
|
14
|
+
def required_label(form, key, args = {}, &block)
|
15
|
+
append = args[:optional] ? capture { block&.call } : "<small>#{capture { block&.call }}(*)</small>"
|
16
|
+
form.label(key, args) { |l| "#{args[:label] || l} #{append}".html_safe } # rubocop:disable Rails/OutputSafety
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.translated_value_for(data)
|
20
|
+
data = { en: data } unless data.is_a?(Hash)
|
21
|
+
data[I18n.locale].presence ||
|
22
|
+
data[I18n.default_locale].presence ||
|
23
|
+
data.values.find(&:present?)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GacoCms
|
4
|
+
module FieldsAssignable
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
included do
|
7
|
+
has_many :field_groups, -> { ordered }, as: :record, inverse_of: :record, dependent: :destroy
|
8
|
+
has_many :fields, through: :field_groups
|
9
|
+
has_many :field_values, dependent: :destroy, as: :record, inverse_of: :record
|
10
|
+
accepts_nested_attributes_for :field_values, allow_destroy: true
|
11
|
+
accepts_nested_attributes_for :field_groups, allow_destroy: true
|
12
|
+
end
|
13
|
+
|
14
|
+
def the_value(key, cache: true)
|
15
|
+
callback = proc { field_values.ordered.find_by(field_key: key)&.the_value }
|
16
|
+
return callback.call unless cache
|
17
|
+
|
18
|
+
Rails.cache.fetch(cache_key_locale(:the_value, key), expires_at: Time.current.end_of_day, &callback)
|
19
|
+
end
|
20
|
+
|
21
|
+
def the_values(key, cache: true)
|
22
|
+
callback = proc { field_values.ordered.where(field_key: key).map(&:the_value) }
|
23
|
+
return callback.call unless cache
|
24
|
+
|
25
|
+
Rails.cache.fetch(cache_key_locale(:the_values, key), expires_at: Time.current.end_of_day, &callback)
|
26
|
+
end
|
27
|
+
|
28
|
+
def the_grouped_values(*keys, cache: true)
|
29
|
+
callback = proc do
|
30
|
+
field_values.where(field_key: keys).grouped.map do |fields|
|
31
|
+
fields.map { |f| [f.field_key, f.the_value] }.to_h
|
32
|
+
end
|
33
|
+
end
|
34
|
+
return callback.call unless cache
|
35
|
+
|
36
|
+
cache_key = cache_key_locale(:the_grouped_values, keys.join('-'))
|
37
|
+
Rails.cache.fetch(cache_key, expires_at: Time.current.end_of_day, &callback)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GacoCms
|
4
|
+
module UnionScope
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
included do
|
7
|
+
def self.union_scope(*scopes)
|
8
|
+
id_column = "#{table_name}.id"
|
9
|
+
sub_query = scopes.map { |s| s.reorder(nil).select(id_column).to_sql }.compact.join(' UNION ')
|
10
|
+
where("#{id_column} IN (#{sub_query})")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|