scrivito_sdk 0.16.0 → 0.17.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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/scrivito/default_cms_controller.rb +3 -3
  3. data/app/controllers/scrivito/objs_controller.rb +18 -7
  4. data/app/controllers/scrivito/webservice_controller.rb +13 -1
  5. data/app/controllers/scrivito/workspaces_controller.rb +5 -1
  6. data/app/helpers/scrivito/cms_asset_helper.rb +8 -1
  7. data/app/helpers/scrivito/default_cms_routing_helper.rb +2 -4
  8. data/app/helpers/scrivito/display_helper.rb +0 -7
  9. data/app/helpers/scrivito/editing_helper.rb +10 -8
  10. data/app/helpers/scrivito/layout_helper.rb +4 -11
  11. data/config/ca-bundle.crt +1773 -1416
  12. data/config/cms_routes.rb +2 -2
  13. data/config/routes.rb +1 -0
  14. data/lib/assets/javascripts/scrivito_editing.js +969 -533
  15. data/lib/assets/stylesheets/scrivito_editing.css +99 -9
  16. data/lib/generators/cms/migration/templates/migration.erb +34 -6
  17. data/lib/generators/cms/widget/templates/migration.erb +3 -6
  18. data/lib/scrivito/attribute.rb +158 -0
  19. data/lib/scrivito/attribute_collection.rb +72 -0
  20. data/lib/scrivito/attribute_content.rb +39 -3
  21. data/lib/scrivito/basic_obj.rb +48 -27
  22. data/lib/scrivito/basic_widget.rb +15 -5
  23. data/lib/scrivito/client_config.rb +46 -19
  24. data/lib/scrivito/cms_field_tag.rb +1 -1
  25. data/lib/scrivito/cms_rest_api/attribute_serializer.rb +6 -1
  26. data/lib/scrivito/cms_rest_api/blob_uploader.rb +1 -1
  27. data/lib/scrivito/configuration.rb +32 -2
  28. data/lib/scrivito/connection_manager.rb +1 -6
  29. data/lib/scrivito/content_conversion.rb +11 -7
  30. data/lib/scrivito/editing_context.rb +12 -0
  31. data/lib/scrivito/gem_info.rb +13 -0
  32. data/lib/scrivito/membership.rb +26 -0
  33. data/lib/scrivito/memberships_collection.rb +78 -0
  34. data/lib/scrivito/migrations/migration.rb +1 -1
  35. data/lib/scrivito/migrations/migration_dsl.rb +37 -0
  36. data/lib/scrivito/obj_class.rb +282 -0
  37. data/lib/scrivito/obj_data.rb +20 -1
  38. data/lib/scrivito/obj_params_parser.rb +2 -0
  39. data/lib/scrivito/obj_search_builder.rb +1 -1
  40. data/lib/scrivito/obj_search_enumerator.rb +11 -6
  41. data/lib/scrivito/objs_collection.rb +130 -0
  42. data/lib/scrivito/restriction_set.rb +54 -0
  43. data/lib/scrivito/user.rb +114 -0
  44. data/lib/scrivito/user_definition.rb +159 -0
  45. data/lib/scrivito/widget_garbage_collection.rb +4 -4
  46. data/lib/scrivito/workspace.rb +13 -78
  47. data/lib/scrivito/workspace_data_from_service.rb +2 -0
  48. metadata +15 -5
@@ -450,16 +450,16 @@ html.scrivito_bottombar_on {
450
450
  line-height: 15px;
451
451
  color: #eee;
452
452
  }
