Новости Joomla

Вышли релизы Joomla 6.1 и Joomla 5.4.5: новые возможности и стабильность

Релиз Joomla 6.1.0

Проект Joomla! объявил о доступности Joomla 6.1 [Nyota] — новой минорной версии шестой серии, а также о выпуске релиза исправлений ошибок Joomla 5.4.5. Релиз 6.1 приносит ряд долгожданных функций, повышающих удобство управления контентом и защиту от спама.

👩‍💻 Компонент "CS Афиши" для Joomla.

👩‍💻 Компонент "CS Афиши" для Joomla.

Расширение "CS Афиши" позволяет выводить список мероприятий, фильтровать их по датам, поиск по заголовкам и описанию.

В состав пакета расширений входят:
- Компонент "CS Афиши"
- Модуль "Календарь событий"
- Модуль "Предстоящие события"
- Библиотека "ImgResize"

Расширение "CS Афиши" позволяет выводить список мероприятий, фильтровать их по датам, поиск по заголовкам и описанию.

Модуль "Календарь событий" отображает предстоящие и прошедшие мероприятие на календаре, с отображением мероприятий на конкретную дату во всплывающем окне.

Модуль "Предстоящие события" показывает список предстоящий событий по порядку их наступления.

P.S. Расширение платное, но плата символическая, чисто для отработки приема платежей. Ключи без ограничения по времени, купившие сейчас - смогут обновляться без ограничений.

Разработчик - участник нашего сообщества Дмитрий Денисов (@codersite).

Страница расширения
Демо

0 Пользователей и 1 Гость просматривают эту тему.
  • 36 Ответов
  • 3132 Просмотров
*

borro

  • Завсегдатай
  • 1379
  • 22 / 0
  • желаю вам счастья
Здравствуйте!

Ищу пример того, как в разрабатываемом мной компоненте можно вывести содержимое некоторой таблицы в зависимости от выбранного значения в выпадающем списке. То есть это фильтр по значениям из связанной таблицы.
Мне в com_content в список статей?
*

b2z

  • Глобальный модератор
  • 7288
  • 778 / 0
  • Разраблю понемногу
Цитировать
Мне в com_content в список статей?
Как вариант. А в чём сложность? Фильтр же работает по полю, которое участвует в WHERE.

В com_content - это категория.
*

borro

  • Завсегдатай
  • 1379
  • 22 / 0
  • желаю вам счастья
Сложность в том, что нет примера :)
*

b2z

  • Глобальный модератор
  • 7288
  • 778 / 0
  • Разраблю понемногу
*

borro

  • Завсегдатай
  • 1379
  • 22 / 0
  • желаю вам счастья
А вообще есть понятие, как фильтры делать?
Доброе утро! Пока не хватает всех пазлов в картине. Из того, что я пока изучил, у меня сложилась такая картина для получения фильтра:
1. Вот такой вид(view.html.php):
Спойлер
[свернуть]
2. Вот такая модель для этого вида:
Спойлер
[свернуть]
3. Это XML формы фильтра, который располагается по пути site/models/forms/filter_contacts.xml(у меня вид для фронта)
Спойлер
[свернуть]
4. layout вида:
Спойлер
[свернуть]
В браузере данный вид пока выкидывает ошибку, что не может найти getItem, что понятно, его я пока не определил. Верной дорогой иду я, товарищи, к построению фильтра книг(аналог фильтра по категории среди списка статей в com_content)? Особенно интересует какой должная быть функция loadFormData(), которая, как надеюсь, должна наполнять фильтр книг, в которые сгруппированы отображаемые видом контакты.
*

sivers

  • Живу я здесь
  • 2610
  • 363 / 0
Чтение фильтра обычно добавляю в метод модели populateState, который имеет вид:
Код
	protected function populateState( $ordering = null, $direction = null )
{
parent::populateState( $ordering, $direction );
$input = JFactory::getApplication()->input;
$params = JComponentHelper::getParams( 'com_component' );
$this->setState( 'list.start', $input->get( 'start' ) );
$this->setState( 'list.limit', $params->get( 'limit', 10 ) );
}
Фрагмент кода взят из конструктора компонент на сайте _http://ссылка вырезана, так как домен распространяет вирусы/ за что спасибо автору - пользуюсь регулярно.

