[SeoFilter] долгожданное обновление: меню, sitemap


[ купить дополнение ] [ демо ] [ документация ]

Выкладываю долгожданное обновление SeoFilter со сниппетами для формирования меню и карты сайта.



Кто ещё не знаком с SeoFilter, рассказываю его возможности.

Компонент позволяет создавать виртуальные страницы с красивым постоянным адресом по любым полям ресурса, товара, включая дополнительные поля(TV) и поля, значения которых хранятся в других таблицах. Также можно использовать одновременно несколько полей для формирования страниц.

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

Всё это может работать даже через AJAX совместно с mSearch2 или без него.
Подробнее про все возможности в первом анонсе и документации.

А в этом обновлении два новых сниппета и небольшие изменения в коде:

sfMenu — формирование меню

Первый и самый функциональный это sfMenu. Для формирования меню создал новый класс. Очень многое взято из pdoMenu, в том числе почти вся поддержка классов. Очередное спасибо Василию. Мой код, пока не такой изящный, но стараюсь делать всё красиво. Всю документацию напишу позже.

! Важно ! Отличается от pdoMenu тем, что за сформированную ссылку на страницу здесь отвечает параметр [[+url]], а за её название параметр [[+name]].
Вообще можете задавать пустые чанки и проверять что можно использовать :) Параметров, которыми можно управлять формированием меню много, что я наверно и не все проверил) Можно вообще не указывать параметры и получить все ссылки. Но вот основные:
  • rules — список правил, чьи ссылки нужно использовать в меню; (можно с минусом)
  • parents — список страниц, к которым привязаны правила; (можно с минусом)
  • urls — отдельно id виртуальных страниц из таблицы url; (можно с минусом)
  • countChildren — подсчёт ресурсов(товаров) которые будут на странице;
  • mincount — минимальное количество ресурсов для включения ссылки в меню;
  • sortcount: — сортировка по количеству ресурсов, приоритетнее той что в sortby;
  • relative — экспериментальная перестройка меню исходя из выбранной seo-страницы;
  • nesting — виртуальное вкладывание ссылок в ссылки, попробуйте :) ;
  • double — дублирование ссылок при вкладывании, так как могут относится к нескольким правилам, так сказать мультикатегории;
  • nesting — виртуальное вкладывание ссылок в ссылки, попробуйте :) ;
  • groupbyrule — группировка по правилам (отдельный чанк-обёртка tplGroup);
Для всех параметров есть описания, что не понятно — пишите сюда) Вообще, не хватает пользовательских примеров использования меню. Но несколько своих примеров напишу:

1. Пример с группировкой на отдельной странице с исключением «пустых» страниц.
Самый первый скриншот.
[[!sfMenu? 
    &countChildren=`1`
    &groupbyrule=`1`
    &sortby=`createdon`
    &sortdir=`ASC`
    &mincount=`1`
    &parents=`9`
    &tplGroup=`@INLINE <div class="col-sm-6"><h4>[[+name]] <small>[[+total]] ссылок</small></h4>[[+wrapper]]</div>`
    &tplOuter=`@INLINE <ul[[+classes]]>[[+wrapper]]</ul>`
    &tpl=`@INLINE <li[[+classes]]><a href="[[+url]]">[[+name]]</a> <nobr><span>([[+total]] [[+total:units=`товар|товара|товаров`]])</span><small> - [[+count]] [[+count:units=`просмотр|просмотра|просмотров`]]</small></nobr>[[+wrapper]]</li>`
]]

2. Пример с вложенностью ссылок от двух ресурсов

[[!sfMenu? 
    &countChildren=`1`
    &nesting=`1`
    &double=`0`
    &mincount=`2`
    &parents=`9`
]]

3. Меню только первого уровня с сортировкой по количеству

[[!sfMenu? 
    &countChildren=`1`
    &sortcount=`1`
    &sortby=`createdon`
    &sortdir=`DESC`
    &mincount=`1`
    &parents=`9`
    &level=`1`
]]

sfSitemap — карта сайта

