Imperavi Redactor — візуальний редактор для Yii Framework 1.1 / Студія Віталія Комлєва, розробка веб-сайтів Харків

Чувствуете себя не в своей тарелке?..

Перейти к русскоязычной версии

Imperavi Redactor — візуальний редактор для Yii Framework 1.1

Веб-дизайн і аналітика

Imperavi Redactor — один із найкращих WYSIWYG-редакторів на jQuery.

В процесі проектування панелі керування для одного із своїх ранніх проектів я був поставлений перед питанням вибору візуального редактора. Критерії були приблизно наступні: легкий (в той же час інтернет-з'єднання було не таке швидке), без гальм в роботі і «випадкових» збоїв із втратою тексту, функціональний і гарний. Топові на той момент FCKEditor і TinyMCE здавалися мені схожими на неандертальців: великі, неповороткі, страшні. Зрештою, прямих конкурентів у них практично не було: більшість рішень справлялися з розміткою, але питання завантаження зображень і файлів делікатно обходили стороною.

Зайдений мною Imperavi Redactor був не те, щоб зручніше, але однозначно красивіше як WYSIWYG-монстрів, так і маленьких редакторів. Зрештою, з часом команда розробників більш ніж заповнила недолік функціоналу. На сьогодні цей інструмент дозволяє:

  • створювати основнуі розмітку тексту (жирний, курсив, підкреслення, списки, вирівнювання, таблиці, посилання)
  • завантажувати в текст зображення
  • завантажувати файли
  • окрім базових функцій є велика база розширень-плагінів, яка постійно поповнюється

На даний момент скрипт є платним, однак спільнота розробників Yii Framework придбало OEM-ліцензію, яка дозволяє користуватися редактором в Yii-проектах.

Як встановити Imperavi Redactor?

Після завантаження розширення розпаковуємо його в теку protected/extensions/.

Далі, в проекті імпортуємо розширення в конфігураційному файлі або підключаємо віджет на сторінці:

Yii::import('ext.imperavi-redactor-widget.ImperaviRedactorWidget');

Викликаємо віджет:

$this->widget('ImperaviRedactorWidget', array(
    // Можно использовать для атрибута модели  
    'model' => $my_model,
    'attribute' => 'my_field',
    // или для обычного текстового поля
    'name' => 'my_input_name',
    // Больше опций на <a href="http://imperavi.com/redactor/docs/">http://imperavi.com/redactor/docs/</a>
    'options' => array(
        'lang' => 'ru',
        'toolbar' => false,
        'iframe' => true,
        'css' => 'wym.css',
    ),
));

Більш детальноо про це розказано на сторінці розширення.

Як налаштувати завантаження зображень і файлів?

Окрім налаштування візуального редактора знадобиться також додати функціонал обробки даних в контролер. Imperavi Redactor дозволяє як завантажити зображення, так і обрати його із списку вже завантажених. Розглянемо перший варіант.

Налаштовуємо віджет:

$this->widget('ImperaviRedactorWidget', array(
    'selector' => '.redactor',
    'options' => array(     
        'imageGetJson' => Yii::app()->createAbsoluteUrl('/site/imageGetJson'),
        'imageUpload' => Yii::app()->createAbsoluteUrl('/site/imageUpload'),
        'clipboardUploadUrl' => Yii::app()->createAbsoluteUrl('/site/imageUpload'),
        'fileUpload' => Yii::app()->createAbsoluteUrl('/site/fileUpload')
    )
));

Створюємо екшен в контролері, наприклад в SiteController, при цьому не забуваючи про політику безпеки:

public function accessRules() {
    return array(
        array('allow',
            'actions'=>array('index'),
            'users'=>array('*'),
        ),
        array('allow',
            'actions'=>array('imageUpload', 'imageGetJson', 'fileUpload'),
            'users'=>array('admin'),
        ),
        array('deny',
            'users'=>array('*'),
        ),
    );
}

Другий і третій екшени знадобляться нам для отримання списку завантажених зображень і для завантаження файлів.

При завантаженні зображення я радже одразу робити і прев'ю, щоб видавати його у списку завантажених. Сам екшен завантаження зображення actionImageUpload може виглядати так:

public function actionImageUpload() {
    $image=CUploadedFile::getInstanceByName('file');
    $filename = 'a_'.date('YmdHis').'_'.substr(md5(time()), 0, rand(7, 13)).'.'.$image->extensionName;
    $path = dirname(__FILE__).'/../../resources/articles/'.$filename;
    $image->saveAs(dirname(__FILE__).'/../../resources/articles/'.$filename);
    $image_open = Yii::app()->image->load(dirname(__FILE__).'/../../resources/articles/'.$filename);
    if (isset($image_open)) {
        if ($image_open->width > $image_open->height) $dim = Image::HEIGHT; else $dim = Image::WIDTH;
        $image_open->resize(100, 100, $dim)->crop(100, 100);
        $image_open->save(dirname(__FILE__).'/../../resources/articles/thumbs/'.$filename);
    }
    $array = array(
        'filelink' => Yii::app()->request->hostInfo.'/resources/articles/'.$filename,
        'filename' => $filename
    );
    echo stripslashes(json_encode($array));
}

Трохи простіше виглядає завантаження файлу. При бажанні можні додати перевірку MIME-типу чи хоча б розширення файлу, якщо потрібна підвищена увагу до безпеки:

public function actionFileUpload() {
    $file=CUploadedFile::getInstanceByName('file');
    $filename = md5(time()).'.'.$file->extensionName;
    $path = dirname(__FILE__).'/../../resources/articles/'.$filename;
    copy($_FILES['file']['tmp_name'], $path);
    $array = array(
        'filelink' => Yii::app()->request->hostInfo.'/resources/articles/'.$filename,
        'filename' => $filename
    );
    echo stripslashes(json_encode($array));
}

При формуванні списку завантажених зображень скористаємося текою з прев'ю, яке ми дбайливо генерували при завантаженні:

public function actionImageGetJson() {
    $dir = dirname(__FILE__).'/../../resources/articles/thumbs/';
    $files = array();
    if (is_dir($dir)) {
        if ($dh = opendir($dir)) {
            while (($file = readdir($dh)) !== false) {
                if ($file != '.' && $file != '..')
                    $files[] = array(
                        'thumb' => Yii::app()->request->hostInfo.'/resources/articles/thumbs/'.$file,
                        'image' => Yii::app()->request->hostInfo.'/resources/articles/'.$file,
                        'title' => $file,
                    );
            }
            closedir($dh);
        }
    }
    echo json_encode($files);
}

В підсумку отримаємо візуальний редактор, який крім надійної роботи і приємного зовнішнього виду дає користувачу можливість оформлювати матеріали за допомогою завантажених зображень, підвантажувати файли.

Корисним буде не просто завантажувати на сервер все, що надсилається із візуального редактора. Зображення найчастіше можна (і треба) стискати до більш-менш адекватного розміру. Звично 1500 пікселів по великій стороні вистачить з головою, коли як клієнт може завантажувати на сайт вихідник фотографії розмірами 4000х3000 пікселів.

Цікавим буде також питання зберігання назв файлів в зрозумілому видгляді: приємніше завантажувати файл «Прайси за 21.10.2014.xls», аніж який-небудь «20141021150314_4fsedf9sdfs.xls». Але зберігати в теці «різну» компанію таких «прайсів» також не кращий варіант, особливо коли починається різне «Прайси за 21.10.2014 (1).xls», «Прайси за 21.10.2014 (2).xls» тощо. У кого є гарне рішення, яке дає універсальність перейменованих файлів і зручність зрозумілих назв — дайте знати.