drg_cms 0.6.0.8 → 0.6.1.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +25 -10
- data/app/assets/javascripts/drg_cms/drg_cms.js +208 -81
- data/app/assets/stylesheets/drg_cms/drg_cms.css +298 -93
- data/app/assets/stylesheets/drg_cms/select-multiple.css +1 -1
- data/app/controllers/cmsedit_controller.rb +174 -167
- data/app/controllers/dc_application_controller.rb +230 -196
- data/app/controllers/dc_common_controller.rb +88 -50
- data/app/controls/dc_help_control.rb +138 -0
- data/app/controls/dc_report.rb +12 -16
- data/app/forms/all_options.yml +14 -5
- data/app/forms/cms_menu.yml +7 -1
- data/app/forms/dc_big_table.yml +0 -2
- data/app/forms/dc_big_table_value.yml +0 -2
- data/app/forms/dc_category.yml +2 -1
- data/app/forms/dc_design.yml +2 -2
- data/app/forms/dc_folder_permission.yml +0 -2
- data/app/forms/dc_help_1.yml +110 -0
- data/app/forms/dc_journal.yml +3 -1
- data/app/forms/dc_json_ld.yml +0 -3
- data/app/forms/dc_link.yml +1 -1
- data/app/forms/dc_menu.yml +8 -12
- data/app/forms/dc_menu_item.yml +2 -3
- data/app/forms/dc_page.yml +7 -2
- data/app/forms/dc_part.yml +1 -0
- data/app/forms/dc_piece.yml +1 -0
- data/app/forms/dc_policy.yml +2 -5
- data/app/forms/dc_poll.yml +13 -16
- data/app/forms/dc_seo.yml +1 -2
- data/app/forms/dc_simple_menu.yml +3 -2
- data/app/forms/dc_site.yml +5 -8
- data/app/forms/dc_user.yml +27 -11
- data/app/forms/dc_user_role.yml +3 -0
- data/app/helpers/cms_common_helper.rb +68 -4
- data/app/helpers/cms_edit_helper.rb +73 -55
- data/app/helpers/cms_helper.rb +70 -32
- data/app/helpers/cms_index_helper.rb +155 -102
- data/app/helpers/dc_application_helper.rb +132 -109
- data/app/models/concerns/dc_page_concern.rb +14 -4
- data/app/models/concerns/dc_piece_concern.rb +1 -1
- data/app/models/concerns/dc_policy_rule_concern.rb +20 -8
- data/app/models/concerns/dc_site_concern.rb +56 -44
- data/app/models/concerns/dc_user_concern.rb +58 -19
- data/app/models/dc_big_table.rb +2 -2
- data/app/models/dc_design.rb +29 -19
- data/app/models/dc_filter.rb +28 -22
- data/app/models/dc_key_value_store.rb +1 -0
- data/app/models/dc_permission.rb +19 -9
- data/app/models/dc_policy.rb +25 -14
- data/app/models/dc_policy_role.rb +22 -11
- data/app/models/dc_temp.rb +8 -1
- data/app/models/dc_user_role.rb +2 -2
- data/app/models/drgcms_form_fields/comment.rb +11 -2
- data/app/models/drgcms_form_fields/date_picker.rb +2 -0
- data/app/models/drgcms_form_fields/drgcms_field.rb +2 -1
- data/app/models/drgcms_form_fields/embedded.rb +9 -10
- data/app/models/drgcms_form_fields/file_field.rb +1 -1
- data/app/models/drgcms_form_fields/file_select.rb +2 -2
- data/app/models/drgcms_form_fields/hash_field.rb +11 -7
- data/app/models/drgcms_form_fields/link_to.rb +2 -2
- data/app/models/drgcms_form_fields/method.rb +5 -4
- data/app/models/drgcms_form_fields/multitext_autocomplete.rb +1 -1
- data/app/models/drgcms_form_fields/number_field.rb +4 -3
- data/app/models/drgcms_form_fields/readonly.rb +13 -17
- data/app/models/drgcms_form_fields/select.rb +24 -25
- data/app/models/drgcms_form_fields/text_autocomplete.rb +22 -14
- data/app/renderers/dc_page_renderer.rb +7 -6
- data/app/renderers/dc_poll_renderer.rb +16 -20
- data/app/views/cmsedit/_edit_stuff.html.erb +5 -2
- data/app/views/cmsedit/_form.html.erb +3 -2
- data/app/views/cmsedit/_result.html.erb +21 -18
- data/app/views/cmsedit/edit.html.erb +4 -1
- data/app/views/cmsedit/index.html.erb +3 -2
- data/app/views/cmsedit/new.html.erb +5 -2
- data/app/views/dc_common/_help.html.erb +17 -0
- data/app/views/layouts/models.html.erb +2 -1
- data/config/locales/drgcms_en.yml +17 -2
- data/config/locales/drgcms_sl.yml +20 -2
- data/config/locales/models_en.yml +7 -5
- data/config/locales/models_sl.yml +12 -9
- data/drg_cms.gemspec +16 -16
- data/lib/drg_cms/version.rb +1 -1
- data/lib/drg_cms.rb +94 -2
- metadata +32 -30
- data/app/models/__dc_dummy.rb +0 -102
@@ -0,0 +1,110 @@
|
|
1
|
+
## Form for creating help files
|
2
|
+
---
|
3
|
+
table: dc_temp
|
4
|
+
title: drgcms.dc_help.title
|
5
|
+
control: dc_help
|
6
|
+
|
7
|
+
index:
|
8
|
+
actions:
|
9
|
+
|
10
|
+
10:
|
11
|
+
type: field
|
12
|
+
name: select_project
|
13
|
+
field_type: select
|
14
|
+
caption: drgcms.dc_help.project
|
15
|
+
eval: DcHelpControl.choices_for_project
|
16
|
+
default:
|
17
|
+
eval: '@parent.session[:help_project]'
|
18
|
+
|
19
|
+
20:
|
20
|
+
type: field
|
21
|
+
name: lang_1
|
22
|
+
caption: drgcms.dc_help.lang
|
23
|
+
field_type: text_with_select
|
24
|
+
size: 5
|
25
|
+
eval: DcHelpControl.choices_for_locales
|
26
|
+
default:
|
27
|
+
eval: '@parent.session[:help_lang]'
|
28
|
+
html:
|
29
|
+
placeholder: drgcms.dc_help.lang
|
30
|
+
|
31
|
+
50:
|
32
|
+
type: ajax
|
33
|
+
caption: drgcms.dc_help.project_refresh
|
34
|
+
title: drgcms.dc_help.project_refresh_title
|
35
|
+
icon: refresh
|
36
|
+
action: run
|
37
|
+
method: post
|
38
|
+
control: dc_help.project_refresh
|
39
|
+
|
40
|
+
60: new
|
41
|
+
|
42
|
+
result_set:
|
43
|
+
filter: data_filter
|
44
|
+
actions:
|
45
|
+
1: edit
|
46
|
+
columns:
|
47
|
+
10:
|
48
|
+
name: form_name
|
49
|
+
caption: drgcms.dc_help.form_name
|
50
|
+
width: 10%
|
51
|
+
20:
|
52
|
+
name: lang
|
53
|
+
caption: drgcms.dc_help.lang
|
54
|
+
width: 10%
|
55
|
+
30:
|
56
|
+
name: updated_at
|
57
|
+
caption: drgcms.dc_help.updated_at
|
58
|
+
width: 10%
|
59
|
+
format: T
|
60
|
+
|
61
|
+
form:
|
62
|
+
actions:
|
63
|
+
1: back
|
64
|
+
2: save
|
65
|
+
|
66
|
+
title:
|
67
|
+
edit: dc_help edit_title
|
68
|
+
show: dc_help show_title
|
69
|
+
|
70
|
+
tabs:
|
71
|
+
1basic:
|
72
|
+
caption: drgcms.dc_help.1basic
|
73
|
+
10:
|
74
|
+
name: project
|
75
|
+
type: readonly
|
76
|
+
size: 20
|
77
|
+
20:
|
78
|
+
name: form_name
|
79
|
+
caption: drgcms.dc_help.form_name
|
80
|
+
type: text_with_select
|
81
|
+
eval: DcHelpControl.choices_for_form_name(@parent.session)
|
82
|
+
size: 20
|
83
|
+
html:
|
84
|
+
minlength: 4
|
85
|
+
30:
|
86
|
+
name: lang
|
87
|
+
caption: drgcms.dc_help.lang
|
88
|
+
type: text_field
|
89
|
+
size: 2
|
90
|
+
html:
|
91
|
+
minlength: 2
|
92
|
+
maxlength: 2
|
93
|
+
|
94
|
+
2index:
|
95
|
+
caption: drgcms.dc_help.2index
|
96
|
+
10:
|
97
|
+
name: index
|
98
|
+
caption: false
|
99
|
+
line: top
|
100
|
+
type: html_field
|
101
|
+
options: "height: 600"
|
102
|
+
|
103
|
+
3form:
|
104
|
+
caption: drgcms.dc_help.3form
|
105
|
+
10:
|
106
|
+
name: form
|
107
|
+
caption: false
|
108
|
+
line: top
|
109
|
+
type: html_field
|
110
|
+
options: "height: 600"
|
data/app/forms/dc_journal.yml
CHANGED
data/app/forms/dc_json_ld.yml
CHANGED
data/app/forms/dc_link.yml
CHANGED
data/app/forms/dc_menu.yml
CHANGED
@@ -32,25 +32,21 @@ form:
|
|
32
32
|
10:
|
33
33
|
name: name
|
34
34
|
type: text_field
|
35
|
-
|
36
|
-
size: 20
|
35
|
+
size: 20
|
37
36
|
|
38
37
|
20:
|
39
38
|
name: description
|
40
39
|
type: text_field
|
41
|
-
|
42
|
-
size: 20
|
40
|
+
size: 20
|
43
41
|
|
44
42
|
30:
|
45
43
|
name: div_name
|
46
44
|
type: text_field
|
47
|
-
|
48
|
-
size: 20
|
45
|
+
size: 20
|
49
46
|
40:
|
50
47
|
name: link_prepend
|
51
48
|
type: text_field
|
52
|
-
|
53
|
-
size: 20
|
49
|
+
size: 20
|
54
50
|
50:
|
55
51
|
name: dc_site_id
|
56
52
|
type: select
|
@@ -62,13 +58,13 @@ form:
|
|
62
58
|
10:
|
63
59
|
name: dc_menu_items
|
64
60
|
type: embedded
|
61
|
+
caption: false
|
65
62
|
form_name: dc_menu_item
|
66
|
-
|
67
|
-
height: 1000
|
63
|
+
load: delay
|
68
64
|
|
69
65
|
tab3:
|
70
66
|
20:
|
71
67
|
name: css
|
68
|
+
caption: false
|
72
69
|
type: text_area
|
73
|
-
|
74
|
-
size: 100x50
|
70
|
+
size: 100x50
|
data/app/forms/dc_menu_item.yml
CHANGED
data/app/forms/dc_page.yml
CHANGED
@@ -99,6 +99,10 @@ form:
|
|
99
99
|
eval: DcDesign.choices4_design(@parent.dc_get_site)
|
100
100
|
html:
|
101
101
|
include_blank: true
|
102
|
+
15:
|
103
|
+
name: div_class
|
104
|
+
type: text_field
|
105
|
+
size: 20
|
102
106
|
|
103
107
|
20:
|
104
108
|
name: menu_id
|
@@ -143,16 +147,17 @@ form:
|
|
143
147
|
3content:
|
144
148
|
10:
|
145
149
|
name: body
|
150
|
+
caption: false
|
146
151
|
type: html_field
|
147
152
|
options: 'height: 1000'
|
148
153
|
|
149
154
|
4parts:
|
150
155
|
10:
|
151
156
|
name: dc_parts
|
157
|
+
caption: false
|
152
158
|
type: embedded
|
153
159
|
form_name: dc_part
|
154
|
-
|
155
|
-
height: 600
|
160
|
+
load: delay
|
156
161
|
|
157
162
|
5iframe:
|
158
163
|
10:
|
data/app/forms/dc_part.yml
CHANGED
data/app/forms/dc_piece.yml
CHANGED
data/app/forms/dc_policy.yml
CHANGED
data/app/forms/dc_poll.yml
CHANGED
@@ -37,14 +37,12 @@ form:
|
|
37
37
|
10:
|
38
38
|
name: name
|
39
39
|
type: text_field
|
40
|
-
|
41
|
-
size: 50
|
40
|
+
size: 50
|
42
41
|
|
43
42
|
20:
|
44
43
|
name: title
|
45
44
|
type: text_field
|
46
|
-
|
47
|
-
size: 50
|
45
|
+
size: 50
|
48
46
|
|
49
47
|
30:
|
50
48
|
name: sub_text
|
@@ -54,8 +52,7 @@ form:
|
|
54
52
|
35:
|
55
53
|
name: pre_display
|
56
54
|
type: text_field
|
57
|
-
|
58
|
-
size: 50
|
55
|
+
size: 50
|
59
56
|
40:
|
60
57
|
name: operation
|
61
58
|
type: select
|
@@ -63,8 +60,7 @@ form:
|
|
63
60
|
50:
|
64
61
|
name: parameters
|
65
62
|
type: text_field
|
66
|
-
|
67
|
-
size: 50
|
63
|
+
size: 50
|
68
64
|
|
69
65
|
60:
|
70
66
|
name: display
|
@@ -73,8 +69,7 @@ form:
|
|
73
69
|
70:
|
74
70
|
name: captcha_type
|
75
71
|
type: text_field
|
76
|
-
|
77
|
-
size: 10
|
72
|
+
size: 10
|
78
73
|
|
79
74
|
80:
|
80
75
|
name: valid_from
|
@@ -92,8 +87,7 @@ form:
|
|
92
87
|
100:
|
93
88
|
name: css
|
94
89
|
type: text_area
|
95
|
-
|
96
|
-
size: 100x20
|
90
|
+
size: 100x20
|
97
91
|
|
98
92
|
110:
|
99
93
|
name: active
|
@@ -102,20 +96,23 @@ form:
|
|
102
96
|
10:
|
103
97
|
name: js
|
104
98
|
type: text_area
|
99
|
+
caption: false
|
100
|
+
size: 100x50
|
105
101
|
html:
|
106
|
-
size: 100x50
|
107
102
|
style: 'font-family:courier;'
|
108
103
|
tab3:
|
109
104
|
20:
|
110
105
|
name: dc_poll_items
|
106
|
+
caption: false
|
111
107
|
type: embedded
|
112
108
|
form_name: dc_poll_item
|
113
|
-
|
114
|
-
|
109
|
+
load: delay
|
110
|
+
|
115
111
|
tab4:
|
116
112
|
10:
|
117
113
|
name: form
|
114
|
+
caption: false
|
118
115
|
type: text_area
|
116
|
+
size: 100x50
|
119
117
|
html:
|
120
|
-
size: 100x50
|
121
118
|
style: 'font-family:courier;'
|
data/app/forms/dc_seo.yml
CHANGED
@@ -61,13 +61,14 @@ form:
|
|
61
61
|
10:
|
62
62
|
name: dc_simple_menu_items
|
63
63
|
type: embedded
|
64
|
+
caption: false
|
64
65
|
form_name: dc_simple_menu_item
|
65
|
-
|
66
|
-
height: 800
|
66
|
+
load: delay
|
67
67
|
|
68
68
|
tab3:
|
69
69
|
20:
|
70
70
|
name: css
|
71
|
+
caption: false
|
71
72
|
type: text_area
|
72
73
|
size: 100x50
|
73
74
|
|
data/app/forms/dc_site.yml
CHANGED
@@ -132,8 +132,7 @@ form:
|
|
132
132
|
type: text_area
|
133
133
|
size: 130x40
|
134
134
|
|
135
|
-
5permissions:
|
136
|
-
|
135
|
+
5permissions:
|
137
136
|
10:
|
138
137
|
name: inherit_policy
|
139
138
|
type: select
|
@@ -143,15 +142,13 @@ form:
|
|
143
142
|
20:
|
144
143
|
name: dc_policies
|
145
144
|
type: embedded
|
145
|
+
caption: false
|
146
146
|
form_name: dc_policy
|
147
|
-
|
148
|
-
|
147
|
+
load: delay
|
148
|
+
|
149
149
|
6parts:
|
150
150
|
10:
|
151
151
|
name: dc_parts
|
152
|
+
caption: false
|
152
153
|
type: embedded
|
153
154
|
form_name: dc_part
|
154
|
-
html:
|
155
|
-
height: 1000
|
156
|
-
|
157
|
-
|
data/app/forms/dc_user.yml
CHANGED
@@ -22,8 +22,9 @@ result_set:
|
|
22
22
|
name: last_name
|
23
23
|
width: 20%
|
24
24
|
4:
|
25
|
-
name:
|
26
|
-
|
25
|
+
name: active
|
26
|
+
eval: dc_icon4_boolean
|
27
|
+
width: 5%
|
27
28
|
|
28
29
|
form:
|
29
30
|
title:
|
@@ -32,12 +33,18 @@ form:
|
|
32
33
|
actions: standard
|
33
34
|
|
34
35
|
tabs:
|
35
|
-
|
36
|
+
1base:
|
36
37
|
|
37
38
|
10:
|
38
39
|
name: username
|
39
40
|
type: text_field
|
40
41
|
size: 10
|
42
|
+
group: 2
|
43
|
+
html:
|
44
|
+
autocomplete: 'off'
|
45
|
+
15:
|
46
|
+
name: group
|
47
|
+
type: check_box
|
41
48
|
20:
|
42
49
|
name: title
|
43
50
|
type: text_field
|
@@ -45,7 +52,8 @@ form:
|
|
45
52
|
30:
|
46
53
|
name: first_name
|
47
54
|
type: text_field
|
48
|
-
size:
|
55
|
+
size: 30
|
56
|
+
group: 3
|
49
57
|
|
50
58
|
40:
|
51
59
|
name: middle_name
|
@@ -65,12 +73,13 @@ form:
|
|
65
73
|
70:
|
66
74
|
name: address
|
67
75
|
type: text_field
|
68
|
-
size:
|
76
|
+
size: 30
|
77
|
+
group: 2
|
69
78
|
|
70
79
|
80:
|
71
80
|
name: post
|
72
81
|
type: text_field
|
73
|
-
size:
|
82
|
+
size: 30
|
74
83
|
|
75
84
|
90:
|
76
85
|
name: country
|
@@ -81,11 +90,12 @@ form:
|
|
81
90
|
name: email
|
82
91
|
type: text_field
|
83
92
|
size: 30
|
93
|
+
group: 2
|
84
94
|
|
85
95
|
110:
|
86
96
|
name: phone
|
87
97
|
type: text_field
|
88
|
-
size:
|
98
|
+
size: 20
|
89
99
|
|
90
100
|
120:
|
91
101
|
name: birthdate
|
@@ -101,12 +111,16 @@ form:
|
|
101
111
|
140:
|
102
112
|
name: about
|
103
113
|
type: text_area
|
104
|
-
size:
|
114
|
+
size: 100x5
|
105
115
|
|
106
116
|
150:
|
107
117
|
name: password
|
108
118
|
type: password_field
|
109
119
|
size: 20
|
120
|
+
group: 2
|
121
|
+
line: top
|
122
|
+
html:
|
123
|
+
autocomplete: 'off'
|
110
124
|
|
111
125
|
160:
|
112
126
|
name: password_confirmation
|
@@ -120,6 +134,8 @@ form:
|
|
120
134
|
size: 20
|
121
135
|
|
122
136
|
180:
|
123
|
-
name:
|
124
|
-
type:
|
125
|
-
|
137
|
+
name: member
|
138
|
+
type: select
|
139
|
+
multiple: true
|
140
|
+
eval: DcUser.groups_for_select
|
141
|
+
size: 30
|
data/app/forms/dc_user_role.yml
CHANGED
@@ -44,7 +44,7 @@ module CmsCommonHelper
|
|
44
44
|
# Returns:
|
45
45
|
# String. Translated text.
|
46
46
|
####################################################################
|
47
|
-
def self.t(key, default=nil)
|
47
|
+
def self.t(key, default=nil)
|
48
48
|
c = I18n.t(key)
|
49
49
|
if c.class == Hash or c.match( 'translation missing' )
|
50
50
|
c = I18n.t(key, locale: 'en')
|
@@ -194,12 +194,13 @@ end
|
|
194
194
|
############################################################################
|
195
195
|
def dc_name_for_id(model, field, field_name, id=nil)
|
196
196
|
return '' if id.nil?
|
197
|
+
|
197
198
|
field_name = (field_name || 'id').strip.to_sym
|
198
199
|
field = field.strip.to_sym
|
199
|
-
|
200
200
|
model = model.strip.classify.constantize if model.class == String
|
201
|
-
|
202
|
-
|
201
|
+
doc = Mongoid::QueryCache.cache { model.find_by(field_name => id) }
|
202
|
+
|
203
|
+
doc.nil? ? '' : (doc.send(field) rescue 'not defined')
|
203
204
|
end
|
204
205
|
|
205
206
|
############################################################################
|
@@ -255,6 +256,13 @@ def self.dc_format_date_time(value, format=nil)
|
|
255
256
|
value.strftime(format)
|
256
257
|
end
|
257
258
|
|
259
|
+
############################################################################
|
260
|
+
# Returns html code for displaying date/time formatted by strftime. Will return '' if value is nil.
|
261
|
+
#
|
262
|
+
# Parameters:
|
263
|
+
# [value] Date/DateTime/Time.
|
264
|
+
# [format] String. strftime format mask. Defaults to locale's default format.
|
265
|
+
############################################################################
|
258
266
|
def dc_format_date_time(value, format=nil) #:nodoc:
|
259
267
|
CmsCommonHelper.dc_format_date_time(value, format)
|
260
268
|
end
|
@@ -304,8 +312,64 @@ def self.dc_format_number(value=0, decimals=nil, separator=nil, delimiter=nil, c
|
|
304
312
|
"#{sign}#{ar.reverse.join(delimiter)}#{separator}#{dec}"
|
305
313
|
end
|
306
314
|
|
315
|
+
############################################################################
|
316
|
+
# Returns html code for displaying formatted number.
|
317
|
+
#
|
318
|
+
# Parameters:
|
319
|
+
# [value] Numeric number.
|
320
|
+
# [decimals] Integer. Number of decimals
|
321
|
+
# [separator] String. Decimals separator
|
322
|
+
# [delimiter] String. Thousands delimiter.
|
323
|
+
# [currency] String. Currency symbol if applied to result string.
|
324
|
+
############################################################################
|
307
325
|
def dc_format_number(value=0, decimals=nil, separator=nil, delimiter=nil, currency=nil) #:nodoc:
|
308
326
|
CmsCommonHelper.dc_format_number(value, decimals, separator, delimiter, currency)
|
309
327
|
end
|
310
328
|
|
329
|
+
############################################################################
|
330
|
+
# Create help text for fields on single tab
|
331
|
+
############################################################################
|
332
|
+
def dc_help_for_tab(tab)
|
333
|
+
return '' if tab.nil?
|
334
|
+
|
335
|
+
html = ''
|
336
|
+
if tab.class == Array
|
337
|
+
tab_name = tab.last['caption'] || tab.first
|
338
|
+
tab_label, tab_help = dc_tab_label_help(tab_name)
|
339
|
+
html << %(<div class="help-tab">#{tab_label}</div><div class="help-tab-help">#{tab_help}</div>)
|
340
|
+
|
341
|
+
tab = tab.last
|
342
|
+
end
|
343
|
+
|
344
|
+
tab.each do |field|
|
345
|
+
label, help = dc_label_help(field.last)
|
346
|
+
next if help.blank?
|
347
|
+
|
348
|
+
html << %(<div class="help-field"><div class="help-label">#{label}</div><div class="help-text">#{help.gsub("\n",'<br>')}</div></div>)
|
349
|
+
end
|
350
|
+
html
|
351
|
+
end
|
352
|
+
|
353
|
+
############################################################################
|
354
|
+
# Will scoop fields and help text associated with them to create basic help text.
|
355
|
+
############################################################################
|
356
|
+
def dc_help_fields
|
357
|
+
return '' if @form['form'].nil?
|
358
|
+
|
359
|
+
html = '<a id="fields"></a>'
|
360
|
+
if @form['form']['tabs']
|
361
|
+
@form['form']['tabs'].each { |tab| html << dc_help_for_tab(tab) }
|
362
|
+
else
|
363
|
+
html << dc_help_for_tab(@form['form']['fields'])
|
364
|
+
end
|
365
|
+
html.html_safe
|
366
|
+
end
|
367
|
+
|
368
|
+
############################################################################
|
369
|
+
# Will return text from help files
|
370
|
+
############################################################################
|
371
|
+
def dc_help_body
|
372
|
+
(params[:type] == 'index' ? @help['index'] : @help['form']).html_safe
|
373
|
+
end
|
374
|
+
|
311
375
|
end
|