А вот на отсутствие метода getItem ругани быть не должно - у вас же модель листинга, а в ней используется getItems. Но этот метод есть в родительском классе, а значит и его не обязательно определять в модели. Ищите причину ругани в другом. Возможно, где-то в коде вы забыли удалить вызов getItem при переносе кода с другого места.
На связи в telegram @sivers
sivers @ inbox . ru
https://sivers.su/
*

borro

  • Завсегдатай
  • 1379
  • 22 / 0
  • желаю вам счастья
sivers, не увидел в вашем коде, как вы собственно 1. фильтруете листинг и как 2. наполняете фильтр значениями. Можете подробнее?
А мой подход рабочий?
populateState используется для сохранения значений переменных для использования в следующем обращении к данным модели?
*

sivers

  • Живу я здесь
  • 2610
  • 363 / 0
sivers, не увидел в вашем коде, как вы собственно 1. фильтруете листинг и как 2. наполняете фильтр значениями. Можете подробнее?
А мой подход рабочий?
populateState используется для сохранения значений переменных для использования в следующем обращении к данным модели?
Ваш код не проверял.
Да, в populateState читаю значения фильтра и записываю в state методом $this->setState - так же, как и метод сортировки в фрагменте выше.
В файле view.html.php делаю сперва $this->state = $this->get('State'); (при этом отрабатывает populateState), а потом уже $this->items = $this->get('Items');.
При запросе элементов сперва отрабатывает getListQuery(), в котором получаю параметры фильтра через $this->state->get('param1') (если получать через $this->getState, то будет повторно отрабатывать populateState, а это бывает нежелательно). Параметры фильтра используете для построения части WHERE запроса. У вас это вроде бы есть.
Если над прочитанными из БД объектами никаких действий делать не требуется, то метод модели getItems можно не определять. Иначе пишете:
Код
public function getItems()
{
   $items = parent::getItems();
   foreach($items as $i => $item){
      $items[$i]->link = ....;
      ......
   }
   return $items;
}
Это бывает полезно для подготовки объектов к выводу. Чтоб не перегружать sql-запрос форматированием данных (как у вас), либо для дополнения объектов вычисляемыми свойствами (та же ссылка к примеру).
На связи в telegram @sivers
sivers @ inbox . ru
https://sivers.su/
*

borro

  • Завсегдатай
  • 1379
  • 22 / 0
  • желаю вам счастья
sivers, спасибо. Пока у меня что-то не срастается все в целую картину :) Как вы наполняете фильтр(выпадающий список) значениями и затем его выводите? Приложил скриншот о чем я говорю.
*

sivers

  • Живу я здесь
  • 2610
  • 363 / 0
Как вы наполняете фильтр(выпадающий список) значениями и затем его выводите? Приложил скриншот о чем я говорю.
А, понятно теперь. Т.е. вы про верстку фильтра, а не о его применении. Делать можно по разному. Например, модулем. Дергаете из БД справочники полей, по которым хотите фильтровать, и строите из них селекты.
Если же вы разобрались как использовать XML для построения фильтров, то можно использовать Поле с типом sql для получения значений справочника (те же категории или свойства какие-нибудь). Синтаксис поля здесь:
https://docs.joomla.org/Special:MyLanguage/SQL_form_field_type
Про все поля здесь:
https://docs.joomla.org/Form_field#Standard_form_field_types
Если стандартных типов полей недостаточно, то можно на их основе делать свои. Они складываются в папку компонента /models/fields/mytype.php

Если сложность с рендерингом формы через модель компонента, то можете создать тестовый компонент в конструкторе (ссылку выше давал) - там добавьте 1 таблицу и 1 представление для админки с функцией редактирования и той таблицей. Потом скачайте и посмотрите как там все подключено в представлении админки. Для фронта аналогично все. Не знаю только делает ли конструктор для фронта фильтр (не проверял), но для админки точно делает.

А если надо в отрыве от компонента (допустим, в модуле), то вот есть еще одна мини-инструкция:
Спойлер
[свернуть]
На связи в telegram @sivers
sivers @ inbox . ru
https://sivers.su/
*

b2z

  • Глобальный модератор
  • 7288
  • 778 / 0
  • Разраблю понемногу
Делаем свой тип поля, добавляем в XML фильтров - профит ;) Но это в админке.

