{"id":2215,"date":"2016-07-03T15:28:27","date_gmt":"2016-07-03T21:28:27","guid":{"rendered":"http:\/\/www.mooreds.com\/wordpress\/?p=2215"},"modified":"2016-08-05T16:53:51","modified_gmt":"2016-08-05T22:53:51","slug":"adding-a-sitemap-to-sharetribe","status":"publish","type":"post","link":"https:\/\/www.mooreds.com\/wordpress\/archives\/2215","title":{"rendered":"Adding a sitemap to sharetribe"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-2217 alignright\" src=\"http:\/\/www.mooreds.com\/wordpress\/wp-content\/uploads\/2016\/07\/map-1434486_640.jpg\" alt=\"map-1434486_640\" width=\"640\" height=\"404\" srcset=\"http:\/\/edit.mooreds.com\/wordpress\/wp-content\/uploads\/2016\/07\/map-1434486_640.jpg 640w, http:\/\/edit.mooreds.com\/wordpress\/wp-content\/uploads\/2016\/07\/map-1434486_640-300x189.jpg 300w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/>I have using the excellent <a href=\"https:\/\/github.com\/sharetribe\/sharetribe\">Sharetribe<\/a> framework to build a marketplace for food businesses and commercial kitchens for my new startup, <a href=\"http:\/\/www.thefoodcorridor.com\/\">The Food Corridor<\/a>.\u00a0 However, it didn&#8217;t have support for generating a <code>sitemap.xml<\/code> file for all the listings available.<\/p>\n<p>How is someone going to find the right kitchen space when they use google, but we don&#8217;t have a sitemap so google can keep apprised of all the options?<\/p>\n<p>This wouldn&#8217;t do.\u00a0 So, I added the ability to generate a sitemap for all the listings in the marketplace.<\/p>\n<p>First off, install the gem&#8211;I used <a href=\"https:\/\/github.com\/kjvarga\/sitemap_generator\/\">sitemap_generator<\/a> as it seemed to do what I needed&#8211;allow me to call out certain routes and add them to my sitemap.\u00a0 Then you need to create a configuration file, at <code>config\/sitemap.rb<\/code>.\u00a0 Mine looks like:<\/p>\n<pre><code>\r\nSitemapGenerator::Sitemap.default_host = \"https:\/\/\"+APP_CONFIG.domain\r\n\r\nSitemapGenerator::Sitemap.create do\r\n  Listing.where(deleted: false, open: true).find_each do |listing|\r\n    add listing_path(listing), :lastmod =&gt; listing.updated_at\r\n  end\r\nend\r\n<\/code><\/pre>\n<p>&nbsp;<\/p>\n<p>Then I just ran <code>bundle exec rake sitemap:refresh:no_ping<\/code> and a <code>sitemap.xml.gz<\/code> was generated in my <code>public<\/code> directory.<\/p>\n<p>If you are running on AWS or someplace else with a persistent filesystem, you can skip to the text starting with &#8220;Then, I scheduled&#8221;.<\/p>\n<p>If you are running on a PAAS like Heroku, where you don&#8217;t get a persistent filesystem, you&#8217;ll want to push this generated file to a persistent place. I chose S3. Since sharetribe already has paperclip as a dependency, I used the instructions <a href=\"https:\/\/github.com\/kjvarga\/sitemap_generator\/wiki\/Uploading-the-sitemap-to-S3-with-paperclip,-aws-s3-and-aws-sdk\">here<\/a> and <a href=\"https:\/\/status203.me\/2015\/04\/11\/rails-sitemap-heroku-aws\/\">here<\/a>, with a few modifications for sharetribe.  <\/p>\n<p>My rake task to upload the sitemap file was:<\/p>\n<pre><code>\r\nrequire 'aws'\r\nnamespace :sitemap do\r\n  desc 'Upload the sitemap files to S3'\r\n  task upload_to_s3: :environment do\r\n    s3 = AWS::S3.new(\r\n      access_key_id: ENV['aws_access_key_id'],\r\n      secret_access_key: ENV['aws_secret_access_key']\r\n    )\r\n    bucket = s3.buckets[ENV['s3_bucket_name']]\r\n      file = File.join(Rails.root, \"public\", \"sitemap.xml.gz\")\r\n      path = \"sitemap\/sitemap.xml.gz\"\r\n\r\n      begin\r\n        object = bucket.objects[path]\r\n        object.write(file: file)\r\n        object.acl=(:public_read)\r\n      rescue Exception =&gt; e\r\n        raise e\r\n      end\r\n  end\r\nend\r\n\r\n<\/code>\r\n<\/pre>\n<p>I then run the <code>sitemap:refresh:no_ping<\/code> and <code>upload_to_s3<\/code> tasks in the same heroku scheduled task: <code>rake sitemap:refresh:no_ping sitemap:upload_to_s3<\/code>. If you don&#8217;t do that (and instead do separate dynos) then the upload task won&#8217;t have access to the file (because it will have been generated on the first dyno&#8217;s filesystem).<\/p>\n<p>You also need to make sure to add a sitemap controller to redirect from <code>yourdomain.com\/sitemap.xml.gz<\/code> to the S3 bucket (again, as outlined in the articles linked above.<\/p>\n<p>Then, I scheduled a daily refresh of the <code>sitemap.xml<\/code> file and submitted the file to relevant search engines.<\/p>\n<p>Things I didn&#8217;t do:<\/p>\n<ul>\n<li>handle more than 50k urls<\/li>\n<li>support multiple communities (not really needed for me, but I bet if the folks behind <a href=\"https:\/\/sharetribe.com\/\">sharetribe.com<\/a> wanted to use this, they&#8217;d want such support).<\/li>\n<li>add the sitemap.xml file to my robots.txt file, as <a href=\"https:\/\/www.woorank.com\/en\/blog\/how-to-locate-a-sitemap-in-a-robots-txt-file\">outlined here<\/a>.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>I have using the excellent Sharetribe framework to build a marketplace for food businesses and commercial kitchens for my new startup, The Food Corridor.\u00a0 However, it didn&#8217;t have support for [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[77,78,33],"tags":[],"class_list":["post-2215","post","type-post","status-publish","format-standard","hentry","category-rails","category-sharetribe","category-useful-tools"],"_links":{"self":[{"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/posts\/2215","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/comments?post=2215"}],"version-history":[{"count":6,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/posts\/2215\/revisions"}],"predecessor-version":[{"id":2222,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/posts\/2215\/revisions\/2222"}],"wp:attachment":[{"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/media?parent=2215"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/categories?post=2215"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/tags?post=2215"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}