Updated on November 4, 2019
I wrote previously about how and why I decided to create my own blog on Toofr. Here I'll describe the short and sweet process to add drafts and an RSS feed, two more critical components of a well-oiled blog machine.
Let's start with the drafts feature. Like most a lot of new features, it starts with a database migration.
rails g migration AddFieldsToArticles slug:string published:boolean
This adds a boolean field to the Articles table we created in the last post. I then added it to my form.
#views/articles/_form.html.erb
#other form fields and whatnot
<div class="form-inputs">
<%= f.input :title %>
<%= f.input :subtitle %>
<%= f.input :meta %>
<%= f.input :published %> #I added this
<%= f.input :category, collection: Article::CATEGORIES, label: 'Category' %>
<%= f.input :text %>
<%= f.input :image, as: :file %>
</div>
#submit, etc
Now the form looks like this!
Then I just needed to weak the controller so it only shows published posts, and added another view to show my drafts. The controller actions look like this:
def index
@articles = Article.published.order(id: :desc)
end
def drafts
@articles = Article.drafts.order(id: :desc)
render template: 'articles/index'
end
And those published and draft scopes sit on the model like so:
#models/article.rb
scope :published, -> { where(published: true) }
scope :drafts, -> { where(published: false) }
And voila! In about 30 minutes work (because I'm still a noob) I built a drafts feature. And now for the RSS feed...
Giving credit where it's due, I relied a lot on this blog post from Codingfish to build my feed.
Starting with the controller, I added the feed action. It responds to the RSS format and renders a blank page (that's the :layout => false) so the feed isn't burdened with my header and footer.
#controllers/articles.rb
def feed
@articles = Article.published
respond_to do |format|
format.rss { render :layout => false }
end
end
The most tedious part would have been to build the feed from scratch. Fortunately, again, Codingfish had a template which I modified for my own blog. I'm posting it here:
#views/articles/feed.rss.builder
#encoding: UTF-8
xml.instruct! :xml, :version => "1.0"
xml.rss :version => "2.0" do
xml.channel do
xml.title "Toofr"
xml.author "Ryan Buckley"
xml.description "Sales hacking, entrepreneurship, email marketing"
xml.link "https://www.toofr.com"
xml.language "en"
for article in @articles
xml.item do
if article.title
xml.title article.title
else
xml.title ""
end
xml.author "Ryan Buckley"
xml.pubDate article.created_at.to_s(:rfc822)
xml.link "https://www.toofr.com/articles/#{article.slug.to_s}"
xml.guid article.slug
xml.description "<p>#{article.subtitle}</p>"
end
end
end
end
This is the view file that the controller will call to build the actual RSS feed. Of course, we need a route:
#config/routes.rb
resources :articles do
collection do
get :drafts, to: 'articles#drafts'
get :feed, to: 'articles#feed'
end
end
And lastly, on Codingfish's recommendation, I added this link
tag in the header. I think this is so bots (like the MeetEdgar one I use to automatically post my Toofr articles to social media) can find my feed.
#layouts/application.html.erb
<link rel="alternate" type="application/rss+xml" title="Toofr Blog RSS Feed" href="https://www.toofr.com/articles/feed?format=rss">
And with this, I'm done for a while. In part 3 I'll probably add a search field and some pagination, but I won't bother with that until I've published a few more posts and the page load time suffers. For now it's totally fine and I'm happy with the SEO value and traffic this blog is already starting to create.
Okay, I'm clicking that new publish checkbox now!