Permalink
Browse files

Make file meta data items more flexible

* Allow displaying custom views as value
* Allow linking to a file settings dialog tab
  • Loading branch information...
1 parent a9e76f1 commit 81f37718fcbb2f22d3cfb513ba78edbc80d0d12d @tf tf committed Dec 15, 2016
@@ -12,9 +12,18 @@ pageflow.FileType = pageflow.Object.extend({
this.configurationUpdaters = options.configurationUpdaters || [];
this.nestedFileTableColumns = options.nestedFileTableColumns || [];
this.skipUploadConfirmation = options.skipUploadConfirmation || false;
- this.metaDataAttributes = options.metaDataAttributes || [];
this.filters = options.filters || [];
+ this.metaDataAttributes = [
+ {
+ name: 'rights',
+ valueView: pageflow.TextFileMetaDataItemValueView,
+ valueViewOptions: {
+ settingsDialogTabLink: 'general'
+ }
+ },
+ ].concat(options.metaDataAttributes || []);
+
this.settingsDialogTabs = [
{
name: 'general',
@@ -34,6 +34,7 @@
//= require_tree ./views/mixins
//= require ./views/model_thumbnail_view
//= require ./views/file_item_view
+//= require ./views/file_meta_data_item_value_view
//= require ./views/chapter_item_view
//= require ./views/page_item_view
//= require ./views/inputs/reference_input_view
@@ -7,7 +7,11 @@ pageflow.app.addInitializer(function(options) {
pageflow.editor.fileTypes.register('video_files', {
model: pageflow.VideoFile,
- metaDataAttributes: ['format', 'dimensions', 'duration'],
+ metaDataAttributes: [
+ 'format',
+ 'dimensions',
+ 'duration',
+ ],
matchUpload: /^video/,
settingsDialogTabs: [
{
@@ -0,0 +1,3 @@
+<a class="edit" href="" title="<%= I18n.t('pageflow.editor.templates.file_meta_data_item_value_view.edit') %>">
+</a>
+<span class="value"></span>
@@ -94,11 +94,17 @@ pageflow.FileItemView = Backbone.Marionette.ItemView.extend({
metaDataViews: function() {
var model = this.model;
- return _.map(this.options.metaDataAttributes, function(attribute) {
- return new pageflow.FileMetaDataItemView({
- model: model,
- attribute: attribute
- });
+ return _.map(this.options.metaDataAttributes, function(options) {
+ if (typeof options === 'string') {
+ options = {
+ name: options,
+ valueView: pageflow.TextFileMetaDataItemValueView
+ };
+ }
+
+ return new pageflow.FileMetaDataItemView(_.extend({
+ model: model
+ }, options));
});
},
@@ -0,0 +1,49 @@
+/**
+ * Base class for views used as `valueView` for file type meta data
+ * attributes.
+ *
+ * @param {string} [options.name]
+ * Name of the meta data item used in translation keys.
+ *
+ * @param {string} [options.settingsDialogTabLink]
+ * Dispaly a link to open the specified tab of the file settings
+ * dialog.
+ *
+ * @since edge
+ *
+ * @class
+ * @memberof module:pageflow/editor
+ */
+pageflow.FileMetaDataItemValueView = Backbone.Marionette.ItemView.extend({
+ template: 'templates/file_meta_data_item_value_view',
+
+ ui: {
+ value: '.value',
+ editLink: '.edit'
+ },
+
+ events: {
+ 'click .edit': function() {
+ pageflow.FileSettingsDialogView.open({
+ model: this.model,
+ tabName: this.options.settingsDialogTabLink
+ });
+ }
+ },
+
+ onRender: function() {
+ this.listenTo(this.model, 'change:' + this.options.name, this.update);
+ this.ui.editLink.toggle(!!this.options.settingsDialogTabLink);
+
+ this.update();
+ },
+
+ update: function() {
+ this.ui.value.text(this.getText() ||
+ I18n.t('pageflow.editor.views.file_meta_data_item_value_view.blank'));
+ },
+
+ getText: function() {
+ throw new Error('Not implemented');
+ }
+});
@@ -8,12 +8,23 @@ pageflow.FileMetaDataItemView = Backbone.Marionette.ItemView.extend({
},
onRender: function() {
- this.update();
- this.listenTo(this.model, 'change:' + this.options.attribute, this.update);
+ this.subview(new this.options.valueView(_.extend({
+ el: this.ui.value,
+ model: this.model,
+ name: this.options.name
+ }, this.options.valueViewOptions || {})));
+
+ this.ui.label.text(this.labelText());
},
- update: function() {
- this.ui.label.text(I18n.t('activerecord.attributes.' + this.model.i18nKey + '.' + this.options.attribute));
- this.ui.value.text(this.model.get(this.options.attribute));
+ labelText: function() {
+ return pageflow.i18nUtils.attributeTranslation(this.options.name, 'label', {
+ prefixes: [
+ 'pageflow.editor.files.attributes.' + this.model.fileType().collectionName,
+ 'pageflow.editor.files.common_attributes'
+ ],
+ fallbackPrefix: 'activerecord.attributes',
+ fallbackModelI18nKey: this.model.i18nKey
+ });
}
});
@@ -0,0 +1,16 @@
+/**
+ * Renders the value of the attribute given in `options.name`.
+ *
+ * @see {@link module:pageflow/editor.pageflow.FileMetaDataItemValueView
+ * pageflow.FileMetaDataItemValueView} for further options.
+ *
+ * @since edge
+ *
+ * @class
+ * @memberof module:pageflow/editor
+ */
+pageflow.TextFileMetaDataItemValueView = pageflow.FileMetaDataItemValueView.extend({
+ getText: function() {
+ return this.model.get(this.options.name);
+ }
+});
@@ -1,18 +1,28 @@
+$file-meta-data-label-color: #888 !default;
+$file-meta-data-icon-link-color: #555 !default;
+$file-meta-data-active-icon-link-color: #000 !default;
+
.file_meta_data {
margin-left: -65px;
+ white-space: normal;
table {
margin-bottom: 5px;
width: 100%;
}
+ th,
+ td {
+ vertical-align: top;
+ }
+
th {
width: 45px;
- padding: 5px 20px 5px 0;
+ padding: 7px 20px 5px 0;
font-weight: normal;
text-align: right;
font-size: 11px;
- color: #888;
+ color: $file-meta-data-label-color;
}
td {
@@ -23,9 +33,19 @@
text-decoration: underline;
}
- input[type="text"] {
- display: block;
- line-height: 15px;
- margin: -5px 0;
+ .edit {
+ @include background-icon-center($font-size: 15px,
+ $color: $file-meta-data-icon-link-color);
+ @include pencil-icon;
+
+ display: inline-block;
+ width: 20px;
+ height: 20px;
+ float: right;
+ margin-top: -2px;
+
+ &:hover {
+ @include background-icon-color($file-meta-data-active-icon-link-color);
+ }
}
}
@@ -0,0 +1,13 @@
+de:
+ pageflow:
+ editor:
+ files:
+ common_attributes:
+ text_tracks:
+ label: "Untertitel"
+ templates:
+ file_meta_data_item_value_view:
+ edit: "Bearbeiten"
+ views:
+ file_meta_data_item_value_view:
+ blank: "-"
@@ -0,0 +1,13 @@
+de:
+ pageflow:
+ editor:
+ files:
+ common_attributes:
+ text_tracks:
+ label: "Subtitles"
+ templates:
+ file_meta_data_item_value_view:
+ edit: "Edit"
+ views:
+ file_meta_data_item_value_view:
+ blank: "-"
@@ -122,6 +122,27 @@ type.
metaDataAttributes: ['dimensions']
};
+Meta data attributes can also specify a Backbone view to render the
+value:
+
+ # app/assets/javascripts/pageflow/rainbow/editor/config.js
+ pageflow.editor.fileTypes.register('pageflow_rainbow_files', {
+ model: pageflow.ImageFile,
+ matchUpload: /^image/,
+ metaDataAttributes: [
+ {
+ name: 'custom',
+ valueView: pageflow.TextFileMetaDataItemValueView,
+ valueViewOptions: {
+ settingsDialogTabLink: 'general'
+ }
+ ]
+ };
+
+See `pageflow.TextFileMetaDataItemValueView` for more information. You
+can also create a custom view by extending
+`pageflow.FileMetaDataItemValueView`.
+
## Custom Processing Stages
The `HostedFile` mixin defines a state machine which captures the
@@ -0,0 +1,9 @@
+support.dom.FileMetaDataTable = support.dom.Base.extend({
+ selector: '.file_meta_data table',
+
+ values: function() {
+ return this.$el.find('.value').map(function() {
+ return $(this).text();
+ }).get();
+ }
+});
@@ -0,0 +1,43 @@
+describe('FileItemView', function() {
+ it('renders meta data items given as string', function() {
+ var file = support.factories.file(
+ {dimension: '200x100px'}
+ );
+ var fileItemView = new pageflow.FileItemView({
+ model: file,
+ metaDataAttributes: ['dimension']
+ });
+
+ fileItemView.render();
+ var fileMetaDataTable = support.dom.FileMetaDataTable.find(fileItemView);
+
+ expect(fileMetaDataTable.values()).include('200x100px');
+ });
+
+ it('renders meta data items with custom view and options', function() {
+ var file = support.factories.file(
+ {dimension: '200x100px'}
+ );
+ var fileItemView = new pageflow.FileItemView({
+ model: file,
+ metaDataAttributes: [
+ {
+ name: 'dimension',
+ valueView: pageflow.FileMetaDataItemValueView.extend({
+ getText: function() {
+ return this.model.get(this.options.name) + this.options.suffix;
+ }
+ }),
+ valueViewOptions: {
+ suffix: '!!'
+ }
+ }
+ ]
+ });
+
+ fileItemView.render();
+ var fileMetaDataTable = support.dom.FileMetaDataTable.find(fileItemView);
+
+ expect(fileMetaDataTable.values()).include('200x100px!!');
+ });
+});
@@ -0,0 +1,42 @@
+describe('FileMetaDataItemView', function() {
+ describe('#labelText', function() {
+ support.useFakeTranslations({
+ 'pageflow.editor.files.attributes.image_files.alt.label': 'Image alt text',
+ 'pageflow.editor.files.common_attributes.text_tracks.label': 'Text tracks',
+ 'activerecord.attributes.pageflow/image_files.rights': 'Rights'
+ });
+
+ it('uses file type specific translatons', function() {
+ var view = new pageflow.FileMetaDataItemView({
+ model: support.factories.imageFile(),
+ name: 'alt'
+ });
+
+ var result = view.labelText();
+
+ expect(result).to.eq('Image alt text');
+ });
+
+ it('falls back to common file translation', function() {
+ var view = new pageflow.FileMetaDataItemView({
+ model: support.factories.imageFile(),
+ name: 'text_tracks'
+ });
+
+ var result = view.labelText();
+
+ expect(result).to.eq('Text tracks');
+ });
+
+ it('falls back to legacy translation', function() {
+ var view = new pageflow.FileMetaDataItemView({
+ model: support.factories.imageFile(),
+ name: 'rights'
+ });
+
+ var result = view.labelText();
+
+ expect(result).to.eq('Rights');
+ });
+ });
+});

0 comments on commit 81f3771

Please sign in to comment.