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.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/drg_cms/drg_cms.js +54 -7
  3. data/app/assets/javascripts/drg_cms_application.js +1 -1
  4. data/app/assets/javascripts/drg_cms_cms.js +1 -1
  5. data/app/assets/stylesheets/drg_cms/drg_cms.css +32 -1
  6. data/app/controllers/cmsedit_controller.rb +49 -18
  7. data/app/controllers/dc_application_controller.rb +82 -21
  8. data/app/controllers/dc_common_controller.rb +64 -5
  9. data/app/forms/all_options.yml +2 -0
  10. data/app/forms/dc_ad.yml +11 -22
  11. data/app/forms/dc_design.yml +13 -13
  12. data/app/forms/dc_json_ld.yml +59 -0
  13. data/app/forms/dc_key_value.yml +32 -0
  14. data/app/forms/dc_menu_item.yml +1 -0
  15. data/app/forms/dc_page.yml +1 -5
  16. data/app/forms/dc_seo.yml +33 -0
  17. data/app/forms/json_ld_schema.yml +168 -0
  18. data/app/helpers/cmsedit_helper.rb +29 -24
  19. data/app/helpers/dc_application_helper.rb +105 -4
  20. data/app/models/concerns/dc_page_concern.rb +30 -5
  21. data/app/models/concerns/dc_seo_concern.rb +66 -0
  22. data/app/models/dc_design.rb +2 -0
  23. data/app/models/dc_json_ld.rb +152 -0
  24. data/app/models/dc_key_value.rb +48 -0
  25. data/app/models/dc_page.rb +0 -1
  26. data/app/models/drgcms_form_fields/hash_field.rb +86 -0
  27. data/app/models/drgcms_form_fields/select.rb +48 -15
  28. data/app/models/drgcms_form_fields/text_autocomplete.rb +14 -2
  29. data/app/models/drgcms_form_fields/tree_select.rb +4 -1
  30. data/app/{helpers → renderers}/dc_ad_renderer.rb +0 -0
  31. data/app/{helpers → renderers}/dc_big_menu_renderer.rb +0 -0
  32. data/app/{helpers → renderers}/dc_captcha_renderer.rb +0 -0
  33. data/app/{helpers → renderers}/dc_common_renderer.rb +0 -0
  34. data/app/{helpers → renderers}/dc_gallery_renderer.rb +0 -0
  35. data/app/{helpers → renderers}/dc_menu_renderer.rb +10 -4
  36. data/app/{helpers → renderers}/dc_page_renderer.rb +0 -0
  37. data/app/{helpers → renderers}/dc_part_renderer.rb +4 -4
  38. data/app/{helpers → renderers}/dc_piece_renderer.rb +0 -0
  39. data/app/{helpers → renderers}/dc_poll_renderer.rb +13 -5
  40. data/app/{helpers → renderers}/dc_renderer.rb +0 -0
  41. data/app/{helpers → renderers}/dc_simple_menu_renderer.rb +0 -0
  42. data/app/views/cmsedit/_edit_stuff.html.erb +3 -22
  43. data/config/locales/drgcms_en.yml +3 -1
  44. data/config/locales/drgcms_sl.yml +2 -0
  45. data/config/locales/models_en.yml +38 -6
  46. data/config/locales/models_sl.yml +39 -7
  47. data/lib/drg_cms.rb +2 -1
  48. data/lib/drg_cms/version.rb +1 -1
  49. metadata +22 -14
@@ -0,0 +1,48 @@
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_key_value : Key value items
28
+ #
29
+ # _id BSON::ObjectId _id
30
+ # key String Key
31
+ # value String Value
32
+ #
33
+ # Key-Value items can be embedded into any model and are replacing Hash fields.
34
+ # They can also appear cyclic if required.
35
+ #########################################################################
36
+ class DcKeyValue
37
+ include Mongoid::Document
38
+ include Mongoid::Timestamps
39
+
40
+ field :key, type: String
41
+ field :value, type: String
42
+
43
+ field :created_by, type: BSON::ObjectId
44
+ field :updated_by, type: BSON::ObjectId
45
+
46
+ embedded_in :key_values, polymorphic: true
47
+
48
+ end
@@ -31,7 +31,6 @@
31
31
  # created_at Time created_at
32
32
  # updated_at Time Updated
33
33
  # subject String Articles subject
34
- # title String Browser title. Optimization for SEO.
35
34
  # subject_link String Friendly link defined