На фронте я лично не использую search tools, а вывожу каждый список отдельно. Ну например вот так:

Код
<div>
    <label class="filter-status-lbl" for="filter-status" hidden>
        <?php echo JText::_('COM_COMPETITION_FILTER_STATUS_LABEL'); ?>
    </label>

    <select name="filter-status" class="uk-select" onchange="this.form.submit()">
        <?php echo
        JHtml::_('select.options',
            CompetitionHelperHtmlFilters::getStatusOptions(),
            'value',
            'text',
            $this->state->get('filter.status'),
            true
        );
        ?>
    </select>
</div>

Код
public static function getStatusOptions($showFirstOption = true)
{
    $options = array();

    if ($showFirstOption)
    {
        $options[] = JHtml::_('select.option', -1, JText::_('COM_COMPETITION_ALL'));
    }

    $options[] = JHtml::_('select.option', 1, JText::_('COM_COMPETITION_STATUSES_ACTIVE'));
    $options[] = JHtml::_('select.option', 0, JText::_('COM_COMPETITION_STATUSES_CLOSED'));

    return $options;
}
Вообще тут нужно пространство для манёвра, всё таки это фронт. Если использовать search tools, то будешь привязан к BS2.

Далее в модели учитываю этот фильтр, согласно классическому применению.

Спойлер
[свернуть]
*

borro

  • Завсегдатай
  • 1379
  • 22 / 0
  • желаю вам счастья
Здравствуйте!
Спасибо, попробую что-то скомпилировать из ваших советов.
BS2 - это bootstrap2?
b2z, скажите, где должен лежать и как подключать файл, содержащий определение функции getStatusOptions?Увидеть бы как он строится. Этот файл должен подключаться в главном контроллере?
Как понимаю в этой самой getStatusOptions мне нужно добыть из БД мои варианты для выпадающего списка?
Не заметил, где вы используете getStoreId()...
Получается в $config['filter_fields'] упоминаются не только поля, по которым возможна сортировка, но и фильтруемые поля...
« Последнее редактирование: 22.08.2020, 15:23:19 от borro »
*

b2z

  • Глобальный модератор
  • 7288
  • 778 / 0
  • Разраблю понемногу
Здравствуйте!
Спасибо, попробую что-то скомпилировать из ваших советов.
BS2 - это bootstrap2?
Он самый  ^-^

b2z, скажите, где должен лежать и как подключать файл, содержащий определение функции getStatusOptions?Увидеть бы как он строится. Этот файл должен подключаться в главном контроллере?
Это просто класс со статическими функциями.

Например у меня он находится в site/helpers/html/filters.php, а подключаю сразу в точке входа через JLoader:
Код
\JLoader::discover('CompetitionHelperHtml', NC_PATH_SITE . '/helpers/html');
Но это зависит от ситации. Если он только в парочке мест нужен, то можно его в конкретном файле через JLoader подключить.

Как понимаю в этой самой getStatusOptions мне нужно добыть из БД мои варианты для выпадающего списка?
Именно так.

Не заметил, где вы используете getStoreId()...
В модели.

Получается в $config['filter_fields'] упоминаются не только поля, по которым возможна сортировка, но и фильтруемые поля...
Глянул в ListModel, действительно, не обязательно добавлять фильтры в $config['filter_fields']. Но если используется Search Tools, то надо, так как этот массив участвует в getActiveFilters().
*

borro

  • Завсегдатай
  • 1379
  • 22 / 0
  • желаю вам счастья
Здравствуйте!
Например у меня он находится в site/helpers/html/filters.php, а подключаю сразу в точке входа через JLoader:
Код
\JLoader::discover('CompetitionHelperHtml', NC_PATH_SITE . '/helpers/html');
Дмитрий, почему-то у меня этот метод, использованный в точке входа в компонент, возвращает
Цитировать
0 - Class 'AnysendHelperHtmlFilters' not found
Заметил, что вылетает предупреждение:
Цитировать
Use of undefined constant NC_PATH_SITE
Заменил ее на JPATH_COMPONENT_SITE и ошибка ушла, появилась следующая. Буду разбираться :)
« Последнее редактирование: 29.08.2020, 12:07:52 от borro »
*

borro

  • Завсегдатай
  • 1379
  • 22 / 0
  • желаю вам счастья
