Preface
In today’s web world, is SEO (search engine optimization) indispensable after creating a website? With that in mind, a newbie Ruby on Rails developer like me will have to solve that requirement in the near future. Through the protocol, sitemaps are encoded as UTF-8 and saved as XML files. It provides the clearest map for bots, a crawler to provide search services like Google , duckduckgo . This is extremely simple but becomes complicated if the object to create sitemaps is a large and complex website. Complicated, should let the computer do it, but create sitemaps with rice how: v Let’s get started
Solution (gem sitemap_generator)
There are many solutions to create sitemaps for Rails, but I prefer the gem sitemap_generator
. Let’s see if it has any interesting functions.
- It works independently. So we can use it without Rails
- Extremely flexible
- Gem has its own rules that are not affected by other app’s configurations
- It allows us to upload a sitemaps file from a third party (the file was created by another tool).
- It will automatically pings when the sitemap is created
- Support multi-sitemap with many media formats like video, images, news, etc
In this article I will use Rails to create web apps with a few simple features to make sitemaps.
Create project
Open terminal and type command
1 2 | $ rails new Sitemapper -T |
The command must be very familiar every time you start a new project, I add -T
to remove the test files. This gem is compatible with all versions of Rails, so you can use any version. Rails 5, or Rails 6 (newest) also oke. After the command has finished running, go to the project folder cd Sitemapper
then run rails s
and open the browser to the path localhost:3000
if it appears on the screen Yay! You’re on Rails! is okay then.
Now we need some routes, models, controllers, migrations for the project. The project will be a blog with categories , each category has many posts with a simple attribute of title
and content
.
1 2 3 4 | $ rails g model Category title:string $ rails g model Post category:belongs_to title:string body:text $ rails db:migrate |
We add the link to link the model if not already
1 2 3 4 5 | <span class="token keyword">class</span> <span class="token class-name">Category</span> <span class="token operator"><</span> <span class="token constant">ApplicationRecord</span> has_many <span class="token symbol">:posts</span> <span class="token keyword">end</span> |
1 2 3 4 | <span class="token keyword">class</span> <span class="token class-name">Post</span> <span class="token operator"><</span> <span class="token constant">ApplicationRecord</span> belongs_to <span class="token symbol">:category</span> <span class="token keyword">end</span> |
Now the indispensable part is Routes
1 2 3 4 5 6 | <span class="token constant">Rails</span> <span class="token punctuation">.</span> application <span class="token punctuation">.</span> routes <span class="token punctuation">.</span> draw <span class="token keyword">do</span> resources <span class="token symbol">:categories</span> <span class="token keyword">do</span> resources <span class="token symbol">:posts</span> <span class="token keyword">end</span> <span class="token keyword">end</span> |
And don’t forget to add the default link.
1 2 | root to <span class="token punctuation">:</span> <span class="token string">'pages#index'</span> |
Create Controller corresponding to the model
1 2 3 4 | $ rails g controller categories $ rails g controller posts $ rails g controller pages |
Next to create some sample data we use gem fake
1 2 3 4 5 6 7 | <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> group <span class="token symbol">:development</span> <span class="token punctuation">,</span> <span class="token symbol">:test</span> <span class="token keyword">do</span> gem <span class="token string">"byebug"</span> <span class="token punctuation">,</span> platforms <span class="token punctuation">:</span> <span class="token punctuation">[</span> <span class="token symbol">:mri</span> <span class="token punctuation">,</span> <span class="token symbol">:mingw</span> <span class="token punctuation">,</span> <span class="token symbol">:x64_mingw</span> <span class="token punctuation">]</span> gem <span class="token string">"faker"</span> <span class="token keyword">end</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> |
Then remember to run bundle install
Change the seed file again to be oke.
1 2 3 4 5 6 7 8 | <span class="token number">5.</span> times <span class="token keyword">do</span> category <span class="token operator">=</span> <span class="token constant">Category</span> <span class="token punctuation">.</span> <span class="token function">create</span> <span class="token punctuation">(</span> <span class="token punctuation">{</span> title <span class="token punctuation">:</span> <span class="token constant">Faker</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token constant">Book</span> <span class="token punctuation">.</span> title <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token number">5.</span> times <span class="token keyword">do</span> category <span class="token punctuation">.</span> posts <span class="token punctuation">.</span> <span class="token function">create</span> <span class="token punctuation">(</span> <span class="token punctuation">{</span> title <span class="token punctuation">:</span> <span class="token constant">Faker</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token constant">Book</span> <span class="token punctuation">.</span> title <span class="token punctuation">,</span> body <span class="token punctuation">:</span> <span class="token constant">Faker</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token constant">Lorem</span> <span class="token punctuation">.</span> sentence <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token keyword">end</span> <span class="token keyword">end</span> |
Number “5” you can customize if you want more data offline. Now run the seed data command
1 2 | rails db:seed |
gem “sitemap_generator”
Add gem to Gemfile
and run bundle install command
1 2 3 4 | ... gem "sitemap_generator" ... |
1 2 | $ bundle install |
Using rake to install sitemaps, run:
1 2 | $ rake sitemap:install |
The above command will create a configuration file configs/sitemap.rb
. Open the file and you can see the first line (excluding comments).
1 2 | <span class="token constant">SitemapGenerator</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token constant">Sitemap</span> <span class="token punctuation">.</span> default_host <span class="token operator">=</span> <span class="token string">"http://www.example.com"</span> |
That is the domain config line of the website. We can change it according to our domain.
Or we can configure a multi sitemap if needed such as:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <span class="token comment"># config/google_sitemap.rb</span> <span class="token constant">SitemapGenerator</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token constant">Sitemap</span> <span class="token punctuation">.</span> default_host <span class="token operator">=</span> <span class="token string">"https://google.mysite.com"</span> <span class="token constant">SitemapGenerator</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token constant">Sitemap</span> <span class="token punctuation">.</span> sitemaps_path <span class="token operator">=</span> <span class="token string">"sitemaps/google"</span> <span class="token constant">SitemapGenerator</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token constant">Sitemap</span> <span class="token punctuation">.</span> create <span class="token keyword">do</span> add <span class="token string">'/home'</span> <span class="token keyword">end</span> <span class="token comment"># config/apple_sitemap.rb</span> <span class="token constant">SitemapGenerator</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token constant">Sitemap</span> <span class="token punctuation">.</span> default_host <span class="token operator">=</span> <span class="token string">"https://apple.mysite.com"</span> <span class="token constant">SitemapGenerator</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token constant">Sitemap</span> <span class="token punctuation">.</span> sitemaps_path <span class="token operator">=</span> <span class="token string">"sitemaps/apple"</span> <span class="token constant">SitemapGenerator</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token constant">Sitemap</span> <span class="token punctuation">.</span> create <span class="token keyword">do</span> add <span class="token string">'/home'</span> <span class="token keyword">end</span> <span class="token comment"># config/bing_sitemap.rb</span> <span class="token constant">SitemapGenerator</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token constant">Sitemap</span> <span class="token punctuation">.</span> default_host <span class="token operator">=</span> <span class="token string">"https://bing.mysite.com"</span> <span class="token constant">SitemapGenerator</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token constant">Sitemap</span> <span class="token punctuation">.</span> sitemaps_path <span class="token operator">=</span> <span class="token string">"sitemaps/bing"</span> <span class="token constant">SitemapGenerator</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token constant">Sitemap</span> <span class="token punctuation">.</span> create <span class="token keyword">do</span> add <span class="token string">'/home'</span> <span class="token keyword">end</span> |
I will correct it as:
1 2 | <span class="token constant">SitemapGenerator</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token constant">Sitemap</span> <span class="token punctuation">.</span> default_host <span class="token operator">=</span> <span class="token string">"http://test-sitemap.sun-asterisk.com"</span> |
To the main part that is SitemapGenerator::Sitemap.create
we add the default page
1 2 3 4 | <span class="token constant">SitemapGenerator</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token constant">Sitemap</span> <span class="token punctuation">.</span> create <span class="token keyword">do</span> add root_path <span class="token keyword">end</span> |
add
can take a bunch of arguments of arguments we add code to generate for the Post , Category and have the following complete file:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <span class="token constant">SitemapGenerator</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token constant">Sitemap</span> <span class="token punctuation">.</span> default_host <span class="token operator">=</span> <span class="token string">"http://test-sitemap.sun-asterisk.com"</span> <span class="token constant">SitemapGenerator</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token constant">Sitemap</span> <span class="token punctuation">.</span> create <span class="token keyword">do</span> add root_path <span class="token constant">Category</span> <span class="token punctuation">.</span> find_each <span class="token keyword">do</span> <span class="token operator">|</span> category <span class="token operator">|</span> add <span class="token function">category_posts_path</span> <span class="token punctuation">(</span> category <span class="token punctuation">)</span> <span class="token punctuation">,</span> <span class="token symbol">:changefreq</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token string">'weekly'</span> <span class="token punctuation">,</span> <span class="token symbol">:lastmod</span> <span class="token operator">=</span> <span class="token operator">></span> category <span class="token punctuation">.</span> updated_at category <span class="token punctuation">.</span> posts <span class="token punctuation">.</span> <span class="token keyword">each</span> <span class="token keyword">do</span> <span class="token operator">|</span> post <span class="token operator">|</span> add <span class="token function">category_post_path</span> <span class="token punctuation">(</span> category <span class="token punctuation">,</span> post <span class="token punctuation">)</span> <span class="token punctuation">,</span> <span class="token symbol">:changefreq</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token string">'yearly'</span> <span class="token punctuation">,</span> <span class="token symbol">:lastmod</span> <span class="token operator">=</span> <span class="token operator">></span> post <span class="token punctuation">.</span> updated_at <span class="token keyword">end</span> <span class="token keyword">end</span> <span class="token keyword">end</span> |
changefreq
is the time interval each time that data changes. The default will be Time.zone.now
Done, now run the following command to scan and create a sitemap file automatically.
1 2 | $ rails sitemap:refresh |
This is my result
If you go to public
folder, you will find sitemap.xml.gz , extract the file and we will sitemap.xml. Open it with a browser to make it easier to see