36
35
  # alt_link String Alternative link, by which page could be found
37
36
  # sub_subject String Sub subject, short description of text
@@ -0,0 +1,86 @@
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
+ module DrgcmsFormFields
24
+
25
+ ###########################################################################
26
+ # Implementation of text_field DRG CMS form field.
27
+ #
28
+ # ===Form options:
29
+ # * +type:+ text_field (required)
30
+ # * +name:+ Field name (required)
31
+ # * +html:+ html options which apply to text_field field (optional)
32
+ #
33
+ # Form example:
34
+ # 10:
35
+ # name: title
36
+ # type: text_field
37
+ # size: 30
38
+ # html:
39
+ # required: yes
40
+ ###########################################################################
41
+ class HashField < DrgcmsField
42
+
43
+ ###########################################################################
44
+ # Returns value for readonly field
45
+ ###########################################################################
46
+ def ro_standard()
47
+ return self if @record[@yaml['name']].nil?
48
+ html = ''
49
+ @record[@yaml['name']].each do |key, value|
50
+ html << "#{key}:#{value}<br>"
51
+ end
52
+ super(html)
53
+ end
54
+
55
+ ###########################################################################
56
+ # Render text_field field html code
57
+ ###########################################################################
58
+ def render
59
+ return ro_standard if @readonly
60
+ set_initial_value
61
+ #
62
+ record = record_text_for(@yaml['name'])
63
+ # Convert Hash to values separated by colon
64
+ if @record[@yaml['name']]
65
+ @yaml['html']['value'] = @record[@yaml['name']].to_a.inject('') {|r, e| r << "#{e.first}:#{e.last}\n"}
66
+ end
67
+ @html << @parent.text_area( record, @yaml['name'], @yaml['html'])
68
+ self
69
+ end
70
+
71
+ ###########################################################################
72
+ # Return value. Return nil if input field is empty
73
+ ###########################################################################
74
+ def self.get_data(params, name)
75
+ return nil if params['record'][name].blank?
76
+ #
77
+ result = params['record'][name].split("\n").select {|e| !e.blank? }
78
+ return nil if result.size == 0
79
+ # convert to Hash
80
+ ret = {}
81
+ result.map { |e| key,value = e.chomp.split(':'); ret[key.strip] = value.strip unless value.blank? }
82
+ ret
83
+ end
84
+
85
+ end
86
+ end
@@ -44,6 +44,8 @@ module DrgcmsFormFields
44
44
  # your local language then select choices will be localized.
45
45
  # en.helpers.model_name.choices4_status: 'OK:0,Ready:1,Error:2'
46
46
  # sl.helpers.model_name.choices4_status: 'V redu:0,Pripravljen:1,Napaka:2'
47
+ # * +depend:+ Select options may depend on a value in some other field. If depend option is specified
48
+ # then chices must be provided by class method and defined in eval option.
47
49
  # * +html:+ html options which apply to select field (optional)
48
50
  #
49
51
  # Form example:
@@ -56,35 +58,66 @@ module DrgcmsFormFields
56
58
  # eval: DcCategory.values_for_parent
57
59
  # html:
58
60
  # include_blank: true
61
+ # 50:
62
+ # name: company
63
+ # type: select
64
+ # choices: Audi,BMW,Mercedes
65
+ # 60:
66
+ # name: type
67
+ # type: select
68
+ # eval: Cars.choices4_type
69
+ # depend: company
59
70
  ###########################################################################
60
71
  class Select < DrgcmsField
61
72
 
62
73
  ###########################################################################
63
- # Return values, when choices options will be returned by evaluating expression
74
+ # Choices are defined in helper as:
75
+ # helper.label.table_name.choices_for_fieldname or
76
+ # choices4_tablename_fieldname
77
+ ###########################################################################
78
+ def choices_in_helper(all)
79
+ helper = "helpers.label.#{@form['table']}.choices4_#{@yaml['name']}"
80
+ c = t(helper)
81
+ if c.match( 'translation missing' )
82
+ helper = "choices_for_#{@form['table']}_#{@yaml['name']}"
83
+ return "Error. #{helper} not defined" if c.match( 'translation missing' )
84
+ end
85
+ c
86
+ end
87
+
88
+ ###########################################################################
89
+ # Choices are defined by evaluating an exspression. This is most common class
90
+ # method defined in a class. SomeClass.get_choices4.
64
91
  ###########################################################################
