Previsouly to add an image or a PDF document to a widget field an editor had to create a special widget, for example an ImageWidget
in case of an image or a DownloadWidget
in case of a PDF document, and then attach the file to the newly created widget.
Now Scrivito offers a much easier way for adding random content to widget fields.
In case, that the content you want to add already exists in the CMS, just click "Insert content" in a menu of after which you want the content to be inserted and the Content Browser will pop up. After the desired content has been selected, it will be appended at the corresponding position:
If you have to upload new content, simply dran-and-drop the file from your lokal file system into browser and drop it at the desired position. The file will be automatically uploaded and appended at the corresponding position.
The classes for content upload are created by the installation migration, which is generated by the install generator in new applications. In order to be able to use content upload in existing applications, you should create the class Scrivito::ContentWidget
:
rails g scrivito:migration create_scrivito_content_widget
class CreateScrivitoContentWidgetMigration < Scrivito::Migration
def up
ObjClass.create(name: 'Scrivito::ContentWidget', attributes: [
{name: 'content', type: :reference}
])
end
end
bundle exec rake scrivito:migrate scrivito:migrate:publish
If an image file is dropped, then it will be uploaded and stored as a Image
and will be rendered using the helper scrivito_image_tag
. Anything else will be stored as a Download
and will be rendered as a download link.
You can customize how the uploaded files should be stored and rendered. In order to do that, you have to:
- Tell the UI which class to use for which type of dropped content, using
scrivito.register_default_obj_class_for_content_type
. - Tell the server how to render a special resource class by providing a special view template
embed.html.*
.
Here is an example how to customize the handling of MP3 files.
First we create a new ObjClass
names Mp3Audio
with a binary attribute:
rails g scrivito:migration create_mp3_audio
# scrivito/migrate/*_create_mp3_audio_migration.rb
class CreateMp3AudioMigration < Scrivito::Migration
def up
Scrivito::ObjClass.create(name: 'Mp3Audio', attributes: [
{name: 'blob', type: :binary}
])
end
end
bundle exec rake scrivito:migrate
Then we tell Scrivito to use that ObjClass
for files with content type audio/mpeg
:
scrivito.on('load', function() {
scrivito.register_default_obj_class_for_content_type({'audio/mpeg': 'Mp3Audio'});
});
Also we create the corresponding model. The return value of description_for_editor
will be displayed a different places in the UI. We map the description to the filename of the uploaded MP3, so that the editor can easily distinguish between the different audio files.
# app/models/mp3_audio.rb
class Mp3Audio < Obj
def description_for_editor
blob.filename
end
end
Finally we create a template, which renders an appropriate audio tag:
<%# app/views/mp3_audio/embed.html.erb %>
<%= audio_tag obj.binary_url, controls: true %>
Now you should be able to drag and drop MP3 files in the Scrivito UI...
... and they will be rendered as audio tags:
You can now customize menus of widgets, widget fields and tag lists.
Use menu
to access a menu object related to a dom element that represents a piece of cms content. Currently this is only possible for DOM elements that represent widgets, i.e. if the attribute data-scrivito-widget-obj-class
is present and DOM elements that represent widget fields, i.e. the attribute data-scrivito-field-type
equals widget
. The menu object has several methods.
Use add
to create new menu items:
$("...").scrivito("menu").add("my_app.my_menu_item", {
title: "My Menu Item",
icon: "relation",
present: function(dom_element) {
// see below
},
disabled: function(dom_element) {
// see below
},
execute: function(dom_element) {
// invoked when the user clicks
},
})
The first argument is the id
. The id
is used to reference your command. When command are used in more than one application, you should namespace the ids and use dots to separate namespace components. The top-level namespace (i.e. an id without “dots”) is reserved for the application and should not be used by libraries. For example: all menu items provided by the SDK have the prefix scrivito.sdk.
as in scrivito.sdk.copy_widget
.
The following options are accepted:
title
(String) The title of the menu item that is shown to the user.execute
(Function) A callback that will be invoked when the user clicks the menu item. It receives the affected dom element as a parameter.present
(Function, optional) A callback that controls if the menu item should be present. It will be executed when the user opens the menu. If the function returnsfalse
, the menu item will not be part of the menu. It receives the affected dom element as a parameter. By default, a menu item is present.disabled
(Function, optional) A callback that controls if the menu item should be disabled. It will be executed when the user opens the menu. If the function returnstrue
or a String, the menu item will be disabled. The user will see the menu item but it will not be clickable. If a String is returned, it will be shown to the user as an explanation of why the item is not clickable. It receives the affected dom element as a parameter. By default, a menu item is not disabled.icon
(String, optional) A name of a built-in icon. At the moment Scrivito offers following icons:
You can also use other methods to manipulate menu items:
// remove the menu item with the given id
$("...").scrival("menu").remove(id)
// return an array containing all menu items in the menu of the element.
$("...").scrival("menu").list()
// replace a menu item
$("...").scrival("menu").replace(id, new_menu_item)
// change properties of a menu item
$("...").scrival("menu").update(id, {
title: "A new title"
})
Use configure_menu_order
to specify an order for menu items. The parameter order
is an Array of Strings. Each String may be either the fully qualified id of a menu item or a namespace of several menu items, followed by a wildcard (*
):
scrival.configure_menu_order([
"special_command",
"scrival.editors.cool_stuff",
"scrival.sdk.*",
"scrival.editors.*"
])
This example specifies that the menu item special_command
should always be the first menu item (if it is present in a menu), followed by the scrival.editors.cool_stuff
menu item. Afterwards, all menu item from the scrival.sdk
namespace are inserted and finally all remaining menu items from the scrival.editors
namespace.
Please note that configure_menu_order
defines a global order for all menu items in the application. An individual menu is sorted using the configured order, even though individual menus typically only feature a subset of the menu items mentioned in configure_menu_order
.
Menu items not mentioned in configure_menu_order
are inserted at the end, in the order they were added to the individual menu. Menu items matched by a namespace-wildcard are also inserted in the order they were added to the menu.
configure_menu_order
is intended to be called once by the application, it should not be called by gems. Instead, gems should provide their menu items in a sensible default order (by adding them in that order via add
) and by providing a common namespace to group menu items. This allows the application developer to easily specify the position for all menu items from a gem by inserting a namespace wildcard into the menu_order
of the application.
Scrivito now support adding a custom second level cache to its cache store chain with Scrivito::Configuration.second_level_cache=
. This is useful for example when deploying to Heroku, which has only a volatile filesystem.
By default there is no second level cache configured. If it is set, then Scrivito will additionally store its cache in both: the filesystem cache and the second level cache. Also Scrivito will search in the second level cache if searching in the filesystem cache returns no results. If the second level cache returns results, then the results will be store in the filesystem cache.
# Use Memcached as the second level cache (https://rubygems.org/gems/dalli):
require 'active_support/cache/dalli'
Scrivito.configure do |config|
config.second_level_cache = ActiveSupport::Cache::DalliStore.new(
'server-downstairs.localnetwork:1234', 'server-downstairs.localnetwork:4321',
username: 'root', password: 'secret'
)
end
The Content Browser now allows you to specify preset
-attributes that are automatically set on Objs
created using the Content Browser. The preset
configuration can be specified for each selectable filter:
[...]
language:
title: 'Languages'
field: 'language'
type: 'check_box'
options:
en:
title: 'English'
preset:
language: 'en'
fr:
title: 'French'
preset:
language: 'fr'
[...]
Setting presets for check boxes may result in the user selecting conflicting filters. For example if he selects both English
and French
. If the users has these items select an error message is shown that tells the user that an upload is not possible for the current selection and which items cause the conflict.
- [CRITICAL] Fixed a bug, where the client sometimes added new widgets to wrong fields.
- Fixed a problem with wrong redirect location after a logout in Firefox.
- The
scrivito_dialog
layout and thedetails
dialogs ofObjs
andWidgets
now allow you to use helpers defined in theApplicationController
. - Link and linklist editors initially show the description for editors (for internal link destinations).
- Fixed issue: when editing an internal link of a link or linklist the content browser now always shows the current selection.
- It is now possible to copy widgets between different working copies in the UI.
- Fixed issue: Opening a second content browser from the details view of a previewed page no longer renders the content browser unusable.