Last active
March 31, 2025 10:44
-
-
Save Julian-Nash/aa3041b47183176ca9ff81c8382b655a to your computer and use it in GitHub Desktop.
Flask dynamic sitemap generator
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@app.route("/sitemap") | |
@app.route("/sitemap/") | |
@app.route("/sitemap.xml") | |
def sitemap(): | |
""" | |
Route to dynamically generate a sitemap of your website/application. | |
lastmod and priority tags omitted on static pages. | |
lastmod included on dynamic content such as blog posts. | |
""" | |
from flask import make_response, request, render_template | |
import datetime | |
from urllib.parse import urlparse | |
host_components = urlparse(request.host_url) | |
host_base = host_components.scheme + "://" + host_components.netloc | |
# Static routes with static content | |
static_urls = list() | |
for rule in app.url_map.iter_rules(): | |
if not str(rule).startswith("/admin") and not str(rule).startswith("/user"): | |
if "GET" in rule.methods and len(rule.arguments) == 0: | |
url = { | |
"loc": f"{host_base}{str(rule)}" | |
} | |
static_urls.append(url) | |
# Dynamic routes with dynamic content | |
dynamic_urls = list() | |
blog_posts = Post.objects(published=True) | |
for post in blog_posts: | |
url = { | |
"loc": f"{host_base}/blog/{post.category.name}/{post.url}", | |
"lastmod": post.date_published.strftime("%Y-%m-%dT%H:%M:%SZ") | |
} | |
dynamic_urls.append(url) | |
xml_sitemap = render_template("public/sitemap.xml", static_urls=static_urls, dynamic_urls=dynamic_urls, host_base=host_base) | |
response = make_response(xml_sitemap) | |
response.headers["Content-Type"] = "application/xml" | |
return response |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<urlset | |
xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" | |
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 | |
http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"> | |
{% for url in static_urls %} | |
<url> | |
<loc>{{ url["loc"] }}</loc> | |
</url> | |
{% endfor %} | |
{% for url in dynamic_urls %} | |
<url> | |
<loc>{{ url["loc"] }}</loc> | |
<lastmod>{{ url["lastmod"] }}</lastmod> | |
</url> | |
{% endfor %} | |
</urlset> |
Thanks
thanks
thank you :)
great!
Appreciate it
really helpful, thanks
Thank you !!!
thanks !
thanks, this seems to be best solution so far.
I just made a slight change to hide private endpoints, 'startswith' can also take a tuple of values which makes adding multiple endpoints quite easy...
private_endpoints = ("/admin", "/user", "/foo", "/bar")
...
# Static routes with static content
static_urls = list()
for rule in app.url_map.iter_rules():
if not str(rule).startswith(private_endpoints):
if "GET" in rule.methods and len(rule.arguments) == 0:
url = {
"loc": f"{host_base}{str(rule)}"
}
static_urls.append(url)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
thank you!