Repository: fidals/shopelectro

Issue:
Gen categories tags to sitemap
Сейчас в sitemap выгружаются, помимо прочего, страницы категорий.
Выгружай не только страницы, но и все варианты их тегов.
Однако, не должно быть страниц, удовлетворяющих паттерну `*-or-*`

Пример страницы, которую нужно выгрузить в sitemap:
https://www.shopelectro.ru/catalog/categories/universalnye-ot-seti-12-v/tags/vanson/

Строчку `Disallow: /*-or-*` из `robots.txt` не выпиливай ни в коем случае



Discussion:
Стоит обратить внимание на то, что в `robots.txt` есть [ограничение на часть страниц с тегами](https://www.shopelectro.ru/robots.txt):
```
Disallow: /*-or-*
```

> Стоит обратить внимание на то, что в robots.txt есть ограничение ...

@themygit , выпиливаем?
@duker33 да, лучше исключить. 

> да, лучше исключить.

@themygit , эм, нес-ко двусмысленно звучит. Кароч выпиливаем строчку `Disallow: /*-or-*` из robots
@duker33 да, плохо написал, извиняюсь.
Строчку выпиливать нельзя. ибо заедут дубли и сео ребята нас покарают.
Нужно выпилить эти страницы(удовлетворяющие /*-or-*) при генерации sitemap 

Resolving patch:
diff --git a/shopelectro/sitemaps.py b/shopelectro/sitemaps.py
--- a/shopelectro/sitemaps.py
+++ b/shopelectro/sitemaps.py
@@ -1,9 +1,11 @@
+from typing import Generator, Tuple
+
 from django.contrib.sitemaps import Sitemap
 from django.urls import reverse
 
 from pages.models import Page
 
-from shopelectro.models import Product, Category
+from shopelectro.models import Category, Product, TagGroup, Tag
 
 
 class AbstractSitemap(Sitemap):
@@ -37,6 +39,39 @@ def items(self):
         return Category.objects.filter(page__is_active=True)
 
 
+def get_categories_with_tags() -> Generator[
+    Tuple[Category, Tuple[TagGroup, Tag]], None, None
+]:
+    """
+    Return all unique Category+TagGroup pairs.
+
+    Currently, tags per category is limited to 1 tag (by SEO requirements).
+    So, for each tags group in each category we'll get 1 tag.
+    """
+    for category in Category.objects.filter(page__is_active=True):
+        products = Product.objects.get_by_category(category)
+        tags = Tag.objects.filter(products__in=products).distinct()
+        for group_name, group_tags in tags.get_group_tags_pairs():
+            for group_tag in group_tags:
+                yield category, (group_name, [group_tag])
+
+
+class CategoryWithTagsSitemap(AbstractSitemap):
+
+    def items(self):
+        # `items` method can't return generator (by django design)
+        # so we moved items collection code to dedicated function
+        return list(get_categories_with_tags())
+
+    def location(self, item):
+        category, tags = item
+        tags_slug = Tag.serialize_url_tags([tags])
+        return reverse('category', kwargs={
+            'slug': category.page.slug,
+            'tags': tags_slug,
+        })
+
+
 class ProductSitemap(AbstractSitemap):
 
     def items(self):
diff --git a/shopelectro/urls.py b/shopelectro/urls.py
--- a/shopelectro/urls.py
+++ b/shopelectro/urls.py
@@ -16,6 +16,7 @@
 sitemaps = OrderedDict([
     ('index', sitemaps.IndexSitemap),
     ('category', sitemaps.CategorySitemap),
+    ('category-with-tags', sitemaps.CategoryWithTagsSitemap),
     ('products', sitemaps.ProductSitemap),
     ('site', sitemaps.PagesSitemap)
 ])


Test patch: