0.9.37 • Published 7 years ago

giftd-editor v0.9.37

Weekly downloads
2
License
MIT
Repository
-
Last release
7 years ago

Giftd Editor

Оглавление

Описание

Визуальный редактор настроек (кастомизаций) различных страниц - виджеты, емейлы и т.д.

Редактор позволяет изменять различные настройки с возможностью предпросмотра изменений и дальнейшим сохранением значений на бэкенде.

Кроме того, пакет поддерживает возможность расширения путём добавления кастомных полей настроек (по умолчанию с пакетом идут текстовое поле, выпадающий список и список чекбоксов).

Требования

Редактор был разработан таким образом, что его основные элементы находятся в главном окне (странице), а редактируемый контент загружается в iframe. Такой подход позволяет выполнять предпросмотр изменений без перезагрузки основной страницы (что может быть невозможно в случае, если в редактируемом контенте имеется большое количество скриптов, запускаемых при загрузке страницы).

Связь между этими окнами осуществляется с помощью механизма PostMessage.

Требования к подключению скриптов

Для того, чтобы оба окна взаимодействовали корректно, необходимо подключать скрипт редактора перед любыми другими, которые могут добавлять обработчики событий на DOM-элементы (особенно это важно при подключении скрипта на стороне редактируемой страницы). Это объясняется тем, что редактор должен установить свои обработчики раньше всех остальных скриптов, чтобы не допустить выполнения остальных обработчиков по умолчанию.

Для того, чтобы редактор проигнорировал клик по элементам и вызвал оригинальный обработчик события, необходимо кликать по ним с зажатой клавишей Shift.

Требования к редактируемым элементам

Для каждого элемента, который доступен для редактирования, необходимо задать уникальный класс (по умолчанию - giftd-editable), а так же data-атрибут (по умолчанию - data-editable), значением которого нужно указать соответствующий ID редактируемого элемента (см. след. раздел).

Список редактируемых элементов и их настроек

Для того, чтобы редактор знал что именно он должен обрабатывать и как именно, ему необходимо передать список всех возможных элементов и их настроек.

Настройки должны быть сгруппированы произвольным образом. Каждая группа должна иметь ID, название и список настроек.

Полный список должен примерно так (подробнее в разделе Поля и их настройки):

{
    "texts": {
        "id": "widget-texts-settings",
        "title": "Заголовки виджета",
        "settings": {
            "heading": {
                "title": "Заголовок",
                "type": "text",
                "value": "Hello!",
                "inline": true
            },
            "main_text": {
                "title": "Основной текст",
                "type": "text",
                "value": "This is automated message, {user}, please do not reply.",
                "placeholders": {
                    "user": {
                        "title": "Имя пользователя",
                        "value": "John Doe"
                    }
                }
            }
        }
    }
}

Ключами этих настроек (поле settings каждой группы) должны быть уникальные ID элементов (именно эти ID нужно указывать в атрибутах data-editable). Значением - обязательные поля title, type и value, а так же доп. поля в зависимости от типа настройки.

Предпросмотр и сохранение настроек

Функциональность предпросмотра заключается в следующем алгоритме:

  1. При нажатии на кнопку "Предпросмотр" скрипт получает текущие значения всех настроек и выполняет POST-запрос на URL, указанный в параметре savePreviewUrl. В поле settings будет находиться key-value объект всех настроек;
  2. Контроллер по этому адресу должен выполнить сохранение настроек в сессию или в любое другое удобное для него место, после чего вернуть успешный HTTP-ответ (2XX);
  3. После того, как редактор получил ответ на этот запрос, в редактируемый iframe отправляется команда на переход на страницу, указанную в параметре previewUrl (методом GET);
  4. Контроллер, отвечающий за URL previewUrl должен получить сохраненные ранее настройки предпросмотра и выполнить рендеринг страницы виджета с этими значениями. ВНИМАНИЕ: страница на этом URL не должна ничем отличаться от оригинальной страницы редактируемого контента, за исключением новых значений настроек (т.е. скрипт инициализации редактора должен присутствовать, у редактируемых элементов должны быть установлены класс и data-editable атрибут);
  5. Новая страница автоматически переподключится к родительскому редактору и будет доступна для редактирования и повторных вызовов предпросмотра.

Функциональность сохранения настроек аналогична предпросмотру за исключением сохранения промежуточных настроек. При нажатии на кнопку "Сохранить" редактор отправляет текущие значения на URL, указанный в параметре saveUrl, который должен сохранить настройки и выполнить рендеринг страницы виджета с новыми значениями. Как и в случае предпросмотра, эта страница не должна ничем отличаться от оригинальной редактируемой страницы, за исключением новых значений настроек.

Установка

yarn add giftd-editor # или npm install giftd-editor

Подключение

<script src="giftd-editor.min.js"></script>

После подключения скрипта будет доступна глобальная переменная window.Giftd, позволяющая инициализировать редактор как со стороны основной страницы, так и со стороны редактируемого контента.

Import/require

// ES6 import:
import GiftdEditor from 'giftd-editor'

// require():
const GiftdEditor = require('giftd-editor');

После подключения в переменной GiftdEditor будет находиться объект, позволяющий инициализировать редактор как со стороны основной страницы, так и со стороны редактируемого контента.

Настройки

Основное окно редактора

Модуль редактора должен быть инициализирован со следующими обязательными параметрами:

ПараметрТипОписание
editablesobjectСписок всех настроек и их параметров
containerIdstringID DOM-элемента, в который будет добавлен iframe редактируемого контента
urlstringURL редактируемого контента (на этой странице так же должен быть инициализирован скрипт редактора)
savePreviewUrlstringURL сохранения настроек для предпросмотра изменений
saveUrlstringURL для сохранения настроек (на этой странице так же должен быть инициализирован скрипт редактора)
Giftd.initEditor({
    editables: {},
    containerId: 'editor-container',
    url: '/widget/edit-mode',
    savePreviewUrl: '/widget/save-preview',
    saveUrl: '/widget/save'
})

Кроме того, редактор поддерживает опциональные настройки:

ПараметрТипОписаниеЗначение по умолчанию
titlestringНазвание редактируемого элементаПустая строка
subtitlestringОписание редактируемого элементаПустая строка
localestringЯзык интерфейса редактора (en или ru)en
translationsobjectПереводы отдельных строк (см. раздел "Локализация")Пустой объект
editorContainerstringID элемента, в котором расположен тег <giftd-editor>editor-app
loadingClassstringНазвание CSS-класса, который добавляется контейнеру редактируемого iframegiftd-editor-loading

Окно редактируемого контента

Модуль редактируемого контента должен быть инициализирован со следующими обязательными параметрами:

ПараметрТипОписание
editablesobjectСписок всех настроек и их параметров
editablesSelectorstringСелектор редактируемых DOM-элементов
previewUrlstringURL предпросмотра изменений; редактор перенаправит страницу на этот адрес после сохранения настроек для предпросмотра
Giftd.initContent({
    editables: {},
    editablesSelector: '.giftd-editable',
    previewUrl: '/widget/preview'
})

Редактируемый контент на данный момент не имеет дополнительных опциональных настроек.

Поля и их настройки

Редактор поставляется со следующими типами полей:

  1. Текст - обычный текст, который редактируется с помощью contenteditable, либо текст с предопределенными вставками (плейсхолдеры);
  2. Выпадающий список;
  3. Один или несколько чекбоксов;
  4. Color Picker.

У каждого типа поля имеется свой набор параметров.

Общие параметры

ПараметрТипОписание
titlestringНазвание редактируемой настройки. Отображается в окне редактора
typestringТип редактируемой настройки
valuemixedЗначение настройки по умолчанию

Текст (text)

ПараметрТипОписание
inlinebooleantrue - если текст должен редактироваться с помощью contenteditable. Параметр игнорируется, если у настройки есть параметр placeholders.
placeholdersplaceholders objectСписок возможных вставок (плейсхолдеров)

Каждый элемент параметра placeholders должен иметь следующие параметры:

ПараметрТипОписание
titlestringОписание плейсхолдера. Отображается в виде тултипа при наведении на плейсхолдер.
valuestringЗначение плейсхолдера по умолчанию.

Выпадающий список (select)

ПараметрТипОписание
optionsoptions objectСписок возможных значений выпадающего списка

Каждый элемент параметра options должен иметь следующие параметры:

ПараметрТипОписание
valuemixedЗначение опции
labelstringЛейбл опции

Список чекбоксов (checkboxes)

ПараметрТипОписание
optionsoptions objectСписок значений чекбоксов

Каждый элемент параметра options должен иметь следующие параметры:

ПараметрТипОписание
valuemixedЗначение чекбокса
labelstringЛейбл чекбокса, возможно использовать HTML

Значением настройки с типом checkboxes будет массив, состоящий из отмеченных значений (поле value).

Color Picker (colorpicker)

ПараметрТипОписание
settingsobjectДополнительные настройки компонента

Поле settings может иметь следующие настройки:

ПараметрТипОписаниеПо умолч.
color_typestringТип цвета (hex, rgb, rgba, hsl, hsla), который будет передан в качестве значенияhex

В зависимости от значения color_type в поле попадет цвет с одним из следующих форматов:

  • hex (по умолчанию): #245EA7;
  • rgb: rgb(36, 94, 167);
  • rgba: rgba(36, 94, 167, 0.5);
  • hsl: hsl(213, 64%, 39%);
  • hsl: hsla(213, 64%, 39%, 0.5).

Загрузка изображений(image-upload)

ПараметрТипОписание
settingsobjectДополнительные настройки компонента

Поле settings может иметь следующие настройки:

ПараметрТипОписаниеОбязательно?По умолч.
upload_urlstringАдрес загрузки изображения. Запрос отправляется методом POSTДа--
fieldstringНазвание поля, в котором будет отправлен файл изображенияНетfile
headersobjectСписок заголовков и их значений, которые должны быть отправлены вместе с запросомНет--
response_srcstringПуть к адресу изображения в JSON-ответе от upload_urlНетdata.src

Внимание: адрес, указанный в параметре upload_url при успешной загрузке должен вернуть JSON со структурой, указанной в параметре response_src!

Например, если вы не указывали значение параметра response_src, то компонент будет ожидать JSON-ответ со следующей структурой:

{
    "data": {
        "src": "https://example.org/image.png"
    }
}

В пути data.src (значение response_src по умолчанию) должен находиться URL к загруженному изображению.

Если ваш ответ выглядит (например) так:

{
    "response": {
        "upload": {
            "id": 1,
            "src_big": "https://example.org/image_big.png",
            "src_medium": "https://example.org/image_medium.png",
            "src_thumb": "https://example.org/image_thumb.png"
        }
    }
}

и вы хотите, чтобы значением поля стал адрес medium-изображения, параметр response_src должен выглядеть так: response.upload.src_medium.

События окна редактора

Окно редактора на данный момент поддерживает 2 события: beforePreview и beforeSave. Первое событие вызывается перед сохранением данных предпросмотра, второе - перед сохранением данных.

Обработчики этих событий можно зарегистрировать в параметре events:

Giftd.initEditor({
    events: {
        beforePreview: function (service, values, resolve, reject) {
            console.log('In beforePreview()')
            return resolve()
        },
        beforeSave: function (service, values, resolve, reject) {
            console.log('In beforeSave()')
            return resolve()
        }
    }
})

Оба метода принимают следующие аргументы:

  • service - инстанс класса EditorService;
  • values - key-value объект измененных настроек (editables);
  • resolve - функция, которую необходимо вызвать по завершению работы обработчика события, в том случае, если данные можно сохранять;
  • reject - функция, которую необходимо вызвать по завершению работа обработчика события, в том случае, если должна произойти отмена сохранения данных.

Передача произвольных данных

Кроме передачи системных данных, пакет поддерживает передачу произвольных пользовательских данных. Для того, чтобы устроить такую передачу, необходимо выполнить следующую настройку на обоих сторонах редактора:

Сторона редактируемого контента:

В параметре requestHandlers настроек редактора необходимо указать функции-передатчики данных, каждая из которых должна возвращать Promise-объект:

Giftd.initContent({
    requestHandlers: {
        getLinkValues: function (data) {
            return new Promise(function (resolve, reject) {
                var links = [];

                $('a' + data).each(function () {
                    links.push($(this).attr('href'))
                })

                return resolve(links)
            })
        }
    }
})

Сторона редактора:

На данный момент единственным способом запроса данных являются события beforePreview и beforeSave. Следующий пример показывает как можно запросить все ссылки со страницы редактируемого контента (обработчик, зарегистрированный в первом пункте):

