JavaScript
Содержание
Модули JavaScript
Разработчики должны использовать нативные для браузера модули ECMAScript для написания кода JavaScript в Elgg.
Здесь мы опишем создание и импорт этих модулей в Elgg.
Выполнение модуля на текущей странице
Указать Elgg загрузить существующий модуль на текущей странице просто:
<?php
elgg_import_esm('myplugin/say_hello');
На стороне клиента это асинхронно загрузит модуль, загрузит любые зависимости и выполнит код модуля, если он есть.
Определение модуля
Файлы с расширением «.mjs» автоматически добавляются в importmap, чтобы их можно было импортировать на основе имени представления.
Например, если у нас есть файл в «views/default/myplugin/say_hello.mjs», мы можем импортировать из PHP с помощью elgg_import_esm('myplugin/say_hello') или из JavaScript с помощью оператора import import 'myplugin/say_hello'; или по требованию с помощью функции import().
Если ваши модули не имеют расширения «.mjs», например, когда они поступают из зависимости, вам может потребоваться зарегистрировать их в importmap. После регистрации их можно импортировать под зарегистрированным именем.
<?php
elgg_register_esm('myplugin/say_hello', elgg_get_simplecache_url('external/dependency/modulename.js'));
Передача настроек в модули
События elgg.data
Модуль elgg предоставляет объект elgg.data, который заполняется из двух событий на стороне сервера:
elgg.data, page: Фильтрует ассоциативный массив данных, передаваемых клиенту.
Передадим некоторые данные в модуль:
<?php
function myplugin_config_page(\Elgg\Event $event) {
$value = $event->getValue();
$value['myplugin']['api'] = elgg_get_site_url() . 'myplugin-api';
$value['myplugin']['key'] = 'none';
$user = elgg_get_logged_in_user_entity();
if ($user) {
$value['myplugin']['key'] = $user->myplugin_api_key;
}
return $value;
}
elgg_register_event_handler('elgg.data', 'page', 'myplugin_config_page');
define(['elgg'], function(elgg) {
var api = elgg.data.myplugin.api;
var key = elgg.data.myplugin.key; // "none" or a user's key
// ...
});
Установка URL модуля
У вас может быть скрипт AMD вне ваших представлений, который вы хотите сделать доступным как модуль.
Лучший способ сделать это — настроить путь к файлу с помощью секции views файла elgg-plugin.php в корне вашего плагина:
<?php // elgg-plugin.php
return [
'views' => [
'default' => [
'underscore.js' => 'vendor/npm-asset/underscore/underscore.min.js',
],
],
];
Если вы скопировали скрипт напрямую в ваш плагин вместо управления им через Composer, вы можете использовать что-то подобное:
<?php // elgg-plugin.php
return [
'views' => [
'default' => [
'underscore.js' => __DIR__ . '/node_modules/underscore/underscore.min.js',
],
],
];
Вот и всё! Теперь Elgg будет загружать этот файл всякий раз, когда запрашивается модуль «underscore».
Модули, предоставляемые с Elgg
Модуль elgg
elgg.normalize_url()
Нормализует URL относительно корня elgg:
// "http://localhost/elgg/blog"
elgg.normalize_url('/blog');
elgg.forward()
Перенаправляет на новую страницу.
elgg.forward('/blog');
Эта функция автоматически нормализует URL.
elgg.parse_url()
Разбирает URL на составные части:
// returns {
// fragment: "fragment",
// host: "community.elgg.org",
// path: "/file.php",
// query: "arg=val"
// }
elgg.parse_url('http://community.elgg.org/file.php?arg=val#fragment');
elgg.get_logged_in_user_guid()
Возвращает guid авторизованного пользователя.
elgg.is_logged_in()
True, если пользователь авторизован.
elgg.is_admin_logged_in()
True, если пользователь авторизован и является администратором.
В объекте elgg установлено несколько значений конфигурации:
// The root of the website.
elgg.config.wwwroot;
// The default site language.
elgg.config.language;
// The Elgg release (X.Y.Z).
elgg.config.release;
Модуль elgg/Ajax
См. страницу Ajax для подробностей.
Модуль elgg/hooks
Модуль elgg/hooks можно использовать для взаимодействия плагинов друг с другом.
Перевод текста интерфейса
define(['elgg/hooks'], function (hooks) {
hooks.register('my_plugin:filter', 'value', handler, priority);
var result = hooks.trigger('my_plugin:filter', 'value', {}, 'default');
Модуль elgg/i18n
Модуль elgg/i18n можно использовать для использования переводов.
Перевод текста интерфейса
define(['elgg/i18n'], function (i18n) {
i18n.echo('example:text', ['arg1']);
});
Модуль elgg/system_messages
Модуль elgg/system_messages можно использовать для показа системных сообщений пользователю.
define(['elgg/system_messages'], function (system_messages) {
system_messages.success('Your success message');
system_messages.error('Your error message');
system_messages.clear();
});
Модуль elgg/security
Модуль elgg/security можно использовать для добавления токена безопасности к объекту, URL или строке запроса:
define(['elgg/security'], function (security) {
// returns {
// __elgg_token: "1468dc44c5b437f34423e2d55acfdd87",
// __elgg_ts: 1328143779,
// other: "data"
// }
security.addToken({'other': 'data'});
// returns: "action/add?__elgg_ts=1328144079&__elgg_token=55fd9c2d7f5075d11e722358afd5fde2"
security.addToken("action/add");
// returns "?arg=val&__elgg_ts=1328144079&__elgg_token=55fd9c2d7f5075d11e722358afd5fde2"
security.addToken("?arg=val");
});
Модуль elgg/spinner
Модуль elgg/spinner можно использовать для создания индикатора загрузки, закреплённого в верхней части окна. Это можно использовать для предоставления пользователям обратной связи о том, что система выполняет задачу, занимающую больше времени. Использование функций ajax из elgg/Ajax сделает это по умолчанию. Вы также можете использовать его в своём коде.
define(['elgg/spinner'], function (spinner) {
spinner.start();
// your code
spinner.stop();
});
Модуль elgg/popup
Модуль elgg/popup можно использовать для отображения наложения, позиционированного относительно его якоря (триггера).
Модуль elgg/popup автоматически загружается для контента, отрисованного с помощью output/url с атрибутом class='elgg-popup' и определения целевого модуля с атрибутом href (или data-href). Позиционирование модуля popup можно определить с помощью атрибута data-position элемента триггера.
echo elgg_format_element('div', [
'class' => 'elgg-module-popup hidden',
'id' => 'popup-module',
], 'Popup module content');
// Simple anchor
echo elgg_view('output/url', [
'href' => '#popup-module',
'text' => 'Show popup',
'class' => 'elgg-popup',
]);
// Button with custom positioning of the popup
elgg_import_esm('elgg/popup');
echo elgg_format_element('button', [
'class' => 'elgg-button elgg-button-submit elgg-popup',
'text' => 'Show popup',
'data-href' => '#popup-module',
'data-position' => json_encode([
'my' => 'center bottom',
'at' => 'center top',
]),
]);
Модуль elgg/popup позволяет создавать более сложные элементы интерфейса/пользовательского опыта. Вы можете открывать и закрывать модули popup программно:
define(['jquery', 'elgg/popup'], function($, popup) {
$(document).on('click', '.elgg-button-popup', function(e) {
e.preventDefault();
var $trigger = $(this);
var $target = $('#my-target');
var $close = $target.find('.close');
popup.open($trigger, $target, {
'collision': 'fit none'
});
$close.on('click', popup.close);
});
});
Вы можете использовать хук плагина getOptions, ui.popup для манипуляции позицией popup перед его открытием. Вы можете использовать события jQuery open и close для манипуляции модулем popup после его открытия или закрытия.
define(['jquery', 'elgg/Ajax'], function($, Ajax) {
$('#my-target').on('open', function() {
var $module = $(this);
var $trigger = $module.data('trigger');
var ajax = new Ajax();
ajax.view('my_module', {
beforeSend: function() {
$trigger.hide();
$module.html('').addClass('elgg-ajax-loader');
},
success: function(output) {
$module.removeClass('elgg-ajax-loader').html(output);
}
});
}).on('close', function() {
var $trigger = $(this).data('trigger');
$trigger.show();
});
});
Открытые модули popup всегда будут содержать следующие данные, к которым можно получить доступ через $.data():
trigger— элемент jQuery, используемый для запуска открытия модуля popup
position— объект, определяющий позицию модуля popup, который был передан в$.position()
По умолчанию элемент target будет добавлен в $('body'), тем самым изменяя иерархию DOM. Если вам нужно сохранить позицию DOM модуля popup, вы можете добавить класс .elgg-popup-inline к вашему триггеру.
Модуль elgg/widgets
Плагины, которые загружают макет виджета через Ajax, должны инициализироваться через этот модуль:
import('elgg/widgets').then((widgets) => {
widgets.default.init();
});
Модуль elgg/lightbox
Elgg распространяется с библиотекой jQuery Colorbox. Пожалуйста, перейдите на http://www.jacklmoore.com/colorbox для получения дополнительной информации о параметрах этого лайтбокса.
Используйте следующие классы для привязки элементов якоря к лайтбоксу:
elgg-lightbox— загружает ресурс HTML
elgg-lightbox-photo— загружает ресурс изображения (следует использовать, чтобы избежать отображения необработанных байтов изображения вместо тегаimg)
elgg-lightbox-inline— отображает встроенный элемент HTML в лайтбоксе
elgg-lightbox-iframe— загружает ресурс вiframe
Вы можете применить параметры colorbox к отдельному элементу elgg-lightbox, установив атрибут data-colorbox-opts в объект настроек JSON.
echo elgg_view('output/url', [
'text' => 'Open lightbox',
'href' => 'ajax/view/my_view',
'class' => 'elgg-lightbox',
'data-colorbox-opts' => json_encode([
'width' => '300px',
])
]);
Используйте хук плагина "getOptions", "ui.lightbox" для фильтрации параметров, передаваемых в $.colorbox() каждый раз, когда открывается лайтбокс.
Модуль AMD elgg/lightbox следует использовать для программного открытия и закрытия лайтбокса:
define(['elgg/lightbox', 'elgg/spinner'], function(lightbox, spinner) {
lightbox.open({
html: '<p>Hello world!</p>',
onClosed: function() {
lightbox.open({
onLoad: spinner.start,
onComplete: spinner.stop,
photo: true,
href: 'https://elgg.org/cache/1457904417/default/community_theme/graphics/logo.png',
});
}
});
});
Для поддержки наборов галереи (через атрибут rel) вам нужно привязать colorbox напрямую к определённому селектору (обратите внимание, что это проигнорирует data-colorbox-opts на всех элементах в наборе):
import('elgg/lightbox').then((lightbox) => {
var options = {
photo: true,
width: 500
};
lightbox.default.bind('a[rel="my-gallery"]', options, false); // 3rd attribute ensures binding is done without proxies
});
При необходимости вы также можете изменить размер лайтбокса программно:
define(['elgg/lightbox'], function(lightbox) {
lightbox.resize({
width: '300px'
});
});
Если вы хотите, чтобы ваш контент загружался модулем AMD elgg/Ajax, который автоматически загружает зависимости JS, вы можете передать опцию ajaxLoadWithDependencies
define(['elgg/lightbox'], function(lightbox) {
lightbox.open({
href: 'some/view/with/js/dependencies',
ajaxLoadWithDependencies: true
});
});
Модуль elgg/ckeditor
Этот модуль можно использовать для добавления редактора WYSIWYG к textarea (требуется включение плагина ckeditor). Обратите внимание, что WYSIWYG будет автоматически прикрепляться ко всем экземплярам .elgg-input-longtext.
import('elgg/ckeditor').then((elggCKEditor) => {
elggCKEditor.default.bind('#my-text-area');
// Toggle CKEditor
elggCKEditor.default.toggle('#my-text-area');
// Focus on CKEditor input
elggCKEditor.default.focus('#my-text-area');
// or
$('#my-text-area').trigger('focus');
// Reset CKEditor input
elggCKEditor.default.reset('#my-text-area');
// or
$('#my-text-area').trigger('reset');
});
Компонент встроенных вкладок
Компонент встроенных вкладок запускает событие open каждый раз, когда вкладка открывается и, в случае вкладок ajax, завершает загрузку:
// Add custom animation to tab content
$(document).on('open', '.theme-sandbox-tab-callback', function() {
$(this).find('a').text('Clicked!');
$(this).data('target').hide().show('slide', {
duration: 2000,
direction: 'right',
complete: function() {
alert('Thank you for clicking. We hope you enjoyed the show!');
$(this).css('display', ''); // .show() adds display property
}
});
});
Традиционные скрипты
Хотя мы настоятельно рекомендуем использовать модули AMD, и нет API Elgg для загрузки скриптов, вы можете зарегистрировать скрипты в обработчике событий для добавления элементов в ссылки заголовка;
elgg_register_event_handler('head', 'page', $callback);
Хуки
Движок JS имеет систему хуков, аналогичную событиям движка PHP: хуки запускаются, и плагины могут регистрировать функции для реакции или изменения информации.
Регистрация обработчиков хуков
Функции обработчиков регистрируются с помощью hooks.register(). Несколько обработчиков могут быть зарегистрированы для одного и того же хука.
define(['elgg/hooks'], function(hooks) {
hooks.register('name', 'type', {handler}, {priority});
});
Функция обработчика
Обработчик получит 4 аргумента:
hook — имя хука
type — тип хука
params — объект или набор параметров, специфичных для хука
value — текущее значение
value будет передаваться через каждый хук. В зависимости от хука, обратные вызовы могут просто реагировать или изменять данные.
Запуск пользовательских хуков
Плагины могут запускать свои собственные хуки:
define(['elgg/hooks'], function(hooks) {
hooks.trigger('name', 'type', {params}, "value");
});
Доступные хуки
- init, system
Плагины должны регистрировать свои функции init для этого хука. Он запускается после загрузки JS Elgg и инициализации всех модулей загрузки плагинов.
- getOptions, ui.popup
Этот хук запускается для всплывающих отображений (
"rel"="popup") и позволяет настраивать параметры размещения.- getOptions, ui.lightbox
Этот хук можно использовать для фильтрации параметров, передаваемых в
$.colorbox()- config, ckeditor
Это фильтрует объект конфигурации CKEditor. Зарегистрируйтесь для этого хука в модуле загрузки плагина. Значения по умолчанию можно увидеть в модуле
elgg/ckeditor/config.- prepare, ckeditor
Этот хук можно использовать для декорирования глобального
CKEDITOR. Вы можете использовать этот хук для регистрации новых плагинов CKEditor и добавления привязок событий.- ajax_request_data, *
Это фильтрует данные запроса, отправляемые модулем
elgg/Ajax. См. Ajax для подробностей. Хук должен проверить, являются ли данные простым объектом или экземпляромFormData, чтобы добавить значения с использованием правильного API.- ajax_response_data, *
Это фильтрует данные ответа, возвращаемые пользователям модуля
elgg/Ajax. См. Ajax для подробностей.
Сторонние ресурсы
Мы рекомендуем управлять сторонними скриптами и стилями с помощью Composer. composer.json Elgg настроен для установки зависимостей из репозиториев пакетов NPM или Yarn с помощью инструмента командной строки Composer. Конфигурация ядра устанавливает ресурсы из Asset Packagist (репозиторий, управляемый сообществом Yii).
В качестве альтернативы вы можете установить fxp/composer-asset-plugin глобально для достижения тех же результатов, но установка и обновление занимают гораздо больше времени.
Например, чтобы включить jQuery, вы можете выполнить следующие команды Composer:
composer require npm-asset/jquery:~2.0
Если вы используете starter-project или подтягиваете Elgg как зависимость composer через пользовательский проект composer, обновите ваш composer.json следующей конфигурацией:
{
"repositories": [
{
"type": "composer",
"url": "https://asset-packagist.org"
}
],
"config": {
"fxp-asset": {
"enabled": false
}
},
}
Дополнительную информацию можно найти на сайте Asset Packagist.