scrivito_sdk 0.18.1 → 0.30.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/controllers/scrivito/blobs_controller.rb +1 -2
- data/app/controllers/scrivito/default_cms_controller.rb +9 -75
- data/app/controllers/scrivito/objs_controller.rb +107 -119
- data/app/controllers/scrivito/tasks_controller.rb +1 -1
- data/app/controllers/scrivito/users_controller.rb +1 -1
- data/app/controllers/scrivito/webservice_controller.rb +6 -2
- data/app/controllers/scrivito/workspaces_controller.rb +57 -17
- data/app/helpers/scrivito_helper.rb +285 -0
- data/app/views/google_maps_widget/show.html.erb +1 -0
- data/app/views/scrivito/_editing_auth_warning.html.erb +43 -0
- data/app/views/scrivito/blobs/upload_permission.json.jbuilder +1 -0
- data/app/views/scrivito/objs/copy.json.jbuilder +1 -0
- data/app/views/scrivito/objs/copy_widget.html.erb +1 -1
- data/app/views/scrivito/objs/create.json.jbuilder +1 -0
- data/app/views/scrivito/objs/create_widget.html.erb +1 -1
- data/app/views/scrivito/objs/details.json.jbuilder +1 -0
- data/app/views/scrivito/objs/format_missing_error.json.jbuilder +1 -0
- data/app/views/scrivito/objs/modification.json.jbuilder +1 -0
- data/app/views/scrivito/objs/page_class_selection.json.jbuilder +1 -0
- data/app/views/scrivito/objs/search.json.jbuilder +6 -0
- data/app/views/scrivito/objs/search_only_size.json.jbuilder +1 -0
- data/app/views/scrivito/objs/update.json.jbuilder +1 -0
- data/app/views/scrivito/objs/widget_class_selection.json.jbuilder +1 -0
- data/app/views/scrivito/objs/widget_modification.json.jbuilder +1 -0
- data/app/views/scrivito/tasks/show.json.jbuilder +3 -0
- data/app/views/scrivito/users/suggest.json.jbuilder +1 -0
- data/app/views/scrivito/webservice/empty.json +1 -0
- data/app/views/scrivito/webservice/error.json.jbuilder +2 -0
- data/app/views/scrivito/workspaces/_workspace.json.jbuilder +5 -0
- data/app/views/scrivito/workspaces/check.json.jbuilder +1 -0
- data/app/views/scrivito/workspaces/create.json.jbuilder +1 -0
- data/app/views/scrivito/workspaces/index.json.jbuilder +1 -0
- data/app/views/scrivito/workspaces/show.json.jbuilder +1 -0
- data/app/views/scrivito/workspaces/task.json.jbuilder +5 -0
- data/config/ca-bundle.crt +259 -234
- data/config/cms_routes.rb +2 -2
- data/config/routes.rb +3 -0
- data/lib/assets/javascripts/{scrivito_editing.js → scrivito_sdk.js} +1662 -1180
- data/lib/assets/stylesheets/{scrivito_editing.css → scrivito_sdk.css} +242 -6
- data/lib/generators/scrivito/install/install_generator.rb +62 -0
- data/lib/generators/scrivito/install/templates/app/controllers/cms_controller.rb +3 -0
- data/lib/generators/scrivito/install/templates/app/controllers/page_controller.rb +2 -0
- data/lib/generators/scrivito/install/templates/app/models/headline_widget.rb +7 -0
- data/lib/generators/scrivito/install/templates/app/models/image.rb +5 -0
- data/lib/generators/scrivito/install/templates/app/models/image_widget.rb +7 -0
- data/lib/generators/scrivito/install/templates/app/models/obj.rb +2 -0
- data/lib/generators/scrivito/install/templates/app/models/page.rb +8 -0
- data/lib/generators/scrivito/install/templates/app/models/text_widget.rb +7 -0
- data/lib/generators/scrivito/install/templates/app/models/widget.rb +2 -0
- data/lib/generators/scrivito/install/templates/app/views/headline_widget/show.html.erb +1 -0
- data/lib/generators/scrivito/install/templates/app/views/headline_widget/thumbnail.html.erb +3 -0
- data/lib/generators/scrivito/install/templates/app/views/image_widget/show.html.erb +1 -0
- data/lib/generators/scrivito/install/templates/app/views/image_widget/thumbnail.html.erb +3 -0
- data/lib/generators/scrivito/install/templates/app/views/page/details.html.erb +1 -0
- data/lib/generators/scrivito/install/templates/app/views/page/index.html.erb +16 -0
- data/lib/generators/scrivito/install/templates/app/views/page/thumbnail.html.erb +3 -0
- data/lib/generators/scrivito/install/templates/app/views/text_widget/show.html.erb +1 -0
- data/lib/generators/scrivito/install/templates/app/views/text_widget/thumbnail.html.erb +3 -0
- data/lib/generators/scrivito/install/templates/config/initializers/scrivito.rb +10 -0
- data/lib/generators/scrivito/install/templates/scrivito/migrate/install_scrivito.rb +49 -0
- data/lib/generators/scrivito/migration/USAGE +9 -0
- data/lib/generators/{cms → scrivito}/migration/migration_generator.rb +4 -9
- data/lib/generators/{cms → scrivito}/migration/templates/migration.erb +3 -3
- data/lib/generators/{cms → scrivito}/widget/templates/details.html.erb +0 -0
- data/lib/generators/{cms → scrivito}/widget/templates/migration.erb +0 -0
- data/lib/generators/{cms → scrivito}/widget/templates/model.erb +0 -0
- data/lib/generators/{cms → scrivito}/widget/templates/show.html.erb +0 -0
- data/lib/generators/scrivito/widget/templates/thumbnail.html.erb +3 -0
- data/lib/generators/{cms → scrivito}/widget/widget_generator.rb +3 -2
- data/lib/obj.rb +17 -3
- data/lib/scrivito/attribute_collection.rb +7 -12
- data/lib/scrivito/attribute_content.rb +31 -12
- data/lib/scrivito/basic_obj.rb +186 -96
- data/lib/scrivito/basic_widget.rb +25 -10
- data/lib/scrivito/binary.rb +75 -0
- data/lib/scrivito/cache_garbage_collector.rb +19 -4
- data/lib/scrivito/child_list_tag.rb +108 -0
- data/lib/scrivito/client_config.rb +2 -1
- data/lib/scrivito/client_error.rb +3 -2
- data/lib/scrivito/cms_backend.rb +81 -16
- data/lib/scrivito/cms_dispatch_controller.rb +7 -0
- data/lib/scrivito/cms_env.rb +0 -2
- data/lib/scrivito/cms_field_tag.rb +44 -35
- data/lib/scrivito/cms_rest_api.rb +23 -6
- data/lib/scrivito/cms_rest_api/attribute_serializer.rb +1 -1
- data/lib/scrivito/cms_routing.rb +120 -0
- data/lib/scrivito/configuration.rb +69 -58
- data/lib/scrivito/connection_manager.rb +30 -1
- data/lib/scrivito/content_service.rb +10 -7
- data/lib/scrivito/controller_actions.rb +108 -0
- data/lib/scrivito/diff.rb +30 -15
- data/lib/scrivito/editing_context.rb +4 -0
- data/lib/scrivito/editing_context_helper.rb +19 -0
- data/lib/scrivito/editing_context_middleware.rb +20 -1
- data/lib/scrivito/image_tag_helper.rb +44 -0
- data/lib/scrivito/layout_tags.rb +33 -0
- data/lib/scrivito/link.rb +4 -2
- data/lib/scrivito/membership.rb +0 -8
- data/lib/scrivito/migrations.rb +0 -1
- data/lib/scrivito/migrations/installer.rb +1 -1
- data/lib/scrivito/migrations/migration.rb +0 -2
- data/lib/scrivito/migrations/migrator.rb +2 -3
- data/lib/scrivito/obj_class.rb +64 -16
- data/lib/scrivito/obj_class_data.rb +4 -0
- data/lib/scrivito/obj_search_enumerator.rb +1 -1
- data/lib/scrivito/routing_helper.rb +42 -0
- data/lib/scrivito/{engine.rb → sdk_engine.rb} +15 -29
- data/lib/scrivito/tag_renderer.rb +40 -0
- data/lib/scrivito/test_request.rb +40 -0
- data/lib/scrivito/type_computer.rb +1 -6
- data/lib/scrivito/user.rb +33 -15
- data/lib/scrivito/user_definition.rb +34 -6
- data/lib/scrivito/widget_tag.rb +67 -0
- data/lib/scrivito/workspace.rb +12 -24
- data/lib/scrivito_sdk.rb +17 -1
- data/lib/tasks/cache.rake +4 -5
- data/lib/tasks/migration.rake +1 -1
- data/lib/widget.rb +21 -3
- metadata +119 -70
- data/README +0 -6
- data/app/controllers/cms_controller.rb +0 -7
- data/app/helpers/cms_helper.rb +0 -7
- data/app/helpers/cms_routing_helper.rb +0 -7
- data/app/helpers/scrivito/cms_asset_helper.rb +0 -110
- data/app/helpers/scrivito/cms_tag_helper.rb +0 -232
- data/app/helpers/scrivito/default_cms_helper.rb +0 -21
- data/app/helpers/scrivito/default_cms_routing_helper.rb +0 -128
- data/app/helpers/scrivito/display_helper.rb +0 -64
- data/app/helpers/scrivito/editing_helper.rb +0 -32
- data/app/helpers/scrivito/layout_helper.rb +0 -21
- data/app/models/named_link.rb +0 -2
- data/app/views/cms/_index.html.erb +0 -7
- data/app/views/cms/index.html.erb +0 -1
- data/app/views/scrivito/_editing_javascript.html.erb +0 -7
- data/app/views/scrivito/default_cms/show_widget.html.erb +0 -1
- data/lib/assets/stylesheets/scrivito.css +0 -199
- data/lib/generators/cms/migration/USAGE +0 -9
- data/lib/generators/cms/widget/templates/thumbnail.html.erb +0 -2
- data/lib/scrivito/blob.rb +0 -48
- data/lib/scrivito/cms_accessible.rb +0 -30
- data/lib/scrivito/cms_rest_api/blob_uploader.rb +0 -18
- data/lib/scrivito/cms_test_request.rb +0 -23
- data/lib/scrivito/migrations/migration_dsl.rb +0 -180
@@ -0,0 +1 @@
|
|
1
|
+
<%= scrivito_tag :div, widget, :text %>
|
@@ -0,0 +1,10 @@
|
|
1
|
+
Scrivito.configure do |config|
|
2
|
+
#
|
3
|
+
# Uncomment following lines in order to explicitly set the tenant and the API key.
|
4
|
+
# If not explicitly set, the tenant and the API key are obtained from the environment variables
|
5
|
+
# SCRIVITO_TENANT and SCRIVITO_API_KEY.
|
6
|
+
#
|
7
|
+
# config.tenant = 'my-tenant-123'
|
8
|
+
# config.api_key = 'secret'
|
9
|
+
#
|
10
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
class InstallScrivito < Scrivito::Migration
|
2
|
+
def up
|
3
|
+
Scrivito::ObjClass.create(name: 'Page', attributes: [
|
4
|
+
{name: 'title', type: 'string'},
|
5
|
+
{name: 'body', type: 'widget'},
|
6
|
+
{name: 'child_order', type: 'referencelist'},
|
7
|
+
])
|
8
|
+
|
9
|
+
Scrivito::ObjClass.create(name: 'HeadlineWidget', attributes: [
|
10
|
+
{name: 'headline', type: 'string'},
|
11
|
+
])
|
12
|
+
|
13
|
+
Scrivito::ObjClass.create(name: 'TextWidget', attributes: [
|
14
|
+
{name: 'text', type: 'html'},
|
15
|
+
])
|
16
|
+
|
17
|
+
Scrivito::ObjClass.create(name: 'Image', attributes:[
|
18
|
+
{name: 'blob', type: 'binary'},
|
19
|
+
])
|
20
|
+
|
21
|
+
Scrivito::ObjClass.create(name: 'ImageWidget', attributes: [
|
22
|
+
{name: 'image', type: 'reference'}
|
23
|
+
])
|
24
|
+
|
25
|
+
Page.create(_path: '/', title: 'Welcome to Scrivito!', body: [
|
26
|
+
HeadlineWidget.new(headline: 'A professional Cloud CMS built for Ruby on Rails.'),
|
27
|
+
TextWidget.new(text: %{
|
28
|
+
<h3>Add content management to your website</h3>
|
29
|
+
<p>
|
30
|
+
With Scrivito, you can develop your website like you always did.
|
31
|
+
It just works, and it just works "The Rails Way".
|
32
|
+
</p>
|
33
|
+
<h3>No training for your editors required.</h3>
|
34
|
+
<p>
|
35
|
+
Your clients can edit content in-place, directly on the website itself.
|
36
|
+
Intuitively, without any training or HTML skills.
|
37
|
+
</p>
|
38
|
+
<h3>No installation required</h3>
|
39
|
+
<p>
|
40
|
+
You should focus on the important things:
|
41
|
+
Developing the functionality and look of your website.
|
42
|
+
That's why we built Scrivito as a cloud service.
|
43
|
+
So you don't have to keep on updating your CMS or worry about uptime all the time.
|
44
|
+
And you always get the newest features.
|
45
|
+
</p>
|
46
|
+
})
|
47
|
+
])
|
48
|
+
end
|
49
|
+
end
|
@@ -1,21 +1,16 @@
|
|
1
|
-
module
|
1
|
+
module Scrivito
|
2
2
|
class MigrationGenerator < ::Rails::Generators::NamedBase
|
3
3
|
include ::Rails::Generators::Migration
|
4
4
|
|
5
5
|
source_root File.expand_path('../templates', __FILE__)
|
6
6
|
|
7
|
-
class_option :path,
|
8
|
-
type: :string,
|
9
|
-
default: 'cms/migrate',
|
10
|
-
desc: 'Relative path to Rails.root where to place the migration file. Defaults to "cms/migrate".',
|
11
|
-
banner: 'PATH'
|
12
|
-
|
13
7
|
def self.next_migration_number(dirname)
|
14
8
|
Time.now.utc.strftime('%Y%m%d%H%M%S')
|
15
9
|
end
|
16
10
|
|
17
11
|
def create_migration_file
|
18
|
-
|
12
|
+
base_path = Scrivito::Configuration.migration_path
|
13
|
+
migration_template('migration.erb', File.join(base_path, "#{file_name}.rb"))
|
19
14
|
end
|
20
15
|
end
|
21
|
-
end
|
16
|
+
end
|
@@ -4,12 +4,12 @@ class <%= class_name %> < ::Scrivito::Migration
|
|
4
4
|
# content programatically. All Scrivito SDK classes and methods are available and arbitrary Ruby
|
5
5
|
# code can be executed.
|
6
6
|
#
|
7
|
-
# Use `bundle exec rake
|
7
|
+
# Use `bundle exec rake scrivito:migrate` to run all migrations that are new to the `rtc` workspace.
|
8
8
|
# Migrations are identified by an ID and only get executed once. If you migrate the CMS an
|
9
9
|
# existing `rtc` workspace is used or a new `rtc` workspace is created. Only one developer at a
|
10
10
|
# time can run migrations, which means to quickly try to publish the current migrations.
|
11
11
|
#
|
12
|
-
# Use `bundle exec rake
|
12
|
+
# Use `bundle exec rake scrivito:migrate:publish` to publish your `rtc` workspace that holds the
|
13
13
|
# latest unpublished migrations.
|
14
14
|
#
|
15
15
|
# To get you started, here is a list of the most common SDK methods to alter the CMS content.
|
@@ -26,7 +26,7 @@ class <%= class_name %> < ::Scrivito::Migration
|
|
26
26
|
# Scrivito::ObjClass.find('Homepage').update(is_active: false)
|
27
27
|
#
|
28
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
|
29
|
+
# Scrivito::ObjClass.find('Homepage').attributes.add(name: 'category', type: :enum, values: %w(tech social))
|
30
30
|
#
|
31
31
|
# @example Update the "category" attribute and add another value.
|
32
32
|
# attribute = Scrivito::ObjClass.find('Homepage').attributes['category']
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -1,4 +1,4 @@
|
|
1
|
-
module
|
1
|
+
module Scrivito
|
2
2
|
module Generators
|
3
3
|
class WidgetGenerator < ::Rails::Generators::NamedBase
|
4
4
|
include ::Rails::Generators::Migration
|
@@ -23,7 +23,8 @@ module Cms
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def generate_migration
|
26
|
-
|
26
|
+
base_path = Scrivito::Configuration.migration_path
|
27
|
+
migration_template('migration.erb', File.join(base_path, "/create_#{file_name}.rb"))
|
27
28
|
end
|
28
29
|
end
|
29
30
|
end
|
data/lib/obj.rb
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
-
#
|
2
|
-
#
|
3
|
-
|
1
|
+
# The class +Obj+ should be overridden by the application (see example).
|
2
|
+
# The SDK provides methods for {Obj} through it's abstract base class, {Scrivito::BasicObj}.
|
3
|
+
# The Scrivito SDK provides this empty implementation for {Obj}
|
4
|
+
# which will only be used in case the app does not define the class {Obj} itself.
|
5
|
+
# @example
|
6
|
+
# # in app/models/obj.rb
|
7
|
+
# class Obj < Scrivito::BasicObj
|
8
|
+
# # put your custom extensions that apply to every Obj here
|
9
|
+
# end
|
10
|
+
#
|
11
|
+
# # in app/models/page.rb
|
12
|
+
# class Page < Obj
|
13
|
+
# # put custom extensions that only apply to Objs with class Page here
|
14
|
+
# end
|
15
|
+
# @api public
|
16
|
+
class Obj < Scrivito::BasicObj
|
17
|
+
end
|
@@ -24,24 +24,19 @@ module Scrivito
|
|
24
24
|
# @api public
|
25
25
|
def_delegators :@attributes, :each
|
26
26
|
|
27
|
+
#
|
27
28
|
# Finds an attribute in this collection by its name.
|
28
29
|
#
|
29
30
|
# @api public
|
30
31
|
#
|
31
|
-
#
|
32
|
+
# @param [String] name the name of the attribute
|
33
|
+
# @return [Scrivito::Attribute] if there is an attribute with name +name+
|
34
|
+
# @return [nil] if there is no attribute with name +name+
|
35
|
+
#
|
36
|
+
# @see Scrivito::ObjClass#attributes Examples of how to find an attribute by name.
|
32
37
|
#
|
33
|
-
# @param [String] name
|
34
|
-
# @return [Scrivito::Attribute]
|
35
|
-
# @raise [Scrivito::ResourceNotFound] Raised when no attribute with the given +name+ can be found.
|
36
38
|
def [](name)
|
37
|
-
|
38
|
-
|
39
|
-
unless attribute
|
40
|
-
raise ResourceNotFound, "Could not find #{Attribute} with name '#{name}' for" \
|
41
|
-
" obj class '#{@obj_class.name}'."
|
42
|
-
end
|
43
|
-
|
44
|
-
attribute
|
39
|
+
@attributes.detect { |attribute| attribute.name == name.to_s }
|
45
40
|
end
|
46
41
|
|
47
42
|
# Adds an attribute to this collection and updates the obj class.
|
@@ -41,7 +41,7 @@ module AttributeContent
|
|
41
41
|
|
42
42
|
def has_custom_attribute?(name)
|
43
43
|
name = name.to_s
|
44
|
-
|
44
|
+
data_from_cms.has_custom_attribute?(name)
|
45
45
|
end
|
46
46
|
alias_method :has_attribute?, :has_custom_attribute?
|
47
47
|
|
@@ -56,11 +56,7 @@ module AttributeContent
|
|
56
56
|
def [](key)
|
57
57
|
key = key.to_s
|
58
58
|
|
59
|
-
|
60
|
-
obj_class
|
61
|
-
else
|
62
|
-
has_attribute?(key) ? read_attribute(key) : nil
|
63
|
-
end
|
59
|
+
has_attribute?(key) ? read_attribute(key) : nil
|
64
60
|
end
|
65
61
|
|
66
62
|
# Hook method to control which widget classes should be available for this page.
|
@@ -124,6 +120,14 @@ module AttributeContent
|
|
124
120
|
end
|
125
121
|
end
|
126
122
|
|
123
|
+
def to_show_view_path
|
124
|
+
to_view_path('show')
|
125
|
+
end
|
126
|
+
|
127
|
+
def to_details_view_path
|
128
|
+
to_view_path('details')
|
129
|
+
end
|
130
|
+
|
127
131
|
private
|
128
132
|
|
129
133
|
attr_writer :data_from_cms
|
@@ -137,6 +141,10 @@ module AttributeContent
|
|
137
141
|
end
|
138
142
|
|
139
143
|
def prepare_attribute_value(attribute_value, attribute_type, attribute_name)
|
144
|
+
if attribute_name == '_obj_class'
|
145
|
+
return obj_class
|
146
|
+
end
|
147
|
+
|
140
148
|
case attribute_type
|
141
149
|
when "html"
|
142
150
|
StringTagging.tag_as_html(attribute_value)
|
@@ -147,22 +155,30 @@ module AttributeContent
|
|
147
155
|
when "link"
|
148
156
|
build_link(attribute_value)
|
149
157
|
when "reference"
|
150
|
-
|
158
|
+
workspace.objs.find([attribute_value]).first
|
151
159
|
when "referencelist"
|
152
|
-
|
160
|
+
workspace.objs.find(attribute_value).compact
|
153
161
|
when "widget"
|
154
162
|
build_widgets(attribute_value, attribute_name)
|
163
|
+
when "binary"
|
164
|
+
build_binary(attribute_value)
|
155
165
|
else
|
156
166
|
attribute_value
|
157
167
|
end
|
158
168
|
end
|
159
169
|
|
170
|
+
def build_binary(binary_definition)
|
171
|
+
if binary_definition && binary_definition['id']
|
172
|
+
Binary.new(binary_definition['id'], workspace.published?)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
160
176
|
def build_links(link_definitions)
|
161
177
|
if link_definitions.present?
|
162
178
|
link_definitions = link_definitions.map(&:with_indifferent_access)
|
163
179
|
|
164
180
|
object_ids = link_definitions.map { |link_data| link_data[:destination] }.compact.uniq
|
165
|
-
objects = object_ids.empty? ? [] :
|
181
|
+
objects = object_ids.empty? ? [] : workspace.objs.find(object_ids)
|
166
182
|
link_definitions.each_with_object([]) do |link_data, links|
|
167
183
|
obj = objects.detect { |o| o && o.id == link_data[:destination] }
|
168
184
|
link = Link.new(link_data.merge(obj: obj))
|
@@ -185,7 +201,7 @@ module AttributeContent
|
|
185
201
|
|
186
202
|
def build_internal_link(attribute_value)
|
187
203
|
properties = {
|
188
|
-
obj:
|
204
|
+
obj: workspace.objs.find(attribute_value['destination']),
|
189
205
|
title: attribute_value['title'],
|
190
206
|
query: attribute_value['query'],
|
191
207
|
fragment: attribute_value['fragment'],
|
@@ -221,6 +237,10 @@ module AttributeContent
|
|
221
237
|
end
|
222
238
|
end
|
223
239
|
|
240
|
+
def to_view_path(view_name)
|
241
|
+
"#{obj_class_name.underscore}/#{view_name}"
|
242
|
+
end
|
243
|
+
|
224
244
|
module ClassMethods
|
225
245
|
# Instantiate an Obj or Widget instance from obj_data.
|
226
246
|
# If a subclass of Obj or Widget with the same name as the property +_obj_class+ exists,
|
@@ -242,8 +262,7 @@ module AttributeContent
|
|
242
262
|
|
243
263
|
def descendants
|
244
264
|
type_computer = TypeComputer.new(self, nil)
|
245
|
-
|
246
|
-
.map { |obj_class_spec| obj_class_spec['name'] }
|
265
|
+
Workspace.current.obj_classes.map(&:name)
|
247
266
|
.sort
|
248
267
|
.map { |obj_class_name| type_computer.compute_type(obj_class_name) }
|
249
268
|
.compact
|
data/lib/scrivito/basic_obj.rb
CHANGED
@@ -3,7 +3,11 @@ require 'ostruct'
|
|
3
3
|
require 'active_model/naming'
|
4
4
|
|
5
5
|
module Scrivito
|
6
|
-
# The
|
6
|
+
# The abstract base class for cms objects.
|
7
|
+
#
|
8
|
+
# @note Please do not use {Scrivito::BasicObj} directly,
|
9
|
+
# as it is intended as an abstract class.
|
10
|
+
# Always use {Obj} or a subclass of {Obj}.
|
7
11
|
# @api public
|
8
12
|
class BasicObj
|
9
13
|
UNIQ_ATTRIBUTES = %w[
|
@@ -33,16 +37,16 @@ module Scrivito
|
|
33
37
|
@_type_computer = nil
|
34
38
|
end
|
35
39
|
|
36
|
-
# Create a new {BasicObj Obj} in the cms
|
40
|
+
# Create a new {Scrivito::BasicObj Obj} in the cms
|
37
41
|
#
|
38
42
|
# This allows you to set the different attributes types of an obj by
|
39
43
|
# providing a hash with the attributes names as key and the values you want
|
40
44
|
# to set as values
|
41
45
|
#
|
42
|
-
# @example Reference lists have to be provided as an Array of {BasicObj Objs}
|
46
|
+
# @example Reference lists have to be provided as an Array of {Scrivito::BasicObj Objs}
|
43
47
|
# Obj.create(:reference_list => [other_obj])
|
44
48
|
#
|
45
|
-
# @example Passing an {BasicObj Obj} allows you to set a reference
|
49
|
+
# @example Passing an {Scrivito::BasicObj Obj} allows you to set a reference
|
46
50
|
# Obj.create(:reference => other_obj)
|
47
51
|
#
|
48
52
|
# @example you can upload files by passing a ruby File object
|
@@ -72,7 +76,7 @@ module Scrivito
|
|
72
76
|
# @example Arrays of {String Strings} allow you to set multi enum fields
|
73
77
|
# Obj.create(:tags => ["ruby", "rails"])
|
74
78
|
#
|
75
|
-
# @example Simply pass an Array of {BasicWidget Widgets} to change a widget field. See {BasicWidget#clone Widget#clone} on how to clone a widget.
|
79
|
+
# @example Simply pass an Array of {Scrivito::BasicWidget Widgets} to change a widget field. See {Scrivito::BasicWidget#clone Widget#clone} on how to clone a widget.
|
76
80
|
# # Add new widgets
|
77
81
|
# Obj.create(:widgets => [Widget.new(_obj_class: 'TitleWidget', title: 'My Title')])
|
78
82
|
#
|
@@ -87,7 +91,7 @@ module Scrivito
|
|
87
91
|
#
|
88
92
|
# @api public
|
89
93
|
# @param [Hash] attributes
|
90
|
-
# @return [Obj] the newly created {BasicObj Obj}
|
94
|
+
# @return [Obj] the newly created {Scrivito::BasicObj Obj}
|
91
95
|
def self.create(attributes)
|
92
96
|
attributes = with_default_obj_class(attributes)
|
93
97
|
api_attributes, widget_properties = prepare_attributes_for_rest_api(attributes, nil)
|
@@ -97,7 +101,7 @@ module Scrivito
|
|
97
101
|
obj
|
98
102
|
end
|
99
103
|
|
100
|
-
# Create a new {BasicObj Obj} instance with the given values and attributes.
|
104
|
+
# Create a new {Scrivito::BasicObj Obj} instance with the given values and attributes.
|
101
105
|
# Normally this method should not be used.
|
102
106
|
# Instead Objs should be loaded from the cms database.
|
103
107
|
def initialize(attributes = {})
|
@@ -120,7 +124,7 @@ module Scrivito
|
|
120
124
|
|
121
125
|
### FINDERS ####################
|
122
126
|
|
123
|
-
# Find a {BasicObj Obj} by its id.
|
127
|
+
# Find a {Scrivito::BasicObj Obj} by its id.
|
124
128
|
# If the parameter is an Array containing ids, return a list of corresponding Objs.
|
125
129
|
# @param [String, Integer, Array<String, Integer>]id_or_list
|
126
130
|
# @return [Obj, Array<Obj>]
|
@@ -133,7 +137,7 @@ module Scrivito
|
|
133
137
|
Workspace.current.objs.find_by_id(id)
|
134
138
|
end
|
135
139
|
|
136
|
-
# Find a {BasicObj Obj} by its id.
|
140
|
+
# Find a {Scrivito::BasicObj Obj} by its id.
|
137
141
|
# If the parameter is an Array containing ids, return a list of corresponding Objs.
|
138
142
|
# The results include deleted objects as well.
|
139
143
|
# @param [String, Integer, Array<String, Integer>]id_or_list
|
@@ -147,7 +151,10 @@ module Scrivito
|
|
147
151
|
#
|
148
152
|
# Note that +field+ and +value+ can also be arrays for searching several fields or searching for several values.
|
149
153
|
#
|
150
|
-
#
|
154
|
+
# @note If invoked on a subclass of Obj, the result will be restricted to instances of that subclass.
|
155
|
+
#
|
156
|
+
# {ObjSearchEnumerator}s can be chained using one of the chainable methods
|
157
|
+
# (e.g. {ObjSearchEnumerator#and} and {ObjSearchEnumerator#and_not}).
|
151
158
|
#
|
152
159
|
# @example Look for the first 10 Objs whose ObjClass is "Pressrelease" and whose title contains "quarterly":
|
153
160
|
# Obj.where(:_obj_class, :equals, 'Pressrelease').and(:title, :contains, 'quarterly').take(10)
|
@@ -155,20 +162,33 @@ module Scrivito
|
|
155
162
|
# @param [Symbol, String] operator See {ObjSearchEnumerator#and} for details
|
156
163
|
# @param [String, Array<String>] value See {ObjSearchEnumerator#and} for details
|
157
164
|
# @param [Hash] boost See {ObjSearchEnumerator#and} for details
|
165
|
+
# @raise [ScrivitoError] if called on a subclass of +Obj+ with no corresponding {ObjClass}
|
166
|
+
# @raise [ScrivitoError] if called directly on +BasicObj+. Use +Obj.where+ instead.
|
158
167
|
# @return [ObjSearchEnumerator]
|
159
168
|
# @api public
|
160
169
|
def self.where(field, operator, value, boost = nil)
|
161
|
-
|
170
|
+
assert_not_basic_obj('.where')
|
171
|
+
if self == ::Obj
|
172
|
+
Workspace.current.objs.where(field, operator, value, boost)
|
173
|
+
else
|
174
|
+
assert_has_obj_class('.where')
|
175
|
+
Workspace.current.objs.where(:_obj_class, :equals, name)
|
176
|
+
.and(field, operator, value, boost)
|
177
|
+
end
|
162
178
|
end
|
163
179
|
|
164
|
-
# Returns a {ObjSearchEnumerator} of all {BasicObj Obj}s.
|
180
|
+
# Returns a {ObjSearchEnumerator} of all {Scrivito::BasicObj Obj}s.
|
165
181
|
# If invoked on a subclass of Obj, the result will be restricted to instances of that subclass.
|
166
182
|
# @return [ObjSearchEnumerator]
|
183
|
+
# @raise [ScrivitoError] if called on a subclass of +Obj+ with no corresponding {ObjClass}
|
184
|
+
# @raise [ScrivitoError] if called directly on +BasicObj+. Use +Obj.all+ instead.
|
167
185
|
# @api public
|
168
186
|
def self.all
|
169
|
-
|
187
|
+
assert_not_basic_obj('.all')
|
188
|
+
if self == ::Obj
|
170
189
|
Workspace.current.objs.all
|
171
190
|
else
|
191
|
+
assert_has_obj_class('.all')
|
172
192
|
find_all_by_obj_class(name)
|
173
193
|
end
|
174
194
|
end
|
@@ -181,19 +201,19 @@ module Scrivito
|
|
181
201
|
Workspace.current.objs.find_all_by_obj_class(obj_class)
|
182
202
|
end
|
183
203
|
|
184
|
-
# Find the {BasicObj Obj} with the given path.
|
204
|
+
# Find the {Scrivito::BasicObj Obj} with the given path.
|
185
205
|
# Returns +nil+ if no matching Obj exists.
|
186
|
-
# @param [String] path Path of the {BasicObj Obj}.
|
206
|
+
# @param [String] path Path of the {Scrivito::BasicObj Obj}.
|
187
207
|
# @return [Obj]
|
188
208
|
# @api public
|
189
209
|
def self.find_by_path(path)
|
190
210
|
Workspace.current.objs.find_by_path(path)
|
191
211
|
end
|
192
212
|
|
193
|
-
# Find an {BasicObj Obj} with the given name.
|
213
|
+
# Find an {Scrivito::BasicObj Obj} with the given name.
|
194
214
|
# If several Objs with the given name exist, an arbitrary one of these Objs is chosen and returned.
|
195
215
|
# If no Obj with the name exits, +nil+ is returned.
|
196
|
-
# @param [String] name Name of the {BasicObj Obj}.
|
216
|
+
# @param [String] name Name of the {Scrivito::BasicObj Obj}.
|
197
217
|
# @return [Obj]
|
198
218
|
# @api public
|
199
219
|
def self.find_by_name(name)
|
@@ -201,23 +221,25 @@ module Scrivito
|
|
201
221
|
end
|
202
222
|
|
203
223
|
# Returns a {ObjSearchEnumerator} of all Objs with the given name.
|
204
|
-
# @param [String] name Name of the {BasicObj Obj}.
|
224
|
+
# @param [String] name Name of the {Scrivito::BasicObj Obj}.
|
205
225
|
# @return [ObjSearchEnumerator]
|
206
226
|
# @api public
|
207
227
|
def self.find_all_by_name(name)
|
208
228
|
where(:_name, :equals, name)
|
209
229
|
end
|
210
230
|
|
211
|
-
# Returns the {BasicObj Obj} with the given permalink, or +nil+ if no matching Obj
|
212
|
-
#
|
231
|
+
# Returns the {Scrivito::BasicObj Obj} with the given permalink, or +nil+ if no matching Obj
|
232
|
+
# exists.
|
233
|
+
# @param [String] permalink The permalink of the {Scrivito::BasicObj Obj}.
|
213
234
|
# @return [Obj]
|
214
235
|
# @api public
|
215
236
|
def self.find_by_permalink(permalink)
|
216
237
|
Workspace.current.objs.find_by_permalink(permalink)
|
217
238
|
end
|
218
239
|
|
219
|
-
# Returns the {BasicObj Obj} with the given permalink, or raise ResourceNotFound if
|
220
|
-
#
|
240
|
+
# Returns the {Scrivito::BasicObj Obj} with the given permalink, or raise ResourceNotFound if
|
241
|
+
# no matching Obj exists.
|
242
|
+
# @param [String] permalink The permalink of the {Scrivito::BasicObj Obj}.
|
221
243
|
# @return [Obj]
|
222
244
|
# @api public
|
223
245
|
def self.find_by_permalink!(permalink)
|
@@ -245,10 +267,10 @@ module Scrivito
|
|
245
267
|
def self.valid_page_classes_beneath(parent_path)
|
246
268
|
end
|
247
269
|
|
248
|
-
# Update the {BasicObj Obj} with the attributes provided.
|
270
|
+
# Update the {Scrivito::BasicObj Obj} with the attributes provided.
|
249
271
|
#
|
250
272
|
# For an overview of which values you can set via this method see the
|
251
|
-
# documentation of {BasicObj.create Obj.create}.
|
273
|
+
# documentation of {Scrivito::BasicObj.create Obj.create}.
|
252
274
|
#
|
253
275
|
# Additionally, +update+ accepts a +_widget_pool+ hash in +attributes+ to modify widgets.
|
254
276
|
# The keys of +_widget_pool+ are widget instances, the values are the modified attributes of
|
@@ -299,7 +321,7 @@ module Scrivito
|
|
299
321
|
self.class.find(json['_id'])
|
300
322
|
end
|
301
323
|
|
302
|
-
# Destroys the {BasicObj Obj} in the current {Workspace}
|
324
|
+
# Destroys the {Scrivito::BasicObj Obj} in the current {Workspace}
|
303
325
|
# @api public
|
304
326
|
def destroy
|
305
327
|
if children.any?
|
@@ -312,12 +334,12 @@ module Scrivito
|
|
312
334
|
id
|
313
335
|
end
|
314
336
|
|
315
|
-
# return the {BasicObj Obj} that is the parent of this Obj.
|
337
|
+
# return the {Scrivito::BasicObj Obj} that is the parent of this Obj.
|
316
338
|
# returns +nil+ for the root Obj.
|
317
339
|
# @api public
|
318
340
|
def parent
|
319
341
|
if child_path?
|
320
|
-
|
342
|
+
workspace.objs.find_by_path(parent_path)
|
321
343
|
end
|
322
344
|
end
|
323
345
|
|
@@ -334,7 +356,7 @@ module Scrivito
|
|
334
356
|
Workspace.current.objs.find_by_paths(ancestor_paths)
|
335
357
|
end
|
336
358
|
|
337
|
-
# return a list of all child {BasicObj Obj}s.
|
359
|
+
# return a list of all child {Scrivito::BasicObj Obj}s.
|
338
360
|
# @return [Array<Obj>]
|
339
361
|
# @api public
|
340
362
|
def children
|
@@ -345,13 +367,13 @@ module Scrivito
|
|
345
367
|
|
346
368
|
### ATTRIBUTES #################
|
347
369
|
|
348
|
-
# returns the {BasicObj Obj}'s path as a String.
|
370
|
+
# returns the {Scrivito::BasicObj Obj}'s path as a String.
|
349
371
|
# @api public
|
350
372
|
def path
|
351
373
|
read_attribute('_path')
|
352
374
|
end
|
353
375
|
|
354
|
-
# returns the {BasicObj Obj}'s name, i.e. the last component of the path.
|
376
|
+
# returns the {Scrivito::BasicObj Obj}'s name, i.e. the last component of the path.
|
355
377
|
# @api public
|
356
378
|
def name
|
357
379
|
if child_path?
|
@@ -361,12 +383,14 @@ module Scrivito
|
|
361
383
|
end
|
362
384
|
end
|
363
385
|
|
364
|
-
# Returns the root {BasicObj Obj}, i.e. the Obj with the path "/"
|
386
|
+
# Returns the root {Scrivito::BasicObj Obj}, i.e. the Obj with the path "/"
|
365
387
|
# @return [Obj]
|
366
388
|
# @api public
|
367
389
|
def self.root
|
368
|
-
BasicObj.find_by_path(
|
369
|
-
"Obj.root not found: There is no Obj with path
|
390
|
+
BasicObj.find_by_path('/') or raise ResourceNotFound,
|
391
|
+
'"Obj.root" not found: There is no "Obj" with path "/". '\
|
392
|
+
'Maybe you forgot the migration when setting up your Scrivito application? '\
|
393
|
+
'Try "rake scrivito:migrate" and "rake scrivito:migrate:publish".'
|
370
394
|
end
|
371
395
|
|
372
396
|
# Returns the homepage obj. This can be overwritten in your application's +Obj+.
|
@@ -427,18 +451,27 @@ module Scrivito
|
|
427
451
|
(title || '').parameterize
|
428
452
|
end
|
429
453
|
|
430
|
-
#
|
431
|
-
#
|
454
|
+
#
|
455
|
+
# This method determines the description that is shown in the UI
|
456
|
+
# and defaults to {Scrivito::BasicObj#display_title}. It can be overriden by a custom value.
|
457
|
+
#
|
432
458
|
# @api public
|
459
|
+
#
|
433
460
|
def description_for_editor
|
434
|
-
|
461
|
+
display_title
|
435
462
|
end
|
436
463
|
|
437
|
-
#
|
438
|
-
#
|
464
|
+
#
|
465
|
+
# Calculates appropriate title for an +Obj+.
|
466
|
+
#
|
439
467
|
# @api public
|
468
|
+
#
|
469
|
+
# @return [String] {Scrivito::Binary#filename} if +Obj+ is +binary+ and has a +filename+.
|
470
|
+
# @return [String] {Scrivito::BasicObj#title} if +Obj+ has a non-empty +title+.
|
471
|
+
# @return [String] a placeholder +<untitled MyClass>+ otherwise.
|
472
|
+
#
|
440
473
|
def display_title
|
441
|
-
|
474
|
+
(binary_title || title).presence || "<untitled #{obj_class_name}>"
|
442
475
|
end
|
443
476
|
|
444
477
|
# @api public
|
@@ -446,9 +479,25 @@ module Scrivito
|
|
446
479
|
read_attribute('title')
|
447
480
|
end
|
448
481
|
|
449
|
-
#
|
482
|
+
# @api public
|
483
|
+
# This method indicates if the Obj represents binary data. Binaries are
|
484
|
+
# handled differently in that they are not rendered using the normal layout
|
485
|
+
# but sent as a file. Examples of binary resources are Images or PDFs.
|
486
|
+
#
|
487
|
+
# By default every Obj that has an attribute +blob+ of the type +binary+ is
|
488
|
+
# considered a binary
|
489
|
+
#
|
490
|
+
# @note you can override this method to indicate that an Obj is binary,
|
491
|
+
# if the default behavior doesn't fit your needs
|
492
|
+
#
|
493
|
+
# @return true if this Obj represents a binary resource.
|
450
494
|
def binary?
|
451
|
-
|
495
|
+
if obj_type = read_attribute('_obj_type')
|
496
|
+
[:image, :generic].include?(obj_type.to_sym)
|
497
|
+
else
|
498
|
+
blob_attribute = obj_class.attributes['blob']
|
499
|
+
blob_attribute && blob_attribute.type == 'binary'
|
500
|
+
end
|
452
501
|
end
|
453
502
|
|
454
503
|
# Returns true if this object is the root object.
|
@@ -468,9 +517,10 @@ module Scrivito
|
|
468
517
|
toclist
|
469
518
|
end
|
470
519
|
|
471
|
-
# @param objs_to_be_sorted [Array<BasicObj>] unsorted list of Objs
|
472
|
-
# @param list [Array<BasicObj>] list of Objs that defines the order
|
473
|
-
# @return [Array<BasicObj>] a sorted list of Objs. Any objs present in
|
520
|
+
# @param objs_to_be_sorted [Array<Scrivito::BasicObj>] unsorted list of Objs
|
521
|
+
# @param list [Array<Scrivito::BasicObj>] list of Objs that defines the order
|
522
|
+
# @return [Array<Scrivito::BasicObj>] a sorted list of Objs. Any objs present in
|
523
|
+
# +objs_to_be_sorted+ but not in +list+ are appended at the end, sorted by +Obj#id+
|
474
524
|
def self.sort_by_list(objs_to_be_sorted, list)
|
475
525
|
(list & objs_to_be_sorted) + (objs_to_be_sorted - list).sort_by(&:id)
|
476
526
|
end
|
@@ -482,6 +532,7 @@ module Scrivito
|
|
482
532
|
_last_changed
|
483
533
|
_path
|
484
534
|
_permalink
|
535
|
+
_obj_class
|
485
536
|
title
|
486
537
|
])
|
487
538
|
|
@@ -583,19 +634,8 @@ module Scrivito
|
|
583
634
|
end
|
584
635
|
end
|
585
636
|
|
586
|
-
# For a binary Obj, the content_type is equal to the content_type of its body (i.e. its data).
|
587
|
-
# For non-binary Objs, a the default content_type is "text/html".
|
588
|
-
# Override this method in subclasses to define a different content_type.
|
589
|
-
# Note that only Objs with content_type "text/html"
|
590
|
-
# will be rendered with layout and templates by the DefaultCmsController.
|
591
|
-
# @return [String]
|
592
|
-
# @api public
|
593
637
|
def content_type
|
594
|
-
|
595
|
-
body_content_type
|
596
|
-
else
|
597
|
-
"text/html"
|
598
|
-
end
|
638
|
+
raise "The method `content_type' and `mime_type' were removed. Please use `binary_content_type' instead"
|
599
639
|
end
|
600
640
|
alias mime_type content_type
|
601
641
|
|
@@ -619,42 +659,55 @@ module Scrivito
|
|
619
659
|
end
|
620
660
|
end
|
621
661
|
|
622
|
-
# for binary Objs body_length equals the file size
|
623
|
-
# for non-binary Objs body_length equals the number of characters in the body (main content)
|
624
662
|
# @api public
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
663
|
+
# This method is intended for Objs that represent binary resources like
|
664
|
+
# images or pdf documents. If this Obj represents a binary file, an instance
|
665
|
+
# of {Binary} is returned.
|
666
|
+
# The default implementation returns the attribute "blob" (if available and
|
667
|
+
# of type +binary+).
|
668
|
+
# @note You may override this method in your subclasses.
|
669
|
+
# @return [Binary, nil]
|
670
|
+
def binary
|
671
|
+
self[:blob] if self[:blob].is_a?(Binary)
|
632
672
|
end
|
633
673
|
|
634
|
-
# returns an URL to retrieve the Obj's body for binary Objs.
|
635
|
-
# returns +nil+ for non-binary Objs.
|
636
|
-
# @return [String]
|
637
674
|
# @api public
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
end
|
675
|
+
# This method returns the length in bytes of the binary of this obj
|
676
|
+
# @return [Fixnum] If no binary is set it will return 0
|
677
|
+
def binary_length
|
678
|
+
binary.try(:content_length) || 0
|
643
679
|
end
|
644
680
|
|
645
|
-
# returns the content type of the Obj's body for binary Objs.
|
646
|
-
# returns +nil+ for non-binary Objs.
|
647
|
-
# @return [String]
|
648
681
|
# @api public
|
682
|
+
# This method returns the content type of the binary of this obj if it is set.
|
683
|
+
# @return [String, nil]
|
684
|
+
def binary_content_type
|
685
|
+
binary.try(:content_type)
|
686
|
+
end
|
687
|
+
|
688
|
+
# @api public
|
689
|
+
# This method returns the url under which the content of this binary is
|
690
|
+
# available to the public if the binary is set.
|
691
|
+
#
|
692
|
+
# See {Binary#url} for details
|
693
|
+
# @return [String, nil]
|
694
|
+
def binary_url
|
695
|
+
binary.try(:url)
|
696
|
+
end
|
697
|
+
|
698
|
+
def body_length
|
699
|
+
raise %(
|
700
|
+
The method `body_length' was removed. Please use
|
701
|
+
`binary_length' or `body.length' instead
|
702
|
+
)
|
703
|
+
end
|
704
|
+
|
705
|
+
def body_data_url
|
706
|
+
raise "The method `body_data_url' was removed. Please use `binary_url' instead"
|
707
|
+
end
|
708
|
+
|
649
709
|
def body_content_type
|
650
|
-
|
651
|
-
blob = find_blob
|
652
|
-
if blob
|
653
|
-
blob.content_type
|
654
|
-
else
|
655
|
-
"application/octet-stream"
|
656
|
-
end
|
657
|
-
end
|
710
|
+
raise "The method `body_content_type' was removed. Please use `binary_content_type' instead"
|
658
711
|
end
|
659
712
|
|
660
713
|
def inspect
|
@@ -675,10 +728,21 @@ module Scrivito
|
|
675
728
|
find_blob.try(:id)
|
676
729
|
end
|
677
730
|
|
678
|
-
#
|
679
|
-
#
|
680
|
-
#
|
681
|
-
#
|
731
|
+
#
|
732
|
+
# Reverts all changes made to the +Obj+ in the current workspace.
|
733
|
+
#
|
734
|
+
# @api public
|
735
|
+
#
|
736
|
+
# @note This method does not support +Obj+s, which are +new+.
|
737
|
+
# Please use {Scrivito::BasicObj#destroy Obj#destroy} to destroy them.
|
738
|
+
# @note This method does not support +Obj+s, which are +deleted+.
|
739
|
+
# Please use {Scrivito::BasicObj.restore Obj.restore} to restore them.
|
740
|
+
#
|
741
|
+
# @raise [ScrivitoError] If the current workspace is +published+.
|
742
|
+
# @raise [ScrivitoError] If the current workspace is the +rtc+ workspace.
|
743
|
+
# @raise [ScrivitoError] If the +Obj+ is +new+.
|
744
|
+
# @raise [ScrivitoError] If the +Obj+ is +deleted+.
|
745
|
+
#
|
682
746
|
def revert
|
683
747
|
assert_revertable
|
684
748
|
|
@@ -759,6 +823,12 @@ module Scrivito
|
|
759
823
|
data_from_cms.to_h.except(*GENERATED_ATTRIBUTES)
|
760
824
|
end
|
761
825
|
|
826
|
+
def parent_path
|
827
|
+
unless root?
|
828
|
+
path.gsub(/\/[^\/]+$/, '').presence || '/'
|
829
|
+
end
|
830
|
+
end
|
831
|
+
|
762
832
|
private
|
763
833
|
|
764
834
|
def cms_data_for_revision(revision)
|
@@ -785,18 +855,12 @@ module Scrivito
|
|
785
855
|
end
|
786
856
|
end
|
787
857
|
|
788
|
-
def parent_path
|
789
|
-
raise "parent_path called for root" if root?
|
790
|
-
path.gsub(/\/[^\/]+$/, "").presence || "/"
|
791
|
-
end
|
792
|
-
|
793
858
|
def as_date(value)
|
794
859
|
DateAttribute.parse(value) unless value.nil?
|
795
860
|
end
|
796
861
|
|
797
862
|
def find_blob
|
798
|
-
|
799
|
-
Blob.find(blob_spec["id"]) if blob_spec
|
863
|
+
read_attribute('blob')
|
800
864
|
end
|
801
865
|
|
802
866
|
def workspace
|
@@ -823,13 +887,39 @@ module Scrivito
|
|
823
887
|
|
824
888
|
def assert_revertable
|
825
889
|
workspace.assert_revertable
|
826
|
-
raise "revert not supported for binary objs" if binary?
|
827
890
|
if modification == Modification::NEW || modification == Modification::DELETED
|
828
891
|
raise ScrivitoError, "cannot revert changes, since obj is #{modification}."
|
829
892
|
end
|
830
893
|
end
|
831
894
|
|
895
|
+
def binary_title
|
896
|
+
binary.filename if binary? && binary
|
897
|
+
end
|
898
|
+
|
832
899
|
class << self
|
900
|
+
|
901
|
+
def assert_not_basic_obj(method_name)
|
902
|
+
if self == Scrivito::BasicObj
|
903
|
+
raise ScrivitoError, "Can not call #{method_name} on Scrivito::BasicObj."
|
904
|
+
+ " Only call it on Obj or subclasses of Obj"
|
905
|
+
end
|
906
|
+
end
|
907
|
+
|
908
|
+
def assert_has_obj_class(method_name)
|
909
|
+
unless Workspace.current.obj_classes[name].present?
|
910
|
+
raise ScrivitoError, "#{name} has no corresponding ObjClass."
|
911
|
+
+ " Please use Obj.#{method_name} instead."
|
912
|
+
end
|
913
|
+
end
|
914
|
+
|
915
|
+
#
|
916
|
+
# Restores a previously deleted +Obj+.
|
917
|
+
#
|
918
|
+
# @api public
|
919
|
+
#
|
920
|
+
# @raise [ScrivitoError] If the current workspace is +published+.
|
921
|
+
# @raise [ScrivitoError] If the current workspace is the +rtc+ workspace.
|
922
|
+
#
|
833
923
|
def restore(obj_id)
|
834
924
|
Workspace.current.assert_revertable
|
835
925
|
base_revision_path = "revisions/#{Workspace.current.base_revision_id}/objs/#{obj_id}"
|