453
- .scrivito_menu_box .scrivito_menu_item.disabled span:hover,
454
- .scrivito_menu_box .scrivito_menu_item.disabled a:hover {
453
+ .scrivito_menu_box .scrivito_menu_item.scrivito_disabled span:hover,
454
+ .scrivito_menu_box .scrivito_menu_item.scrivito_disabled a:hover {
455
455
  cursor: help;
456
456
  color: #696969!important;
457
457
  background: #274324;
458
458
  }
459
- .scrivito_menu_box .scrivito_menu_item.disabled span,
460
- .scrivito_menu_box .scrivito_menu_item.disabled a,
461
- .scrivito_menu_box .scrivito_menu_item.disabled span .scrivito_icon,
462
- .scrivito_menu_box .scrivito_menu_item.disabled a .scrivito_icon {
459
+ .scrivito_menu_box .scrivito_menu_item.scrivito_disabled span,
460
+ .scrivito_menu_box .scrivito_menu_item.scrivito_disabled a,
461
+ .scrivito_menu_box .scrivito_menu_item.scrivito_disabled span .scrivito_icon,
462
+ .scrivito_menu_box .scrivito_menu_item.scrivito_disabled a .scrivito_icon {
463
463
  color: #696969!important;
464
464
  cursor: help;
465
465
  }
@@ -653,6 +653,11 @@ body.scrivito_editing_active {
653
653
  -moz-transition: box-shadow linear .5s;
654
654
  -o-transition: box-shadow linear .5s;
655
655
  transition: box-shadow linear .5s;
656
+ -webkit-transform: translate3d(0, 0, 0);
657
+ -moz-transform: translate3d(0, 0, 0);
658
+ -ms-transform: translate3d(0, 0, 0);
659
+ -o-transform: translate3d(0, 0, 0);
660
+ transform: translate3d(0, 0, 0);
656
661
  }
657
662
  .scrivito_topbar .scrivito_first_level .scrivito_button_bar:hover,
658
663
  .scrivito_topbar .scrivito_first_level .scrivito_button_bar:focus,
@@ -697,6 +702,11 @@ body.scrivito_editing_active {
697
702
  -moz-transition: box-shadow linear .5s;
698
703
  -o-transition: box-shadow linear .5s;
699
704
  transition: box-shadow linear .5s;
705
+ -webkit-transform: translate3d(0, 0, 0);
706
+ -moz-transform: translate3d(0, 0, 0);
707
+ -ms-transform: translate3d(0, 0, 0);
708
+ -o-transform: translate3d(0, 0, 0);
709
+ transform: translate3d(0, 0, 0);
700
710
  }
701
711
  .scrivito_topbar .scrivito_second_level .scrivito_separator {
702
712
  display: block;
@@ -788,6 +798,11 @@ body.scrivito_editing_active {
788
798
  -moz-transition: all ease-in-out .4s;
789
799
  -o-transition: all ease-in-out .4s;
790
800
  transition: all ease-in-out .4s;
801
+ -webkit-transform: translate3d(0, 0, 0);
802
+ -moz-transform: translate3d(0, 0, 0);
803
+ -ms-transform: translate3d(0, 0, 0);
804
+ -o-transform: translate3d(0, 0, 0);
805
+ transform: translate3d(0, 0, 0);
791
806
  }
792
807
  .scrivito_viewmodes_wrapper.disable_trasitions .scrivito_viewmodes .scrivito_viewmode_pill {
793
808
  -webkit-transition: none;
@@ -887,8 +902,12 @@ body.scrivito_editing_active {
887
902
  font-size: 7px;
888
903
  color: #ddd;
889
904
  }
890
- .scrivito_menu_box.scrivito_switch_mode_menu {
905
+ .scrivito_viewmodes .scrivito_viewmode_label .scrivito_menu_box {
891
906
  left: 18px;
907
+ top: 10px;
908
+ }
909
+ #scrivito_current_page_menu .scrivito_menu_box {
910
+ top: 20px;
892
911
  }
893
912
  .scrivito_editing_confirmation {
894
913
  display: none;
@@ -945,6 +964,11 @@ body.scrivito_editing_active {
945
964
  -moz-transition: background ease-in-out .6s;
946
965
  -o-transition: background ease-in-out .6s;
947
966
  transition: background ease-in-out .6s;
967
+ -webkit-transform: translate3d(0, 0, 0);
968
+ -moz-transform: translate3d(0, 0, 0);
969
+ -ms-transform: translate3d(0, 0, 0);
970
+ -o-transform: translate3d(0, 0, 0);
971
+ transform: translate3d(0, 0, 0);
948
972
  }
949
973
  .scrivito_editing_marker:hover,
950
974
  .scrivito_editing_marker:active {
@@ -953,6 +977,11 @@ body.scrivito_editing_active {
953
977
  -moz-transition: background ease-in-out .2s;
954
978
  -o-transition: background ease-in-out .2s;
955
979
  transition: background ease-in-out .2s;
980
+ -webkit-transform: translate3d(0, 0, 0);
981
+ -moz-transform: translate3d(0, 0, 0);
982
+ -ms-transform: translate3d(0, 0, 0);
983
+ -o-transform: translate3d(0, 0, 0);
984
+ transform: translate3d(0, 0, 0);
956
985
  }
957
986
  .scrivito_editing_marker .scrivito_icon {
958
987
  padding: 0;
@@ -1004,6 +1033,11 @@ body.scrivito_editing_active {
1004
1033
  -moz-transition: opacity ease-in-out .4s;
1005
1034
  -o-transition: opacity ease-in-out .4s;
1006
1035
  transition: opacity ease-in-out .4s;
1036
+ -webkit-transform: translate3d(0, 0, 0);
1037
+ -moz-transform: translate3d(0, 0, 0);
1038
+ -ms-transform: translate3d(0, 0, 0);
1039
+ -o-transform: translate3d(0, 0, 0);
1040
+ transform: translate3d(0, 0, 0);
1007
1041
  pointer-events: none;
1008
1042
  }
1009
1043
  [data-scrivito-display-mode="editing"] [data-scrivito-private-child-list-path].scrivito_entered:hover > .scrivito_editing_marker .scrivito_editing_marker_title,
@@ -1016,6 +1050,11 @@ body.scrivito_editing_active {
1016
1050
  -moz-transition: opacity ease-in-out .4s;
1017
1051
  -o-transition: opacity ease-in-out .4s;
1018
1052
  transition: opacity ease-in-out .4s;
1053
+ -webkit-transform: translate3d(0, 0, 0);
1054
+ -moz-transform: translate3d(0, 0, 0);
1055
+ -ms-transform: translate3d(0, 0, 0);
1056
+ -o-transform: translate3d(0, 0, 0);
1057
+ transform: translate3d(0, 0, 0);
1019
1058
  }
1020
1059
  .scrivito_structure_marker {
1021
1060
  display: block;
@@ -1044,6 +1083,11 @@ body.scrivito_editing_active {
1044
1083
  -moz-transition: background ease-in-out .6s;
1045
1084
  -o-transition: background ease-in-out .6s;
1046
1085
  transition: background ease-in-out .6s;
1086
+ -webkit-transform: translate3d(0, 0, 0);
1087
+ -moz-transform: translate3d(0, 0, 0);
1088
+ -ms-transform: translate3d(0, 0, 0);
1089
+ -o-transform: translate3d(0, 0, 0);
1090
+ transform: translate3d(0, 0, 0);
1047
1091
  }
1048
1092
  .scrivito_structure_marker:hover,
1049
1093
  .scrivito_structure_marker:active {
@@ -1053,6 +1097,11 @@ body.scrivito_editing_active {
1053
1097
  -moz-transition: background ease-in-out .2s;
1054
1098
  -o-transition: background ease-in-out .2s;
1055
1099
  transition: background ease-in-out .2s;
1100
+ -webkit-transform: translate3d(0, 0, 0);
1101
+ -moz-transform: translate3d(0, 0, 0);
1102
+ -ms-transform: translate3d(0, 0, 0);
1103
+ -o-transform: translate3d(0, 0, 0);
1104
+ transform: translate3d(0, 0, 0);
1056
1105
  }
1057
1106
  .scrivito_structure_marker .scrivito_icon {
1058
1107
  padding: 0;
@@ -1222,16 +1271,26 @@ a.scrivito_button:active {
1222
1271
  -moz-transition: opacity 0.1s linear;
1223
1272
  -o-transition: opacity 0.1s linear;
1224
1273
  transition: opacity 0.1s linear;
1274
+ -webkit-transform: translate3d(0, 0, 0);
1275
+ -moz-transform: translate3d(0, 0, 0);
1276
+ -ms-transform: translate3d(0, 0, 0);
1277
+ -o-transform: translate3d(0, 0, 0);
1278
+ transform: translate3d(0, 0, 0);
1225
1279
  background: rgba(0, 0, 0, 0.8);
1226
1280
  }
1227
1281
  .scrivito_overlay.scrivito_show {
1228
- z-index: 222222;
1282
+ z-index: 333333;
1229
1283
  opacity: 0.85;
1230
1284
  filter: alpha(opacity=85);
1231
1285
  -webkit-transition: opacity 0.6s linear;
1232
1286
  -moz-transition: opacity 0.6s linear;
1233
1287
  -o-transition: opacity 0.6s linear;
1234
1288
  transition: opacity 0.6s linear;
1289
+ -webkit-transform: translate3d(0, 0, 0);
1290
+ -moz-transform: translate3d(0, 0, 0);
1291
+ -ms-transform: translate3d(0, 0, 0);
1292
+ -o-transform: translate3d(0, 0, 0);
1293
+ transform: translate3d(0, 0, 0);
1235
1294
  }
1236
1295
  .scrivito_overlay .scrivito_processing {
1237
1296
  display: block;
@@ -1563,7 +1622,7 @@ a.scrivito_button:active {
1563
1622
  position: fixed;
1564
1623
  left: 50%;
1565
1624
  top: -100%;
1566
- z-index: 1000;
1625
+ z-index: 333333;
1567
1626
  overflow: auto;
1568
1627
  color: #fff;
1569
1628
  width: 500px;
@@ -1580,6 +1639,11 @@ a.scrivito_button:active {
1580
1639
  -moz-transition: all 0.45s ease-in;
1581
1640
  -o-transition: all 0.45s ease-in;
1582
1641
  transition: all 0.45s ease-in;
1642
+ -webkit-transform: translate3d(0, 0, 0);
1643
+ -moz-transform: translate3d(0, 0, 0);
1644
+ -ms-transform: translate3d(0, 0, 0);
1645
+ -o-transform: translate3d(0, 0, 0);
1646
+ transform: translate3d(0, 0, 0);
1583
1647
  }
1584
1648
  .scrivito_modal_prompt.scrivito_show {
1585
1649
  top: 50%;
@@ -1667,6 +1731,11 @@ a.scrivito_button:active {
1667
1731
  -moz-transition: all 0.25s ease-in;
1668
1732
  -o-transition: all 0.25s ease-in;
1669
1733
  transition: all 0.25s ease-in;
1734
+ -webkit-transform: translate3d(0, 0, 0);
1735
+ -moz-transform: translate3d(0, 0, 0);
1736
+ -ms-transform: translate3d(0, 0, 0);
1737
+ -o-transform: translate3d(0, 0, 0);
1738
+ transform: translate3d(0, 0, 0);
1670
1739
  }
1671
1740
  .scrivito_modal_small {
1672
1741
  width: 500px;
@@ -1812,6 +1881,12 @@ a.scrivito_button:active {
1812
1881
  vertical-align: middle;
1813
1882
  line-height: 14px;
1814
1883
  }
1884
+ .scrivito_details_dialog .scrivito_modal_header .scrivito_saving_state_bar {
1885
+ right: 50px;
1886
+ }
1887
+ .scrivito_details_dialog .scrivito_modal_header .scrivito_menu_box {
1888
+ top: 20px;
1889
+ }
1815
1890
  .scrivito_changes_overview.scrivito_modal_large .scrivito_modal_header select {
1816
1891
  font-weight: normal;
1817
1892
  border: 0px;
@@ -2147,6 +2222,11 @@ a.scrivito_button:active {
2147
2222
  -moz-transition: all ease-in-out .3s;
2148
2223
  -o-transition: all ease-in-out .3s;
2149
2224
  transition: all ease-in-out .3s;
2225
+ -webkit-transform: translate3d(0, 0, 0);
2226
+ -moz-transform: translate3d(0, 0, 0);
2227
+ -ms-transform: translate3d(0, 0, 0);
2228
+ -o-transform: translate3d(0, 0, 0);
2229
+ transform: translate3d(0, 0, 0);
2150
2230
  -webkit-border-radius: 5px;
2151
2231
  -moz-border-radius: 5px;
2152
2232
  border-radius: 5px;
@@ -2161,6 +2241,11 @@ a.scrivito_button:active {
2161
2241
  -moz-transition: all ease-in-out .3s;
2162
2242
  -o-transition: all ease-in-out .3s;
2163
2243
  transition: all ease-in-out .3s;
2244
+ -webkit-transform: translate3d(0, 0, 0);
2245
+ -moz-transform: translate3d(0, 0, 0);
2246
+ -ms-transform: translate3d(0, 0, 0);
2247
+ -o-transform: translate3d(0, 0, 0);
2248
+ transform: translate3d(0, 0, 0);
2164
2249
  }
2165
2250
  .scrivito_editing_widget_preview:active,
2166
2251
  .scrivito_editing_widget_preview.selected {
@@ -2173,6 +2258,11 @@ a.scrivito_button:active {
2173
2258
  -moz-transition: all ease-in-out .3s;
2174
2259
  -o-transition: all ease-in-out .3s;
2175
2260
  transition: all ease-in-out .3s;
2261
+ -webkit-transform: translate3d(0, 0, 0);
2262
+ -moz-transform: translate3d(0, 0, 0);
2263
+ -ms-transform: translate3d(0, 0, 0);
2264
+ -o-transform: translate3d(0, 0, 0);
2265
+ transform: translate3d(0, 0, 0);
2176
2266
  }
2177
2267
  .scrivito_editing_widget_preview .scrivito_editing_widget_visualization {
2178
2268
  height: 120px;
@@ -1,10 +1,38 @@
1
1
  class <%= class_name %> < ::Scrivito::Migration
2
2
  def up
3
- # get_obj_class('Test')
4
- # create_obj_class(name: 'Test', type: :publication, attributes: [])
5
- # update_obj_class('Test', title: 'Test Title')
6
- # add_attribute_to('Test', { name: 'test', type: 'string' })
7
- # update_attribute_for('Test', 'test', { title: 'New Title' })
8
- # delete_attribute_from('Test', 'test')
3
+ # This migration file allows to create and modify object class definitions or to change the CMS
4
+ # content programatically. All Scrivito SDK classes and methods are available and arbitrary Ruby
5
+ # code can be executed.
6
+ #
7
+ # Use `bundle exec rake cms:migrate` to run all migrations that are new to the `rtc` workspace.
8
+ # Migrations are identified by an ID and only get executed once. If you migrate the CMS an
9
+ # existing `rtc` workspace is used or a new `rtc` workspace is created. Only one developer at a
10
+ # time can run migrations, which means to quickly try to publish the current migrations.
11
+ #
12
+ # Use `bundle exec rake cms:migrate:publish` to publish your `rtc` workspace that holds the
13
+ # latest unpublished migrations.
14
+ #
15
+ # To get you started, here is a list of the most common SDK methods to alter the CMS content.
16
+ #
17
+ # @example Create a new obj class named "Homepage" of type "publication" that has a "string" attribute named "locale".
18
+ # Scrivito::ObjClass.create(name: 'Homepage', type: :publication, attributes: [
19
+ # {name: 'locale', type: :string}
20
+ # ])
21
+ #
22
+ # @example Find the obj class named "Homepage".
23
+ # Scrivito::ObjClass.find('Homepage')
24
+ #
25
+ # @example Update the "title" of an obj class named "Homepage".
26
+ # Scrivito::ObjClass.find('Homepage').update(title: 'Home')
27
+ #
28
+ # @example Add an "enum" attribute named "category" to the obj class named "Homepage".
29
+ # Scrivito::ObjClass.find('Homepage').attributes.add(name: 'category', type: :enum, values: %w(tech, social))
30
+ #
31
+ # @example Update the "category" attribute and add another value.
32
+ # attribute = Scrivito::ObjClass.find('Homepage').attributes['category']
33
+ # attribute.update(values: attribute.values << 'media')
34
+ #
35
+ # @example Destroy the attribute "category" from the obj class "Homepage".
36
+ # Scrivito::ObjClass.find('Homepage').attributes['category'].destroy
9
37
  end
10
38
  end
@@ -1,14 +1,11 @@
1
1
  class Create<%= class_name %> < ::Scrivito::Migration
2
2
  def up
3
- create_obj_class(
3
+ Scrivito::ObjClass.create(
4
4
  name: '<%= class_name %>',
5
- type: 'publication',
5
+ is_binary: false,
6
6
  title: '<%= class_name.underscore.humanize %>',
7
7
  # attributes: [
8
- # {
9
- # name: 'example',
10
- # type: :string,
11
- # },
8
+ # { name: 'example', type: :string },
12
9
  # ]
13
10
  )
14
11
  end
@@ -0,0 +1,158 @@
1
+ module Scrivito
2
+ # This class represents a CMS attribute. Attributes can be created, updated, deleted and all
3
+ # attribute properties can be read. Attributes are part of an
4
+ # {Scrivito::ObjClass} and therefore each attribute belongs to exactly
5
+ # one {Scrivito::ObjClass}. Most of the operations interact with the currently
6
+ # selected {Scrivito::Workspace}. Operations like +create+, +destroy+
7
+ # and +update+ need to be performed in the "rtc" workspace.
8
+ #
9
+ # @api public
10
+ class Attribute
11
+ include ModelIdentity
12
+
13
+ # Initializes a new attribute.
14
+ #
15
+ # @api public
16
+ #
17
+ # This allows you to set the different properties of an attribute by
18
+ # providing a Hash with the property names as keys and the values you want to set as values.
19
+ #
20
+ # @example Create a new attribute with name "locale" and type "string".
21
+ # Attribute.new(name: 'locale', type: :string)
22
+ #
23
+ # @example Create a new "enum" attribute named "category" and provide values.
24
+ # Attribute.new(name: 'category', type: :enum, values: %w(tech social))
25
+ #
26
+ # @param [Hash] properties
27
+ # @option properties [String] :name The name of the attribute.
28
+ # @option properties [String] :type The type of the attribute, can be +string+, +text+, +html+, +linklist+, +link+, +reference+, +referencelist+, +date+, +binary+, +widget+, +enum+ or +multienum+.
29
+ # @option properties [Array<String>] :values Possible values if the type is either +enum+ or +multienum+.
30
+ #
31
+ # @return [Scrivito::Attribute]
32
+ # @raise [Scrivito::ScrivitoError] Raised when no +properties+ are provided.
33
+ def initialize(properties)
34
+ raise ScrivitoError, 'Please provide a hash of Attribute properties.' unless properties
35
+
36
+ update_instance_properties(properties)
37
+ end
38
+
39
+ # Returns the name of this attribute.
40
+ # @api public
41
+ # @return [String]
42
+ def name
43
+ @name
44
+ end
45
+
46
+ # Returns the type of this attribute. The type is either +string+, +text+, +html+, +linklist+,
47
+ # +link+, +reference+, +referencelist+, +date+, +binary+, +widget+, +enum+ or +multienum+.
48
+ # @api public
49
+ # @return [String]
50
+ def type
51
+ @type
52
+ end
53
+
54
+ # Returns the values of this attribute, if it is of type +enum+ or +multienum+.
55
+ # @api public
56
+ # @return [Array<String>] values
57
+ def values
58
+ @values
59
+ end
60
+
61
+ # Returns the obj class this attribute belongs to.
62
+ # @api public
63
+ # @return [Scrivito::ObjClass]
64
+ attr_reader :obj_class
65
+
66
+ # Returns a unique identifier of this attribute. An attribute is unique by
67
+ # its +name+ and its +obj_class+. Implements the {Scrivito::ModelIdentity} interface.
68
+ # @return [Array]
69
+ def id
70
+ [name, obj_class]
71
+ end
72
+
73
+ # Binds this attribute to an obj class.
74
+ # @return [Scrivito::ObjClass]
75
+ attr_writer :obj_class
76
+
77
+ # Updates this attribute and persists the changes
78
+ # in the CMS on its obj class. The +obj_class+ and +name+ of this attribute can not be updated.
79
+ #
80
+ # @api public
81
+ #
82
+ # See {Attribute#initialize} for a detailed overview of what properties are allowed
83
+ # and how to set them.
84
+ #
85
+ # @example Change the +type+ of the "locale" attribute to "string".
86
+ # attribute = ObjClass.find('Homepage').attributes['locale']
87
+ # attribute.update(type: :string)
88
+ #
89
+ # @example Adding the value "sports" to the +enum+ attribute "category" on the "Homepage" obj class.
90
+ # attribute = ObjClass.find('Homepage').attributes['category']
91
+ # attribute.update(values: attribute.values << 'sports')
92
+ #
93
+ # @param [Hash] properties
94
+ #
95
+ # @return [nil]
96
+ # @raise [Scrivito::ScrivitoError] Raised when trying to change the +name+ or +obj_class+ property.
97
+ def update(properties)
98
+ properties = properties.with_indifferent_access
99
+
100
+ if properties.has_key?(:name)
101
+ raise ScrivitoError, "#{self.class} does not support changing its 'name'. Please remove" \
102
+ " the key from the properties."
103
+ end
104
+
105
+ properties = to_cms_rest_api.merge(properties)
106
+ update_instance_properties(properties)
107
+ obj_class.update(attributes: obj_class.attributes.to_a)
108
+
109
+ nil
110
+ end
111
+
112
+ # Destroys this attribute and persists the change in the CMS.
113
+ #
114
+ # @api public
115
+ #
116
+ # @example Remove the "locale" attribute from the "Homepage" obj class.
117
+ # ObjClass.find('Homepage').attributes['locale'].destroy
118
+ #
119
+ # @return [nil]
120
+ def destroy
121
+ obj_class.attributes.delete(self)
122
+ obj_class.update(attributes: obj_class.attributes.to_a)
123
+
124
+ nil
125
+ end
126
+
127
+ # Returns this attribute in the CMS REST API format.
128
+ #
129
+ # @return [Hash]
130
+ def to_cms_rest_api
131
+ data = {
132
+ name: name,
133
+ type: type,
134
+ }
135
+
136
+ if %w(enum multienum).include?(type)
137
+ data[:values] = values
138
+ end
139
+
140
+ data
141
+ end
142
+
143
+ private
144
+
145
+ # Updates the instance properties of this attribute with +properties+
146
+ # given in the CMS REST API format.
147
+ #
148
+ # @param [Hash] properties
149
+ # @return [void]
150
+ def update_instance_properties(properties)
151
+ properties = properties.with_indifferent_access
152
+
153
+ @name = properties[:name].to_s
154
+ @type = properties[:type].to_s
155
+ @values = (properties[:values] || []).map(&:to_s)
156
+ end
157
+ end
158
+ end