Skip to content

Commit

Permalink
Allow wysiwyg for media.
Browse files Browse the repository at this point in the history
  • Loading branch information
haringsrob committed Apr 1, 2022
1 parent 49368da commit 7f42232
Show file tree
Hide file tree
Showing 8 changed files with 101 additions and 27 deletions.
14 changes: 14 additions & 0 deletions config/media-library.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,18 @@
'prefix_uuid_with_local_path' => config('twill.file_library.prefix_uuid_with_local_path', false),
'translated_form_fields' => false,
'show_file_name' => false,
/*
|--------------------------------------------------------------------------
| Wysiwyg options for the caption field.
|--------------------------------------------------------------------------
*/
'media_caption_use_wysiwyg' => false,
'media_caption_wysiwyg_options' => [
'modules' => [
'toolbar' => [
'bold',
'italic',
],
],
],
];
9 changes: 8 additions & 1 deletion frontend/js/components/MediaField.vue
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,11 @@
<!-- Metadatas options -->
<div class="media__metadatas--options" :class="{ 's--active' : metadatas.active }" v-if="hasMedia && withAddInfo">
<a17-mediametadata :name='metadataName' :label="$trans('fields.medias.alt-text', 'Alt Text')" id="altText" :media="media" :maxlength="altTextMaxLength" @change="updateMetadata"/>
<a17-mediametadata v-if="withCaption" :name='metadataName' :label="$trans('fields.medias.caption', 'Caption')" id="caption" :media="media" :maxlength="captionMaxLength" @change="updateMetadata"/>

<a17-mediametadata v-if="withCaption" :wysiwyg="useWysiwyg" :wysiwyg-options="wysiwygOptions" type='text' :name='metadataName' :label="$trans('fields.medias.caption', 'Caption')" id="caption" :media="media" :maxlength="captionMaxLength" @change="updateMetadata"/>

<a17-mediametadata v-if="withVideoUrl" :name='metadataName' :label="$trans('fields.medias.video-url', 'Video URL (optional)')" id="video" :media="media" @change="updateMetadata"/>

