Мне нужно вывести в родительской категории её название, подкатегории и по три статьи из подкатегорий. Выглядит это вот так:

Название (коричневый) - вывел.
Подкатегории (синий) - вывел.

Не могу и не знаю как правильно взять из БД по три статьи для каждой из подкатегорий (красный). Нужно каждый раз делать запрос в цикле и пушить их в массив $subArticles ?

Вот код:

$category = \OctoClub\Articles\Models\Category::where('slug', $this->property('slug'))->first();
    
$subCategories = \OctoClub\Articles\Models\Category::where('parent_id', $category->id)->select('id', 'name', 'slug', 'description')->get();


$subArticles = array();

for ($i = 0; $i <= count($subCategories); $i++) {
    
    $subArticles[] = \OctoClub\Articles\Models\Article::where('category_id', '??? тут id-категории из $subCategories ???')->select('name', 'slug', 'introtext', 'meta_img')->get();

}

$this->page['subCategories'] = $subCategories;
$this->page['subArticles'] = $subArticles;

Вопросами пометил ??? тут id-категории ??? - не могу достучаться до $subCategories[$i]['id'], что то с синтаксисом неправильно делаю.

И как делать выборку из БД - одним запросом можно или в цикле делать?

У тебя у категорий установлена обратная связь со статьями hasMany?
Если нет, то создай ее, будет легче дергать посты из категорий.

Так-же вопрос, у тебя "родительские" категории сделаны через Simple Tree или Nested Tree?

А для твоего макета подойдет примерно такой код.
В компоненте:

use OctoClub\Articles\Models\Category;

public function onRun()
{
    $this->page['category'] = Category::where('slug', $this->property('slug'))->first();
}

В шаблоне компонента:

<h1>{{ category.name }}</h1>

{% for sub_cat in category.getChildren() %} <!-- у Nested Tree есть метод для захвата всех "дочерних" категорий или может немного отличается, сделай dump(category), точно не помню -->

    <h2>{{ sub_cat.name }}</h2>
    
    {% for post in sub_cat.posts|slice(3) %} <!-- Берем 3 поста по связи hasMany -->
        <span class="headline">{{ post.name}}</span>
    {% endfor %}
    
{% endfor %}

