Как фильтровать записи по категориям в PHP Laravel Twig?

Я делаю простую галерею, используя OctoberCMS на основе Laravel и Twig.

Как фильтровать записи по категориям?

Вот как я это делаю сейчас, но я не думаю, что это хорошее решение:

Я фильтрую html, но полные записи по-прежнему существуют для всех элементов вне категории, что приводит к дополнительной нумерации страниц и пустым страницам.

База данных

  • «Галерея» таблицы содержит список названий категорий.

  • Таблица «images» содержит имена изображений и их категории с тегами.

Список изображений

Параметры URL: /gallery/:category?/:page?

При посещении URL-адреса, такого как /gallery/nature/1, изображения будут фильтроваться по категориям с использованием цикла for.

<!-- Gallery Category Record Variable -->
{% set category = record.category %}

<!-- Image List -->
{% for record in records %}

    <!-- If Image Category Tag matches Gallery Category Name -->
    {% if record.category_tag == category %} 
        <img src="/{{ record.name }}.jpg">
    {% endif %}

{% endfor %}

Записи

Результаты для «записей» и «записи».

Цикл for показывает запись «галерея → категория» в записях «изображения → категория_тег».

На странице отображаются все записи «изображения → имя».

{% for record in records %} = (All in 'images')
{{ records }} = {<ul><li>...<a href="gallery/nature?page=2">2</a>} (All in 'images')
{{ record }} = {"category":"nature","id":7} (Current category in 'gallery')

Решение?

Есть ли способ отфильтровать «записи» по категориям перед созданием списка html?


person Matt McManis    schedule 09.02.2017    source источник
comment
Не уверен, что я неправильно понял, но не проще ли получить записи, соответствующие критериям, прежде чем передавать их в представление? как Gallery::where('category_id', $catId)->get(). Конечно, сначала вам нужно будет получить идентификатор категории, используя имя, взятое из параметров.   -  person Christopher Francisco    schedule 09.02.2017
comment
@ChristopherFrancisco Через OctoberCMS вы перетаскиваете список записей или сведения о записи, затем устанавливаете класс модели и столбец отображения. Оттуда вы можете использовать синтаксис Twig для использования записей. Я новичок в этом и использую Laravel вне Twig.   -  person Matt McManis    schedule 09.02.2017
comment
Плохо, ссылка на OctoberCMS перенаправляла на страницу разбивки на страницы, поэтому я предположил, что это просто компонент разбивки на страницы (даже несмотря на то, что в названии было написано CMS, глупо, хахаха)   -  person Christopher Francisco    schedule 09.02.2017
comment
@ChristopherFrancisco Я последовал вашему совету и попробовал использовать Gallery::select()-›where()-›paginate(); Он работает с некоторыми проблемами, такими как отсутствие значения CurrentPage.   -  person Matt McManis    schedule 09.02.2017
comment
Лучше сделать фильтрацию в вашем компоненте, хорошим примером может быть плагин блога RainLab, посмотрите, как он фильтрует сообщения по категориям   -  person Raja Khoury    schedule 15.02.2017


Ответы (1)


Вот как я бы к этому подошел:

  • Создайте область в своей модели изображений, которая фильтрует по странице, категории и т. Д.
  • Обрабатывать свойства и логику URL в вашем компоненте, а не просматривать

Скажем, компонент галереи:

URL: page.com/:cat/:page?

    public function defineProperties()
    {
        return [
            // Page # for pagination..
            'pageNumber' => [
                'title'       => 'Page #',
                'description' => 'Gallery Page #',
                'type'        => 'string',
                'default'     => '{{ :page }}',
            ],
            // Category slug
            'category' => [
                'title'       => 'Category',
                'description' => 'Gallery Cat',
                'type'        => 'string',
                'default'     => '{{ :cat }}',
            ],
            // Images to show per page
            'perPage' => [
                'title'             => 'Images per page',
                'type'              => 'string',
                'validationPattern' => '^[0-9]+$', //  validation
                'validationMessage' =>  'VValidation Error',
                'default'           => '15', 
            ],
            // if you want to add sorting
            'sortOrder' => [
                'title'       => 'Sort Order',
                'description' => 'Images Sort Order',
                'type'        => 'dropdown',
                'default'     => 'updated_at desc' 
            ],
        ];
    }

public function getSortOrderOptions()
{
    return Image::$allowedSortingOptions;
}


public function init()
{
    $this->pageNumber   =  empty($this->property('pageNumber')) ? 1 :   $this->property('pageNumber');
    $this->perPage      =  $this->property('perPage');
    $this->sortOrder    =  $this->property('sortOrder');
    $this->category     =  $this->property('category');
}

public function onRun()
{

  // here you may want to do some checks 
 // and add logic before querying your DB

    return $this->listImages($this->pageNumber , $this->sortOrder,  $this->perPage, $this->category);

}

public function listImages($pageNumber, $sortOrder, $perPage, $category){

  // this is the scope you will define in your Images Model
 // to handle pagination, sorting, category filtering ect..

    $images = Images::listFrontEnd([
        'page'          => $pageNumber,
        'sort'          => $sortOrder,
        'perPage'       => $perPage,
        'category'      => $category,
    ]);



   // small helper if the pagination # is > than last page
  // redirect to last page..

    $lastPage = $images->lastPage();

    if ($this->pageNumber > $lastPage && $this->pageNumber > 1){
            return Redirect::to($this->currentPageUrl(["page" =>  $lastPage]));
        }


 $this->images  = $this->page['images'] = $images;

}

в вашей модели изображения:

// list the allowed sorting options that will show up in your component

public static $allowedSortingOptions = array(
    'created_at asc'            => 'Images Created (ascending)',
    'created_at desc'           => 'Images Created (descending)',
    'updated_at asc'            => 'Images Updated (ascending)',

  //        ect....
);


// Scope for your component
public function scopelistImages($query, $options)
    {
        /*
         * Default options
         */
        extract(array_merge([
            'page'              => 1,
            'perPage'           => 15,
            'sort'              => 'updated_at',
            'category'          => null
        ], $options));



        // SORTING
        if (!is_array($sort)) {
            $sort = [$sort];
        }

        foreach ($sort as $_sort) {

            if (in_array($_sort, array_keys(self::$allowedSortingOptions))) {
                $parts = explode(' ', $_sort);
                if (count($parts) < 2) {
                    array_push($parts, 'desc');
                }
                list($sortField, $sortDirection) = $parts;
                if ($sortField == 'random') {
                    $sortField = Db::raw('RAND()');
                }
                $query->orderBy($sortField, $sortDirection);
            }
        }

        // Filter by category
         ........


        return $query->paginate($perPage, $page);
    }

Ответ взят из плагина блога RainLab

person Raja Khoury    schedule 15.02.2017