Здравствуйте, товарищи!

При перезагрузке страницы не могу получить значение, выбранное в фильтре. Помогите разобраться, пожалуйста.
Вот layout, который выводит фильтр(он с виду наполняется правильно, по крайней мере предлагает к выбору разные текстовые строки)(кстати, может надо добавить какой-то hidden input внизу формы для создаваемого фильтра?):
Спойлер
[свернуть]
Вот view.html.php:
Спойлер
[свернуть]
Вот модель с populateState():
Спойлер
[свернуть]
А вот на всякий случай наполняющая фильтр данными функция getBookOptions() из хелпера:
Спойлер
[свернуть]
*

borro

  • Завсегдатай
  • 1379
  • 22 / 0
  • желаю вам счастья
$params = JComponentHelper::getParams( 'com_component' );
Здравствуйте! sivers, можно про эту строку подробнее? Вы здесь добываете дефолтные настройки, которые задаются пользователем в настройках компонента?
*

borro

  • Завсегдатай
  • 1379
  • 22 / 0
  • желаю вам счастья
Код
...
$params = $app->getParams();
$status = $app->getUserStateFromRequest(
    $this->context . '.filter.status',
    'filter-status',
    $params->get('competitions_default_status_filter', -1),
    'string'
);
...
Дмитрий, вы здесь тоже получаете дефолтную настройку, которую пользователь задает в админке в настройках компонета?
В чем разница между добычей дефолтных значений по методу sivers и методу Дмитрия?
« Последнее редактирование: 02.10.2020, 16:59:49 от borro »
*

sivers

  • Живу я здесь
  • 2610
  • 363 / 0
Здравствуйте! sivers, можно про эту строку подробнее? Вы здесь добываете дефолтные настройки, которые задаются пользователем в настройках компонента?
Добрый день. Здесь вы берете настройки любого компонента, который вам нужен. Второй способ ($app->getParams();) точно не знаю что возвращает (не пользовался им). Возможно, настройки текущего компонента. Сравните вывод.
На связи в telegram @sivers
sivers @ inbox . ru
https://sivers.su/
*

b2z

  • Глобальный модератор
  • 7288
  • 778 / 0
  • Разраблю понемногу
$app->getParams() - это текущие настройки, да. Посмотрите в родные компоненты Joomla, это обычная практика.
*

borro

  • Завсегдатай
  • 1379
  • 22 / 0
  • желаю вам счастья
Здравствуйте!

Спасибо!

На текущий момент осталась одна непонятка: почему-то данные, выбранные в выпадающем списке, не видны в getUserStateFromRequest(), вызываемой во время перезагрузки страницы
Вот как я вывожу фильтр в default.php:
Код
...
<form action="index.php?option=com_anysend&view=contacts" method="post" id="adminForm" name="adminForm">
...
  <select name="filter-book" class="uk-select" onchange="this.form.submit()">
<?php echo JHtml::_('select.options',
AnysendHelperHtmlFilters::getBookOptions(),
'value',
'text',
$this->state->get('filter_book'),
true
);
?>
</select>
...
        <input type="hidden" name="filter_book" value="<?php echo $bookSelected; ?>"/>
<?php echo JHtml::_('form.token'); ?>
</form>
...
В модели этого представления пытаюсь поймать отправленное значение:
Код
        protected function populateState( $ordering = null, $direction = null )
        {
            ...
            $book = $app->getUserStateFromRequest(
                $this->context . '.filter.book',
                'filter_book',
                $results[0]->book_name, //дефолтное значение
                'string'
            );
            $this->setState('filter.book', $book);
        }
и получаю пустую строку, хотя отправляется непустое дефолтное значение. Внутри функции getUserStateFromRequest видно, что переменная $cur_state равна подставленному дефолтному значению, но $new_state уже содержит пустую строку(скриншот)
*

sivers

  • Живу я здесь
  • 2610
  • 363 / 0
А в каком месте из всего этого читается переданный параметр "filter-book"?
На связи в telegram @sivers
sivers @ inbox . ru
https://sivers.su/
*

borro

  • Завсегдатай
  • 1379
  • 22 / 0
  • желаю вам счастья
А в каком месте из всего этого читается переданный параметр "filter-book"?
в приведенной populateState(). Замена 'filter_book' на 'filter-book' не помогла :)
*