65
- def do_eval(e)
92
+ def choices_in_eval(e, all=false)
66
93
  e.strip!
67
- method = e.split(/\ |\(/).first
68
- return eval(e) if respond_to?(method) # id method defined here
69
- return eval('@parent.'+e) if @parent.respond_to?(method) # is method defined in helpers
70
- # eval whatever it is
71
- eval e
94
+ if @yaml['depend'].nil?
95
+ method = e.split(/\ |\(/).first
96
+ return eval(e) if respond_to?(method) # id method defined here
97
+ return eval('@parent.'+e) if @parent.respond_to?(method) # is method defined in helpers
98
+ # eval whatever it is there
99
+ eval e
100
+ else
101
+ # add event listener to depend field
102
+ @js << "$('#record_#{@yaml['depend']}').change( function(e) { update_select_depend('#{@yaml['name']}', '#{@yaml['depend']}','#{e}');})\n"
103
+ depend_value = @record[@yaml['depend']]
104
+ e << " '#{depend_value}'"
105
+ eval e
106
+ end
72
107
  end
73
-
108
+
74
109
  ###########################################################################
75
110
  # Create choices array for select field.
76
111
  ###########################################################################
77
- def get_choices
112
+ def get_choices(all=false)
78
113
  begin
79
114
  choices = case
80
115
  when @yaml['choices'] then
81
- (@yaml['choices'].match('helpers.') ) ? t(@yaml['choices']) : @yaml['choices']
116
+ @yaml['choices']
82
117
  when @yaml['eval'] then
83
- do_eval(@yaml['eval'])
84
- else
85
- c = t('helpers.label.' + @form['table'] + '.choices4_' + @yaml['name'] )
86
- c = 'Error' if c.match( 'translation missing' )
87
- c
118
+ choices_in_eval(@yaml['eval'], all)
119
+ else
120
+ choices_in_helper(all)
88
121
  end
89
122
  # Convert string to Array
90
123
  choices.class == String ?
@@ -29,6 +29,8 @@ module DrgcmsFormFields
29
29
  # * +name:+ field name (required)
30
30
  # * +type:+ text_autocomplete (required)
31
31
  # * +table+ Collection (table) name. When defined search must contain field name
32
+ # * +with_new+ Will add an icon for shortcut to add new document to collection
33
+ # * +not_id+ Field value represent value not an id. Field will save entered value when not selected wit autocomplete.
32
34
  # * +search:+ Search may consist of three parameters from which are separated either by dot (.)
33
35
  # * search_field_name; when table option is defined search must define field name which will be used for search query
34
36
  # * collection_name.search_field_name; Same as above except that table options must be ommited.
@@ -84,7 +86,7 @@ def render
84
86
  end
85
87
  # Found value to be written in field. If field is not found write out value.
86
88
  if value
87
- record = t.find(value)
89
+ record = t.find(value) unless @yaml['not_id'] # don't if it's is not an id
88
90
  value_displayed = record ? record.send(ret_name) : value
89
91
  end
90
92
  # return if readonly
@@ -104,7 +106,15 @@ def render
104
106
  style: "vertical-align: top;", 'data-table' => @yaml['with_new'] )
105
107
  end
106
108
  @html << @parent.hidden_field(record, @yaml['name'], value: value) # actual value will be in hidden field
107
- # JS stuff
109
+ # JS stuff
110
+ # allow unselected values on not_id: true option
111
+ not_id_code = %Q[
112
+ if (ui.item == null) {
113
+ $("##{record}_#{@yaml['name']}").val($("##{record}__#{@yaml['name']}").val() );
114
+ return;
115
+ }
116
+ ] if @yaml['not_id']
117
+ #
108
118
  @js << <<EOJS
109
119
  $(document).ready(function() {
110
120
  $("##{record}_#{_name}").autocomplete( {
@@ -122,7 +132,9 @@ $(document).ready(function() {
122
132
  });
123
133
  },
124
134
  change: function (event, ui) {
135
+ #{not_id_code}
125
136
  $("##{record}_#{@yaml['name']}").val(ui.item.id);
137
+
126
138
  },
127
139
  minLength: 2
128
140
  });
@@ -95,7 +95,10 @@ def render
95
95
  @html << "<div id=\"#{@yaml['name']}\" class=\"tree-select\" #{set_style()} >"
96
96
  # Fill @choices hash. The key is parent object id
97
97
  @choices = {}
98
- do_eval(@yaml['eval']).each {|data| @choices[ data[2].to_s ] ||= []; @choices[ data[2].to_s ] << (data << false)}
98
+ choices_in_eval(@yaml['eval']).each do |data|
99
+ @choices[ data[2].to_s ] ||= []
100
+ @choices[ data[2].to_s ] << (data << false)
101
+ end
99
102
  # put current values hash with. To speed up selection when there is a lot of categories
100
103
  current_values = {}
101
104
  current = @record[@yaml['name']] || []
@@ -97,10 +97,16 @@ def link_4menu(item)
97
97
  caption = item.caption[0] == '-' ? '' : item.caption.to_s
98
98
  img_title = item.caption.to_s.sub('-','')
99
99
  # add picture if picture is not blank
100
- (item.picture.blank? ? '' :
101
- @parent.link_to( @parent.image_tag(item.picture), link, {title: img_title, target: target} )) +
102
- (caption.blank? ? '' :
103
- @parent.link_to(caption, link, {target: target}) )
100
+ html = ''
101
+ if !item.picture.blank?
102
+ if item.picture[0,3] == 'fa-'
103
+ caption << @parent.fa_icon(item.picture[3,20])
104
+ else
105
+ html = @parent.link_to( @parent.image_tag(item.picture), link, {title: img_title, target: target} ) rescue ''
106
+ end
107
+ end
108
+ html << @parent.link_to(caption.html_safe, link, {target: target}) unless caption.blank?
109
+ html
104
110
  end
105
111
 
106
112
  ########################################################################
@@ -98,7 +98,7 @@ def load_parts #:nodoc:
98
98
  # add parts in page
99
99
  @parent.page.dc_parts.where(active: true).each do |part|
100
100
  type = decamelize_type(part._type) || 'dc_part'
101
- @parent.parts << [part, @parent.page.id, type, "#{@parent.site.page_table};#{type}"]
101
+ @parent.parts << [part, @parent.page.id, type, "#{@parent.site.page_class.underscore};#{type}"]
102
102
  end
103
103
  # add parts in site
104
104
  @parent.site.dc_parts.where(active: true).each do |part|
@@ -161,11 +161,11 @@ end
161
161
  def in_page
162
162
  # Part is in page with id
163
163
  page = if @opts[:page_id]
164
- pageclass = @parent.site.page_table.classify.constantize
164
+ pageclass = @parent.site.page_klass
165
165
  pageclass.find(@opts[:page_id])
166
166
  # Part is in page with subject link
167
167
  elsif @opts[:page_link]
168
- pageclass = @parent.site.page_table.classify.constantize
168
+ pageclass = @parent.site.page_klass
169
169
  @page = pageclass.find_by(dc_site_id: @parent.site._id, subject_link: @opts[:page_link])
170
170
  # Part is in current page
171
171
  else
@@ -174,7 +174,7 @@ def in_page
174
174
  return "Error DcPart: Page not found!" if page.nil?
175
175
  #
176
176
  if part = page.dc_parts.find_by(name: @opts[:name])
177
- @opts[:editparams].merge!(id: part, ids: page._id, form_name: 'dc_part', table: "#{@parent.site.page_table};dc_part" )
177
+ @opts[:editparams].merge!(id: part, ids: page._id, form_name: 'dc_part', table: "#{@parent.site.page_class.underscore};dc_part" )
178
178
  render_particle(part, @opts)
179
179
  else
180
180
  "Part with name #{@opts[:name]} not found in page!"
@@ -82,13 +82,18 @@ def do_one_item(poll, yaml)
82
82
  key = "p_#{yaml['name']}"
83
83
  params[key] = yaml['default'] unless params[key]
84
84
  end
85
+ # Label as placeholder
86
+ if poll.display == 'in'
87
+ yaml['html'] ||= {}
88
+ yaml['html']['placeholder'] = text
89
+ end
85
90
  # create form_field object and retrieve html code
86
91
  clas_string = yaml['type'].camelize
87
92
  field_html = if DrgcmsFormFields.const_defined?(clas_string)
88
93
  clas = DrgcmsFormFields.const_get(clas_string)
89
- o = clas.new(@parent, @record, yaml).render
94
+ field = clas.new(@parent, @record, yaml).render
90
95
  #TODO collect all javascript and add it at the end
91
- o.html + (o.js.size > 0 ? @parent.javascript_tag(o.js) : '')
96
+ field.html + (field.js.size > 0 ? @parent.javascript_tag(field.js) : '')
92
97
  else # litle error string
93
98
  "Error: Code for field type #{yaml['type']} not defined!"
94
99
  end
@@ -114,12 +119,15 @@ def do_one_item(poll, yaml)
114
119
  # submit and link tag
115
120
  clas = yaml['type'].match(/submit_tag/) ? '' : 'dc-link-submit'
116
121
  html << "<span class='#{clas} dc-animate'>#{field_html}#{yaml['separator']}</span>"
117
- # other elements
122
+ # other fields
118
123
  else
119
- html << if poll.display == 'lr'
124
+ html << case
125
+ when poll.display == 'lr' then
120
126
  "<div class='row-div'><div class='dc-form-label poll-data-text #{yaml['class']}'>#{text}</div><div class='dc-form-field poll-data-field #{yaml['class']}'>#{field_html}</div></div>\n"
121
- else
127
+ when poll.display == 'tb' then
122
128
  "<div class='poll-data-text #{yaml['class']}'>#{text}</div><div class='poll-data-field #{yaml['class']}'>#{field_html}#{yaml['separator']}</div>\n"
129
+ else
130
+ "<div class='poll-data-field #{yaml['class']}'>#{field_html}#{yaml['separator']}</div>\n"
123
131
  end
124
132
  end
125
133
  end
@@ -1,5 +1,5 @@
1
-
2
1
  <div id="cmsedit-div">
2
+ <div class="cms-toggle mode-<%= session[:edit_mode] %>" title="<%= t('drgcms.toggle_cms')%>">CMS</div>
3
3
  <%= link_to('CMS', controller: 'dc_common', action: 'toggle_edit_mode', return_to: request.url) %>
4
4
  <% if session[:edit_mode] > 1 %>
5
5
  <div class="cmsedit-table cmsedit-top">
@@ -9,7 +9,7 @@
9
9
 
10
10
  <% if @page %>
11
11
  <%= link_to( fa_icon('file-text-o lg', class: "dc-animate", title: "#{t('drgcms.edit_page')}"),
12
- {controller: 'cmsedit', action: 'edit', table: @site.page_table, id: @page._id}, target: 'iframe_cms') %>
12
+ {controller: 'cmsedit', action: 'edit', table: @site.page_class, id: @page._id}, target: 'iframe_cms') %>
13
13
  <% end %>
14
14
 
15
15
  <% if @design %>
@@ -22,6 +22,7 @@
22
22
  {controller: 'cmsedit', action: 'edit', table: 'dc_site', id: @site._id}, target: 'iframe_cms') %>