Сниппет создан на основе класса меню, поэтому поддерживает почти все те параметры, за исключением вложенности и группировки. Также здесь взято почти всё из pdoSitemap и использовать их можно совместно. Здесь напишу только этот пример, в остальном разобраться не сложно.
В pdoSitemap для параметра tplWrapper на демке я использовал чанк. Его содержимое:
<?xml version="1.0" encoding="{'modx_charset' | option}"?>
<urlset xmlns="{$schema}">
{$output}
{$_modx->runSnippet('sfSitemap',['tplWrapper'=>'sitemap.output', 'countChildren'=>1, 'mincount'=>1, 'forceXML'=>''])}
</urlset>
Где в сниппете sfSitemap в параметр tplWrapper написал чанк sitemap.output с содержимым {$output}.

! Важно ! При совместном использовании на одной странице нужно задавать пустой параметр forceXML, чтобы не было конфликтов заголовков header.

sfLink — обновление логики работы

Его смысл остался таким же, выводить ссылку при вводе id правила(или нескольких). Но код и формат использования стали лучше. Простой пример для того, чтобы вывести ссылку на сложную страницу. (у меня включён Fenom в шаблонах)
Ссылка на категорию:
{foreach $_modx->resource.color as $cvet}
	{'!sfLink'|snippet:[ 
	     'rules'=>'22,17',
	     'category'=>$_modx->resource.parent,
	     'cvet'=>$cvet
	]}
{/foreach}
Где-то выведет одну ссылку, где-то несколько:

Теперь не нужно вызывать дополнительные сниппеты для названия ссылки, так как в одном из предыдущих обновлений для всех ссылок правила (виртуальных страниц) можно задавать шаблон для формирования названия.

Если же какой-то цвет исключается правилом 22 (цвет + категория) или ссылка отключена, то будет поиск по правилу 17 (категория). Оно здесь специально стоит последним.

Меню и карта сайта кэшируются по-умолчанию на час. Подсчёт ресурсов дорогая операция на запросы, так как для каждой ссылки прогоняется. Но по времени у меня даже первый запуск не особо долгий, но всё сильно зависит от количества ссылок.

Описал, что вспомнил. Документация будет позже, а пока задавайте вопросы, если есть :)
28 сентября 2017, 23:21    Евгений Шеронов   
4    708 +15

