2

I'm trying to follow the first answer here: Google sitemap files for Rails projects

In my routes I have the following:

  match '/sitemap.xml' => "sitemap#index"

In my views (app/views/sitemap/index.xml.erb) I have the following:

<% base_url = "http://#{request.host_with_port}" %>
<% urlset{:xmlns => "http://www.sitemaps.org/schemas/sitemap/0.9"} %>
<% @posts.each do |post| %>
  <url>
    <loc><%= "#{base_url}#{post.permalink}" %></loc>
    <lastmod><%= post.last_modified %></lastmod>
    <priority>0.5</priority>
<% end %>

In my controller I have the following:

class SitemapController < ApplicationController
  layout nil

  def index
    headers['Content-Type'] = 'application/xml'
    last_post = Post.last
    if stale?(:etag => last_post, :last_modified => last_post.updated_at.utc)
      respond_to do |format|
        format.xml { @posts = Post.sitemap } # sitemap is a named scope
      end
    end
  end
end

When I go to http://localhost:3000/sitemap.xml I get a pink/peach colored box that says the following:

This page contains the following errors:

error on line 1 at column 1: Extra content at the end of the document
Below is a rendering of the page up to the first error.

Any idea what this means or where I went wrong?

Added:

Here is the source from the page loading:

<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<parsererror style="display: block; white-space: pre; border: 2px solid #c77; padding: 0 1em 0 1em; margin: 1em; background-color: #fdd; color: black">
<h3>This page contains the following errors:</h3>
<div style="font-family:monospace;font-size:12px">error on line 1 at column 1: Extra content at the end of the document
</div>
<h3>Below is a rendering of the page up to the first error.</h3>
</parsererror></body></html>

As an additional experiment I added the following:

<?xml version="1.0" ?> 
<note>
<to>Tove</to> 
<from>Jani</from> 
<heading>Reminder</heading> 
<body>Don't forget me this weekend!</body> 
</note>

This creates the same error, but I've tested this and this is valid XML code.

Community
  • 1
  • 1
Noah Clark
  • 8,101
  • 14
  • 74
  • 116
  • you need to look at the page source in your browser! – Tilo Nov 16 '11 at 00:22
  • @Tilo I've added the page source. Unless, I'm missing something there isn't anything useful there. – Noah Clark Nov 16 '11 at 00:27
  • http://www.w3schools.com/xml/note.xml ?? that doesn't seem to be _your_ XML – Tilo Nov 16 '11 at 01:18
  • @Tilo That isn't my XML, but if that fails it proves it isn't something to do with the index.xml.erb. It fails so we've eliminated the view as the issue. The only other thing it can be is the controller, the route, or the webpage rendering it. – Noah Clark Nov 16 '11 at 01:21
  • @Tilo I've already put what the browser outputs and what I have in my views above. Is there something else you're asking for? – Noah Clark Nov 16 '11 at 03:24
  • 1
    If you are using rails 3.1 and Builder for generating xml file there is some issue with builder you just follow this post and you will get an idea. http://stackoverflow.com/questions/5954198/is-rails-3-1-edge-breaking-xmlmarkupbuilder. You also please check your gem file and if it contains hpricot, sometimes it also cause problem because hpricot breaks to_xml in rails 3.1 – Jay Nov 16 '11 at 04:39

1 Answers1

3

Here is what I had to do to get it to work:

First in my routes I put the following:

match "/sitemap.xml", :to => "sitemap#index", :defaults => {:format => :xml}

Then I created a Sitemap controller with an index action:

class SitemapController < ApplicationController
  layout nil

  def index
    @posts = Post.all
    @base_url = "http://#{request.host_with_port}"
    headers['Content-Type'] = 'application/xml'
    def index
      respond_to do |format|
        format.html
        format.xml
      end
    end
  end
end

And finally, I created index.xml.erb that looks like this:

<?xml version="1.0" ?> 
<% @posts.each do |post| %>
  <url>
    <loc><%= "#{@base_url}/#{post.slug_url}" %></loc>
    <lastmod><%= post.updated_at %></lastmod>
    <priority>0.5</priority>
  </url>
<% end %>
Noah Clark
  • 8,101
  • 14
  • 74
  • 116
  • @ylluminate I've updated it to make the last mod work. If you want a dynamic priority you'll have to create a priority field in your db. You can of course set this as a default and then change it only on the posts you want it changed on. A less flexible, but easier way is to hard code your pages at a value of 1 for your home page and .75 for your other pages (or however you see fit) and then leave your posts at .5. – Noah Clark Dec 14 '11 at 15:19