diff --git a/assets/scripts/admin-cms.js b/assets/scripts/admin-cms.js index 46ea4565..23563e78 100644 --- a/assets/scripts/admin-cms.js +++ b/assets/scripts/admin-cms.js @@ -22,6 +22,7 @@ import './admin/content-edit/preview-media-choice'; import './admin/content-edit/preview-media-modal'; import './admin/content-edit/preview-tag-type'; import './admin/content-edit/preview-toggle'; +import './admin/content-edit/translations-json'; import './admin/content-edit/wysiwyg'; import './admin/confirm-modal'; diff --git a/assets/scripts/admin/content-edit/translations-json.js b/assets/scripts/admin/content-edit/translations-json.js new file mode 100644 index 00000000..1821b0d9 --- /dev/null +++ b/assets/scripts/admin/content-edit/translations-json.js @@ -0,0 +1,40 @@ +import {cmsEditListener} from './event-listeners'; +import {registerFeature} from '@softspring/cms-bundle/scripts/tools'; + +registerFeature('admin_content_edit_translations_json', _init); + +/** + * Init behaviour + * @private + */ +function _init() { + cmsEditListener('[data-translation-json-field]', 'input', onEditTranslationInput); + cmsEditListener('[data-edit-content-target]', 'input', onEditTranslationContent); +} + +/** + * On translation input change, update json field + */ +function onEditTranslationInput(inputElement, module, preview, form/*, event*/) { + updateTranslationJson(inputElement); +}; + +/** + * On translation input change, update json field + */ +function onEditTranslationContent(editableContent, module, preview, form/*, event*/) { + let inputElement = form.querySelector('[data-edit-content-input="' + editableContent.dataset.editContentTarget + '"]'); + if (!inputElement.dataset.translationJsonField) { + return; + } + + updateTranslationJson(inputElement); +}; + + +function updateTranslationJson(inputElement) { + let jsonField = document.getElementById(inputElement.dataset.translationJsonField); + let jsonValue = JSON.parse(jsonField.value); + jsonValue[inputElement.dataset.inputLang] = inputElement.value; + jsonField.value = JSON.stringify(jsonValue); +} \ No newline at end of file diff --git a/src/Form/Type/TranslationType.php b/src/Form/Type/TranslationType.php index 98b7884f..1942bd18 100644 --- a/src/Form/Type/TranslationType.php +++ b/src/Form/Type/TranslationType.php @@ -6,8 +6,15 @@ use Softspring\CmsBundle\Translator\TranslatableContext; use Softspring\Component\DynamicFormType\Form\Resolver\TypeResolverInterface; use Softspring\TranslatableBundle\Form\Type\TranslationType as BaseTranslationType; +use Softspring\TranslatableBundle\Model\Translation; use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\Extension\Core\Type\HiddenType; use Symfony\Component\Form\Extension\Core\Type\TextType; +use Symfony\Component\Form\FormBuilderInterface; +use Symfony\Component\Form\FormEvent; +use Symfony\Component\Form\FormEvents; +use Symfony\Component\Form\FormInterface; +use Symfony\Component\Form\FormView; use Symfony\Component\OptionsResolver\OptionsResolver; class TranslationType extends AbstractType @@ -30,8 +37,6 @@ public function getBlockPrefix(): string public function configureOptions(OptionsResolver $resolver): void { - // parent::configureOptions($resolver); - $resolver->setDefaults([ 'default_language' => $this->translatableContext->getDefaultLocale(), 'languages' => $this->translatableContext->getLocales(), @@ -42,4 +47,41 @@ public function configureOptions(OptionsResolver $resolver): void return $this->getFieldType($value); }); } + + public function buildForm(FormBuilderInterface $builder, array $options): void + { + $builder->add('_json', HiddenType::class); + + $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) { + $data = $event->getData(); + if ($data instanceof Translation) { + unset($data['_json']); + $data->setTranslation('_json', json_encode($data->__toArray())); + } + }); + + $builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) { + $data = $event->getData(); + + $json = json_decode($data['_json'], true); + unset($json['_json']); + $data = array_merge($data, $json); + $event->setData($data); + }); + } + + public function finishView(FormView $view, FormInterface $form, array $options): void + { + $translationJsonFieldId = $view->children['_json']->vars['id']; + + foreach ($view->children as $locale => $field) { + if ('_json' !== $locale) { + $field->vars['full_name'] = ''; + + if (!str_starts_with($locale, '_')) { + $field->vars['attr']['data-translation-json-field'] = $translationJsonFieldId; + } + } + } + } } diff --git a/templates/forms/translatable_type.html.twig b/templates/forms/translatable_type.html.twig index 7c057b13..23ec4ae7 100644 --- a/templates/forms/translatable_type.html.twig +++ b/templates/forms/translatable_type.html.twig @@ -7,5 +7,23 @@ {% if attr['data-media-preview-input']|default(false) %} {% set attr = attr|merge({'data-media-preview-input': attr['data-media-preview-input']~'.'~form.vars.label|lower}) -%} {% endif %} - {{ parent() }} -{% endblock %} \ No newline at end of file + {% if not translate_prepend_button|default(false) %} + {# adding data-lang allows to filter fields in content edition #} +
+ + {{ form.vars.label|upper }} + + {% endif %} + + {{ form_widget(form, {'attr':attr}) }} + + {% if not translate_prepend_button|default(false) %} +
+ {% endif %} +{% endblock %} + +{% block cms_translation_widget %} + {{ form_widget(form._trans_id) }} + {{ form_widget(form._json) }} + {{ block('translatable_widget') }} +{% endblock cms_translation_widget %}