""" Sitemap und Robots.txt Views für SEO """ from django.http import HttpResponse from django.template.loader import render_to_string from django.views.decorators.cache import cache_page from django.utils.decorators import method_decorator from django.views import View from django.contrib.sites.models import Site from .models import Product, Category from .seo import SEOManager import xml.etree.ElementTree as ET import json @cache_page(60 * 60 * 24) # 24 Stunden Cache def sitemap_xml(request): """XML Sitemap generieren""" seo_manager = SEOManager(request) sitemap_data = seo_manager.generate_sitemap_xml() # XML generieren root = ET.Element('urlset') root.set('xmlns', 'http://www.sitemaps.org/schemas/sitemap/0.9') for url_data in sitemap_data['urlset']['url']: url_elem = ET.SubElement(root, 'url') loc = ET.SubElement(url_elem, 'loc') loc.text = url_data['loc'] lastmod = ET.SubElement(url_elem, 'lastmod') lastmod.text = url_data['lastmod'] changefreq = ET.SubElement(url_elem, 'changefreq') changefreq.text = url_data['changefreq'] priority = ET.SubElement(url_elem, 'priority') priority.text = url_data['priority'] # XML als String xml_string = ET.tostring(root, encoding='unicode', method='xml') response = HttpResponse(xml_string, content_type='application/xml') response['Content-Type'] = 'application/xml; charset=utf-8' return response @cache_page(60 * 60 * 24) # 24 Stunden Cache def robots_txt(request): """Robots.txt generieren""" seo_manager = SEOManager(request) robots_content = seo_manager.generate_robots_txt() response = HttpResponse(robots_content, content_type='text/plain') return response class SitemapView(View): """Erweiterte Sitemap View mit Kategorisierung""" @method_decorator(cache_page(60 * 60 * 24)) def get(self, request): """Sitemap mit Kategorisierung""" site = Site.objects.get_current() base_url = f"https://{site.domain}" # Sitemap Index if request.GET.get('type') == 'index': return self.sitemap_index(request, base_url) # Produkt-Sitemap elif request.GET.get('type') == 'products': return self.products_sitemap(request, base_url) # Kategorie-Sitemap elif request.GET.get('type') == 'categories': return self.categories_sitemap(request, base_url) # Standard-Sitemap else: return self.main_sitemap(request, base_url) def sitemap_index(self, request, base_url): """Sitemap Index""" root = ET.Element('sitemapindex') root.set('xmlns', 'http://www.sitemaps.org/schemas/sitemap/0.9') sitemaps = [ {'loc': f"{base_url}/sitemap.xml", 'lastmod': '2024-01-15'}, {'loc': f"{base_url}/sitemap.xml?type=products", 'lastmod': '2024-01-15'}, {'loc': f"{base_url}/sitemap.xml?type=categories", 'lastmod': '2024-01-15'}, ] for sitemap in sitemaps: sitemap_elem = ET.SubElement(root, 'sitemap') loc = ET.SubElement(sitemap_elem, 'loc') loc.text = sitemap['loc'] lastmod = ET.SubElement(sitemap_elem, 'lastmod') lastmod.text = sitemap['lastmod'] xml_string = ET.tostring(root, encoding='unicode', method='xml') response = HttpResponse(xml_string, content_type='application/xml') return response def products_sitemap(self, request, base_url): """Produkt-Sitemap""" root = ET.Element('urlset') root.set('xmlns', 'http://www.sitemaps.org/schemas/sitemap/0.9') products = Product.objects.filter(is_active=True).order_by('-updated_at') for product in products: url_elem = ET.SubElement(root, 'url') loc = ET.SubElement(url_elem, 'loc') loc.text = f"{base_url}{product.get_absolute_url()}" lastmod = ET.SubElement(url_elem, 'lastmod') lastmod.text = product.updated_at.strftime('%Y-%m-%d') changefreq = ET.SubElement(url_elem, 'changefreq') changefreq.text = 'weekly' priority = ET.SubElement(url_elem, 'priority') priority.text = '0.8' xml_string = ET.tostring(root, encoding='unicode', method='xml') response = HttpResponse(xml_string, content_type='application/xml') return response def categories_sitemap(self, request, base_url): """Kategorie-Sitemap""" root = ET.Element('urlset') root.set('xmlns', 'http://www.sitemaps.org/schemas/sitemap/0.9') categories = Category.objects.all() for category in categories: url_elem = ET.SubElement(root, 'url') loc = ET.SubElement(url_elem, 'loc') loc.text = f"{base_url}{category.get_absolute_url()}" lastmod = ET.SubElement(url_elem, 'lastmod') lastmod.text = '2024-01-15' # TODO: Kategorie updated_at hinzufügen changefreq = ET.SubElement(url_elem, 'changefreq') changefreq.text = 'weekly' priority = ET.SubElement(url_elem, 'priority') priority.text = '0.7' xml_string = ET.tostring(root, encoding='unicode', method='xml') response = HttpResponse(xml_string, content_type='application/xml') return response def main_sitemap(self, request, base_url): """Haupt-Sitemap mit statischen Seiten""" root = ET.Element('urlset') root.set('xmlns', 'http://www.sitemaps.org/schemas/sitemap/0.9') # Statische Seiten static_pages = [ {'url': '/', 'priority': '1.0', 'changefreq': 'daily'}, {'url': '/products/', 'priority': '0.8', 'changefreq': 'weekly'}, {'url': '/gallery/', 'priority': '0.7', 'changefreq': 'weekly'}, {'url': '/contact/', 'priority': '0.5', 'changefreq': 'monthly'}, {'url': '/about/', 'priority': '0.5', 'changefreq': 'monthly'}, {'url': '/faq/', 'priority': '0.6', 'changefreq': 'monthly'}, {'url': '/custom-order/', 'priority': '0.7', 'changefreq': 'weekly'}, ] for page in static_pages: url_elem = ET.SubElement(root, 'url') loc = ET.SubElement(url_elem, 'loc') loc.text = f"{base_url}{page['url']}" lastmod = ET.SubElement(url_elem, 'lastmod') lastmod.text = '2024-01-15' changefreq = ET.SubElement(url_elem, 'changefreq') changefreq.text = page['changefreq'] priority = ET.SubElement(url_elem, 'priority') priority.text = page['priority'] xml_string = ET.tostring(root, encoding='unicode', method='xml') response = HttpResponse(xml_string, content_type='application/xml') return response def manifest_json(request): """Web App Manifest für PWA""" manifest = { "name": "Kasico Fursuit Shop", "short_name": "Kasico", "description": "Premium Fursuit Shop - Handgefertigte Fursuits made in Germany", "start_url": "/", "display": "standalone", "background_color": "#FF6B9D", "theme_color": "#FF6B9D", "orientation": "portrait-primary", "icons": [ { "src": "/static/images/kasicoLogo.png", "sizes": "192x192", "type": "image/png" }, { "src": "/static/images/kasicoLogo.png", "sizes": "512x512", "type": "image/png" } ], "categories": ["shopping", "fashion"], "lang": "de", "dir": "ltr" } response = HttpResponse( json.dumps(manifest, indent=2), content_type='application/json' ) return response