Универсальные списки-каталоги (list)

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

  • Каталогов на одном домене может быть несколько, все они храняться в as_lists, каждый имеет свою разметку, и свои процедуры search и getItem.
  • Такие каталоги не привязаны жёстко к базе. Таким образом, выступать в роли Категорий и Фильтров могут абсолютно разные данные (а не as_cat_categories и as_cat_filters как в варианте выше).
  • Сохранение URL элемента каталога необходимо реализовать самостоятельно.

Расположены каталоги по адресу /list/{code}

Формат URL категории

  • /list/{code}/{category1}/{category2}

Формат URL категории с фильтрами

  • /list/{code}/{category1}/{category2}/f/{filter1}-{text1},{text2}/{filter2}-{text3}/{filter3}-{text4}

Формат URL товара

  • /list/{code}/{category1}/{category2}/p/{url элемента каталога}

Управление выведено в Компоненты / Универсальные каталоги:

Таблица as_lists

  • id - id каталога
  • code - код каталога
  • rootURL - код каталога в URL
  • listMakeup - HTML разметка каталога
  • listItemMakeup - HTML разметка списковой части каталога (элементов)
  • itemDetailsMakeup - HTML разметка страницы элемента каталога

Процедура list_{code}_search

Примечание: 

  • в filters также передается langID для локализации.
  • Типы фильтров(typeCode из SELECT 2) :
    • checks - галочки (в процеду передаются как строка со значениями через запятую)
    • radio - радио-переключатели
    • select - выбор из списка с поиском
    • selectmultiple - множетсвенный выбор из списка (в процеду передаются как строка со значениями через запятую)
    • switch - переключатель да-нет
    • text - строка для ввода
    • color - выбор цвета
    • range - выбор диапазона
CREATE PROCEDURE [dbo].[list_new_search]
	@filters DictionaryParameter READONLY,
	@cats nvarchar(256),
	@sort nvarchar(24),
	@page int,
	@username nvarchar(32)