Как видишь, использовать TWIG не очень страшно, и достаточно красиво)

  • Koresh ответили на это сообщение.
    • Изменено

    reazzon У тебя у категорий установлена обратная связь со статьями hasMany?

    Нет, не установлена. А что в ней писать? Что то такое:

    public $hasMany = [
        'articles' => [
            'Octoclub\Articles\Models\Article',
            'table' => 'octoclub_articles_content',
            'order' => 'id'
        ]
    ];

    reazzon Так-же вопрос, у тебя "родительские" категории сделаны через Simple Tree или Nested Tree?

    Сортировка категорий Nested Tree

    • reazzon ответили на это сообщение.
      • Изменено

      Koresh Нет, не установлена. А что в ней писать?

      public $hasMany = [
          'articles' => ['Octoclub\Articles\Models\Article'] // Учитывая что у статьей есть столбец category_id
      ];

      Подробнее в документации, как делать разные связи в моделях: https://octobercms.com/docs/database/relations

      Koresh Сортировка категорий Nested Tree

      Ну все, делаешь связь, и по моему примеру выводишь структуру страницы.

      • Koresh ответили на это сообщение.

        reazzon Ну все, делаешь связь, и по моему примеру выводишь структуру страницы.

        Категорию выводит, подкатегории выводит, а статьи - нет.
        В html коде даже спана вот этого нет: <span class="headline"></span>

        Сейчас ещё раз проверю всё ли я правильно написал.

        • Изменено

        А вот в sub_cat.posts
        posts - это правильно?

        Я вот так вывожу:

        {{ sub_cat }}
        {% for post in sub_cat.posts|slice(3) %} <!-- Берем 3 поста по связи hasMany -->
            <span class="headline">{{ post.name }}</span>
        {% endfor %}

        У sub_cat нет никакого posts, просто данные этой sub_cat из таблицы БД

          Koresh вместо posts название связи из hasMany.

          Koresh posts - это правильно?

          Нет конечно, это я уже после рабочего дня не соображаю, тут ты должен обращаться к hasMany связи, то есть {{ sub_cat.articles }}

          Исправил - теперь выводит статьи, но поведение странное.
          У первой подкатегории выводится 1 статья
          У второй - 2
          У третьей - 3 статьи.

          • reazzon ответили на это сообщение.

            Koresh поведение странное.

            Изучай что у тебя в базе, делай dump, смотри на связи, может у тебя так статьи и связаны в базе, что выводятся так "странно".

            У себя сделал связь hasMany с предметами, в шаблоне компонента Catalog, который был сделан по инструкции Создание плагина часть 2, и все работает как нужно, без изменений в Catalog.php.

            <ul>
                {% for category in categories %}
                    <li>
                        <a href="/catalog/{{ category.slug }}">{{ category.name }}</a>            
                        {% if category.items %}
                            <ul>
                                {% for item in category.items %}
                                    <li>
                                        <span class="headline">{{ item.name }}</span>
                                    </li>
                                {% endfor %}
                            </ul>
                        {% endif %}
                    </li>
                {% endfor %}
            </ul>

            Так выводится на фронте:

            • Изменено

            Да, я уже понял что это проблема у меня.
            Удалил все статьи из таблицы БД и импортнул их по новому. У меня при переезде сайта у категорий поменялся id, поэтому я в ручную проставляю категории статьям.

            Я пару статьям назначил категории и открыл посмотреть страницу не сломалась ли. Выводило 2 статьи у первой субкатегории и одна у второй субкатегории.
            Потом назначил ещё категории 20 статьям, но они уже не выводятся. Как будто страницу где то закешировало, так же выводится 2 - 1.
            Но открываю странице субкатегории - статьи выводятся все.

            У меня стоит RainLab.Blog, я его пока не удаляю. Там так же вручную статьям категории назначал. И есть тоже странность что в админке на странице категорий, где подсчёт кол-ва материалов у категории всего 2.
            По моему я двум статьям добавил категории и открыл страницу категорий. Так вот по сей день там показывает что у одной из категорий 2 статьи, а все остальные категории пустые, хотя я многим статьям успел назначить категорию.

            Может какую настройку нужно поменять?

            • reazzon ответили на это сообщение.

              Koresh зайди напрямую в базу и проверь что в статьях стоит в столбце category_id.

              • Koresh ответили на это сообщение.
                • Изменено

                reazzon зайди напрямую в базу и проверь что в статьях стоит в столбце category_id.

                По умолчанию category_id проставился ноль. Запись в создании БД $table->integer('category_id');, но я заливал статьи через импорт.
                Есть статьи где уже назначил категорию, там целые положительные числа.

                • reazzon ответили на это сообщение.

                  Koresh По умолчанию должно стоять NULL, 0 - это уже запись для Eloquent.

                  • Koresh ответили на это сообщение.

                    reazzon По умолчанию должно стоять NULL, 0 - это уже запись для Eloquent.

                    Это я исправил.
                    Всё равно статьи для подкатегорий выводит по непонятному. Есть где у подкатегорий выводит далеко задесяток статей, есть где только 2 статьи, а есть подкатегории у которых вообще статьи не выводит. При том что открываю страницы подкатегорий - там статьи есть.
                    Мне нужно что бы у меня выводилось по три статьи для каждой подкатегории. Сортировку я пока не вспоминаю, так как и без неё выводит некоректно.

                    Вот мой код, правда я добавил if sub_cat.published и if article.published == 1 в условия циклов (нашёл в документации что вроде так можно делать), так как у меня и для категорий и для статей есть параметр "Опубликовано" со значениями

                    • 0 - неопубликовано
                    • 1 - опубликовано
                    <h1>{{ category.name }}</h1>
                    {{ category.description|raw }}
                    
                    
                    {% for sub_cat in category.getChildren() if sub_cat.published == 1 %}
                        
                        <h2><a href="/{{ category.slug }}/{{ sub_cat.slug }}">{{ sub_cat.name }}</a></h2>
                        {{ sub_cat.description|raw }}
                        
                        <div class="row">
                            {% for article in sub_cat.articles|slice(3) if article.published == 1 %} <!-- Берем 3 статьи по связи hasMany -->
                                <div class="col-md-4">
                                            <h5>
                                                <a href="/{{ category.slug }}/{{ sub_cat.slug }}/{{ article.slug }}">
                                                    {{ article .name }}
                                                </a>
                                            </h5>
                                            
                                            <a href="/{{ category.slug }}/{{ sub_cat.slug }}/{{ article .slug }}" >Подробнее</a>
                                </div>
                            {% endfor %}
                        </div>
                        <hr/>
                        
                    {% endfor %}

                    Может ли быть проблема из за того что у меня для статей в БД есть поле order (заложено для сортировки вывода статей, пока у всех статей значение 0)? Я уже натыкался что название столбцов может приносить проблемы.

                    • BlackCat ответили на это сообщение.
                      месяц спустя
                      • Изменено

                      Koresh Вот вспомни, что я тебе говорил про проверку публикации в твиг.

                      {% for article in sub_cat.articles|slice(3) if article.published == 1 %}

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

                      articles | slice(3) - вот это может быть таким массивом
                      $articles = [
                         [ 'name' => 'Первый пост', 'is_public' => 1 ],
                         [ 'name' => 'Второй пост', 'is_public' => 0 ],
                         [ 'name' => 'Третий пост', 'is_public' => 0 ],
                      ]

                      Попробуй, убери проверку на бупликацию, если выведет 3 статьи, то я прав

                      • Koresh ответили на это сообщение.

                        BlackCat Я ни в коем случае не спорю с вами - у меня знаний мало, опыта ещё меньше. Если мне первый месяц было сложно смотреть доки октября, то сейчас более менее привыкаю.

                        Но понимаете в чём дело, у меня выводится не по три статьи и меньше, а вообще не понятно сколько: где десять, где две, где вообще ничего не выводит.

                        • BlackCat ответили на это сообщение.

                          Koresh Вы уже пробовали убрать проверку на публикацию? Если убрали изменилось ли что-нибудь.

                          • Koresh ответили на это сообщение.

                            BlackCat Вы уже пробовали убрать проверку на публикацию? Если убрали изменилось ли что-нибудь.

                            Вот только что специально убрал две проверки на published == 1 (код выше). Положительных изменений не наблюдается.

                            • reazzon ответили на это сообщение.

                              Koresh Выложи свою папку /plugins и /themes на GitHub, трудно оценивать так ситуацию.

                              • Koresh ответили на это сообщение.