Иногда бывает необходимо отобразить на сайте файл не просто ссылкой, а как-нибудь иначе. Видео и аудиофайлы хочется отображать плеером, с возможностью просмотра (прослушивания), swf — сразу отображать на странице. Для прикрепления файлов к материалам есть отличный модуль Filefield, однако выбор форматтеров для него невелик. Файл можно отобразить просто ссылкой. Немного расширяют его функционал другие модули, например Imagefield позволяет отображать картинки. Я попытаюсь доступно объяснить как добавить возможность отображения Flash контента на примере модуля SWFfield.
Далее будет много кода, мало картинок и вообще всё скучно и уныло...
Создаем в директории модулей новый каталог swffield.
Как и для любого модуля нам потребуется файл .info, в нашем случае — swffield.info
Также, нам необходим файл swffield.install
Создадим файлы swffield.module, swffield.render.inc (вынесем сюда весь код, связанный с отображением контента пользователю) и swffield.widget.inc (отображение поля в админке). В принципе, весь код можно писать в swffield.module — работать будет.
swffield.module
swffield.widget.inc
swffield.render.inc
Здесь используется отличная js библиотека SWFobject. Файл swfobject.js необходимо положить в каталог с нашим модулем.
Еще один тонкий момент. Для каждого отображения нашего элемента на странице необходимо сгенерировать уникальный ID, по которому позднее javascript'ом вставится контент. У меня используется rand(1, 10000). Если есть более адекватный способ, буду рад услышать его в комментариях.
Вот собственно и всё, что необходимо для добавления отображения SWF контента на страницах нашего сайта. Аналогичным образом можно например добавить отображение «Видеоплеер» для FLV или «Аудиоплеер» для MP3.
Удачи!
Далее будет много кода, мало картинок и вообще всё скучно и уныло...
Начало
Создаем в директории модулей новый каталог swffield.
Как и для любого модуля нам потребуется файл .info, в нашем случае — swffield.info
Copy Source | Copy HTML
- name = SwfField
- description = Добавляет поле Flash в CCK.
- dependencies[] = content
- dependencies[] = filefield
- package = CCK
- core = 6.x
- version = "6.x-1.1"
Также, нам необходим файл swffield.install
Copy Source | Copy HTML
- // hook_install (установка модуля)
- function swffield_install() {
- // Подгружаем модуль content
- drupal_load('module', 'content');
- // Сообщаем CCK об установке нового модуля
- content_notify('install', 'swffield');
- }
-
- // hook_uninstall (удаление модуля)
- function swffield_uninstall() {
- drupal_load('module', 'content');
- // Сообщаем CCK об удалении нового модуля
- content_notify('uninstall', 'swffield');
- }
-
- // hook_enable (включение модуля)
- function swffield_enable() {
- drupal_load('module', 'content');
- // Сообщаем CCK о включении нового модуля
- content_notify('enable', 'swffield');
- }
-
- // hook_disable (отключение модуля)
- function swffield_disable() {
- drupal_load('module', 'content');
- // Сообщаем CCK об отключении нового модуля
- content_notify('disable', 'swffield');
- }
Модуль
Создадим файлы swffield.module, swffield.render.inc (вынесем сюда весь код, связанный с отображением контента пользователю) и swffield.widget.inc (отображение поля в админке). В принципе, весь код можно писать в swffield.module — работать будет.
swffield.module
Copy Source | Copy HTML
- // Подключаем необходимые файлы
- module_load_include('inc', 'swffield', 'swffield.render');
- module_load_include('inc', 'swffield', 'swffield.widget');
-
- // Инициализация. Проверяем, есть ли Filefield, если нету, отключаем модуль.
- function swffield_init() {
- if (!module_exists('filefield')) {
- module_disable(array('swffield'));
- return;
- }
- }
-
- // Задаем форму ввода данных виджета и способ ее обработки.
- // Наше поле ничем не отличается от поля Filefield
- function swffield_elements() {
- $filefield_elements = module_invoke('filefield', 'elements');
- $elements['swffield_widget'] = $filefield_elements['filefield_widget'];
-
- return $elements;
- }
-
- // Сообщаем CCK информацию о форматтере
- function swffield_field_formatter_info() {
- $formatters = array(
- 'swffield_flash' => array(
- 'label' => t('Flash'),
- 'field types' => array('filefield'),
- 'description' => t('Displays Flash content'),
- ),
- );
- return $formatters;
- }
-
- // Указываем стандартное значение поля такое же как и у Filefield
- function swffield_default_value(&$form, &$form_state, $field, $delta) {
- return filefield_default_value($form, $form_state, $field, $delta);
- }
-
- // Указываем, когда считать поле пустым
- function swffield_content_is_empty($item, $field) {
- return filefield_content_is_empty($item, $field);
- }
-
- // Добавляем еще один обработчик для сохранения настроек поля
- function swffield_form_content_field_overview_form_alter(&$form, &$form_state) {
- $form['#submit'][] = 'swffield_form_content_field_overview_submit';
- }
-
- // Обработчик сохранения настроек поля
- function swffield_form_content_field_overview_submit(&$form, &$form_state) {
- // Если добавляем новое поле к материалу
- if (isset($form_state['fields_added']['_add_new_field']) && isset($form['#type_name'])) {
- // Тип поля
- $new_field = $form_state['fields_added']['_add_new_field'];
- // Тип материала
- $node_type = $form['#type_name'];
- // Массив с данными о поле
- $field = content_fields($new_field, $node_type);
- // Если поле добавляется нашим модулем
- if ($field['widget']['module'] == 'swffield') {
- foreach ($field['display_settings'] as $display_type => $display_settings) {
- if ($field['display_settings'][$display_type]['format'] == 'default') {
- // Устанавливаем отображение поля "swffield_flash"
- $field['display_settings'][$display_type]['format'] = 'swffield_flash';
- }
- }
- // Обновляем поле
- content_field_instance_update($field);
- }
- }
- }
swffield.widget.inc
Copy Source | Copy HTML
- // Сообщаем CCK информацию о виджете
- function swffield_widget_info() {
- return array(
- 'swffield_widget' => array(
- 'label' => t('Flash'),
- 'field types' => array('filefield'),
- 'multiple values' => CONTENT_HANDLE_CORE,
- 'callbacks' => array('default value' => CONTENT_CALLBACK_CUSTOM),
- 'description' => 'Flash content',
- ),
- );
- }
-
- // Этот хук будет вызываться каждый раз, когда наше поле добавляется в форму
- function swffield_widget(&$form, &$form_state, $field, $items, $delta = 0) {
- $element = filefield_widget($form, $form_state, $field, $items, $delta);
-
- return $element;
- }
-
- // Настройки виджета (поля)
- function swffield_widget_settings($op, $widget) {
- switch ($op) {
- case 'form':
- return swffield_widget_settings_form($widget);
- case 'validate':
- return swffield_widget_settings_validate($widget);
- case 'save':
- return swffield_widget_settings_save($widget);
- }
- }
-
- // Форма настроек поля
- function swffield_widget_settings_form($widget) {
- $form = module_invoke('filefield', 'widget_settings', 'form', $widget);
- // По умолчанию CCK подставляет тип файла txt
- // Заменим его на swf
- if ($form['file_extensions']['#default_value'] == 'txt') {
- $form['file_extensions']['#default_value'] = 'swf';
- }
- // Поле "Ширина" для указания ширины отображаемого контента
- $form['width'] = array(
- '#type' => 'textfield',
- '#title' => 'Ширина',
- '#default_value' => $widget['width'] ? $widget['width'] : 470,
- '#size' => 15,
- '#maxlength' => 5,
- '#description' => 'Ширина flash контента',
- '#weight' => 2.1,
- );
- // Аналогично "Высота"
- $form['height'] = array(
- '#type' => 'textfield',
- '#title' => 'Высота',
- '#default_value' => $widget['height'] ? $widget['height'] : 350,
- '#size' => 15,
- '#maxlength' => 5,
- '#description' => 'Высота flash контента',
- '#weight' => 2.2,
- );
- // Настройки альтернативного текста, если у пользователя отключен Javascript или нет Flash Player'а
- $form['alt_text'] = array(
- '#type' => 'textarea',
- '#title' => 'Альтернативный текст',
- '#default_value' => $widget['alt_text'] ? $widget['alt_text'] : 'Дорогие друзья!<br />В связи с тем, что технология работы нашего сайта требует предустановленного Adobe Flash Player, мы настоятельно рекомендуем Вам установить последнюю версию плагина для вашего браузера с сайта <a href="http://www.adobe.com/go/getflashplayer">Adobe.com</a>.',
- '#description' => 'Этот текст будет отображаться, если у пользователя не установлен Flash плеер',
- '#weight' => 2.3,
- );
- return $form;
- }
-
- // Валидатор формы настроек
- function swffield_widget_settings_validate($widget) {
- $extensions = array_filter(explode(' ', $widget['file_extensions']));
- $flash_extensions = array('swf');
- // Проверяем расширение файла
- if (count(array_diff($extensions, $flash_extensions))) {
- form_set_error('file_extensions', 'Поддерживается только формат SWF');
- }
- // Проверяем ширирну и высоту
- foreach (array('width', 'height') as $resolution) {
- if (empty($widget[$resolution]) || !preg_match('/^[0-9]+$/', $widget[$resolution])) {
- form_set_error($resolution, 'Указан неверный размер контента.');
- }
- }
- return module_invoke('filefield', 'widget_settings', 'validate', $widget);
- }
-
- // Сохраняем настройки поля
- function swffield_widget_settings_save($widget) {
- $filefield_settings = module_invoke('filefield', 'widget_settings', 'save', $widget);
- return array_merge($filefield_settings, array('width', 'height', 'alt_text'));
- }
swffield.render.inc
Copy Source | Copy HTML
- // Хук темизации
- // Задаем функции темизации для виджета, форматтера и отображения на сайте
- function swffield_theme() {
- $theme = array(
- 'swffield_widget' => array(
- 'arguments' => array('element' => NULL),
- ),
- 'swffield_formatter_swffield_flash' => array(
- 'arguments' => array('element' => NULL),
- ),
- 'swffield_flash' => array(
- 'arguments' => array('item' => NULL, 'attributes' => NULL),
- ),
- );
- return $theme;
- }
-
- // Темизация виджета такая же как и у любого элемента формы
- function theme_swffield_widget($element) {
- return theme('form_element', $element, $element['#children']);
- }
-
- // Темизация форматтера
- function theme_swffield_formatter_swffield_flash($element) {
- // Проверяем, загружен ли файл
- if (empty($element['#item']['fid'])) {
- return '';
- }
-
- $field = content_fields($element['#field_name'], $element['#node']->type);
- $item = $element['#item'];
-
- // Класс для отображения поля
- $class = 'swffield swffield-'. $field['field_name'];
- // Возвращаем темизированный с помощью функции "swffield_flash" вывод
- return theme('swffield_flash', $item, array('class' => $class, 'width' => $field['widget']['width'], 'height' => $field['widget']['height'], 'alt' => $field['widget']['alt_text']));
- }
-
- // Вспомогательная функция темизации
- function theme_swffield_flash($item, $attributes) {
- // Загружаем библиотеку "swfobject.js"
- drupal_add_js(drupal_get_path('module', 'swffield') . "/" . "swfobject.js");
- // Генерируем ID для отображаемого элемента
- $id = "swffield-" . rand(1, 10000);
- // Путь к файлу
- $file = "/" . $item['filepath'];
- // Готовый элемент
- return "<div id='".$id."' class='".$attributes['class']."'>"
- .$attributes['alt']
- ."<script type='text/javascript'>"
- ."var flashvars = {};"
- ."var params = {bgcolor:'#ffffff',allowFullScreen:'false',allowScriptAccess:'always',wmode:'opaque'};"
- ."new swfobject.embedSWF('".$file."', '".$id."', '".$attributes['width']."', '".$attributes['height']."', '9.0.0', false, flashvars, params);"
- ."</script>"
- ."</div>";
- }
Здесь используется отличная js библиотека SWFobject. Файл swfobject.js необходимо положить в каталог с нашим модулем.
Еще один тонкий момент. Для каждого отображения нашего элемента на странице необходимо сгенерировать уникальный ID, по которому позднее javascript'ом вставится контент. У меня используется rand(1, 10000). Если есть более адекватный способ, буду рад услышать его в комментариях.
Заключение
Вот собственно и всё, что необходимо для добавления отображения SWF контента на страницах нашего сайта. Аналогичным образом можно например добавить отображение «Видеоплеер» для FLV или «Аудиоплеер» для MP3.
Удачи!