Комментарии (42)

  1. Алексей 29 сентября 2017, 07:31 # 0
    У меня такой вопрос: а ресурсы кроме виртуальных ссылок так же остаются доступны по оригинальному пути или нет? Т.е. как обстоят дела с дублями страниц?
    1. Евгений Шеронов 29 сентября 2017, 08:55 # 0
      Вопрос не совсем понял, но компонент никак не затрагивает роботу обычных ресурсов. Все виртуальные станицы привязаны к физической странице и их адрес всегда будет зависеть от этой страницы. Метод формирования адреса можно задавать в параметре scheme (abs, full и т.д).

      Дублями вы называете то, когда одна страница доступна по нескольким адресам?
      Если так, то в системных настройках SeoFilter можно включить переадресацию на страницу с нужным окончанием (слэш, .html и т.д).
    2. Антон 29 сентября 2017, 12:36 # +1
      Добрый день, Евгений, спасибо за обновление. Есть одна проблема со сниппетом sfmenu. Если страницы на сайте не имеют окончания, то есть вида site.ru/category, то ссылки в меню выводятся неправильно, site.ru/categorystranica1, при этом при работе через фильтрацию mfilter2, все работает правильно site.ru/category/stranica1. Это можно как-то исправить или подождать следующего обновления?
      1. Евгений Шеронов 29 сентября 2017, 12:48 # +3
        Можете сами поправить, но в следующем обновлении учту, как наберутся ещё несколько замечаний.
        В чанке ссылки (параметр tpl) вместо плейсхолдера [[+url]] можете прописать так:
        [[~[[+page_id]]]]/[[+new_url:default=`[[+old_url]]`]]
        При этом чанк ссылки в таком варианте лучше не в inline формате использовать.

        Или же в синтаксисе Fenom: (что приятнее выглядит)
        {$page_id|url}/{$new_url ?: $old_url} 
        
        P.S. Эта инструкция для тех, у кого в качестве суффикса контейнера пустое значение.
      2. Александр 12 октября 2017, 11:30 # 0
        Евгений, а доступ тестовый в админ можно получить? Как Василий в минишоп с фильтрами открыл, чтобы посмотреть как под капотом все устроено, чтобы понять можно будет как то совместить ваше решение со своим сайтом?
        спасибо.
        1. Евгений Шеронов 12 октября 2017, 12:14 # +1
          Можно) Даже на целый день — modhost.pro

          Заодно поставьте mSearch2, miniShop2 и пройдите Быстрый старт SeoFilter

          Проблем с совместимостью пока ещё не бывало.
          Раз задались таким вопросам — то на 99% дополнение Вам подойдёт)

          1. Александр 12 октября 2017, 12:26 # 0
            s11324.h9.modhost.pro/manager/
            s11324
            EeYrtfL6AqMZ
        2. Михаил 12 октября 2017, 19:42 # 0
          А в самом ресурсе можно получить обратные ссылки на эти созданные страницы?
          1. Евгений Шеронов 12 октября 2017, 21:15 # 0
            Да, даже на те, что состоят из двух или более полей.

            Для этого предусмотрен сниппет sfLink.
          2. Артем 13 октября 2017, 20:30 # 0
            Подскажите, как в сниппете получить параметры страницы, например поле, где хранится Заголовок страницы
            seofilter_title
            1. Евгений Шеронов 13 октября 2017, 21:01 # 0
              Здравствуйте!
              А в каком именно сниппете?

              Если в SEO шаблонах правила, то вот так:
              {$id | resource:'pagetitle'}
              Здесь $id — это id страницы, куда относится правило.

              А сама настройка seofilter_title отвечает за то, чтобы подставлять оригинальный заголовок страницы, когда, например, будет выбрано много значений одного поля.
              1. Артем 13 октября 2017, 22:40 # 0
                Я имею ввиду в собственном сниппете подключенном в шаблоне. Нужно в нем получить +sf.title и другие
                1. Евгений Шеронов 13 октября 2017, 23:43 # 0
                  В своих сниппетах вот так:
                  $modx->getPlaceholder('sf.title'); //sf.description и т.д.
                  

                  Либо же можете передавать как параметры:
                  [[!mySnippet? &title=`[[!+sf.title]]` &introtext=`[[!+sf.introtext]]`]]
                  
                  1. Артем 14 октября 2017, 10:33 # 0
                    Спасибо
                    1. Артем 14 октября 2017, 10:59 # 0
                      А такой ещё вопрос, есть ли возможность генерации seo полей для всех категорий по единому шаблону и возврату к нему?
                      Например, для всех категорий каталога одежды сформирован один стиль генерации description (default), но при указании индивидуального описания и в фильтре при возврате к товару без фильтра, description остаётся как при индивидуальном, но уже не default т.к. он генерировался в другом месте и брался не из поля.
                      Вот есть ли возможность вернуть значение к default?
                      1. Евгений Шеронов 14 октября 2017, 11:30 # 0
                        Покажите пример, как у Вас изначально формируется description.

                        Как вариант, можете сделать ТВ поле, куда можете записать свой вызов сниппета для формирования description и в системных настройках для поля description задать это ТВ поле, для подстановки по умолчанию.
                        1. Артем 14 октября 2017, 12:06 # 0
                          Да, как вариант, но для вновь созданных категорий надо не забывать добавлять этот сниппет в ТВ. А через системные настройки/ClientConfig нельзя ли тоже самое сделать?
                          Я думаю было бы не плохо в системных настройках сделать возможность указания сниппета по обработке seo данных при возврате значений на default или что-то подобное.
                          1. Евгений Шеронов 14 октября 2017, 14:18 # +1
                            Как значение по-умолчанию поставьте в ТВ и всё :)

                            Думал когда-то над тем, чтобы сделать там возможность писать @INLINE чанки, где можно будет и сниппеты на Fenom запускать, но что-то взвесил все за и против, решил остаться на одном варианте.

                            Но так как много категорий может быть разных — это не самый удобный вариант.

                            Я просто всё равно не понимаю, что у Вас там по умолчанию делает сниппет?)
                            Берёт значение из description и изменяет его?

                            Или в самом description какие нибудь параметры-плейсхолдеры, выставляемые другими сниппетами? Если так, то все возвращаемые текстовые шаблоны (даже для страниц по умолчанию) через AJAX могут обрабатываться сниппетом из настройки prepareSnippet.

                            Вот пример сниппета обработчика:
                            <?php
                            $row = unserialize($row);  
                            if($rule_id) {
                            	// здесь же можете добавлять, изменять и обрабатывать значения
                            } else {
                            	// здесь делаете любые запросы, на подчсёты свои и т.д
                            	// и выставляете так: $row['myparam'] = 'Мой параметр';
                            }
                            return serialize($row);
                            
                            1. Артем 14 октября 2017, 23:40 # 0
                              description формируется в зависимости от категории/родителя/названия страницы и пр.
                              И мне нужно вернуть именно такой дефолт.

                              И ещё одно, например, у страницы фильтра есть контент а у дефолтной нет, но чтобы текст при переходе на дефолт пропадал приходится в каждой категории вставлять пустые символы.
                              1. Евгений Шеронов 15 октября 2017, 09:32 # 0
                                Первое — пока только свой вызов сниппета в возвращаемом ТВ поле для страниц по умолчанию.

                                А если кому-то наоборот, не надо, чтобы контент пропадал?)

                                Какое решение Вы можете предложить, чтобы всех устроило?
                                1. Артем 15 октября 2017, 10:55 # 0
                                  В поля для подстановки по умолчанию добавить возможность указания ещё и сниппета, тогда всё будет в одном месте и не надо создавать тв чтобы для него указывать сниппет по умолчанию.
                2. Ольга 18 октября 2017, 13:35 # 0
                  Мне необходимо на страницу производителя вывести все подразделы, в которых он встречается. Например, есть категория детские коляски. В ней разделы — прогулочные коляска, модульные коляски и тд. В каждой есть производитель Riko. На странице производителя нужно чтобы было прогулочные коляски Riko, модульные коляски Riko и тд. И изображение, которое вытягивается из TV раздела. Получится такое сделать с вашим дополнением?
                  1. Евгений Шеронов 18 октября 2017, 21:18 # 0
                    Добрый вечер!
                    С компонентом точно можно создать страницы производителей, производителей с категориями, привязав это к родительской категории.

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

                    В целом ответ, да, можно)

                    Если не разберётесь как — напишите в поддержку, сделаю пример именно для вашего сайта.
                    1. Ольга 18 октября 2017, 21:58 # 0
                      Спасибо за ответ, куплю — напишу в ТП, если будут затруднения
                  2. Артем 19 октября 2017, 10:34 # 0
                    Как быть с canonical?
                    У меня был сниппет который разбирал текущий url и если там присутствовал вопросительный знак возвращал канонический адрес страницы. Т.е это site.com/a?raz=dva превращал в это

                    <link rel="canonical" href="site.com/a">
                    Установил сеофильтр, и думал он будет возвращать в сниппет для преобразования site.com/a/dva, а он все равно возвращает site.com/a?raz=dva
                    1. Евгений Шеронов 19 октября 2017, 14:20 # 0
                      А как Вы формируете этот тег?
                      В принципе можете прописать туда плейсхолдер:
                      [[!+sf.url:default=`[[~[[*id]]]]`]]
                      1. Артем 19 октября 2017, 20:37 # 0
                        То что нужно, спасибо!
                    2. Серегин Анатолий 25 октября 2017, 00:39 # +1
                      Евгений, здравствуйте. Классное у вас дополнение получилось. Сложное правда, но свое дело делает:). Спасибо.
                      Теперь о проблеме. Я пробовал сделать через сниппет sfMenu меню. И хотелось сделать его так, чтобы пустые категории не выводились. И тут я столкнулся с проблемой. У меня есть составные разделы. К ним привязано несколько полей. Для таких разделов сниппет неправильно считает кол-во вложенных товаров, если фильтровать по msProductOption. Он учитывает только одно значение, а остальные игнорирует.
                      Я решил эту проблему изменением функции countChildren. Вот мое решение gist.github.com/Kookabura/e9ef4c0f94faa8deaf1fe6e02c41d1d7. Правки в коде в строках 18-21, 30-33, 70-82.
                      Посмотрите, пожалуйста, у себя. Если решение вам понравится, то включите в следующее обновление.
                      1. Евгений Шеронов 25 октября 2017, 11:26 # 0
                        Вам спасибо!)
                        Протестирую у себя и добавлю)
                        1. Серегин Анатолий 26 октября 2017, 00:29 # 0
                          Чуть исправил код по ссылке. Нашел ошибку.
                        2. fred Oushen 10 ноября 2017, 16:54 # 0
                          Простите, а вы в каком файле это меняли?
                          1. Евгений Шеронов 10 ноября 2017, 16:57 # 0
                            core\components\seofilter\model\seofilter\sfmenu.class.php
                            Но советую дождаться официального обновления, где проблема с подсчётом двух и более опций будет исправлена.
                        3. fred Oushen 02 ноября 2017, 08:48 # 0
                          Добрый день, вот такой у меня вопрос, на тестовом сайте, пробовал сделать следующий функционал с вашим модулем.

                          Каталог->подкатегории (>10)
                          вывел я их селектом, кое как разобрался, конечно :-)
                          Но, теперь выявилась проблема, при обновлении страницы пропадает заголовок, он просто пустой. Далее, ссылка формируется такая же, как и реальная ссылка с подкатегорией товаров. И там, оказывается, вообще не отображается заголовок h1. Решил я вопрос таким образом
                          [[!+sf.title:notempty=`[[!+sf.title]] / `]][[!pdoTitle? &registerJs=`1` &limit=`1`]]
                          Но, это же стоит и в title, каким образом можно исправить?
                          до этого стоял такой вариант.
                          [[!+sf.h1:default=`{$pagetitle}`]]
                          1. Евгений Шеронов 02 ноября 2017, 13:06 # 0
                            Добрый день!
                            Такой вариант точно не будет работать в заголовке:
                            [[!+sf.h1:default=`{$pagetitle}`]]

                            Правильно так:
                            [[!+sf.title:default=`[[*pagetitle]]`]] // или так:
                            {$_modx->getPlaceholder('sf.title')?:$_modx->resource.pagetitle}
                            

                            По таким вопросам лучше в поддержку на Modstore пишите modstore.pro/office/support#office/support/add
                          2. Konstantin 17 ноября 2017, 11:48 # 0
                            У кого-то работает меню? У меня нет, вообще никак…
                            1. Евгений Шеронов 17 ноября 2017, 13:40 # 0
                              Напишите в поддержку на modstore.pro/office/support#office/support/add с подробностями что делаете, а лучше сразу с доступом.

                              Ещё не было случая, где не удавалось помочь)
                            2. fred Oushen 21 ноября 2017, 15:56 # +1
                              Было бы не плохо, реализовать такой функционал.
                              1) Одно SEO правило на все.
                              2) Возможность, указать — разделы где выводить то или иное правило (массово — проставление галок + поиск).
                              3) Было бы не плохо, сделать возможность, выводить несколько — sfMenu, указав одно правило, которое обрабатывается согласно текущего ID ресурса. C применением параметра rules.
                              4) Картинки
                              1. Alex 02 декабря 2017, 03:52 # 0
                                Здравствуйте. Пробовал на тестовом сайте настроить seoFilter. Вроде со всем разобрался, но ЧПУ и замена Н1 по полю ms|price принципиально не хочет работать.
                                Вызов фильтра:
                                {$_modx->runSnippet('!mFilter2@filter', [
                                        'parents' => $_modx->resource.id,
                                        'paginator' => 'pdoPage@pagination',
                                        'element' => 'msProducts',
                                        'setMeta' => '1',
                                        'class' => 'msProduct',
                                        'limit' => '12',
                                        'pageLimit' => '7',
                                        'ajaxMode' => 'button',
                                        'tpl' => '@FILE chunks/productItem.tpl',
                                        'filters' => '
                                        ms|price:number,
                                        msoption|gender,
                                        msoption|povod,
                                        msoption|hobbymen,
                                        msoption|hobbywomen,
                                        msoption|yearold,
                                        ',
                                        'aliases' => '
                                        ms|price==price,
                                        msoption|gender==komy,
                                        msoption|povod==podarok,
                                        msoption|hobbymen==dlya,
                                        msoption|hobbywomen==whobby,
                                        msoption|yearold==vozrast
                                        
                                        ',
                                        'tplFilter.outer.price' => 'tpl.mFilter2.filter.slider',
                                        'tplFilter.row.price' => 'tpl.mFilter2.filter.number',
                                ])}
                                
                                Создал «Поле Фильтра», поставил там галку «Поле типа „Слайдер“ (number фильтры)»
                                Создал «Правило SEO» для цены и в «Заголовок Н1» добавил примерно так — «лоауцло».
                                В общем при фильтрации по цене выдает вот такую ссылку: site.com/catalog/?price=526,829 и не производит замену заголовка. Можно вообще сделать ссылку site.com/catalog/price=526,829 без? и замену заголовка или такого нет в функционале? Для остальных полей все прекрасно работает и чпу и замена заголовка.
                                1. Евгений Шеронов 02 декабря 2017, 06:03 # +1
                                  Доброе утро!)

                                  Так, видимо с последним обновлением mSearch2 (где добавлена фишка с динамическим слайдером) перестало работать (на демке тоже).

                                  Раньше работало так:

                                  Для полей с галочкой «Слайдер», нужно в ручную записывать необходимый диапазон в словарь.
                                  (так как различных значений цен может быть очень и очень много).

                                  Например, записав в словарь запрос «0,1000», можно отнести его к недорогим товарам.


                                  Тогда когда в слайдере будут выбраны значения в диапазоне от 0 до 1000: («100,300», «526,829» и т.д.) url не будет меняться, но фильтрация по уточнению стоимости будет работать.

                                  Этот функционал в ближайшем обновлении поправлю.
                                  А если имеете ввиду что-то другое, то напишите, как это должно работать)
                                  1. Alex 02 декабря 2017, 06:36 # +1
                                    Спасибо за ответ, но что-то не взлетело. Предполагаю, что я что-то не так делаю, так как ни ссылка, ни заголовок меняться не хотят. Поле цена вообще не реагирует на правила. Возможно надо что-то до настроить, может в системных настройках что-то или еще где. Просто в доках конкретно по настройке слайдера толком ничего не написано.
                                    Но это уже не важно)) На самом деле поле цена было не принципиальным, я думал оно мне будет ломать заголовки в других правилах если его выбрать, но нет, если выбрать, например, чекбоксы Повод: День рождения и Интересы: IT-шник + отфильтровать по цене, то все норм
                                    УРЛ: dev.site.com/catalog/podarok-den-rozhdeniya/dlya-it-shnik?price=485,829
                                    И красивый динамический заголовок: Подарок на день рождения для IT-Шника
                                    Но все-таки было бы круто, если бы вы добавили в доки пример для слайдера.
                                    Вообще, я считаю, чем лучше доки с примерами, тем больше интереса к дополнению, так как людям понятней и меньше с бубном придется танцевать думая «Или я что-то не так делаю или так нельзя в принципе».
                                    Желаю вашему дополнению стремительного развития, а вам побольше продаж;)
                                    1. Евгений Шеронов 02 декабря 2017, 12:13 # +1
                                      Спасибо) А я же в начале так и написал, что перестало работать из-за обновления mSearch2 (mFilter2).

                                      А краткая инструкция, что описал, пригодится тем, кто не обновлялся и чтобы мне самому потом документацию дополнить, скоро доберусь до этого.

                                      Когда поправлю, то можно будет создать такие страницы:
                                      dev.site.com/catalog/podarok-den-rozhdeniya/dlya-it-shnik/nedorogie
                                      И красивые заголовки: «Недорогие подарки на день рождения для IT-Шника» :)
                                2. Андрей 11 декабря 2017, 10:09 # 0
                                  ПРИВЕТ всем. Вопрос такой. Думаю сам не потяну привязку СУПЕР-ПУПЕР фильтра к своему сайту =) с доменами 3го уровня. Может кто-нибудь поможем мне с этим. Платно, естественно. Для связи скайп — nagahit (такой же профиль в ВК) или почта — nagahit@mail.ru
                                  Вы должны авторизоваться, чтобы оставлять комментарии.