読者です 読者をやめる 読者になる 読者になる

vaguely

和歌山に戻りました。ふらふらと色々なものに手を出す毎日。

RSS生成とか

Ruby Sinatra

引き続きSinatraの話。

Blogといえば、RSS(またはAtom)配信は欲しいところ。早速調べてみました。

RSSを生成する

  • Controllerであるapp.rb(ファイル構成などはこの辺参照)で行います。
  • デフォルトで用意されているライブラリ(rss/maker)を使うため、Gemfileなどは特に変更なし。
  • 'localhost:9292/feed'にアクセスした時にRSSリーダーで取得できるようxmlを生成します。

app.rb

require 'rss/maker'
require 'sinatra'
require 'sinatra/base'
require 'sinatra/reloader'
require './models/dbAccessers'

class MainApp < Sinatra::Base
  get '/feed' do
    # RSSフィードの出力設定.
    newRss = RSS::Maker.make("2.0") do |newRss|
    newRss.channel.title = "Vaguely"
    newRss.channel.description = "なんとなくやってみたことを書き残します"
    newRss.channel.link = 'http://localhost:9292'
    newRss.channel.language = "ja"

    newRss.items.do_sort = true
    newRss.items.max_size = 10

    # DBからブログ記事の最新10件を取得して、RSSのアイテムとしてセットする.
    aryPosts = Post.all.order(post_id: 'desc').limit(10)
    aryPosts.each do |post|
      rssItem = newRss.items.new_item
      rssItem.title = post.post_title
      rssItem.link = 'http://localhost:9292/article/' + post.post_id.to_s
      rssItem.description = post.post
      rssItem.date = post.updated_at
    end
    # xml形式を指定して、文字列として返す.
    content_type "application/xml"
    newRss.to_s
  end
end
  • 最後の「content_type〜」はコメントアウトしても問題なく認識されていましたが(Firefoxで確認)、念のため。

RSS配信をブラウザに認識させる

上記の処理を加えただけだと、ブラウザではRSS配信が認識されず、ページ購読のボタンがEnableになりません。

RSS配信をブラウザに認識させるためには、HTML(Slim)のヘッダに以下のリンクを追加します。

layout.slim

DOCTYPE
  html
    head
      meta charset="utf-8"
      title Vaguely
      link href="/css/stylesheet.css" rel="stylesheet"
      link rel="alternate" type="application/rss+xml" title="Vaguely" href="/feed"
    body

Viewでの処理をControllerに移す

前回、DBから取得したデータをそのままblog.slimに渡して、そこでIDやブログタイトルに渡していました。

ただこれ、Viewは表示だけを行い処理はControllerで行う、というMVCのルールからはズレていたので、Controller側に処理を移してみました。

before

app.rb

get '/' do
  intPageOffsetNum = getPageOffset(params[:page])
  aryPosts = Post.all.order(post_id: 'desc').limit(POST_LIMIT_COUNT).offset(intPageOffsetNum)
  slim :blog
end

blog.slim

- @aryPosts.each do |post|
  - postid = post.post_id
  article
    - posturl = "/article/" + postid.to_s
    a href=posturl =post.post_title

after

app.rb

get '/' do
  intPageOffsetNum = getPageOffset(params[:page])
  aryPosts = Post.all.order(post_id: 'desc').limit(POST_LIMIT_COUNT).offset(intPageOffsetNum)

  @intCount = aryPosts.count - 1
  @aryPostUrl = []
  @aryPostTitle = []
  aryPosts.each do |post|
    @aryPostUrl << '/article/' + post.post_id.to_s
    @aryPostTitle << post.post_title
  end
  slim :blog
end

blog.slim

- for i in 0..@intCount
  article
    a href==@aryPostUrl[i] =@aryPostTitle[i]

上記の例だと表示する項目が少ないのですが、ブログ記事本文をある文字数から省略するなどの処理が入ってくるとより分かりやすくなりそうです。

文字数が一定以上なら省略する

あらかじめ文字数を設定しておき、チェック対象(今回はブログ記事本文)がそれ数以上かを確認して、trueなら文字数-1でカットして、最後に「…」をつける、という単純なものです。

strTarget = "あいうえおかきくけこ"
if strTarget.size >= 5
  strTarget = strTarget[0, 4]
  strTarget += "…"
end
puts strTarget # "あいうえ…"

この処理の欠点としては、半角全角関係なしに実行するため、半角のみの文字列と全角のみの文字列で処理後の表示量が変わってしまうことです。

決められた横幅をオーバーしたら自動で省略する処理はCSSで実現できたり、Javascriptなどを使って縦の幅に合わせて省略、ということもできるようなので、そちらも考えてみたいと思ってはいます。

ただ次はまず本文内で改行やリンク表示を可能にするところからかな。

参考