↩️ Назад

Категории

Как добавить кастомные поля в плагин вывода команды для Joomla

30.03.2026 | Статья из категории: Создание сайтов

В прошлый раз мы сделали плагин для Joomla, который выводит карточки сотрудников по тегу {darvil_team}. Плагин брал фото, имя, должность из подписи к картинке, а полное резюме — из полного текста статьи. Всё работало, но появилась новая проблема: 60 резюме уже сверстаны в HTML, а менеджеры хотят добавлять новых сотрудников через админку, не копаясь в коде. Пришлось дорабатывать.

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


Задача

Есть 60 сотрудников с резюме в виде HTML внутри полного текста статьи. Их трогать нельзя — всё работает. Новых сотрудников нужно добавлять через кастомные поля:

В модальном окне должно быть так: сначала старый HTML (если есть), потом — новые поля с разделителем.


Шаг 1. Создаём кастомные поля в админке Joomla

Заходим в админку: Контент → Поля → Создать.

Создаём 4 поля типа "Редактор":

Название Имя (в системе)
Основные направления деятельности prof-directions
Опыт работы prof-experience
Образование prof-education
Курсы повышения квалификации prof-courses

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


Шаг 2. Модернизируем плагин — добавляем загрузку полей

В основном файле плагина darvil_team.php нужно изменить функцию getTeamMembers. Теперь она не только получает статьи, но и подтягивает к ним кастомные поля.

Функция getTeamMembers (обновлённая):

private function getTeamMembers($categoryId)
{
    $db = Factory::getDbo();
    $query = $db->getQuery(true);
    
    $query->select($db->quoteName(array('a.id', 'a.title', 'a.alias', 'a.introtext', 'a.fulltext', 'a.images', 'a.catid')))
          ->from($db->quoteName('#__content', 'a'))
          ->where($db->quoteName('a.catid') . ' = ' . (int) $categoryId)
          ->where($db->quoteName('a.state') . ' = 1')
          ->order($db->quoteName('a.ordering') . ' ASC');
    
    $db->setQuery($query);
    $articles = $db->loadObjectList();
    
    // Загружаем кастомные поля
    if (!empty($articles)) {
        // Получаем ID нужных полей по их именам
        $fieldsQuery = $db->getQuery(true);
        $fieldsQuery->select('id, name')
                    ->from($db->quoteName('#__fields'))
                    ->where($db->quoteName('name') . ' IN ("prof-directions", "prof-experience", "prof-education", "prof-courses")');
        $db->setQuery($fieldsQuery);
        $fieldNames = $db->loadObjectList('id');
        
        // Получаем ID статей
        $articleIds = array_column($articles, 'id');
        
        if (!empty($articleIds)) {
            // Получаем значения полей
            $valuesQuery = $db->getQuery(true);
            $valuesQuery->select('*')
                        ->from($db->quoteName('#__fields_values'))
                        ->where($db->quoteName('item_id') . ' IN (' . implode(',', $articleIds) . ')');
            $db->setQuery($valuesQuery);
            $fieldValues = $db->loadObjectList();
            
            // Группируем по статье
            $valuesByArticle = array();
            foreach ($fieldValues as $fv) {
                $valuesByArticle[$fv->item_id][$fv->field_id] = $fv->value;
            }
            
            // Добавляем поля к каждой статье
            foreach ($articles as $article) {
                $article->jcfields = array();
                if (isset($valuesByArticle[$article->id])) {
                    foreach ($valuesByArticle[$article->id] as $fieldId => $value) {
                        if (isset($fieldNames[$fieldId])) {
                            $field = new stdClass();
                            $field->name = $fieldNames[$fieldId]->name;
                            $field->value = $value;
                            $article->jcfields[] = $field;
                        }
                    }
                }
            }
        }
    }
    
    return $articles;
}

Теперь у каждой статьи в свойстве jcfields будет массив с именами и значениями кастомных полей.


Шаг 3. Меняем шаблон вывода — совмещаем старый HTML и новые поля

