Форум пользователей Impera CMS
Impera CMS - отличный движок для лёгкого создания интернет магазина.
Обладает невероятным количеством функций, необходимых в онлайн торговле.

Сортировка массивов в шаблоне

Следить
Главная
22:08
21 дек
#
?
Максим написал:

Добрый день.

Хочу отсортировать блок "Бренды" по количеству товаров, у которых указан этот бренд.

Код шаблона:

<h2>Бренды</h2>
<div>
    {foreach $all_brands as $br}
        {inputValue from='br->brand_id' assign=id}
        {$checked = (isset($smarty.request.filter_brand.$id)) ? 'checked' : ''}
        <div class="checkbox">
            <label {(intval($br->products_count) == 0) ? 'class="text-muted"' : ""}>
                <input type="checkbox" name="filter_brand[{$id}]" value="{$checked}" {$checked} {(intval($br->products_count) > 0) ? "" : 'disabled="disabled"'}/>
                {$br->name}
                {if intval($br->products_count) > 0}
                    <small>({$br->products_count})</small>
                {/if}
            </label>
        </div>
    {/foreach}

Таким образом в шаблоне будет выведен список брендов, и рядом с каждым брендом в скобках будет указано количество товаров этого бренда.

В шаблоне:

  • массив брендов $all_brands;
  • один очередной бренд $br;
  • количество товаров этого бренда $br->products_count

Хочу отсортировать список foreach по количеству товаров бренда.

Что сделал: в файле objects\.def-models\ClientPage.php ориентировочно на 490 строку до строки

$this->smarty->assignByRef('brands_list', $this->brands);

добавил:

// сортировка брендов по убыванию товаров этого бренда
$sorted_brands_tree = $this->brands_tree;
foreach ($sorted_brands_tree as $key_id => $value_prop_list) {
    foreach ($value_prop_list as $key_prop_id => $value) {
        if ( $key_prop_id == 'products_count' ) {
            $products_count[$key_id] = $value;
        }
    }
}
array_multisort($products_count, SORT_DESC, $sorted_brands_tree);
$this->smarty->assignByRef('all_brands_sorted', $sorted_brands_tree);

И в шаблоне указал

{foreach $all_brands_sorted as $br}

1. Вопрос: как сделать лучше? Например, в smarty есть модификатор sortby, но конструкция

{foreach from=$all_brands|@sortby:"#products_count" as $br}

не работает. Может быть нужно записать её под другому?

2. Вопрос: как аккуратно то же сделать и со свойствами товаров? Если нельзя средствами смарти, то в каком файле задаётся переменная $properties, которая выводится в шаблоне template/products.htm, где можно её изменить в ядре движка?

Спасибо.

11:21
22 дек
#
Разработчик написал:

Изменять код ядра - лишнее, так как создаст вам трудности при обновлении версии движка. Для целей выполнения собственного PHP-кода в момент, когда движок отработал и выполняется генерация страницы по шаблону, предусмотрена поддержка файла design/ИмяШаблона/html/helper.php.

По сути helper.php - это способ расширить шаблон вашими собственными функциями. Покажу простейший вариант использования хелпера, чтобы решить вашу задачу сортировки брендов.

Сначала пишем хелпер

Он содержит общедоступный метод sortBy для универсальной сортировки массива элементов по любому имени полю, а также передаёт себя под видом переменной $myHelper в шаблон, чтобы через эту переменную можно было вызвать любой из общедоступных методов хелпера.

<?php
    class TemplateEmulator {
        private $sortByFieldName;

        public function __construct ( & $cms ) {
            $cms->smarty->assignByRef('myHelper', $this);
        }

        private function compareBy ( $left, $right ) {
            $field = $this->sortByFieldName;
            if (!isset($left->$field)) return -1;
            if (!isset($right->$field)) return 1;
            if ($left->$field == $right->$field) return 0;
            return $left->$field < $right->$field ? -1 : 1;
        }

        public function sortBy ( & $items, $fieldName ) {
            $this->sortByFieldName = $fieldName;
            usort($items, array($this, 'compareBy'));
            return '';
        }
    }
?>

Особенности compareBy Строки if (!isset($...->$field)) return ...; могут быть удалены, так как служат страховочным целям, чтобы обслужить ситуацию, когда в шаблоне ошиблись и передали не массив объектов.

Особенности sortBy Это версия метода с возвратом результата во входной параметр, а не на выход метода. Последняя команда "возврат пустой строки" связана с особенностями работы Smarty - вывод результата на экран, если явно не присваивался какой-то переменной.

Теперь в шаблоне

Прежде чем начать перебирать записи брендов для вывода, мы просто вызываем наш метод сортировки, указав по какому полю хотим сортировать. И уже потом выводим бренды как обычно.

{$myHelper->sortBy($all_brands, 'products_count')}

{foreach $all_brands as $br}
    ...
    ...
{/foreach}