b2z

  • Глобальный модератор
  • 7288
  • 778 / 0
  • Разраблю понемногу
А почему одновременно
<select name="filter-book" class="uk-select" onchange="this.form.submit()">
и
<input type="hidden" name="filter_book" value="<?php echo $bookSelected; ?>"/>
*

borro

  • Завсегдатай
  • 1379
  • 22 / 0
  • желаю вам счастья
А почему одновременно
<select name="filter-book" class="uk-select" onchange="this.form.submit()">
и
<input type="hidden" name="filter_book" value="<?php echo $bookSelected; ?>"/>
От незнания. Как правильно, нужен ли инпут или дело в подчеркивании?
*

b2z

  • Глобальный модератор
  • 7288
  • 778 / 0
  • Разраблю понемногу
*

borro

  • Завсегдатай
  • 1379
  • 22 / 0
  • желаю вам счастья
input вообще не нужен. У вас из select прилетает значение.
Здравствуйте!
Спасибо. Уже не знаю, что еще можно попробовать изменить в коде. Может вы опытным глазом увидите. Прикладываю установочный архив компонента. Проблема все таже. В модели с именем contacts (фронтенд) не отлавливается параметр, вводимый в теге <select name="filter_book"> этого же представления. А именно в функции populateState модели строка
Код
            $book = $app->getUserStateFromRequest(
                $this->context . '.filter_book',
                'filter_book',
                $results[0]->book_name,
                'string'
            );
возвращает пустую строку, что все ломает.
« Последнее редактирование: 12.10.2020, 18:09:00 от borro »
*

sivers

  • Живу я здесь
  • 2610
  • 363 / 0
в приведенной populateState(). Замена 'filter_book' на 'filter-book' не помогла :)
Менять может и не надо было, но читаться оно где-то должно
возвращает пустую строку, что все ломает.
а для чего там getUserStateFromRequest?
почему не прочитать строку как $book = $app->input->getString('filter_book', '');?
Или там как-то на сессии увязано?

И еще стоит проверить (удостовериться) идет ли передача этого параметра при отправке формы - это в отладчике браузера можно.
На связи в telegram @sivers
sivers @ inbox . ru
https://sivers.su/
*

robert

  • Живу я здесь
  • 4974
  • 457 / 20
Вы записываете данные в 'filter_book', но хотите их извлечь из $this->context . '.filter_book'.
А populateState() выполняется только 1 раз при каждом вызове модели, я вам об этом уже давно говорил.
И значение 'filter_book' из селекта будет в 'jform', $app->input->get('filter_book') вам его не даст.
« Последнее редактирование: 13.10.2020, 16:10:11 от robert »
Не будь паразитом, сделай что-нибудь самостоятельно!
*

borro

  • Завсегдатай
  • 1379
  • 22 / 0
  • желаю вам счастья
Здравствуйте! Спасибо.
Получается populateState() должна читать фильтр следующим образом:
Код
$book = $app->getUserStateFromRequest(
                'filter_book',
                'filter_book',
                $results[0]->book_name,
                'string'
            );
А populateState() выполняется только 1 раз при каждом вызове модели, я вам об этом уже давно говорил.
А вот этот совет я не понял, как применить. Нужно еще раз параметр где-то считать и сохранить?
*

b2z

  • Глобальный модератор
  • 7288
  • 778 / 0
  • Разраблю понемногу
@robert
Цитировать
Вы записываете данные в 'filter_book', но хотите их извлечь из $this->context . '.filter_book'.
Нет, это не так. В getUserStateFromRequest первый параметр - это ключ в сессии. Вытаскивается из инпута по второму параметру, а он верный - filter_book.

Цитировать
И значение 'filter_book' из селекта будет в 'jform', $app->input->get('filter_book') вам его не даст.
С чего это вдруг? Это простой select в простой форме и это никак не связано с JForm. Фильтр выбирается, происходит отправка формы. А значит всё должно быть в $app->input.

@borro есть же отладчик, проверь, что приходит в $app->input->get('filter_book'). Можешь также в отладчике посмотреть глобальные массивы POST и REQUEST, что там за данные находятся.

P.S.
Исходный код компонента посмотрел, не увидел, где может быть проблема...
Чтобы оставить сообщение,
Вам необходимо Войти или Зарегистрироваться