Sitemaps
Buraq’s sitemap framework generates sitemap.xml files for search engines. It mirrors Django’s django.contrib.sitemaps API and supports async querysets natively.
XML is generated using Python’s stdlib xml.etree.ElementTree (C accelerator) — no extra dependencies.
from buraq.contrib.sitemaps import Sitemap, GenericSitemapfrom buraq.contrib.sitemaps.views import sitemapBasic Sitemap
Section titled “Basic Sitemap”Subclass Sitemap and override items() and optionally location(), lastmod(), changefreq, and priority:
from buraq.contrib.sitemaps import Sitemap
class PostSitemap(Sitemap): changefreq = "weekly" priority = 0.8
async def items(self): return await Post.objects.filter(published=True)
def location(self, post): return f"/posts/{post.slug}"
def lastmod(self, post): return post.updated_at # datetime or date — auto-formattedWire it up in urls.py:
from buraq.urls import pathfrom buraq.contrib.sitemaps.views import sitemapfrom myapp.sitemaps import PostSitemapfrom functools import partial
sitemaps = { "posts": PostSitemap(),}
urlpatterns = [ path("/sitemap.xml", partial(sitemap, sitemaps=sitemaps)), # ... other urls]The sitemap is served at /sitemap.xml:
<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> <url> <loc>https://example.com/posts/hello-world</loc> <lastmod>2026-08-04</lastmod> <changefreq>weekly</changefreq> <priority>0.8</priority> </url></urlset>Multiple Sitemaps
Section titled “Multiple Sitemaps”Pass multiple sitemap objects to cover different sections of your site:
class PostSitemap(Sitemap): changefreq = "weekly" priority = 0.8
async def items(self): return await Post.objects.filter(published=True)
def location(self, post): return f"/posts/{post.slug}"
class PageSitemap(Sitemap): changefreq = "monthly" priority = 0.5
def items(self): return ["/", "/about", "/contact"]
def location(self, path): return pathsitemaps = { "posts": PostSitemap(), "pages": PageSitemap(),}
urlpatterns = [ path("/sitemap.xml", partial(sitemap, sitemaps=sitemaps)),]GenericSitemap
Section titled “GenericSitemap”For quick sitemaps from a queryset — no subclassing needed:
from buraq.contrib.sitemaps import GenericSitemapfrom buraq.contrib.sitemaps.views import sitemapfrom functools import partial
info_dict = { "queryset": Post.objects.filter(published=True), "date_field": "updated_at", # used for <lastmod>}
sitemaps = { "posts": GenericSitemap(info_dict, priority=0.6, changefreq="daily"),}
urlpatterns = [ path("/sitemap.xml", partial(sitemap, sitemaps=sitemaps)),]GenericSitemap calls item.get_absolute_url() for each item’s location. Define it on your model:
class Post(models.Model): slug = models.SlugField()
def get_absolute_url(self): return f"/posts/{self.slug}"Dynamic changefreq and priority
Section titled “Dynamic changefreq and priority”Both changefreq and priority can be callables that receive the item:
class PostSitemap(Sitemap): def changefreq(self, post): return "daily" if post.is_featured else "weekly"
def priority(self, post): return 1.0 if post.is_featured else 0.6
async def items(self): return await Post.objects.filter(published=True)
def location(self, post): return f"/posts/{post.slug}"Sitemap index
Section titled “Sitemap index”For large sites, split sitemaps by content type and serve a <sitemapindex> that lists them:
from buraq.contrib.sitemaps import sitemap_indexfrom buraq.urls import pathfrom . import sitemaps
urlpatterns = [ path("/sitemap.xml", sitemap_index, { "sitemaps": { "posts": sitemaps.PostSitemap, "pages": sitemaps.PageSitemap, } }), path("/sitemap-posts.xml", sitemap, {"sitemaps": {"posts": sitemaps.PostSitemap}}), path("/sitemap-pages.xml", sitemap, {"sitemaps": {"pages": sitemaps.PageSitemap}}),]The index view returns a <sitemapindex> XML document with one <sitemap><loc> entry per key, pointing to /{key}-sitemap.xml.
Sitemap Reference
Section titled “Sitemap Reference”Sitemap class attributes
Section titled “Sitemap class attributes”| Attribute | Default | Description |
|---|---|---|
changefreq |
None |
"always", "hourly", "daily", "weekly", "monthly", "yearly", "never" — or a callable |
priority |
None |
Float 0.0–1.0, or a callable |
protocol |
"https" |
URL scheme for absolute URLs |
limit |
50000 |
Max URLs per sitemap (sitemap protocol limit) |
Sitemap methods
Section titled “Sitemap methods”| Method | Returns | Description |
|---|---|---|
items() |
list or coroutine |
Items to include — can be async def |
location(item) |
str |
URL path for the item |
lastmod(item) |
datetime | date | None |
Last modification time |