В файле tmpl/default.php нужно изменить вывод модального окна. Логика простая: сначала выводим fulltext (старые резюме), потом — кастомные поля с разделителем.

Код внутри модального окна:

<?php
// Сначала выводим HTML из полного текста статьи (старые резюме)
if (!empty($member->fulltext)) {
    echo '<div style="margin-bottom:25px;">';
    echo $member->fulltext;
    echo '</div>';
} elseif (!empty($member->introtext)) {
    echo '<div style="margin-bottom:25px;">';
    echo $member->introtext;
    echo '</div>';
}

// Затем выводим кастомные поля (новые)
$fieldLabels = array(
    'prof-directions' => '📌 Основные направления деятельности',
    'prof-experience' => '💼 Опыт работы',
    'prof-education' => '🎓 Образование',
    'prof-courses' => '📚 Курсы повышения квалификации'
);

$hasFields = false;
$fieldsHtml = '';

if (isset($member->jcfields) && !empty($member->jcfields)) {
    foreach ($member->jcfields as $field) {
        $fieldName = $field->name;
        $fieldValue = $field->value;
        
        if (!empty($fieldValue) && isset($fieldLabels[$fieldName])) {
            $hasFields = true;
            $fieldsHtml .= '<p style="font-size: 16pt; font-weight:bold; margin-top:20px; color:#ffd966;">' . $fieldLabels[$fieldName] . '</p>';
            $fieldsHtml .= '<div style="margin-bottom:15px; line-height:1.5;">' . nl2br($fieldValue) . '</div>';
        }
    }
}

// Если есть поля, добавляем разделитель
if ($hasFields) {
    if (!empty($member->fulltext)) {
        echo '<hr style="background:#ffd966; height:2px; margin:20px 0;">';
        echo '<p style="font-size: 14pt; font-weight:bold; color:#ffd966;">📋 Дополнительная информация:</p>';
    }
    echo $fieldsHtml;
}
?>

Если у сотрудника заполнен старый HTML — он показывается. Если заполнены кастомные поля — они показываются ниже с разделителем. Если старый HTML пуст, но поля заполнены — разделитель не нужен, поля выводятся сразу.


Что получилось в итоге

Теперь модальное окно у сотрудника выглядит так:

Андреева Виктория Николаевна
Директор сети логопедических садов ДАРвиль

─────────────────────────────────

[ЗДЕСЬ СТАРЫЙ HTML ИЗ FULLTEXT]
(образование, опыт, курсы — всё как было сверстано)

─────────────────────────────────
📋 Дополнительная информация:

📌 Основные направления деятельности
Диагностика и коррекция нарушений речи у детей...

💼 Опыт работы
Более 16 лет...

🎓 Образование
Педагогический колледж № 4
Московский городской педагогический университет

📚 Курсы повышения квалификации
Детская академия речи
Нейроакустическая стимуляция по методу ТОМАТИС

Как это работает для менеджеров

При создании нового сотрудника менеджер:

  1. Создаёт статью в категории "Сотрудники"
  2. Заполняет заголовок (ФИО) и загружает фото с подписью (должность)
  3. Переходит на вкладку "Поля" и заполняет 4 блока
  4. Публикует статью

Старые 60 резюме остались нетронутыми — они продолжают выводиться из полного текста. Новые сотрудники заполняются через поля. Всё вместе красиво совмещается в модальном окне.


Плюсы такого подхода


Заключение

Кастомные поля Joomla — мощный инструмент, который позволяет расширять функционал без написания сложных компонентов. Мы использовали их для модернизации существующего плагина, не ломая то, что уже работало.

Теперь менеджеры счастливы (не лезут в HTML), разработчики спокойны (старые данные целы), а сайт продолжает работать как часы.

Исходный код плагина доступен — дорабатывайте под свои задачи.

Теги: #joomla



Категории:

Категории

Комментарии

Пока нет комментариев. Будьте первым!

Оставить комментарий

← Назад к списку статей

Посетителей сегодня: 0
о блоге | карта блога

© Digital Specialist | Не являемся сотрудниками Google, Яндекса и NASA