Разделить ресурсы на блоки в pdoResources mFilter2

Александр, здравствуйте, бывает что нужно в анонсах pdoResources или mFilter2, между ресурсами что-то вывести к примеру баннер или разделить по блокам для того чтобы по разному их стилизовать и тому подобное. В pdoResources, это можно сделать так: Создать сниппет: printColumnItem
<?php
$phn = $placeholderName;
$colums = (int)$colums ? (int)$colums : 2;
$cols = array();
if(empty($placeholderName)){
    echo "Для сниппета printColumnItem не указан параметр placeholderName";
    return;
}
foreach ($modx->placeholders as $key => $ph) {
    if (strpos($key, $phn) === 0 && $key != $phn."log") {
        $placeholders[$key] = $ph;
    }
}
$qw = 0;
foreach(array_chunk($placeholders, count($placeholders) / $colums) as $column){
    $data = "";
    foreach($column as $v){
        $data .= $v;
    }
    $cols['column'.(++$qw)] = $data;
}
$modx->setPlaceholders($cols);
return;
В шаблон:
[[!pdoResources?
   &tpl=`Чанк оформления`
   &toSeparatePlaceholders=`column_item_`
]]
[[!printColumnItem?
    &placeholderName=`column_item_`
    &colums=`2`
]]
Плейсхолдеры: [[+column1]], [[+column2]] Александр если возможно, расскажите пожалуйста, как можно использовать этот вариант в mFilter2? Учитывая что параметр toSeparatePlaceholders в вызове фильтра:
&toSeparatePlaceholders=`my.`

Комментарии: 10

Александр Мальцев
Александр Мальцев
Привет!
С mFilter2 так не получится. Плейсхолдер [[+my.results]] будет содержать весь результат, он не будет как в случае с pdoResources разделён на отдельные плейсхолдеры с индексами.

А зачем это делать? Задачи, которые вы описали можно решить с помощью CSS и JavaScript.
Для стилизации блоков по разному в зависимости от их порядкового номера можно выполнить с использованием CSS селекторов :nth-child и :nth-of-type.
Вывести баннер между блоками можно выполнить с помощью JavaScript.
Александр
Александр
Здравствуйте! Мне это вариант почему-то показался более удобным. Спасибо за разъяснения. Александр не могли бы Вы привести не большой пример по поводу баннера на js в mFilter2, чтобы более понимать как это лучше делать?
Александр Мальцев
Александр Мальцев
Привет! Этот процесс ничем не отличается от вставки другого элемента на страницу.
Например, следующий javascript код вставит блок после каждого третьего элемента в результате:
$(function(){
  // функция, выполняющая вставку блока после каждого третьего элемента
  var insertAd = function() {
    var
      mse2row = $('.mse2-row'),
      banner = '<div style="height: 200px; background-color: green; margin-top: 20px; margin-bottom: 20px;" ></div>';
    if (mse2row.length > 0) {
      mse2row.each(function(index){
        if ((index + 1) % 3 === 0) {
          $(this).after($(banner));
        }
      });
    }
  }
  $(document).on('mse2_load', insertAd);
  $(document).ready(insertAd);
})
Александр
Александр
Здравствуйте! Огромное спасибо. Александр к примеру мне необходимо вывести только после третьего, правильно я сделал?

mse2row.each(function(index){
        if ((index === 3) + 0) {
          $(this).after($(banner));
        }
И как сделать вывод, только перед первым?
Александр
Александр
Хотел бы немного дополнить вопрос, в моём в предыдущем комментарии пример кода показывает банер только после третьего, но если ресурсов меньше трёх то банера нет, а как сделать чтобы был?
Александр Мальцев
Александр Мальцев
После третьего можно так:
$(function(){
  // функция, выполняющая вставку блока после каждого третьего элемента
  var insertAd = function() {
    var banner = '<div style="height: 200px; background-color: green; margin-top: 20px; margin-bottom: 20px;" ></div>';
    $('.mse2-row:nth-child(3)').after(banner);
  }
  $(document).on('mse2_load', insertAd);
  $(document).ready(insertAd);
})
Перед первым можно так:
$(function(){
  // функция, выполняющая вставку блока после каждого третьего элемента
  var insertAd = function() {
    var banner = '<div style="height: 200px; background-color: green; margin-top: 20px; margin-bottom: 20px;" ></div>';
    $('#mse2_results').prepend(banner);
  }
  $(document).on('mse2_load', insertAd);
  $(document).ready(insertAd);
})
Александр Мальцев
Александр Мальцев
Можно написать различные условия. Если количество элементов (результатов) одно, то выводить там и там, если другое — то в других местах, и т.д.
Александр
Александр
Спасибо
Александр
Александр
Александр Здравствуйте! Эти варианты работают, но есть одна проблема, если в mfiler2 нажимаешь подгрузить ещё, дублирует блоки, как я понимаю срабатывает этот параметр: mse2_load и по этому идёт дубляж блоков, как это можно исправить?
Александр Мальцев
Александр Мальцев
Привет! Пример приводил для пагинации.
Если нужно для подгрузки данных, то тогда нужно ещё писать какую-то дополнительную логику. Тут всё засисит что необходимо.
Например, если подгружаем по 10 штук записей, то можно так:
$(function(){
  var limit = 10;
  var count = $('#mse2_results .mse2-row').length;
  var adscount = 0;
  // функция, выполняющая вставку блока после каждого третьего элемента
  var insertAd = function() {
    var banner = '<div style="height: 200px; background-color: green; margin-top: 20px; margin-bottom: 20px;" ></div>';
    count = $('#mse2_results .mse2-row').length;
    if (count > 3 && count <= limit) {
      $('.mse2-row:nth-child(3)').after(banner);
      adscount++;
    } else if ((count + adscount) > limit) {
      $('.mse2-row:nth-child(' + (count - limit + 3 + adscount) + ')').after(banner);
      adscount++;
    }
  }
  $(document).on('mse2_load', insertAd);
  $(document).ready(insertAd);
})
В этом случае баннер бедут вставляться, сначала после 3, потом после 13 записи, 23 записи и т.д.