drg_cms 0.6.0.1 → 0.6.0.3
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 +4 -4
- data/app/assets/javascripts/drg_cms/drg_cms.js +54 -7
- data/app/assets/javascripts/drg_cms_application.js +1 -1
- data/app/assets/javascripts/drg_cms_cms.js +1 -1
- data/app/assets/stylesheets/drg_cms/drg_cms.css +32 -1
- data/app/controllers/cmsedit_controller.rb +49 -18
- data/app/controllers/dc_application_controller.rb +82 -21
- data/app/controllers/dc_common_controller.rb +64 -5
- data/app/forms/all_options.yml +2 -0
- data/app/forms/dc_ad.yml +11 -22
- data/app/forms/dc_design.yml +13 -13
- data/app/forms/dc_json_ld.yml +59 -0
- data/app/forms/dc_key_value.yml +32 -0
- data/app/forms/dc_menu_item.yml +1 -0
- data/app/forms/dc_page.yml +1 -5
- data/app/forms/dc_seo.yml +33 -0
- data/app/forms/json_ld_schema.yml +168 -0
- data/app/helpers/cmsedit_helper.rb +29 -24
- data/app/helpers/dc_application_helper.rb +105 -4
- data/app/models/concerns/dc_page_concern.rb +30 -5
- data/app/models/concerns/dc_seo_concern.rb +66 -0
- data/app/models/dc_design.rb +2 -0
- data/app/models/dc_json_ld.rb +152 -0
- data/app/models/dc_key_value.rb +48 -0
- data/app/models/dc_page.rb +0 -1
- data/app/models/drgcms_form_fields/hash_field.rb +86 -0
- data/app/models/drgcms_form_fields/select.rb +48 -15
- data/app/models/drgcms_form_fields/text_autocomplete.rb +14 -2
- data/app/models/drgcms_form_fields/tree_select.rb +4 -1
- data/app/{helpers → renderers}/dc_ad_renderer.rb +0 -0
- data/app/{helpers → renderers}/dc_big_menu_renderer.rb +0 -0
- data/app/{helpers → renderers}/dc_captcha_renderer.rb +0 -0
- data/app/{helpers → renderers}/dc_common_renderer.rb +0 -0
- data/app/{helpers → renderers}/dc_gallery_renderer.rb +0 -0
- data/app/{helpers → renderers}/dc_menu_renderer.rb +10 -4
- data/app/{helpers → renderers}/dc_page_renderer.rb +0 -0
- data/app/{helpers → renderers}/dc_part_renderer.rb +4 -4
- data/app/{helpers → renderers}/dc_piece_renderer.rb +0 -0
- data/app/{helpers → renderers}/dc_poll_renderer.rb +13 -5
- data/app/{helpers → renderers}/dc_renderer.rb +0 -0
- data/app/{helpers → renderers}/dc_simple_menu_renderer.rb +0 -0
- data/app/views/cmsedit/_edit_stuff.html.erb +3 -22
- data/config/locales/drgcms_en.yml +3 -1
- data/config/locales/drgcms_sl.yml +2 -0
- data/config/locales/models_en.yml +38 -6
- data/config/locales/models_sl.yml +39 -7
- data/lib/drg_cms.rb +2 -1
- data/lib/drg_cms/version.rb +1 -1
- metadata +22 -14
|
@@ -206,9 +206,9 @@ end
|
|
|
206
206
|
############################################################################
|
|
207
207
|
def dc_table_title_for_result(result=nil)
|
|
208
208
|
title = if @form['title'] # form has title section
|
|
209
|
-
t(@form['title']
|
|
209
|
+
t(@form['title'], @form['title'])
|
|
210
210
|
else # get name from translations
|
|
211
|
-
t(
|
|
211
|
+
t("helpers.label.#{@form['table']}.tabletitle", @form['table'])
|
|
212
212
|
end
|
|
213
213
|
dc_table_title(title, result)
|
|
214
214
|
end
|
|
@@ -281,6 +281,7 @@ def dc_actions_for_result(document)
|
|
|
281
281
|
when yaml['type'] == 'delete' then
|
|
282
282
|
parms['action'] = 'destroy'
|
|
283
283
|
parms['id'] = document.id
|
|
284
|
+
parms['return_to'] = request.url
|
|
284
285
|
dc_link_to( nil, 'remove lg', parms, data: { confirm: t('drgcms.confirm_delete') }, method: :delete )
|
|
285
286
|
# undocumented so far
|
|
286
287
|
when yaml['type'] == 'edit_embedded'
|
|
@@ -552,7 +553,6 @@ def dc_actions_for_form()
|
|
|
552
553
|
session[:form_processing] = "form:actions: #{element}"
|
|
553
554
|
v = element[1]
|
|
554
555
|
next if v.nil? # yes it happends
|
|
555
|
-
p "Using text option in actions_for form is replaced with caption. Table #{@form['table']}" if v['text']
|
|
556
556
|
# on_save_ok should't go inside td tags
|
|
557
557
|
if (element[0] == 'on_save_ok') then
|
|
558
558
|
c << hidden_field_tag(:on_save_ok, v)
|
|
@@ -639,9 +639,10 @@ def dc_actions_for_form()
|
|
|
639
639
|
end
|
|
640
640
|
# add current id to parameters
|
|
641
641
|
parms['id'] = dc_document_path(@record)
|
|
642
|
-
# additional parameters
|
|
642
|
+
# overwrite with or add additional parameters when params defined
|
|
643
643
|
v['params'].each { |k,v| parms[k] = dc_value_for_parameter(v) } if v['params']
|
|
644
|
-
|
|
644
|
+
parms['table'] = parms['table'].underscore if parms['table'] # might be CamelCase
|
|
645
|
+
# error if controller parameter is missing
|
|
645
646
|
if parms['controller'].nil?
|
|
646
647
|
"<li>#{t('drgcms.error')}</li>"
|
|
647
648
|
else
|
|
@@ -718,7 +719,7 @@ end
|
|
|
718
719
|
############################################################################
|
|
719
720
|
# Creates top or bottom horizontal line on form.
|
|
720
721
|
############################################################################
|
|
721
|
-
def top_bottom_line(
|
|
722
|
+
def top_bottom_line(options)
|
|
722
723
|
'<div class="dc-separator"></div>'
|
|
723
724
|
end
|
|
724
725
|
|
|
@@ -749,8 +750,9 @@ def dc_fields_for_tab(fields_on_tab) #:nodoc:
|
|
|
749
750
|
next
|
|
750
751
|
end
|
|
751
752
|
# label
|
|
752
|
-
|
|
753
|
-
|
|
753
|
+
caption = options['caption'] || options['text']
|
|
754
|
+
label = if !caption.blank?
|
|
755
|
+
t(caption, caption)
|
|
754
756
|
elsif options['name']
|
|
755
757
|
t_name(options['name'], options['name'].capitalize.gsub('_',' ') )
|
|
756
758
|
end
|
|
@@ -782,7 +784,7 @@ def dc_fields_for_tab(fields_on_tab) #:nodoc:
|
|
|
782
784
|
html << if labels_pos == 'top'
|
|
783
785
|
%Q[
|
|
784
786
|
<div class="dc-form-label-top dc-color-#{odd_even} dc-align-left" title="#{help}">
|
|
785
|
-
<label for="record_#{options['name']}">#{
|
|
787
|
+
<label for="record_#{options['name']}">#{label} </label>
|
|
786
788
|
<div id="td_record_#{options['name']}">#{field_html}</div>
|
|
787
789
|
</div> ]
|
|
788
790
|
else
|
|
@@ -792,7 +794,7 @@ def dc_fields_for_tab(fields_on_tab) #:nodoc:
|
|
|
792
794
|
data_width = (94 - 10*group_option)/group_option
|
|
793
795
|
%Q[
|
|
794
796
|
<div class="dc-form-label dc-color-#{odd_even} dc-align-#{labels_pos}" style="width:#{label_width}%;" title="#{help}">
|
|
795
|
-
<label for="record_#{options['name']}">#{
|
|
797
|
+
<label for="record_#{options['name']}">#{label} </label>
|
|
796
798
|
</div>
|
|
797
799
|
<div id="td_record_#{options['name']}" class="dc-form-field dc-color-#{odd_even}" style="width:#{data_width}%;">#{field_html}</div>
|
|
798
800
|
]
|
|
@@ -809,7 +811,7 @@ end
|
|
|
809
811
|
# Creates edit form div.
|
|
810
812
|
############################################################################
|
|
811
813
|
def dc_fields_for_form()
|
|
812
|
-
html, tabs,
|
|
814
|
+
html, tabs, tab_data = '',[], ''
|
|
813
815
|
# Only fields defined
|
|
814
816
|
if (form_fields = @form['form']['fields'])
|
|
815
817
|
html << "<div id='data_fields' " + (@form['form']['height'] ? "style=\"height: #{@form['form']['height']}px;\">" : '>')
|
|
@@ -817,33 +819,36 @@ def dc_fields_for_form()
|
|
|
817
819
|
else
|
|
818
820
|
# there are multiple tabs on form
|
|
819
821
|
first = true # first tab
|
|
820
|
-
@form['form']['tabs'].keys.sort.each do |
|
|
821
|
-
next if
|
|
822
|
+
@form['form']['tabs'].keys.sort.each do |tab_name|
|
|
823
|
+
next if tab_name.match('actions')
|
|
822
824
|
# Tricky. If field name is not on the tab skip to next tab
|
|
823
825
|
if params[:edit_only]
|
|
824
826
|
is_on_tab = false
|
|
825
|
-
@form['form']['tabs'][
|
|
827
|
+
@form['form']['tabs'][tab_name].each {|k,v| is_on_tab = true if params[:edit_only] == v['name'] }
|
|
826
828
|
next unless is_on_tab
|
|
827
829
|
end
|
|
828
|
-
# first div is displayed all
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
tabs
|
|
830
|
+
# first div is displayed, all others are hidden
|
|
831
|
+
tab_data << "<div id=\"data_#{tab_name.delete("\s\n")}\""
|
|
832
|
+
tab_data << ' class="div-hidden"' unless first
|
|
833
|
+
tab_data << " style=\"height: #{@form['form']['height']}px;\"" if @form['form']['height']
|
|
834
|
+
tab_data << ">#{dc_fields_for_tab(@form['form']['tabs'][tab_name])}</div>"
|
|
835
|
+
tab_label = @form['form']['tabs'][tab_name]['caption'] || tab_name
|
|
836
|
+
tabs << [tab_name, tab_label]
|
|
834
837
|
first = false
|
|
835
838
|
end
|
|
836
839
|
# make it all work together
|
|
837
840
|
html << '<ul class="dc-form-ul" >'
|
|
838
841
|
first = true # first tab must be selected
|
|
839
|
-
tabs.each do |
|
|
840
|
-
html << "<li id
|
|
842
|
+
tabs.each do |tab_name, tab_label|
|
|
843
|
+
html << "<li id=\"li_#{tab_name}\" data-div=\"#{tab_name.delete("\s\n")}\" class=\"dc-form-li"
|
|
844
|
+
html << ' dc-form-li-selected' if first
|
|
845
|
+
html << "\">#{t(tab_label, t_name(tab_label))}</li>"
|
|
841
846
|
first = false
|
|
842
847
|
end
|
|
843
848
|
html << '</ul>'
|
|
844
|
-
html <<
|
|
849
|
+
html << tab_data
|
|
845
850
|
end
|
|
846
|
-
# add last_updated_at hidden field so controller can check if record was updated in during editing
|
|
851
|
+
# add last_updated_at hidden field so controller can check if record was updated in db during editing
|
|
847
852
|
html << hidden_field(nil, :last_updated_at, value: @record.updated_at.to_i) if @record.respond_to?(:updated_at)
|
|
848
853
|
# add form time stamp to prevent double form submit
|
|
849
854
|
html << hidden_field(nil, :form_time_stamp, value: Time.now.to_i)
|
|
@@ -58,6 +58,8 @@ attr_accessor :parts
|
|
|
58
58
|
attr_accessor :record
|
|
59
59
|
#
|
|
60
60
|
attr_accessor :record_footer
|
|
61
|
+
# json_ld
|
|
62
|
+
attr_reader :json_ld
|
|
61
63
|
|
|
62
64
|
############################################################################
|
|
63
65
|
# When @parent is present then helper methods are called from parent class otherwise
|
|
@@ -575,7 +577,7 @@ def dc_page_edit_menu(opts=@opts)
|
|
|
575
577
|
return '' if opts[:edit_mode] < 2
|
|
576
578
|
# save some data to cookie. This can not go to session.
|
|
577
579
|
page = opts[:page] || @page
|
|
578
|
-
table = _origin.site.
|
|
580
|
+
table = _origin.site.page_class.underscore
|
|
579
581
|
kukis = { "#{table}.dc_design_id" => page.dc_design_id,
|
|
580
582
|
# "#{table}.menu_id" => page.menu_id,
|
|
581
583
|
"#{table}.kats" => page.kats,
|
|
@@ -587,7 +589,7 @@ def dc_page_edit_menu(opts=@opts)
|
|
|
587
589
|
opts[:editparams] ||= {}
|
|
588
590
|
dc_link_menu_tag(title) do |html|
|
|
589
591
|
opts[:editparams].merge!( controller: 'cmsedit', action: 'edit', 'icon' => 'edit' )
|
|
590
|
-
opts[:editparams].merge!( :id => page.id, :table => _origin.site.
|
|
592
|
+
opts[:editparams].merge!( :id => page.id, :table => _origin.site.page_class.underscore, form_name: opts[:form_name], edit_only: 'body' )
|
|
591
593
|
html << dc_link_for_edit1( opts[:editparams], t('drgcms.edit_content') )
|
|
592
594
|
|
|
593
595
|
# opts[:editparams][:edit_only] = nil
|
|
@@ -599,7 +601,7 @@ def dc_page_edit_menu(opts=@opts)
|
|
|
599
601
|
html << dc_link_for_edit1( opts[:editparams], t('drgcms.edit_new_page') )
|
|
600
602
|
|
|
601
603
|
opts[:editparams].merge!(ids: page.id, form_name: 'dc_part', 'icon' => 'plus-square-o',
|
|
602
|
-
table: "#{_origin.site.
|
|
604
|
+
table: "#{_origin.site.page_class.underscore};dc_part" )
|
|
603
605
|
html << dc_link_for_edit1( opts[:editparams], t('drgcms.edit_new_part') )
|
|
604
606
|
end.html_safe
|
|
605
607
|
end
|
|
@@ -618,7 +620,7 @@ end
|
|
|
618
620
|
########################################################################
|
|
619
621
|
def dc_page_class()
|
|
620
622
|
# dc_get_site.page_class.classify.constantize
|
|
621
|
-
dc_get_site.
|
|
623
|
+
dc_get_site.page_klass
|
|
622
624
|
end
|
|
623
625
|
|
|
624
626
|
########################################################################
|
|
@@ -1335,4 +1337,103 @@ def dc_document_path(document)
|
|
|
1335
1337
|
path.reverse.join(';')
|
|
1336
1338
|
end
|
|
1337
1339
|
|
|
1340
|
+
########################################################################
|
|
1341
|
+
# Will return formated code for embedding json+ld data into page
|
|
1342
|
+
#
|
|
1343
|
+
# Returns:
|
|
1344
|
+
# HTML data to be embedded into page header
|
|
1345
|
+
#######################################################################
|
|
1346
|
+
def dc_get_json_ld()
|
|
1347
|
+
return '' if @json_ld.nil? or @json_ld.size == 0
|
|
1348
|
+
|
|
1349
|
+
%Q[
|
|
1350
|
+
<script type="application/ld+json">
|
|
1351
|
+
#{JSON.pretty_generate({'@context' => 'http://schema.org', '@graph' => @json_ld})}
|
|
1352
|
+
</script>
|
|
1353
|
+
].html_safe
|
|
1354
|
+
end
|
|
1355
|
+
|
|
1356
|
+
########################################################################
|
|
1357
|
+
# Will add new element to json_ld structure
|
|
1358
|
+
#
|
|
1359
|
+
# Parameters:
|
|
1360
|
+
# [element] Hash or Array of hashes: json+ld element
|
|
1361
|
+
#######################################################################
|
|
1362
|
+
def dc_add_json_ld(element)
|
|
1363
|
+
@json_ld ||= []
|
|
1364
|
+
if element.class == Array
|
|
1365
|
+
@json_ld += element
|
|
1366
|
+
else
|
|
1367
|
+
@json_ld << element
|
|
1368
|
+
end
|
|
1369
|
+
end
|
|
1370
|
+
|
|
1371
|
+
########################################################################
|
|
1372
|
+
# Will return meta data for SEO optimizations
|
|
1373
|
+
#
|
|
1374
|
+
# Returns:
|
|
1375
|
+
# HTML data to be embedded into page header
|
|
1376
|
+
#######################################################################
|
|
1377
|
+
def dc_get_seo_meta_tags()
|
|
1378
|
+
html = ''
|
|
1379
|
+
html << "<link rel=\"canonical\" href=\"#{@page.canonical_link}\">\n " unless @page&.canonical_link.blank?
|
|
1380
|
+
|
|
1381
|
+
html << @meta_tags.inject('') do |r, hash|
|
|
1382
|
+
r << "<meta #{hash.first} content=\"#{hash.last}\">\n "
|
|
1383
|
+
end if @meta_tags
|
|
1384
|
+
html.html_safe
|
|
1385
|
+
end
|
|
1386
|
+
|
|
1387
|
+
########################################################################
|
|
1388
|
+
# Will add a meta tag to internal hash structure. If meta tag already exists it
|
|
1389
|
+
# will be overwritten.
|
|
1390
|
+
#
|
|
1391
|
+
# Parameters:
|
|
1392
|
+
# [name] String: meta name
|
|
1393
|
+
# [content] String: meta content
|
|
1394
|
+
########################################################################
|
|
1395
|
+
def dc_add_meta_tag(type, name, content)
|
|
1396
|
+
return if content.blank?
|
|
1397
|
+
@meta_tags ||= {}
|
|
1398
|
+
key = "#{type}=\"#{name}\""
|
|
1399
|
+
@meta_tags[key] = content
|
|
1400
|
+
end
|
|
1401
|
+
|
|
1402
|
+
#######################################################################
|
|
1403
|
+
# Will return alt image option when text is provided. When text is blank
|
|
1404
|
+
# it will extract alt name from picture file_name. This method returns
|
|
1405
|
+
# together with alt="image-tag" tag.
|
|
1406
|
+
#
|
|
1407
|
+
# Parameters:
|
|
1408
|
+
# [file_name] String: Filename of a picture
|
|
1409
|
+
# [text] String: Alt text name
|
|
1410
|
+
#
|
|
1411
|
+
# Returns:
|
|
1412
|
+
# [String] alt="image-tag"
|
|
1413
|
+
#######################################################################
|
|
1414
|
+
def dc_img_alt_tag(file_name, text=nil)
|
|
1415
|
+
" alt=\"#{dc_img_alt(file_name, text)}\" ".html_safe
|
|
1416
|
+
end
|
|
1417
|
+
|
|
1418
|
+
#######################################################################
|
|
1419
|
+
# Will return alt image option when text is provided. When text is blank
|
|
1420
|
+
# it will extract alt name from picture file_name. This method returns just
|
|
1421
|
+
# alt name.
|
|
1422
|
+
#
|
|
1423
|
+
# Parameters:
|
|
1424
|
+
# [file_name] String: Filename of a picture
|
|
1425
|
+
# [text] String: Alt text name
|
|
1426
|
+
#
|
|
1427
|
+
# Returns:
|
|
1428
|
+
# [String] alt_image_name
|
|
1429
|
+
#######################################################################
|
|
1430
|
+
def dc_img_alt(file_name, text=nil)
|
|
1431
|
+
if text.blank?
|
|
1432
|
+
name = File.basename(file_name.to_s)
|
|
1433
|
+
text = name[0,name.index('.')].downcase rescue name
|
|
1434
|
+
end
|
|
1435
|
+
text
|
|
1436
|
+
end
|
|
1437
|
+
|
|
1438
|
+
|
|
1338
1439
|
end
|
|
@@ -33,7 +33,6 @@ include Mongoid::Document
|
|
|
33
33
|
include Mongoid::Timestamps
|
|
34
34
|
|
|
35
35
|
field :subject, type: String, default: ''
|
|
36
|
-
field :title, type: String
|
|
37
36
|
field :subject_link, type: String, default: ''
|
|
38
37
|
field :alt_link, type: String, default: ''
|
|
39
38
|
field :sub_subject, type: String, default: ''
|
|
@@ -56,16 +55,19 @@ field :active, type: Boolean, default: true
|
|
|
56
55
|
field :created_by, type: BSON::ObjectId
|
|
57
56
|
field :updated_by, type: BSON::ObjectId
|
|
58
57
|
field :kats, type: Array # Categories
|
|
59
|
-
|
|
58
|
+
# IFRAME
|
|
60
59
|
field :if_url, type: String
|
|
61
60
|
field :if_border, type: Integer, default: 0
|
|
62
61
|
field :if_width, type: Integer
|
|
63
62
|
field :if_height, type: Integer
|
|
64
63
|
field :if_scroll, type: String
|
|
65
64
|
field :if_id, type: String
|
|
66
|
-
field :if_class,
|
|
65
|
+
field :if_class, type: String
|
|
67
66
|
field :if_params, type: String
|
|
68
67
|
|
|
68
|
+
# SEO
|
|
69
|
+
include DcSeoConcern
|
|
70
|
+
|
|
69
71
|
field :policy_id, type: BSON::ObjectId
|
|
70
72
|
|
|
71
73
|
embeds_many :dc_parts
|
|
@@ -80,6 +82,7 @@ index alt_link: 1
|
|
|
80
82
|
before_save :do_before_save
|
|
81
83
|
|
|
82
84
|
validates :publish_date, presence: true
|
|
85
|
+
validate :validate_images_alt_present
|
|
83
86
|
|
|
84
87
|
######################################################################
|
|
85
88
|
# Will return subject_link. Field name link should be common for all documents
|
|
@@ -88,7 +91,15 @@ validates :publish_date, presence: true
|
|
|
88
91
|
def link
|
|
89
92
|
subject_link
|
|
90
93
|
end
|
|
91
|
-
|
|
94
|
+
|
|
95
|
+
######################################################################
|
|
96
|
+
# Will return validation error if all images in body field do not have
|
|
97
|
+
# alt attribute pressent.
|
|
98
|
+
######################################################################
|
|
99
|
+
def validate_images_alt_present
|
|
100
|
+
errors.add('body', I18n.t('drgcms.img_alt_not_present')) unless DcPage.images_alt_present?(self.body)
|
|
101
|
+
end
|
|
102
|
+
|
|
92
103
|
protected
|
|
93
104
|
|
|
94
105
|
######################################################################
|
|
@@ -109,7 +120,7 @@ end
|
|
|
109
120
|
# than link size is not larger than 100 chars.
|
|
110
121
|
######################################################################
|
|
111
122
|
def self.clear_link(link)
|
|
112
|
-
link.gsub!(
|
|
123
|
+
link.gsub!(/\.|\?|\!\&|\||»|«|\,|\"|\'|\:/,'')
|
|
113
124
|
link.gsub!('<br>','')
|
|
114
125
|
link.gsub!('–','-')
|
|
115
126
|
link.gsub!(' ','-')
|
|
@@ -144,6 +155,20 @@ def self.dc_filters
|
|
|
144
155
|
'field' => 'dc_site_id', 'value' => '@current_site'}
|
|
145
156
|
end
|
|
146
157
|
|
|
158
|
+
######################################################################
|
|
159
|
+
# Clears subject link of chars that shouldn't be there and also takes care
|
|
160
|
+
# than link size is not larger than 100 chars.
|
|
161
|
+
######################################################################
|
|
162
|
+
def self.images_alt_present?(text)
|
|
163
|
+
return true if text.blank?
|
|
164
|
+
#
|
|
165
|
+
document = Nokogiri::HTML.parse(text)
|
|
166
|
+
document.xpath('//img').each do |image|
|
|
167
|
+
return false if !image.attributes['alt'] or image.attributes['alt'].text.blank?
|
|
168
|
+
end
|
|
169
|
+
true
|
|
170
|
+
end
|
|
171
|
+
|
|
147
172
|
end
|
|
148
173
|
|
|
149
174
|
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# Copyright (c) 2019+ Damjan Rems
|
|
3
|
+
#
|
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
|
5
|
+
# a copy of this software and associated documentation files (the
|
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
|
10
|
+
# the following conditions:
|
|
11
|
+
#
|
|
12
|
+
# The above copyright notice and this permission notice shall be
|
|
13
|
+
# included in all copies or substantial portions of the Software.
|
|
14
|
+
#
|
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
22
|
+
#++
|
|
23
|
+
|
|
24
|
+
##########################################################################
|
|
25
|
+
# dc_seo_concern, ads SEO optimization fields to any model.
|
|
26
|
+
#
|
|
27
|
+
# title String Browser title. Optimization for SEO.
|
|
28
|
+
# meta_description String SEO optimised page description
|
|
29
|
+
# meta_additional String Additional meta page data. Enter as meta_name=meta data
|
|
30
|
+
# dc_json_lds Embedded:DcJsonLd Page structure data
|
|
31
|
+
#
|
|
32
|
+
# If you want to add SEO optimization data to your document add:
|
|
33
|
+
#
|
|
34
|
+
# "include DcSeoConcern" to your model definition
|
|
35
|
+
#
|
|
36
|
+
# and
|
|
37
|
+
#
|
|
38
|
+
# "include: dc_seo" option to top of DRGCMS edit form for your document.
|
|
39
|
+
##########################################################################
|
|
40
|
+
module DcSeoConcern
|
|
41
|
+
extend ActiveSupport::Concern
|
|
42
|
+
|
|
43
|
+
included do
|
|
44
|
+
field :title, type: String
|
|
45
|
+
field :meta_description, type: String
|
|
46
|
+
field :canonical_link, type: String
|
|
47
|
+
embeds_many :dc_json_lds # JSON-LD structure
|
|
48
|
+
|
|
49
|
+
######################################################################
|
|
50
|
+
# Will return JSON LD data if defined for the page
|
|
51
|
+
######################################################################
|
|
52
|
+
def get_json_ld()
|
|
53
|
+
parent_data = {'datePublished' => self.created_at, 'dateModified' => self.updated_at}
|
|
54
|
+
data = []
|
|
55
|
+
if dc_json_lds.size > 0
|
|
56
|
+
dc_json_lds.where(active: true).each do |element|
|
|
57
|
+
dta = element.get_json_ld(parent_data)
|
|
58
|
+
data << dta if dta.size > 0
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
data
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
end
|
data/app/models/dc_design.rb
CHANGED
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
# updated_at Time updated_at
|
|
32
32
|
# description String Short description of design
|
|
33
33
|
# body String Body of design which will be rendered like any Rails view
|
|
34
|
+
# params String Parameters used by design
|
|
34
35
|
# css String CSS for design
|
|
35
36
|
# rails_view String Rails view (file) name which will be used to render design
|
|
36
37
|
# author String Creater if design
|
|
@@ -94,6 +95,7 @@ class DcDesign
|
|
|
94
95
|
field :css, type: String, default: ''
|
|
95
96
|
field :rails_view, type: String, default: ''
|
|
96
97
|
field :control, type: String, default: ''
|
|
98
|
+
field :params, type: String, default: ''
|
|
97
99
|
field :control_method, type: String, default: ''
|
|
98
100
|
field :author, type: String
|
|
99
101
|
field :active, type: Boolean, default: true
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# Copyright (c) 2019+ Damjan Rems
|
|
3
|
+
#
|
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
|
5
|
+
# a copy of this software and associated documentation files (the
|
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
|
10
|
+
# the following conditions:
|
|
11
|
+
#
|
|
12
|
+
# The above copyright notice and this permission notice shall be
|
|
13
|
+
# included in all copies or substantial portions of the Software.
|
|
14
|
+
#
|
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
22
|
+
#++
|
|
23
|
+
|
|
24
|
+
########################################################################
|
|
25
|
+
# == Schema information
|
|
26
|
+
#
|
|
27
|
+
# Collection name: dc_json_ld : JSON_LD data for site optimization
|
|
28
|
+
#
|
|
29
|
+
# _id BSON::ObjectId _id
|
|
30
|
+
# type String Type of structure
|
|
31
|
+
# data String Structure data in YAML
|
|
32
|
+
# dc_json_lds Object Can embed substructure
|
|
33
|
+
# created_at Time created_at
|
|
34
|
+
# updated_at Time Last updated at
|
|
35
|
+
# created_by BSON::ObjectId created_by
|
|
36
|
+
# updated_by BSON::ObjectId Last updated by
|
|
37
|
+
#
|
|
38
|
+
########################################################################
|
|
39
|
+
class DcJsonLd
|
|
40
|
+
include Mongoid::Document
|
|
41
|
+
include Mongoid::Timestamps
|
|
42
|
+
|
|
43
|
+
field :name, type: String
|
|
44
|
+
field :type, type: String
|
|
45
|
+
field :data, type: String
|
|
46
|
+
field :active, type: Boolean, default: true
|
|
47
|
+
|
|
48
|
+
embeds_many :dc_json_lds, :cyclic => true
|
|
49
|
+
|
|
50
|
+
field :created_by, type: BSON::ObjectId
|
|
51
|
+
field :updated_by, type: BSON::ObjectId
|
|
52
|
+
|
|
53
|
+
validates :name, presence: true
|
|
54
|
+
validates :type, presence: true
|
|
55
|
+
|
|
56
|
+
##########################################################################
|
|
57
|
+
# Returns JSON LD data as YAML
|
|
58
|
+
##########################################################################
|
|
59
|
+
def get_json_ld(parent_data)
|
|
60
|
+
yaml = (YAML.load(self.data) rescue nil) || {}
|
|
61
|
+
yaml['@type'] = self.type if yaml.size > 0
|
|
62
|
+
if dc_json_lds.size > 0
|
|
63
|
+
dc_json_lds.where(active: true).each do |element|
|
|
64
|
+
yml = element.get_json_ld(parent_data)
|
|
65
|
+
if yml.size > 0
|
|
66
|
+
yaml[element.name] ||= []
|
|
67
|
+
yaml[element.name] << yml
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
yaml
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
########################################################################
|
|
75
|
+
# Searches forms path for file_name and returns full file name or nil if not found.
|
|
76
|
+
#
|
|
77
|
+
# @param [String] Form file name. File name can be passed as gem_name.filename. This can
|
|
78
|
+
# be useful when you are extending form but want to retain same name as original form
|
|
79
|
+
# For example. You are extending dc_user form from drg_cms gem and want to
|
|
80
|
+
# retain same dc_user name. This can be done by setting drg_cms.dc_user to extend option.
|
|
81
|
+
#
|
|
82
|
+
# @return [String] Form file name including path or nil if not found.
|
|
83
|
+
########################################################################
|
|
84
|
+
def self.dc_find_form_file(form_file)
|
|
85
|
+
form_path=nil
|
|
86
|
+
if form_file.match(/\.|\//)
|
|
87
|
+
form_path,form_file=form_file.split(/\.|\//)
|
|
88
|
+
end
|
|
89
|
+
DrgCms.paths(:forms).reverse.each do |path|
|
|
90
|
+
f = "#{path}/#{form_file}.yml"
|
|
91
|
+
return f if File.exist?(f) and (form_path.nil? or path.to_s.match(/\/#{form_path}\//i))
|
|
92
|
+
end
|
|
93
|
+
p "Form file #{form_file} not found!"
|
|
94
|
+
nil
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
########################################################################
|
|
98
|
+
# Find document by ids when document are embedded into main d even if embedded
|
|
99
|
+
#
|
|
100
|
+
# @param [tables] Tables parameter as send in url. Tables are separated by ;
|
|
101
|
+
# @param [ids] ids as send in url. ids are separated by ;
|
|
102
|
+
#
|
|
103
|
+
# @return [Document]
|
|
104
|
+
########################################################################
|
|
105
|
+
def self.find_document_by_ids(tables, ids)
|
|
106
|
+
collection = tables.split(';').first.classify.constantize
|
|
107
|
+
ar_ids = ids.split(';')
|
|
108
|
+
# Find top document
|
|
109
|
+
document = collection.find(ar_ids.shift)
|
|
110
|
+
# Search for embedded document
|
|
111
|
+
ar_ids.each {|id| document = document.dc_json_lds.find(id) }
|
|
112
|
+
document
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
#########################################################################
|
|
116
|
+
# Returns possible options for type select field on form.
|
|
117
|
+
#########################################################################
|
|
118
|
+
def self.choices4_type()
|
|
119
|
+
yaml = YAML.load_file( dc_find_form_file('json_ld_schema') )
|
|
120
|
+
|
|
121
|
+
yaml.inject([]) {|result, schema_name| result << schema_name.first }
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
#########################################################################
|
|
125
|
+
# Create menu to add schema element. Called from DRGCMS Form action.
|
|
126
|
+
#########################################################################
|
|
127
|
+
def self.add_schema_menu(parent)
|
|
128
|
+
yaml = YAML.load_file( dc_find_form_file('json_ld_schema') )
|
|
129
|
+
if (level = parent.params['ids'].split(';').size) == 1
|
|
130
|
+
# select only top level elements
|
|
131
|
+
yaml.delete_if { |schema_name, schema_data| schema_data['level'].nil? }
|
|
132
|
+
else
|
|
133
|
+
# select only elemets which are subelements of type
|
|
134
|
+
parent_type = self.find_document_by_ids(parent.params['table'],parent.params['ids']).type
|
|
135
|
+
_yaml = []
|
|
136
|
+
yaml[parent_type].each do |name, data|
|
|
137
|
+
next unless data.class == Hash
|
|
138
|
+
_yaml << [data['type'], yaml[data['type']] ] if data['type'] and yaml[data['type']]
|
|
139
|
+
end
|
|
140
|
+
yaml = _yaml
|
|
141
|
+
end
|
|
142
|
+
# create menu code
|
|
143
|
+
html = '<ul>'
|
|
144
|
+
yaml.each do |schema_name, schema_data|
|
|
145
|
+
next if level == 1 and schema_data['level'].nil?
|
|
146
|
+
url = "/dc_common/add_json_ld_schema?table=#{parent.params['table']}&ids=#{parent.params['ids']}&schema=#{schema_name}&url=#{parent.request.url}"
|
|
147
|
+
html << %Q[<li class="dc-link-ajax dc-animate" data-url="#{url}">#{schema_name}</li>]
|
|
148
|
+
end
|
|
149
|
+
html << '</ul>'
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
end
|