ファイル名をコマンドラインから渡す
filename = ARGV[0] text = File.read(filename) puts text
filename = ARGV[0] text = File.readlines(filename) puts text
filename = ARGV[0] text = File.readlines(filename) text.each_with_index do |line, i| puts "#{i}: #{line}" end
Railsで作る最も簡単なブログシステム(5)
Railsで作る最も簡単なブログシステム(4) - dan5yaの日記の続きです。
今回はRailsとは直接関係のないお話です。日記本文をHikiDocの文法で記述できるようにして、本文の表現力を高めます。
HikiDocを使う
HikiDocはRubyで書かれたテキストをHTMLに変換するツールです。決められた記法に基づいて記述されたテキストからHTMLをジェネレートすることができます。
HikiDocの文法はHTMLよりずっとシンプルです。ブログの原稿の作成では、手で直接HTMLを書かず、このような変換ツールの文法で記述するのが一般的です。
hikidoc.rbをlibにコピーする
http://projects.netlab.jp/hikidoc/?FrontPage.jaからhikidoc.rbを入手して、プロジェクトのlibディレクトリにコピーします。libディレクトリにコピーしたRubyスクリプトはrequreで読み込むことができます。
EntryモデルにHTMLのジェネレート機能を追加する
Entryモデルを次のように修正します。
app/models/entry.rb
require 'hikidoc' class Entry < ActiveRecord::Base def to_html HikiDoc.to_html(body, :level => 3) end end
Entryモデルを定義しているEntryクラスにto_htmlメソッドを追加しています。to_htmlメソッドは、HikiDocライブラリを用いて記事の本文をHTMLに変換した文字列を返します。Entryモデルでは記事の本文がbodyフィールドに格納されているので、bodyというメソッドでDBに格納されているテキストを取得することができます。
ビューの修正
次にビューを修正します。これまではbodyの戻り値をそのまま記事の本文として埋め込んでいましたが、to_htmlメソッドを使って本文をHTMLに変換した文字列を表示するように修正します。
app/views/home/index.html.erb
<% for entry in @entries %> <div class="entry"> <div class="date"> <%= entry.created_at.year %>年<%= entry.created_at.month %>月<%= entry.created_at.day %>日 </div> <h2><%=h entry.title %></h2> <div><%= entry.to_html %></div> <!-- ←この行を書き換える --> <%=link_to 'permalink', :controller => 'entries', :action => 'show', :id => entry %> <hr /> </div> <% end %>
ついでにパーマリンクのリンク先であるentries/showの方のビューも次のように修正しておきます。
app/views/entries/show.html.erb
<div class="entry"> <div class="date"> <%= @entry.created_at.year %>年<%= @entry.created_at.month %>月<%= @entry.created_at.day %>日 </div> <h2><%=h @entry.title %></h2> <div><%= @entry.to_html %></div> </div> <% if logged_in? %> <%= link_to 'Edit', edit_entry_path(@entry) %> | <%= link_to 'Back', entries_path %> <% end %>
書きこみテスト
HikiDocの文法を使って本文を書き込んで見ましょう。例えば次のような本文を書き込んでみてください。
パラグラフ * リスト * リスト * リスト # リスト # リスト # リスト
このようなテキストを書き込めば、HTMLに変換された結果が表示されるのを確認できると思います。
Railsの基本(プログラミング以前の話)
Railsを知らない人、さらにWebアプリケーションプログラミングについて知らない人がRails(の技術的な面)を理解するにはどうしたらいいか。まずはプログラム以前の基本的なところから解説。
RailsはWebアプリを作るフレームワーク
RailsはWebアプリを作るために便利な機能を集めたフレームワーク。Webアプリとはブラウザからアクセスできるアプリケーション。ただの静的で変化のないHTMLとは違って、BBS、Wiki、ブログのような動的なコンテンツがWebアプリケーション。RailsはこのWebアプリを作るためのフレームワーク。
Webアプリとセキュリティ
Webアプリとは切り離せないセキュリティの話。Webアプリを不特定多数のユーザーがアクセスできる場所に設置する場合は、セキュリティについて十分に注視しなければならない。ネット上に公開されたWebサービスは常に危険にさらされている。しっかり管理しないと悪意を持ったユーザーに隙を与えてしまうことになりかねない。具体的なセキュリティ対策についてはここではスルー。
が、セキュリティをスルーすれば、とりあえずRailsを動かして試してみるくらいは割りと簡単(多少のRubyの知識は必要)。またローカル環境で動かすのであればセキュリティ問題は気にしなくて良い。
Railsで作る最も簡単なブログシステム(4)
Railsで作る最も簡単なブログシステム(3) - dan5yaの日記の続きです。
記事の編集と閲覧は可能になりました。しかしまだ重大な仕事が残っています。認証です。
今のままだと誰でも記事を編集できてしまいます。認証機能を追加してオーナー以外には記事の編集ができないようにします。
認証が必要なページ
あとで書く。
acts_as_authenticatedプラグインで認証
認証機能を実現するためにacts_as_authenticatedプラグインを使用します。
次のコマンドで、acts_as_authenticatedプラグインをプロジェクトにインストールすることができます。
ruby script/plugin source http://svn.techno-weenie.net/projects/plugins ruby script/plugin install acts_as_authenticated
上記コマンドによりacts_as_authenticatedプラグインがダウンロードされ、vendor/plugins/ディレクトリ以下に必要なファイルがコピーされます。
プロジェクトにacts_as_authenticatedプラグインがインストールされると、認証に必要な各種ファイルをジェネレートできるようになります。次のコマンドを実行してください。
ruby script/generate authenticated User
上記コマンドにより、認証に必要なモデル、コントローラ、ビューが生成されます。
Migration定義ファイルも生成されます。次のコマンドで実行してください。
rake db:migrate
ユーザー情報を記録するusersテーブルがDBに作成されます。
app/controllers/application.rbをエディタで開いて、ApplicationControllerクラス定義の先頭に次の1行を追加してください。
class ApplicationController < ActionController::Base include AuthenticatedSystem # ←追加 (略)
これですべてのコントローラに対して認証処理を行うAuthenticatedSystemモジュールの機能が追加されます。
また、app/controllers/entries_controller.rbをエディタで開いて、EntriesControllerクラス定義の先頭に次の1行を追加してください。
class EntriesController < ApplicationController before_filter :login_required # ←追加 (略)
これでEntriesのアクションはログインした状態でないとアクセス出来なくなります。
上記のようにapplication.rbとentries_controller.rbを書き換えた後、ブラウザから管理画面(http://localhost:3000/entries)を開いてみてください。するとログイン画面に飛ばされるはずです。今はまだログインしていませんから、管理ページを開くことができずに、ログインページへのリダイレクト(強制ジャンプ)が発生したわけです。
ログインするにはサインアップを行う必要があります。ブラウザでhttp://localhost:3000/users/signupを開いてください。すると次のようなページが開きます。
TODO.SS
各項目を入力し、サインアップを行ってください。無事サインアップが完了するとユーザー情報はDBに登録されます。
サインアップ直後は自動的にログインした状態になるので、管理画面(http://localhost:3000/entries)を開くことができるようになります。
トップメニューの「ログアウト」をクリックするとUsersコントローラのlogoutアクションが呼び出されて、ログアウトが行われます。ログアウト後に管理画面を開くには、もう一度ログイン(http://localhost:3000/users/login)が必要です。
このままだと誰でもサインアップできてしまうので、Usersコントローラを書き換えます。signupメソッドの先頭に次の1行を追加して、1人しかサインアップできないようにしてしまいます。
app/controllers/users_controller.rb
class UsersController < ApplicationController (略) def signup redirect_to(:action => 'login') if User.count > 0 (略)
ブラウザからサインアップページ(http://localhost:3000/users/signup)を開いてみてください。ログインページへリダイレクトするはずです。これでもう新しいユーザーがサインアップすることはできません。
トップメニューを修正する
ログアウトした状態でトップページ(http://localhost:3000/home)を開いてみてください。ログインしていないのに「日記を書く」「管理」「ログアウト」といったメニューが表示されています。これらはログインしたユーザーにだけ見えればいいものです。これらのメニューがログインしていないユーザーから見えないように修正しましょう。
トップメニューはレイアウトのビューに記述されています。
app/views/layouts/application.html.erb
(略) <%= link_to '日記を書く', :controller => 'entries', :action => 'new' %> <%= link_to '管理', :controller => 'entries', :action => '' %> <%= link_to 'ログアウト', :controller => 'users', :action => 'logout' %> </div> (略)
上記の部分を次のように修正します。
(略) <% if logged_in? %> <%= link_to '日記を書く', :controller => 'entries', :action => 'new' %> <%= link_to '管理', :controller => 'entries', :action => '' %> <%= link_to 'ログアウト', :controller => 'users', :action => 'logout' %> <% else %> <%= link_to 'ログイン', :controller => 'users', :action => 'login' %> <% end %> </div> (略)
logged_in?というのはログイン中であるかどうかを調べるメソッドです。ログイン中であれば、管理者に必要なリンクを表示し、ログインしていなければログインページへのリンクだけを表示するようにしました。
showアクションに対する認証解除
Entriesコントローラのshowアクションの認証を外します。
app/controllers/entries_controller.rb
class EntriesController < ApplicationController before_filter :login_required, :except => [:show] (略)
ちなみに、:exceptの代わりに:onlyを指定すると特定のアクションのみに認証をかけることができます。
before_filter :login_required, :only => [:index, :update]
上の例では、indexアクションとupdateアクションに認証がかかります。
またこのページ下部に表示されているリンクは管理者用のページに対するリンクなので、非ログインジは表示しないようにしておきます。
app/views/entries/show.html.erb
<% if logged_in? %> <%= link_to 'Edit', edit_entry_path(@entry) %> | <%= link_to 'Back', entries_path %> <% end %>
上のようにリンクを生成する部分をif文で囲んでおきます。
トップページ表示される記事を5件に制限する
app/controllers/home_controller.rb
class HomeController < ApplicationController def index @entries = Entry.find(:all, :order => "created_at DESC", :limit => 5) end (略)
Entry.fildメソッドの引数に「:limit => 5」を追加します。これで最新の5件の記事が@entriesに代入されます。記事の総数が5件よりも少ない場合は、すべての記事が@entriesに代入されます。
まとめ
- acts_as_authenticatedをインストール
- ruby script/plugin source http://svn.techno-weenie.net/projects/plugins
- ruby script/plugin install acts_as_authenticated
- ruby script/generate authenticated User
- テーブルを作成
- rake db:migrate
- 認証チェックを追加
- app/controllers/application.rb に「include AuthenticatedSystem」を追加
- app/controllers/entries_controller.rb に「before_filter :login_required」を追加
- app/controllers/users_controller.rb を修正してサインアップを1ユーザーに限定
- app/views/layouts/application.html.erb を修正(トップメニューの修正)
- showアクションに対する認証解除
- app/controllers/entries_controller.rb → before_filter :login_required, :except => [:show]
- 記事を5件
- app/controllers/home_controller.rb → @entries = Entry.find(:all, :order => "created_at DESC", :limit => 5)
Railsで作る最も簡単なブログシステム(3)
Railsで作る最も簡単なブログシステム(2) - dan5yaの日記の続きです。
スタイルシートを適用する
あとで書く。
Aboutページ
ブログについての説明や、プロフィールを書いておく「About」のページを作ります。
app/views/home/about.html.erbというビューファイルを作成します。
app/views/home/about.html.erb
<h2>このブログについて</h2> <p>ここにブログの説明を書きます。</p> <h2>プロフィール</h2> <p>ここにプロフィールを書きます。</p>
ブラウザでhttp://localhost:3000/home/aboutを開くとabout.html.erbの内容が表示されます(このページはトップメニューの「About」をクリックすることで開くことも出来ます。)。ここには好きなことを書いておくことができます。
Archiveページ
閲覧者が記事の一覧表示できる「Archive」ページを作ります。
app/views/home/about.html.erbというビューファイルを作成します。
app/views/home/archive.html.erb
<h2>Archive</h2> <ul> <% for entry in @entries %> <li> <%=h entry.created_at.year %>年<%=h entry.created_at.month %>月<%=h entry.created_at.day %>日 …… <%=link_to h(entry.title), :action => 'show', :id => entry %> </li> <% end %> </ul>
上記のビューファイルは@entriesという変数を使用するので、コントローラにarchiveアクションを定義して、ビューが参照する@entriesを用意してやります。
app/controllers/home_controller.rb
class HomeController < ApplicationController def index @entries = Entry.find(:all, :order => "created_at DESC") end # ↓archiveメソッドを追加する def archive @entries = Entry.find(:all, :order => "created_at DESC") end end
上のようにHomeControllerにarchiveメソッドを定義します。
ブラウザでhttp://localhost:3000/home/archiveを開くとアーカイブページが表示されます(このページはトップメニューの「Archive」をクリックすることで開くことも出来ます。)。このページは記事の日付とタイトルの一覧が表示され、タイトルは各記事の本文にリンクされています。
hatena.cssのカスタマイズ
/theme/hatena/hatena.css使ってるけど、どうしても気に入らなくってずっとストレスを感じてたので手を入れた。おぉーぴたっときた。やる気アップ!!!
「管理ツールトップ」→「デザイン」→「詳細」→「スタイルシート」
h3 { margin-bottom: 1%; } h4 { border-bottom: 1px solid #9af; padding-top: 0.1em; padding-bottom: 0; margin-top: 0.8em; margin-bottom: 0.7em; }
以下はついで。このブログ用。
pre { border: 1px solid #555; } blockquote h4 { border: none; }