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

鳥小屋.txt

ゲーム作ったり、Web的なことしたり、ぐだぐだしたりしますねヽ(・x・)ノ

Sinatraで簡易CMS(笑)を作る(1)

web Ruby Sinatra

(※コードの一部追記しました:8/9 13:48)

あまりに更新しなさすぎて逆に更新しづらいRuたんです(

僕のサイト(http://www.hazimu.com/)では昔自分で作った簡易CMS(爆笑)を使ってます.
さすがに(爆笑)なだけあって,不具合がところどころありまして,
更新するときは不具合がおきないように気をつけて作業するという謎システムです;

そんなわけで,ちょっとサーバ移転を考えるついでに
CMSを別のものにしようと思ったのですが,
世の中のCMSは僕みたいな超弱小サイトで使うには規模が大きすぎたり,
設定が面倒だったりとちょっと困り気味.

どうせなら練習がてらに僕好みの簡易CMS(笑)を作ってみようというお話です.
(爆笑)じゃなくて(笑)くらいまで進化させたい!

予定

  • http://ドメイン名/〜 の〜部分を調べて,データベースからページ情報を読み込んで表示
  • ページの本文はWiki記法っぽく書きたい
  • ページごとにテンプレート切り替えとか?
  • 画像のアップロードくらいできたらいいな
  • ブログ的な機能ははいらないかも
    • 更新しないので
    • でも気が向いたら作ってもいい

こんな感じで?

今回はフレームワークとしてSinatraを使います.
Railsよりシンプルらしいので,今回のテーマに合いそうです.
テンプレートエンジンはHaml.理由は僕が使ってみたいからw

あ,僕のテスト環境はWindows7君です.
そのうちSLでテストしたいけどまだ準備できてないの.

必要なものをgemで入れる

>gem install sinatra
>gem install haml
>gem install sqlite3-ruby
>gem install sequel

多分これくらいでいいんじゃない? これで必要なものは勝手に入るでしょう(

フォルダとファイルを作る

./public          # 静的ファイルを置くpublic_html的なところ.未使用.
./db              # データベース(SQLite)ファイル置き場
./views           # テンプレート置き場
config.ru         # なんかこの手のやつではお約束らしい.起動用のファイル.
loader.rb         # ライブラリとか読み込むのはここで全部
main.rb           # 本体.単一ファイルに全部書くとか引くわー(

なるべく小さくまとめてみた.
loaderを分けたのは,前に作った時にこうしたほうが便利だったので.
main.rbの分割はそのうち考える(絶対考えないパターン)

loaderを作る

# -*- coding: utf-8 -*-
require 'sinatra/base'
require 'haml'
require 'sequel'

これだけ.必要なライブラリが増えたらここに追加する.

main.rbを作る

# -*- coding: utf-8 -*-

# データベース生成
Sequel::Model.plugin(:schema)          # これがないとエラーするっぽい?
Sequel.connect('sqlite://db/test.db')  # db/test.dbを読み込む
class DataPage < Sequel::Model
  unless table_exists?
    set_schema do
      primary_key :id
      string      :name
      string      :title
      string      :text
    end
    create_table
  end
end

# アプリケーション本体
class MyApp < Sinatra::Base
  set :haml => {
    :format => :xhtml,       # XHTMLで出力
    :escape_html => true,    # 標準でエスケープ処理
    :attr_wrapper => '"',    # 属性の囲みを"に変更
  }
  # ● アクセス ----------------------------------------------------------------
  get '/*' do
    # http://ドメイン/(ここの部分)を取得する
    load_page("/#{params[:splat].to_a.first}")
  end

  # ● ページ読込 --------------------------------------------------------------
  def load_page(url)
    # paramの末尾が/だったらindex.htmlを付加
    url << 'index.html'  if url =~ /\/$/
  
    # (↓追記)
    # /以降に拡張子が存在しなかったら末尾に/を付けてリダイレクト
    redirect url << '/', 301  unless url =~ /\/.+\..+$/
    # (↑追記ここまで)

    # データベースにページがあるか調べる
    page_data = DataPage.filter(:name => url).all.first
    
    # ページが無かったので404に
    unless page_data
      status 404
      page_data = {
        :title => '404 not found',
        :text => "not found : #{url}",
      }
    end
    
    # ページ内容を出力
    haml :page, :locals => { :page_data => page_data }
  end
end

エスケープ処理は忘れそうなのでデフォで行うようにする.
必要なときだけエスケープ回避のほうが楽だし.

テンプレートを準備

-# -*- coding: utf-8 -*-
!!! XML
!!! Strict
%html
  %head
    %title=page_data[:title]
  %body
    #header
      %h1=page_data[:title]
    #contents=page_data[:text]

DOMツリー作るみたいな感じで直接書くよりいいなぁ.もうちょっと勉強必要そうだけど.

config.ruを作る

# -*- coding: utf-8 -*-
# ライブラリの読み込み
load './loader.rb'

# 本体の読み込み
load './main.rb'

# 起動だー!
MyApp.run! :host => 'localhost', :port => 4567

config.ruのruの辺りがドキっとすRu(わりとどうでもいい)
起動オプションいろいろあるみたいだけど,とりあえずこれで

起動する

ruby config.ru

これでhttp://localhost:4567/にアクセスすればOK
http://localhost:4567/test/にアクセスすれば,
データベースの/test/index.htmlを読み込んでくれるのです! やったね!

まぁデータベースに何も入ってないので全部404なんですけどね(
次回はデータベースの登録をがんばろー,2年後くらいに!