Создание плагина блога

Этот урок научит вас создавать простой плагин блога. Основные функции блога: создание записей, их сохранение и просмотр. Плагин дублирует функции, которые есть в стандартном плагине blog. Вы можете отключить стандартный плагин blog, если хотите, но это не обязательно, так как функции не конфликтуют друг с другом.

Требования:

Создание директории плагина и файла composer

Сначала выберите простое и описательное имя для вашего плагина. В этом уроке имя будет my_blog. Затем создайте директорию для вашего плагина в директории /mod/, которая находится в директории установки Elgg. Другие плагины также расположены в /mod/. В данном случае имя директории должно быть /mod/my_blog/. Эта директория является корнем вашего плагина, и все файлы, которые вы создаёте для нового плагина, будут размещены где-то внутри неё.

Затем в корне плагина создайте файл composer плагина composer.json.

Смотрите Плагины для получения дополнительной информации о файле composer.

Создание формы для создания новой записи блога

Создайте файл по пути /mod/my_blog/views/default/forms/my_blog/save.php, содержащий тело формы. Форма должна иметь поля ввода для заголовка, тела и тегов записи my_blog. Разметка тега form не требуется.

echo elgg_view_field([
    '#type' => 'text',
    '#label' => elgg_echo('title'),
    'name' => 'title',
    'required' => true,
]);

echo elgg_view_field([
    '#type' => 'longtext',
    '#label' => elgg_echo('body'),
    'name' => 'body',
    'required' => true,
]);

echo elgg_view_field([
    '#type' => 'tags',
    '#label' => elgg_echo('tags'),
    '#help' => elgg_echo('tags:help'),
    'name' => 'tags',
]);

$submit = elgg_view_field(array(
    '#type' => 'submit',
    '#class' => 'elgg-foot',
    'value' => elgg_echo('save'),
));
elgg_set_form_footer($submit);

Обратите внимание, как форма вызывает elgg_view_field() для отображения полей ввода. Эта вспомогательная функция поддерживает согласованность разметки полей и используется как сокращение для отображения элементов поля, таких как label, справочный текст и input. Смотрите Формы и действия.

Полный список представлений input можно увидеть в директории /vendor/elgg/elgg/views/default/input/.

Рекомендуется сделать ваш плагин переводимым, используя elgg_echo() всякий раз, когда есть строка текста, которая будет показана пользователю. Подробнее читайте в Интернационализация.

Создание страницы для написания блогов

Создайте файл /mod/my_blog/views/default/resources/my_blog/add.php. Эта страница будет отображать форму, созданную в предыдущем разделе.

<?php

// set the title
$title = "Create a new my_blog post";

// add the form to the main column
$content = elgg_view_form("my_blog/save");

// optionally, add the content for the sidebar
$sidebar = "";

// draw the page, including the HTML wrapper and basic page layout
echo elgg_view_page($title, [
            'content' => $content,
            'sidebar' => $sidebar
]);

Функция elgg_view_form("my_blog/save") отображает форму, созданную в предыдущем разделе. Она также автоматически оборачивает форму тегом <form> с необходимыми атрибутами, а также добавляет anti-csrf токены.

Действие формы будет "<?= elgg_get_site_url() ?>action/my_blog/save".

Создание файла действия для сохранения записи блога

Файл действия сохранит запись my_blog в базу данных. Создайте файл /mod/my_blog/actions/my_blog/save.php:

<?php
// get the form inputs
$title = elgg_get_title_input('title');
$body = get_input('body');
$tags = elgg_string_to_array((string) get_input('tags'));

// create a new my_blog object and put the content in it
$blog = new \ElggBlog();
$blog->title = $title;
$blog->description = $body;
$blog->tags = $tags;

// for now, make all my_blog posts public
$blog->access_id = ACCESS_PUBLIC;

// owner is logged in user
$blog->owner_guid = elgg_get_logged_in_user_guid();

// save to database
// if the my_blog was saved, we want to display the new post
// otherwise, we want to register an error and forward back to the form
if ($blog->save()) {
   return elgg_ok_response('', "Your blog post was saved.", $blog->getURL());
} else {
   return elgg_error_response("The blog post could not be saved.");
}

Как видно из приведённого кода, объекты Elgg имеют несколько встроенных полей. Заголовок записи my_blog хранится в поле title, а тело — в поле description. Также есть поле для тегов, которые хранятся как метаданные.

Объекты в Elgg являются подклассом так называемой «сущности» (entity). Пользователи, сайты и группы также являются подклассами entity. Подтип сущности позволяет детально управлять списком и отображением, поэтому каждая сущность должна иметь подтип. В этом уроке подтип «my_blog» идентифицирует запись my_blog, но любая буквенно-цифровая строка может быть допустимым подтипом. При выборе подтипов убедитесь, что они имеют смысл для вашего плагина.

Создание elgg-plugin.php

Файл /mod/my_blog/elgg-plugin.php используется для объявления различных функций плагина. Он может, например, использоваться для настройки сущностей, действий, виджетов и маршрутов.

<?php

return [
        'entities' => [
                [
                        'type' => 'object',
                        'subtype' => 'my_blog',
                        'capabilities' => [
                                'searchable' => true,
                        ],
                ],
        ],
        'actions' => [
                'my_blog/save' => [],
        ],
        'routes' => [
                'view:object:blog' => [
                        'path' => '/my_blog/view/{guid}/{title?}',
                        'resource' => 'my_blog/view',
                ],
                'add:object:blog' => [
                        'path' => '/my_blog/add/{guid?}',
                        'resource' => 'my_blog/add',
                ],
                'edit:object:blog' => [
                        'path' => '/my_blog/edit/{guid}/{revision?}',
                        'resource' => 'my_blog/edit',
                        'requirements' => [
                                'revision' => '\d+',
                        ],
                ],
        ],
];