Giftd.initEditor({
    events: {
        beforeSave: function (service, values, resolve, reject) {
            service.initiateDataTransfer('getLinkValues', '.my-class', (err, result) {
                if (err !== null) {
                    console.error('Error occuried', err)
                    return reject() // Запрещаем сохранение данных
                }

                // Добавляем ссылки к данным
                // и вызываем сохранение.

                values.links = result.join(';')

                return resolve(values)
            })
        }
    }
})

Добавление новых полей

Vue-компонент

Добавление нового поля необходимо начать с создания необходимого Vue-компонента.

В каждый компонент передается объект editable в качестве атрибута (property). Таким образом, базовый компонент может выглядеть следующим образом (используется Single File Component:

<template>
    <div class="giftd-editor-password-component">
        <div class="form-group">
            <label :for="componentId">Enter Password:</label>
            <input type="password" v-model="editable.value" class="form-control" :id="componentId">
        </div>
    </div>
</template>

<script>
export default {
    props: ['editable'], // Обязательно
    data() {
        return {
            componentId: `giftd-editor-password-component-${Math.random().toString().replace('.', '_')}`
        }
    }
}
</script>

В случае с простыми полями можно воспользоваться биндингом моделей Vue и указать в v-model непосредственно поле value объекта editable. В этом случае изменения будут поступать в редактор сразу же и без необходимости выполнять доп. действия.

Если же вам нужно реализовать более сложную логику, задавайте новое значение с помощью методов (editable.value = 'my-value';).

Объект editable, передаваемый в компонент, содержит следующие поля:

ПолеТипОписание
componentstringНазвание Vue-компонента этого поля
namestringID текущей настройки
valuemixedЗначение настройки
titlestringНазвание настройки
placeholdersplaceholders objectСписок плейсхолдеров настройки
optionsoptions objectСписок опций настройки
originalobjectСписок всех полей из оригинального объекта

Поле original содержит в себе оригинальный объект, переданный в редактор в момент его инициализации.

Регистрация поля

Для того, чтобы редактор мог обработать новый тип поля, его необходимо зарегистрировать в системе.

import Giftd from 'giftd-editor'
import Password from './my-custom-components/Password.vue'

Регистрация полей происходит с помощью вызова метода registerFields:

Giftd.registerFields([
    {
        type: 'password',
        name: 'Password',
        component: Password,
    }
])

Поле type каждого объекта массива, передаваемого в метод registerFields, определяет тип настройки, который будет указан в объекте editables при инициализации редактора и редактируемого контента.

Поле name определяет название компонента, которое будет использовано для рендеринга динамического компонента в главном окне редактора.

Поле component содержит в себе непосредственно сам объект Vue-компонента.

После регистрации нужных полей можно выполнять инициализацию редактора (Giftd.initEditor()) или редактируемого контента (Giftd.initContent()).

Добавление поля в список настраиваемых элементов

Для того, чтобы нужный элемент пометился как настраиваемый, добавьте новое поле в список editables, а так же добавьте класс giftd-editable и атрибут data-editable на странице редактируемого контента.

{
    "my_password": {
        "type": "password",
        "title": "Пароль",
        "value": "secret",
        "inline": false,
    }
}
0.9.37

7 years ago

0.9.36

7 years ago

0.9.35

7 years ago

0.9.34

7 years ago

0.9.33

7 years ago

0.9.32

7 years ago

0.9.31

7 years ago

0.9.30

7 years ago

0.9.29

7 years ago

0.9.28

7 years ago

0.9.27

7 years ago

0.9.26

7 years ago

0.9.25

7 years ago

0.9.24

7 years ago

0.9.23

7 years ago

0.9.22

7 years ago

0.9.21

7 years ago

0.9.20

7 years ago

0.9.19

7 years ago

0.9.18

7 years ago

0.9.17

7 years ago

0.9.16

7 years ago

0.9.15

7 years ago

0.9.14

7 years ago

0.9.13

7 years ago

0.9.12

7 years ago

0.9.11

7 years ago

0.9.10

7 years ago

0.9.9

7 years ago

0.9.8

7 years ago

0.9.7

7 years ago

0.9.6

7 years ago

0.9.5

7 years ago

0.9.4

7 years ago

0.9.3

7 years ago

0.9.2

7 years ago

0.9.1

7 years ago