Поясню особенности Smarty насчёт возврата результата

Для примера изменю последнюю команду метода.

<?php
    class TemplateEmulator {
        ...
        ...
        public function sortBy ( & $items, $fieldName ) {
            $this->sortByFieldName = $fieldName;
            usort($items, array($this, 'compareBy'));
            return 'Hello World';
        }
    }
?>

Тогда следующий код одновременно и отсортирует массив, и выведет на экране "Hello World", именно в месте вызова метода.

{$myHelper->sortBy($all_brands, 'products_count')}

Пример традиционной техники возврата результата

Метод изменён так, чтобы получили новый массив с сохранением старого.

<?php
    class TemplateEmulator {
        ...
        ...
        public function sortBy ( & $items, $fieldName ) {
            $this->sortByFieldName = $fieldName;
            $sorted = $items;
            usort($sorted, array($this, 'compareBy'));
            return $sorted;
        }
    }
?>

И в шаблоне:

{$all_brands_sorted = $myHelper->sortBy($all_brands, 'products_count')}

{foreach $all_brands_sorted as $br}
    ...
    ...
{/foreach}

Насчёт свойств

Принцип сортировки тот же самый, только скорректировать под структуру переменной $properties. Упомяну также о полезной отладочной функции, которая распечатывает на экране структуру конкретной переменной, если та является массивом или объектом. Для этого пишем в шаблоне так:

{dumpStructure from=properties}

Ещё примеры:

{dumpStructure from=all_brands}
{dumpStructure from=categories}
{dumpStructure from='category->path'}
{dumpStructure from=products}
{dumpStructure from='product->variants'}

И так далее. Распечатка не углубляется далее второго уровня вложенности. Позволяет быстро узнать, какие же поля есть в этой переменной и их тип.

18:11
06 янв
#
?
Максим написал:
Разработчик написал: Принцип сортировки тот же самый, только скорректировать под структуру переменной $properties

Прошу подсказать, как скорректировать сортировку под структуру многомерного массива.

Структура вывода свойств такая:

{foreach $properties as $prop}
    {foreach $prop->options as $option}
        {$option->value} ({$option->count})
    {/foreach}
{/foreach}

Пробовал:

1. в функции сортировки писать так:

return $left['options']->$field < $right['options']->$field ? 1 : -1;

2. в шаблоне писать так:

{$emulator->sortBy($prop, 'count')}

или

{$emulator->sortByArr($prop, 'prop->count')}

3. и вот так:

{$emulator->sortBy($properties, 'properties->options->count')}

Функцию сортировки писал и до и после первого foreach.

18:27
06 янв
#
?
Максим написал:

Также пробую вывести содержимое массива $Pages шаблона html/navigation.htm вот так:

{dumpStructure from=Pages}

но ничего не выводится. Почему такое может быть?

11:08
07 янв
#
?
Шамиль написал:
Максим написал:скорректировать сортировку под структуру многомерного массива
{foreach $properties as $prop}
    {$emulator->sortBy($prop->options, 'count')}
    {foreach $prop->options as $option}
        {$option->value} ({$option->count})
    {/foreach}
{/foreach}
Максим написал:{dumpStructure from=Pages} но ничего не выводится

Потому что импера 100500 нюансов недокументированых. Код функции тут objects\.any-models\SmartyTags.php. Печатает объект или масив. $Pages масив строк.

Есть такое

<pre>{print_r($Pages)}</pre>
или
<pre>{var_dump($Pages)}</pre>

Есть еще

<pre>{$Pages|print_r}</pre>
<pre>{$Pages|var_dump}</pre>

Хз чем отличаются.

Написание ответа

Перед публикацией рекомендуется использовать Предпросмотр, чтобы увидеть конечный вид сообщения.


Обратите внимание! Для противодействия спаму новые посты форума проявляются с задержкой от нескольких минут, пока не пройдут модерацию.


Хостинг для сайта

Хостинг для интернет магазина

Svai.net

Украина
г. Черкассы
5+ Заказать

TutHost.ua

Украина
г. Киев
Заказать

Mirohost.net

Украина
г. Киев
? Заказать

HyperHosting.com.ua

Украина
г. Винница
i подробнее Заказать

Agava.ru

Россия
г. Москва
Заказать

Ukraine.com.ua

Украина
г. Киев
5 Заказать
Импераготовасотрудничатьс провайдерами Важно Учтите Этот список перечисляет лишь некоторых хостинг-провайдеров, у которых существуют специальные тарифные планы для интернет магазинов, а сам список не означает, что другие провайдеры чем-то хуже.

Существующие в списке оценки по 5-бальной шкале не должны учитываться при выборе, так как носят субъективный характер и касаются соотношения цена-качество-скорость только для самых дорогих тарифных планов.

Демо Главная Хронология Соглашение Материалы Контакты