23
23
  <% end %>
24
24
  <b>&nbsp; | &nbsp; </b>
25
+
25
26
  <%= link_to( fa_icon('compress lg', class: "dc-animate", title: t('drgcms.minimize')), '#',
26
27
  onclick: "$('#iframe_cms').height(1); return false;" ) %>
27
28
 
@@ -31,13 +32,6 @@
31
32
  <%= link_to( fa_icon('refresh lg', class: "dc-animate", title: t('drgcms.reload')), '#',
32
33
  onclick: "document.location.reload(true); return false;") %>
33
34
  <b>&nbsp; | &nbsp; </b>
34
-
35
- <% if false %>
36
- <%= select('record', 'select', dc_choices4_cmsmenu ) %>
37
-
38
- <%= link_to( fa_icon('bars lg', class: "dc-animate", title: t('drgcms.edit_selected')), '#',
39
- onclick: "$('#iframe_cms').attr('src', $('#record_select').val() ); return false;") %>
40
- <% end %>
41
35
 
42
36
  <%= link_to( fa_icon('copy lg', class: "dc-animate", title: "#{t('drgcms.doc_paste_title')}"),
43
37
  {controller: 'dc_common', action: 'paste_clipboard'}, target: 'iframe_cms') %>
@@ -61,16 +55,3 @@
61
55
 
62
56
  <% end %>
63
57
  </div>
64
-
65
-
66
- <% if false %>
67
- <%= javascript_tag do %>
68
- //
69
- $('#cmsedit-edit-button').click(function() {
70
- $('#iframe_cms').attr('src', $('#record_select').val() );
71
- });
72
- $('#record_select').change( function(e) {
73
- $('#iframe_cms').attr('src', e.target.value );
74
- });
75
- <% end %>
76
- <% end %>