AS
BEGIN
	-- ПРОЦЕДУРА ПОИСКА ПО УНИВЕРСАЛЬНОМУ КАТАЛОГУ
        /*Определяем какие фильтры есть в url, и с учетом этого
          отбираем элементы для каталога*/

	-- Для пагинации
	declare @PAGE_SIZE int = 10, @total int = 0
        /*Сохраняем ID элементов каталога во временной таблице.
          Подсчитываем сразу полученное количество*/
	declare @itemIDs table (id int)

      /*Находим, на какой категории мы сейчас стоим, в общем дереве категорий
      @cats - это часть url где указаны категории, например для
       /list/suppliers/category1/category1_1/category1_1_3 будет @cats =
      'category1,category1_1,category1_1_3'*/

	CREATE TABLE dbo.#cats (id int, code nvarchar(256), name nvarchar(256), level
                                int, parentID int)
	insert into #cats
	select id, code, name, 1 [level], parentID
        from au_projectCategories
        where code in (select Value from dbo.split(@cats, ','))

	-- Выбранных категорий может быть несколько, с учетом вложенности вложенность
	declare @catCount int
	select @catCount = count(*) from #cats
	/* Находим конечную точку в дереве на которой остановились, то есть
           максимального уровня (в примере выше это будет category1_1_3)*/
	declare @selectedCatID int
	select top 1 @selectedCatID = id from #cats order by level desc

    -- Обработка возможных фильтров
    -- declare @filterCity nvarchar(256)
    -- select @filterCity = Value from @filters where [Key] = 'city'

    --- добавляем сортировку в Динамический запрос SELECT 1
    declare @sortStatement nvarchar(512)
    set @sortStatement = (case @sort
                    when 'rating' then ' order by name '
                    end	)

    -- Итак, что находим учитывая выбранные категории и отмеченные фильтры?
    insert into @itemIDs
    select distinct id
      from (select id, 111 catID
              from au_suppliers) t
    -- Категории поставщика входящие в выбранные категории, или в дочерние категории выбранных категорий
	where (isnull(@cats,'')='' or t.catID = @selectedCatID
            					or (select parentID from au_projectCategories where id = t.catID) = @selectedCatID )

	select @total = count(*) from @itemIDs

	-- SELECT 1 - SearchItemsResult (настройки поиска, общие параметры каталога)
	select 'Не найдено' EmptyText,
		   (case when isnull(@cats,'')='' then 'Каталог поставщиков услуг' else (select name from au_projectCategories where id = @selectedCatID) end) Title,
		   'desc' Text,
		   @sort Sort,
		   @page [Page],
		   @PAGE_SIZE PageSize,
		   @total Total,
		   'DEMO' SeoTitle,
		   'DEMO' SeoDescription,
		   'DEMO' SeoKeywords,
		   ''  HeadSection,
		   ''  BodyBottomSection,
		   1 Result,
           '' Msg
	-- SELECT 2 - FilterParameter - Показываем либо все услуги, либо относящиеся к выбранной категории
	select 1
    /*select 0 id,
    	   'Город' title,
		   'Город' tooltip,
		   'city' Code,
		   '' defValue,
		   'checks' typeCode,
		   (select stuff( (
						select ','+ name
						  from (select name from as_geo_regions) t1
						for xml path(''), type
						   ).value('.', 'varchar(max)'), 1, 1, ''
						 )
			) as  commaValues,
		   (select top 1 Value from @filters where [Key] = 'city') commaSelected,
3 showCount
*/

	-- SELECT 3 - Cat  CatChain - Выбранные категории
	select * from #cats
	-- SELECT 4 - Cat  InnerCats - отобразим сбоку либо все категории, либо категории входящие в выбранную
    select *
    from au_projectCategories
	where parentID = @selectedCatID or (parentID is null and @catCount = 0)

	drop table #cats

	-- SELECT 5 - Item (ID, Desc, Price, Name, URL) -- Данные отображаемые в перечне элементов каталога
	select s.id,
		  isnull(surname+' '+firstname+' '+lastname, username) as name,
          '' [desc],
          '0' price,
          '/list/test/'+isnull(c.username,'')+'---'+try_cast(s.id as nvarchar) Url
	 from au_suppliers s join ctr_contacts c on c.id = s.contactID
     where s.id in (select id from @itemIDs)

	-- SELECT 6 - ItemParam
    -- Атрибуты элементов каталога
    -- Структура Атрибута: ID, Name, Code, Value, ItemID
    -- В разметке listItemMakeup атрибут отобразится по {param-code}
	select 1 as ID, 'Категории услуг' as Name, 'categories' as Code,
    	   'value1' as Value, 111 as ItemID
    union

    select 2 as ID,
    'О себе' as Name,
    'description' as Code,
    (select isnull(description,'О себе') from ctr_contacts where id = contactID) as value,
    id as ItemID  from au_suppliers

	-- SELECT 7 - Param общие Атрибуты для каталога (ID, Name, Code, Value)
    -- Атрибуты самого каталога
    -- Структура Атрибута: ID, Name, Code, Value
    -- В разметке listMakeup атрибут отобразится по {param-code}
	select 1

	-- SELECT 8 - DictionaryParameter  Sorts
	select 'rating' [key], 'По рейтингу' Value

	-- select 9 -- Start cats (категории которые показываются на 1 экране каталога как дашборд {catList})
	select id, code, name, 1 level, parentID,'' [Image],
    'fas fa-wrench' iconClass
	  from au_projectCategories where @selectedCatID is null and (parentID is null or parentID in (select id from au_projectCategories where parentID is null) )
END

Процедура list_{code}_getItem

https://pastebin.com/WJFMKYTT

Примечание: 

  • в процедуру может передаваться также необязательный параметр @parameters (тип DictionaryParameter), в котором передается langID
  • Процедуру можно найти с демо проекте.

Разметка as_lists: listMakeup

Дефолт разметка:

{title}
<div class="row align-items-start mt-4">
  <div class="col-12 col-sm-12 col-md-12 col-lg-9 ml-auto as-lightbox">
  <div>{items}</div> </div> <div class="col-12 col-sm-12 col-md-12 col-lg-3">

  <div>{innerCats}</div>

  </div>
</div>

<!--Разметка расположения элементов на странице каталога
     Компоненты {...} определяются в процедуру search -->

 Параметры (используются как {name}):

  • filtes - вставка  фильтров
  • innerCats - категории в текущей категории
  • cats - дерево категорий до текущей категории
  • tags - теги для отображения выбранных фильтров
  • viewTypes - 2 вида просмотра каталога
  • title - заголовок каталога
  • foundCount - метка количества результатов
  • desc - описание текущей категории
  • sorts - элемент управления сортировкой
  • items - вывод элементов каталога
  • paging - элемент управления пагинацией
  • param-[code] - вставка дополнительных параметров
  • filter-{code} - можно также разместить каждый фильтр отдельно. 
    ВАЖНО. Обязательно указывайте {cat}, он необходим для построения адресов. Если не нужно его выводить, используйте 
    {cats}

Разметка as_lists: listItemMakeup

Разметка по умолчанию

<div class="card mb-3" data-itemid="{id}">
   <div class="card-header">
        <h5 class="font-weight-bold">{name}</h5>
   </div>

   <div class="card-body">
       <div class="row align-items-center">
            <div class="col-12 col-sm-12 col-md-12 col-lg-5">
               <a href="#" class="as-lightbox-item" data-title="{name}" data-="" url="/uploads/land/f/{id}.gif"><img src="/uploads/land/f/{id}-thumb.jpg" alt="{param-description}"></a>
             </div>

            <div class="col-12 col-sm-12 col-md-12 col-lg-7 ">
                <div class="text-dark mt-2">{param-description}</div><br>
                <div class="badge badge-pill badge-primary btn-sm"><small>{price}
                </small></div>
            </div>
       </div>
    </div>
</div> 

 Параметры (использовать как {code}):

  • id - ID элемента
  • name - наименование элемента
  • desc - описание элемента
  • price - цена
  • url - URL страницы элемента
  • imgUrl - картинка элемента
  • addToCart - кнопка добавления в корзину
  • addToFav - кнопка добавления в избранное
  • param-[code] - дополнительные параметры, переданные через sql
  • image - картинка элемента (как image-resource)

Разметка as_lists: itemDetailsMakeup

<!-- Разметка элемента страницы каталоге элеметы {...}
     Определются в процедуре getItem-->
<h2>{name}</h2>
<div><!--{param-mark}--></div>
<div class="row align-items-center">
  <div class="col-lg-2 col-md-2 col-sm-12 col-xs-12 mb-3"><!--{param-photo1}--></div>
  <div class="col-lg-10 col-md-10 col-sm-12 col-xs-12 mb-3">
   <!-- {list1}-->
   <!-- -->
  </div>
</div>
<div class="card-header">
  <ul class="nav nav-tabs card-header-tabs">
    <li class="nav-item">
      <a class="nav-link active" data-toggle="tab" href="#item1">Описание</a>
    </li>
    <li class="nav-item">
      <a class="nav-link" data-toggle="tab" href="#item2">Отзывы <!--{param-revCount}--></a>
    </li>
    <li class="nav-item">
      <a class="nav-link" data-toggle="tab" href="#item3">Портфолио</a>
    </li>
  </ul>
</div>
<div class="card-body tab-content">
  <div class="tab-pane fade show active" id="item1">
    <p class="mt-3 text-dark"><!--{desc}--></p>
  </div>
  <div class="tab-pane fade" id="item2">
    
  </div>
  <div class="tab-pane fade" id="item3">
    Портфолио отсутствует
  </div>
</div>

