Flask Snippets

Generating a sitemap.xml

By BlazingQuasar filed in URLs

This uses flasks route map to generate a sitemap.xml of all static pages. There is probably a elegant way of dealing with routes with multiple variables but I just defined a set of urls for each model object.

I closely followed this guide.

# flask-sqlalchemy model for User
class User(db.Model, UserMixin):

    __tablename__ = 'users'

    id = Column(db.Integer, primary_key=True)
    name = Column(db.String(32), nullable=False, unique=True)
    email = Column(db.String, nullable=False, unique=True)
    activation_key = Column(db.String)
    created_time = Column(db.DateTime, default=get_current_time)
    modified_time = Column(db.TIMESTAMP, onupdate=get_current_time(), default=get_current_time())


# a route for generating sitemap.xml
@frontend.route('/sitemap.xml', methods=['GET'])
def sitemap():
      """Generate sitemap.xml. Makes a list of urls and date modified."""
      pages=[]
      ten_days_ago=datetime.now() - timedelta(days=10).date().isoformat()
      # static pages
      for rule in current_app.url_map.iter_rules():
          if "GET" in rule.methods and len(rule.arguments)==0:
              pages.append(
                           [rule.rule,ten_days_ago]
                           )
      
      # user model pages
      users=User.query.order_by(User.modified_time).all()
      for user in users:
          url=url_for('user.pub',name=user.name)
          modified_time=user.modified_time.date().isoformat()
          pages.append([url,modified_time]) 

      sitemap_xml = render_template('frontend/sitemap_template.xml', pages=pages)
      response= make_response(sitemap_xml)
      response.headers["Content-Type"] = "application/xml"    
    
      return response

The jinja2 template for the sitemap.xml

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
    {% for page in pages %}
    <url>
        <loc>{{page[0]|safe}}</loc>
        <lastmod>{{page[1]}}</lastmod>
    </url>
    {% endfor %}
</urlset>

This snippet by BlazingQuasar can be used freely for anything you like. Consider it public domain.