gaco_cms 0.1.0
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/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
|