.. _topics/cms/sitemap:

=======
Sitemap
=======

The CMS system provides an automatic way of generating a sitemap.xml. In order
to enable the generation of the sitemap, simply hook up the following URL
patterns in your ``urls.py``::

    url(r'^sitemap\.xml$', sitemaps_views.sitemap, {'sitemaps': cms.sitemaps}),

Usually this goes together with a robots.txt file::

    url(r'^robots\.txt$', cubane_views.robots_txt),

Putting it all together, a typical ``urls.py`` file may look like this:

.. code-block:: python

    from django.conf.urls import url, include
    from django.contrib.sitemaps import views as sitemaps_views
    from cubane.backend.views import Backend
    from cubane.cms.views import get_cms
    from cubane.urls import *
    from cubane import views as cubane_views

    backend = Backend()
    cms = get_cms()

    setup_default_urls(__name__)

    urlpatterns += [
        # admin
        url(r'^admin/', include(backend.urls)),

        # sitemap and robots
        url(r'^sitemap\.xml$', sitemaps_views.sitemap, {'sitemaps': cms.sitemaps}),
        url(r'^robots\.txt$', cubane_views.robots_txt),

        # cms
        url(r'^', include(cms.urls)),
    ]

The CMS system automatically generates entries for all pages and posts.
However, you can extend the sitemap in order to incorporate your own additional
pages. In fact, other Cubane apps like the shop system for example are
extending the sitemap to include product pages for example.




.. _topics/cms/sitemap/extension:

Extending Sitemap
=================

Sitemaps are constructed by the :meth:`cubane.cms.vies.CMS.get_sitemaps` method
of the :class:`cubane.cms.views.CMS` class. This method is ultimately called
when *hooking up* sitemaps in your ``urls.py`` via the ``sitemaps`` property of
the ``cms`` object (see example above).

In addition, there is also the :meth:`cubane.cms.vies.CMS.on_custom_sitemap`
method of the :class:`cubane.cms.views.CMS` class which can be overridden in
order to add custom sitemap entries more easily.

Your CMS class derived from :class:`cubane.cms.views.CMS` can override one of
those methods in order to customise sitemaps:

.. code-block:: python

    from cubane.cms.views import CMS

    class MyCMS(CMS):
        def on_custom_sitemap(self, sitemap):
            super(MyCMS, self).on_custom_sitemap(sitemap)
            sitemap.add_url('/my-custom-url/')

As demonstrated in this example, the function
:meth:`cubane.cms.views.CMS.on_custom_sitemap` is passed an instance of
:class:`cubane.cms.views.CustomSitemap` which can be used to add additional
sitemap entries by calling :meth:`cubane.cms.views.CustomSitemap.add` or
:meth:`cubane.cms.views.CustomSitemap.add_url`.

Another strategy is to create your own sitemap generators by overriding the
method :meth:`cubane.cms.vies.CMS.get_sitemaps`. This method returns a
dictionary of sitemaps generators based on `Django's sitemap Framework
<https://docs.djangoproject.com/en/1.11/ref/contrib/sitemaps/>`_.




.. _topics/cms/sitemap/cache:

Cacheable Sitemap entries
=========================

Cubane provides a caching system by which full rendered pages are cached on the
disk and are then delivered by the web-server directly without invoking python,
Django or Cubane.

For this purpose, when generating additional entries for the sitemap, they can
be marked as cacheable or not.

By default, custom entries that are added to the sitemap are *not* cached. If
an entry should be cached then the ``cached`` argument of the
:meth:`cubane.cms.views.CustomSitemap.add` or
:meth:`cubane.cms.views.CustomSitemap.add_url` method needs to be set to
``True``.

For example:

.. code-block:: python

    from cubane.cms.views import CMS

    class MyCMS(CMS):
        def on_custom_sitemap(self, sitemap):
            super(MyCMS, self).on_custom_sitemap(sitemap)
            sitemap.add_url('/my-custom-url/', cached=True)

Then the cache system (if enabled) will generate a cached version of the
corresponding page with the URL ``/my-custom-url/``.




.. _topics/cms/sitemap/html_sitemap:

HTML Sitemap
============

The method :meth:`cubane.cms.views.CMS.get_sitemap_links` returns a list of all
sitemap entries sorted alphabetically for the purpose of rendering an HTML
sitemap on its basis.

Likewise, the method :meth:`cubane.cms.views.CMS.get_sitemap_links_az` can be
used to receive a list of sitemap entries that are organised within an A to Z
structure.

The following example would extend the template context for the page to which
the unique identifier ``sitemap`` has been assigned to.

.. code-block:: python

    from cubane.cms.views import CMS

    class MyCMS(CMS):
        def on_page_identifier_sitemap(self, request, context, template_context):
            template_context.update({
                'sitemap': self.get_sitemap_links()
            })
            return template_context

The method ``on_page_identifier_sitemap`` is called by the CMS system whenever
a page is rendered that has a unique identifier ``sitemap`` assigned, since the
name of the method ``on_page_identifier_...`` matches the identifier.

.. seealso::

    Please refer to section :ref:`topics/cms/system/identifier_hooks` for more
    information about using unique page identifiers.

Based on the additional template context variable ``sitemap``, the template may
render an HTML-based sitemap in the following way:

.. code-block:: html+django

    <!DOCTYPE html>
    <html>
        <body>
            {% if sitemap %}
                <ul>
                    {% for page in sitemap %}
                        <li><a href="{{ page.url }}">{{ page.title }}</a></li>
                    {% endfor %}
                </ul>
            {% endif %}
        </body>
    </html>