Параметры (использовать как {code}):

  • id - ID элемента
  • name - наименование элемента
  • desc - описание элемента
  • imgUrl - картинка элемента
  • price - цена
  • addToCart - кнопка добавления в корзину
  • addToFav - кнопка добавления в избранное
  • param-[code] - дополнительные параметры, переданные через sql
  • images - галерея картинок элемента
  • list1-list5 (с параметрами p1-p6) - вывод дополнительные списков (их разметка задается в соответствующих параметрах в хранимых процедурах List1Makeup-List5Makeup). 

Примечания по каталогам List

  • Для категорий вы можете также указывать Url параметр и тогда именно он будет браться за основу, а не строить по иерархическому принципу (вложенность категорий).
  • Можно делать innerCats постоянным (т.е. чтобы всегда категории выводились одни и те же, даже когда мы находимся в одной из них). При этом текущая категория будет выделяться (идет проверка по вхождению URL в текущий адрес страницы). Делайте уникальные названия категорий без возможных пересечений (например car и carPlaces - плохие названия категорий, т.к. одно входит в другое название).

Как добавить микроразметку, стили или скрипты в каталог.

Используйте параметры headSection, bodyBottomSection в SELECT 2 в list_search и аналогичные параметры в  list_getItem. Вы можете туда вставлять коды OpenGraph и JSON LD описание страниц.

Как динамически изменить корень хлебных крошек? 

Используйте параметр BreadcrumbRootTitle в SELECT 2 в list_search и аналогичные параметры в  list_getItem. 

Главное применение - при локализации каталога. 

Как сделать другое число скрываемых параметров в фильтре?

Для этого необходимо установить для фильтров в SELECT 2 процедуры search парамтер showCount (по умолчанию 4). 

Как сделать так чтобы фильтры с Not Selected (или не выбрано) не попадали в адрес?

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

<div class="cat-notSelectedList hide">
  <span data-value="Not selected"></span>
  <span data-value="Не выбрано"></span>
</div>

Как настроить кеширование списка List

Для этого установите в WebConfig в разделе AppSettings параметр listCacheMinutes. Данный параметр указывает сколько минут будет кешироваться результат выдачи в списке List
(кешируются все запросы по списку - вариации выбора фильтров и категорий).

<add key="listCacheMinutes" value="60"></add>

Тип фильтра Цвет color

Для этого указываем в select 2 в Search процедуре
  select 3 id,
    	   'Цвета' title,
		   'Имеется ссылка либо на прототип либо дополнительный скрин' tooltip,
		   'filterColor' Code,
		   '' defValue,
		   'color' typeCode,
		   '#ccc,#a00,#0f0' as  commaValues,
		   (select top 1 Value from @filters where [Key] = 'filterColor') commaSelected
    
Примечание. В URL передается цвет без #. Но в обработке можно использовать формат #abc или #aabbcc

Использование спецсимволов в имени фильтра

Бывает ситуация, когда в значениям фильтров идут специальные символы, которые недопустимы в URL (например, +.#&). В этом случае в SELECT 2 необходимо передавать Values как значения как code||name. 
-- SELECT 2 in SEARCH
 select 2 id,
    	   'Stacks' title,
		   '' tooltip,
		   'stack' Code,
		   '' defValue,
		   'select' typeCode,
		   (select 'Not selected,' +
            stuff((select top 3000 ',' + code + '||'+ name
				   from rg_stacks order by name
				   for xml path(''), type).value('.', 'nvarchar(max)'), 1, 1, '')) as commaValues,
		   (select top 1 Value from @filters where [Key] = 'stack') commaSelected,
Также при проверке на существование фильтра проверяйте на code (а не на выводимый name).

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

Платформа Falcon Space

Это снижение стоимости владения

за счет меньшего количества людей для поддержки

Это быстрое внесение изменений

по ходу эксплуатации программы

Это современный интерфейс

полная адаптация под мобильные устройства

Бесплатное обучение разработке на Falcon Space

Вы можете разрабатывать самостоятельно или сотрудничать с нами в плане веб-разработки на платформе Falcon Space.
Примечание

Google поиск по нашей документации