Регистрация действия save сделает его доступным по адресу /action/my_blog/save. По умолчанию все действия доступны только авторизованным пользователям. Если вы хотите сделать действие доступным только администраторам или открыть его для неаутентифицированных пользователей, вы можете передать ['access' => 'admin'] или ['access' => 'public'] при регистрации действия.

Создание страницы для просмотра записи блога

Чтобы иметь возможность просматривать запись my_blog на отдельной странице, необходимо создать страницу просмотра. Создайте файл /mod/my_blog/views/default/resources/my_blog/view.php:

<?php

// get the entity
$guid = elgg_extract('guid', $vars);
$my_blog = get_entity($guid);

// get the content of the post
$content = elgg_view_entity($my_blog, array('full_view' => true));

echo elgg_view_page($my_blog->getDisplayName(), [
    'content' => $content,
]);

Эта страница имеет много общего со страницей add.php. Наибольшие различия заключаются в том, что некоторая информация извлекается из сущности my_blog, и вместо отображения формы вызывается функция elgg_view_entity. Эта функция передаёт информацию о сущности так называемому представлению объекта (object view).

Создание представления объекта

Когда вызывается elgg_view_entity или когда my_blogs просматриваются в списке, представление объекта генерирует соответствующий контент. Создайте файл /mod/my_blog/views/default/object/my_blog.php:

<?php

echo elgg_view('output/longtext', array('value' => $vars['entity']->description));
echo elgg_view('output/tags', array('tags' => $vars['entity']->tags));

Как видно из предыдущего раздела, каждая запись my_blog передаётся в представление объекта как $vars['entity']. ($vars — это массив, используемый в системе представлений для передачи переменных в представление.)

Последняя строка берёт теги записи my_blog и автоматически отображает их как серию кликабельных ссылок. Поиск обрабатывается автоматически.

(Если вам интересно, что означает «default» в /views/default/, вы можете создавать альтернативные представления. RSS, OpenDD, FOAF, mobile и другие — все это допустимые типы представлений.)

Проверка работы

Перейдите на страницу администрирования вашего сайта Elgg, просмотрите список плагинов и активируйте плагин my_blog.

Страница для создания новой записи my_blog теперь должна быть доступна по адресу https://elgg.example.com/my_blog/add, и после успешного сохранения записи вы должны увидеть её на отдельной странице.

Отображение списка записей блога

Давайте также создадим страницу, которая отображает список созданных записей my_blog.

Создайте /mod/my_blog/views/default/resources/my_blog/all.php:

<?php
$titlebar = "All Site My_Blogs";
$pagetitle = "List of all my_blogs";

$body = elgg_list_entities(array(
    'type' => 'object',
    'subtype' => 'my_blog',
));

echo elgg_view_page($titlebar, [
    'title' => $pagetitle,
    'content' => $body,
]);

Функция elgg_list_entities получает последние записи my_blog и передаёт их в файл представления объекта. Обратите внимание, что эта функция возвращает только те записи, которые пользователь может видеть, поэтому ограничения доступа обрабатываются прозрачно. Эта функция (и её аналоги) также прозрачно обрабатывает пагинацию и даже создаёт RSS-ленту для ваших my_blogs, если вы определили это представление.

Функция списка также может ограничивать записи my_blog записями определённого пользователя. Например, функция elgg_get_logged_in_user_guid получает глобальный уникальный идентификатор (GUID) авторизованного пользователя, и при передаче его в elgg_list_entities список отображает только записи текущего пользователя:

echo elgg_list_entities(array(
    'type' => 'object',
    'subtype' => 'my_blog',
    'owner_guid' => elgg_get_logged_in_user_guid()
));

Далее вам нужно зарегистрировать маршрут, который будет возвращать новую страницу, когда URL установлен в /my_blog/all. Настройте секцию routes в elgg-plugin.php, чтобы она содержала следующее:

'routes' => [
        'collection:object:my_blog:all' => [
                'path' => '/my_blog/all',
                'resource' => 'my_blog/all',
        ],
],

Теперь, если URL содержит /my_blog/all, пользователь увидит страницу «Все записи My_Blogs сайта».

Вы также можете обновить представление объекта для обработки различных видов просмотра, иначе список всех my_blogs также будет показывать полное содержимое всех записей. Измените /mod/my_blog/views/default/object/my_blog.php следующим образом:

<?php
$full = elgg_extract('full_view', $vars, FALSE);

// full view
if ($full) {
    echo elgg_view('output/longtext', array('value' => $vars['entity']->description));
    echo elgg_view('output/tags', array('tags' => $vars['entity']->tags));

// list view or short view
} else {
    // make a link out of the post's title
    echo elgg_view_title(
        elgg_view('output/url', array(
            'href' => $vars['entity']->getURL(),
            'text' => $vars['entity']->getDisplayName(),
            'is_trusted' => true,
    )));
    echo elgg_view('output/tags', array('tags' => $vars['entity']->tags));
}

Теперь, если full_view равно true (как было предварительно установлено в этом разделе), представление объекта покажет содержимое записи и теги (заголовок отображается через view.php). В противном случае представление объекта отобразит только заголовок и теги записи.

Завершение

Ещё многое можно сделать, но надеемся, это даст вам хорошее представление о том, как начать.