Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add image field to XML sitemap in Django

Google recognizes an <image> tag for XML sitemaps (http://support.google.com/webmasters/bin/answer.py?hl=en&answer=178636), and I would like to include an image attribute into my sitemaps.

So, something like this is needed to get the cover_image and then loaded into the xml file:

for article in articles:
        print article.cover_image

I'd also need article.title loaded too for the <image:title> tag.

I've Googled and searched Stack Overflow for an example, but I surprisingly couldn't find any, so help appreciated.

My files so far:

## sitemaps.py ##
from django.contrib.sitemaps import Sitemap
from myproject.article.models import Article

class ArticleSitemap(Sitemap):
    priority = 1.0

    def items(self):
        return  Article.objects.order_by('-id').order_by('-pub_date')

    def lastmod(self, obj):
        return obj.pub_date

## urls.py ##
from myproject.sitemaps import ArticleSitemap

sitemaps = {
    "article": ArticleSitemap
}
urlpatterns += patterns ('',
    (r'^sitemap.xml$', 'django.contrib.sitemaps.views.sitemap', {'sitemaps': sitemaps})
like image 635
AAA Avatar asked Apr 28 '12 13:04

AAA


People also ask

Can you list images in an XML sitemap?

Google extends the XML sitemap schema to include tags for images and videos. These media tags can be added to any URL tag on an XML sitemap. Google extends the standard XML schema for sitemaps, making it possible to submit not just a page URL, but also important images and videos directly to the search engine.

How do you add an image to a sitemap?

Create a separate file for the pictures that organizes the information about them, thus, they are more likely to get indexed. Or edit the existing sitemap. xml file of the website by adding the appropriate tags to the root of the website.

Should I include images in XML sitemap?

Add images to an existing sitemap, or create a separate sitemap just for your images. Adding images to a sitemap helps Google discover images that we might not otherwise find (such as images your site reaches with JavaScript code).


1 Answers

It can be done by

  1. Redefining get_urls method in your inherited class (add image information)
  2. Change default template to the one which required to render image info

here is the code:

  1. Add these methods in your class - these methods are almost same as defined in django's sitemap framework, but differ by the way it prepares data that need to be render in the template

    class MySItemapClass(Sitemap):
      def item():
         .........        
    
      def __get(self, name, obj, default=None):
        try:
          attr = getattr(self, name)
        except AttributeError:
          return default
        if callable(attr):
          return attr(obj)
        return attr
    
      def get_urls(self, page=1, site=None, protocol=None):
        # Determine protocol
        if self.protocol is not None:
          protocol = self.protocol
        if protocol is None:
          protocol = 'http'
    
        # Determine domain
        if site is None:
          if Site._meta.installed:
              try:
                  site = Site.objects.get_current()
              except Site.DoesNotExist:
                  pass
          if site is None:
              raise ImproperlyConfigured("To use sitemaps, either enable the sites framework or pass a Site/RequestSite object in your view.")
        domain = site.domain
    
        urls = []
        for item in self.paginator.page(page).object_list:
          loc = "%s://%s%s" % (protocol, domain, self.__get('location', item))
          priority = self.__get('priority', item, None)
          url_info = {
              'item':       item,
              'location':   loc,
              'lastmod':    self.__get('lastmod', item, None),
              'changefreq': self.__get('changefreq', item, None),
              'priority':   str(priority is not None and priority or ''),
              'images'   :   get_image(protocol, domain,item), # changed here
          }
          urls.append(url_info)
        return urls
    

define get_image method as you please

  1. define your custom template. mine look like this - note change in defining namespaces("urlset")

    <?xml version="1.0" encoding="UTF-8"?>
    <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
      xmlns:image="http://www.google.com/schemas/sitemap-image/1.1">
    {% spaceless %}
    {% for url in urlset %}
      <url>
        <loc>{{ url.location }}</loc>
        {% if url.images %}
            {% for image in url.images %}
                <image:image>
                    <image:loc>{{image}}</image:loc>
                </image:image>
            {% endfor %}
        {% endif %}
        {% if url.lastmod %}<lastmod>{{ url.lastmod|date:"Y-m-d" }}</lastmod>{% endif %}
        {% if url.changefreq %}<changefreq>{{ url.changefreq }}</changefreq>{% endif %}
        {% if url.priority %}<priority>{{ url.priority }}</priority>{% endif %}
       </url>
    {% endfor %}
    {% endspaceless %}
    </urlset>
    
  2. Override to use new template rather than the default template

    url(r'^sitemap-(?P<section>.+)\.xml$', 'django.contrib.sitemaps.views.sitemap', {'sitemaps': sitemaps,'template_name': 'seo/sitemap.xml'}),
    
like image 170
ashish Avatar answered Dec 06 '22 05:12

ashish