<template v-for="field in extraMetadatas">
<a17-mediametadata v-if="extraMetadatas.length > 0"
:key="field.name"
Expand Down Expand Up @@ -189,6 +192,10 @@
},
filters: a17VueFilters,
computed: {
...mapState({
useWysiwyg: state => state.mediaLibrary.config.useWysiwyg,
wysiwygOptions: state => state.mediaLibrary.config.wysiwygOptions
}),
cropThumbnailStyle: function () {
if (this.showImg) return {}
if (!this.hasMedia) return {}
Expand Down
27 changes: 25 additions & 2 deletions frontend/js/components/MediaMetadata.vue
Original file line number Diff line number Diff line change
@@ -1,14 +1,26 @@
<template>
<a17-locale v-if="languages.length > 1 && fieldType === 'text'"
type="a17-textfield"
:type="wysiwyg ? 'a17-wysiwyg' : 'a17-textfield'"
:initialValues="initialValues"
:attributes="attributes"
@change="saveMetadata">
</a17-locale>
<div v-else-if="fieldType === 'text' && wysiwyg">
<a17-wysiwyg :options="wysiwygOptions"
:label="label"
:name="fieldName"
:type="fieldType"
:initialValue="initialValue"
in-store="value"
:maxlength="maxlength"
@change="saveMetadata"
></a17-wysiwyg>
<p class="f--note f--small" v-html="placeholder" />
</div>
<a17-textfield v-else-if="fieldType === 'text'"
:label="label"
:name="fieldName"
type="text"
:type="fieldType"
:placeholder="placeholder"
:initialValue="initialValue"
in-store="value"
Expand Down Expand Up @@ -47,6 +59,17 @@
type: String,
required: true
},
wysiwyg: {
type: Boolean,
default: false
},
wysiwygOptions: {
type: Object,
required: false,
default: function () {
return {}
}
},
type: {
type: String,
required: false
Expand Down
41 changes: 23 additions & 18 deletions frontend/js/components/Wysiwyg.vue
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@
activeSource: false,
quill: null,
counter: 0,
localOptions: {},
defaultModules: {
toolbar: ['bold', 'italic', 'underline', 'link'],
// Complete Toolbar example :
Expand Down Expand Up @@ -156,9 +157,9 @@
}
},
methods: {
initQuill () {
initQuill (options) {
// init Quill
this.quill = new QuillConfiguration.Quill(this.$refs.editor, this.options)
this.quill = new QuillConfiguration.Quill(this.$refs.editor, options)
// set editor content
if (this.value) this.updateEditor(this.value)
Expand Down Expand Up @@ -276,41 +277,45 @@
mounted: function () {
if (this.quill) return
const localOptions = JSON.parse(JSON.stringify(this.options))
/* global hljs */
this.options.theme = this.options.theme || 'snow'
this.options.boundary = this.options.boundary || document.body
this.options.modules = this.options.modules || this.defaultModules
localOptions.theme = localOptions.theme || 'snow'
localOptions.boundary = localOptions.boundary || document.body
localOptions.modules = localOptions.modules || this.defaultModules
const toolbar = {
container: this.options.modules.toolbar !== undefined ? this.options.modules.toolbar : this.defaultModules.toolbar,
container: localOptions.modules.toolbar !== undefined ? localOptions.modules.toolbar : this.defaultModules.toolbar,
handlers: {}
}
this.options.modules.clipboard = this.options.modules.clipboard !== undefined ? this.options.modules.clipboard : this.defaultModules.clipboard
this.options.modules.keyboard = this.options.modules.keyboard !== undefined ? this.options.modules.keyboard : this.defaultModules.keyboard
this.options.modules.syntax = this.options.modules.syntax !== undefined && this.options.modules.syntax ? { highlight: text => hljs.highlightAuto(text).value } : this.defaultModules.syntax
this.options.placeholder = this.options.placeholder || this.placeholder
this.options.readOnly = this.options.readOnly !== undefined ? this.options.readOnly : this.readonly
this.options.formats = QuillConfiguration.getFormats(this.options.modules.toolbar) // Formats are based on current toolbar configuration
this.options.bounds = this.$refs.editor
localOptions.modules.clipboard = localOptions.modules.clipboard !== undefined ? localOptions.modules.clipboard : this.defaultModules.clipboard
localOptions.modules.keyboard = localOptions.modules.keyboard !== undefined ? localOptions.modules.keyboard : this.defaultModules.keyboard
localOptions.modules.syntax = localOptions.modules.syntax !== undefined && localOptions.modules.syntax ? { highlight: text => hljs.highlightAuto(text).value } : this.defaultModules.syntax
localOptions.placeholder = localOptions.placeholder || this.placeholder
localOptions.readOnly = localOptions.readOnly !== undefined ? localOptions.readOnly : this.readonly
localOptions.formats = QuillConfiguration.getFormats(localOptions.modules.toolbar) // Formats are based on current toolbar configuration
localOptions.bounds = this.$refs.editor
// Ensure pasting content do not make editor scroll to the top
// @see https://github.com/quilljs/quill/issues/1374#issuecomment-545112021
this.options.scrollingContainer = 'html'
localOptions.scrollingContainer = 'html'
// register custom handlers
// register anchor toolbar handler
if (toolbar.container.includes('anchor')) {
toolbar.handlers.anchor = this.anchorHandler
}
this.options.modules.toolbar = toolbar
localOptions.modules.toolbar = toolbar
this.localOptions = localOptions
if (this.options.modules.syntax && typeof hljs === 'undefined') {
if (localOptions.modules.syntax && typeof hljs === 'undefined') {
const id = 'highlight-js-script'
loadScript(id, HIGHLIGHT, 'text/javascript').then(() => {
this.initQuill()
this.initQuill(localOptions)
})
} else {
this.initQuill()
this.initQuill(localOptions)
}
},
beforeDestroy () {
Expand Down
24 changes: 18 additions & 6 deletions frontend/js/components/media-library/MediaSidebar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,21 @@
<a17-textfield v-else-if="isImage" :label="$trans('media-library.sidebar.alt-text', 'Alt text')" name="alt_text"
:initialValue="firstMedia.metadatas.default.altText" size="small" @focus="focus" @blur="blur"/>

<a17-locale type="a17-textfield" v-if="isImage && translatableMetadatas.includes('caption')"
:attributes="{ type: 'textarea', rows: 1, label: $trans('media-library.sidebar.caption', 'Caption'), name: 'caption', size: 'small' }"
:initialValues="captionValues" @focus="focus" @blur="blur"></a17-locale>
<a17-textfield v-else-if="isImage" type="textarea" :rows="1" size="small" :label="$trans('media-library.sidebar.caption', 'Caption')" name="caption"
:initialValue="firstMedia.metadatas.default.caption" @focus="focus" @blur="blur"/>
<template v-if="useWysiwyg">
<a17-locale type="a17-wysiwyg" v-if="isImage && translatableMetadatas.includes('caption')"
:attributes="{ options: wysiwygOptions, label: $trans('media-library.sidebar.caption', 'Caption'), name: 'caption', size: 'small' }"
:initialValues="captionValues" @focus="focus" @blur="blur"></a17-locale>
<a17-wysiwyg v-else-if="isImage" type="textarea" :rows="1" size="small" :label="$trans('media-library.sidebar.caption', 'Caption')" name="caption"
:options="wysiwygOptions"
:initialValue="firstMedia.metadatas.default.caption" @focus="focus" @blur="blur"/>
</template>
<template v-else>
<a17-locale type="a17-textfield" v-if="isImage && translatableMetadatas.includes('caption')"
:attributes="{ type: 'textarea', rows: 1, label: $trans('media-library.sidebar.caption', 'Caption'), name: 'caption', size: 'small' }"
:initialValues="captionValues" @focus="focus" @blur="blur"></a17-locale>
<a17-textfield v-else-if="isImage" type="textarea" :rows="1" size="small" :label="$trans('media-library.sidebar.caption', 'Caption')" name="caption"
:initialValue="firstMedia.metadatas.default.caption" @focus="focus" @blur="blur"/>
</template>

<template v-for="field in singleOnlyMetadatas">
<a17-locale type="a17-textfield" v-bind:key="field.name"
Expand Down Expand Up @@ -257,7 +267,9 @@
return this.extraMetadatas.filter(m => !m.multiple || (m.multiple && this.translatableMetadatas.includes(m.name)))
},
...mapState({
mediasLoading: state => state.mediaLibrary.loading
mediasLoading: state => state.mediaLibrary.loading,
useWysiwyg: state => state.mediaLibrary.config.useWysiwyg,
wysiwygOptions: state => state.mediaLibrary.config.wysiwygOptions
})
},
methods: {
Expand Down
4 changes: 4 additions & 0 deletions frontend/js/mixins/mediaField.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ export default {
type: Boolean,
default: true
},
captionTextarea: {
type: Boolean,
default: false
},
altTextMaxLength: {
type: Number,
default: 0
Expand Down
5 changes: 5 additions & 0 deletions frontend/js/store/modules/media-library.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ const state = {
* @type {Object.<string,Object>}
*/
selected: window[process.env.VUE_APP_NAME].STORE.medias.selected || {},
/**
* An object of configs
* @type {Object.<string,Object>}
*/
config: window[process.env.VUE_APP_NAME].STORE.medias.config || { useWysiwyg: false, wysiwygOptions: {} },
/**
* An array of current uploading medias. When upload is ended, array is reset
* @type {Array}
Expand Down
4 changes: 4 additions & 0 deletions views/layouts/main.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@
};
window['{{ config('twill.js_namespace') }}'].STORE.medias = {};
window['{{ config('twill.js_namespace') }}'].STORE.medias.types = [];
window['{{ config('twill.js_namespace') }}'].STORE.medias.config = {
useWysiwyg: {{ config('twill.media_library.media_caption_use_wysiwyg') ? 'true' : 'false' }},
wysiwygOptions: {!! json_encode(config('twill.media_library.media_caption_wysiwyg_options')) !!}
};
window['{{ config('twill.js_namespace') }}'].STORE.languages = {!! json_encode(getLanguagesForVueStore($form_fields ?? [], $translate ?? false)) !!};
@if (config('twill.enabled.media-library'))
Expand Down

0 comments on commit 7f42232

Please sign in to comment.