文章出處

英文版出處:http://www.padrinorb.com/guides/blog-tutorial

派騅諾

樓主按

拿作者自己的話說:Padrino(諧音:派騅諾)是一款基于Sinatra的優雅的Web應用開發框架,旨在使Web應用的開發變得輕松有趣。

樓主主要是在一臺二手筆記本上跑Linux、體驗Padrino并對原文進行翻譯的。Ruby領域推薦平臺是OS X,其次是Linux,如果你對Linux環境感興趣,可以參考我的配置信息


博客搭建指導

每當我看見天邊的綠洲全新的框架,就會想起東方奇諾瓦如何搭博客。我覺得這是讓新人迅速上手的最佳方式。本指南將向大家展示如何利用Padrino框架搭建簡易博客。在這個過程中,我們將對每一步進行詳細的介紹并提供不同相關主題的鏈接以方便大家學以致用。

學習指南

如果你沒功夫跟我磨嘰,給你指條道兒,直接從GitHub下載全部示例代碼

$ git clone git://github.com/padrino/sample_blog.git

或執行博客指導項目模板,它能夠利用模板生成器一步一步地自動建立起博客項目:

$ padrino g project sample_blog --template sampleblog

點擊這里了解模板生成器的詳細信息。

安裝

俗話說:木有蛋/雞,何來雞/蛋?為了開發Padrino應用,我們得先有點兒準備吧。顯然,我們得先把RubyRubyGems裝了;然后,再來安裝Padrino框架:

$ gem install padrino

點擊這里了解關于安裝的詳細信息。安裝流程一旦完成,所有必需的依賴項也都自動準備就緒,我們現在就可以開始開發自己的博客了。

生成項目

原湯化原食。創建Padrino程序的最佳方式采用Padrino生成器。類似于Rails,Padrino也有一個用來創建包含項目所有必備程序和資源的生成器。Padrino是一個混合型框架(agnostic framework)并支持大量不同的模板、測試、JavaScript和數據庫組件。推薦閱讀《生成器指南》來獲取更詳細信息。

就這個示例程序而言,我們將采用ActiveRecord ORM、Haml模板語言、Shoulda測試框架和jQuery類庫。基于這些考慮,我們現在來創建這個新項目:

$ padrino g project sample_blog -t shoulda -e haml -c sass -s jquery -d activerecord -b

這行命令將為我們生成Padrino項目的基礎文件并打印出生成報告。可以從這里查看這條生成命令的輸出信息示例。需要注意的是,-b參數自動指引bundler安裝相關的依賴項。現在我們進入新項目文件夾:

$ cd sample_blog

現在,我們已經從終端中進入到項目文件目錄了,讓我們更近距離地看一下這些可愛的文件吧:

  • Gemfile:確保項目所有gem包依賴項都包含在該文件中!
  • app/app.rb:核心應用程序主要配置文件;
  • config/apps.rb:該文件定義項目要掛載的應用;
  • config/database.rb:顧名思義,定義數據庫適配器信息。

除此之外,還生成了一些重要的目錄:

  • app/controllers:聲明Padrino的路由定義;
  • app/helpers:定義應用的幫助方法;
  • app/views:包含由控制器輸出的模板視圖;
  • lib:包含項目用到的所有擴展、類庫和其它代碼;
  • public:保存圖片、樣式和JavaScript代碼文件;
  • test:保存模型和控制器的測試代碼;

現在,我們來檢查config/database.rb文件以確保數據庫連接配置是正確的。截至目前,默認配置對于示例指導來說是可用的。項目將采用存儲在db/sample_blog_development.db中Sqlite3數據庫。

我們再創建一些簡單的路由來演示Padrino的路由系統。進入app/app.rb文件并輸入:

# app/app.rb
class SampleBlog::App
  register Padrino::Rendering  
  register Padrino::Helpers
  
  # Add these routes below to the app file...
  get "/" do
    "Hello World!"
  end

  get :about, :map => '/about_us' do
    render :haml, "%p Padrino 博客開發示例"
  end
end

可以看到:第一條路由創建一個字符用來返回應用的根URL;第二條路由將"/about_us"顯式映射到由Haml輸出的“關于”頁面;符號:about用來引用這條路由。

強烈建議親查看《控制器指南》來對路由系統有一個綜合的了解喲!

創建后臺管理界面

接下來,為了方便對項目中的數據進行增刪改查,我們來建立Padrino后臺管理面板。在終端程序中輸入:

sample_blog $ padrino g admin
sample_blog $ bundle install

這兩行命令將為項目建立管理子程序,并在config/apps.rb文件中聲明對自己的掛載。通過這里可以查看該命令的輸出結果。

然后,輸入下面的指令來創建數據庫、運行遷移并運行db/seeds.rb里的種子(seed)任務:

sample_blog $ padrino rake ar:create
sample_blog $ padrino rake ar:migrate
sample_blog $ padrino rake seed

在這個過程中,系統將提示你輸入登錄管理系統所用的電子郵箱和密碼。

如果你想要了解更多關于管理面板的功能和特性,歡迎閱讀《管理面板指南》

啟動Padrino

Padrino項目建立了、數據庫也配置了、管理系統也搭好了,輪到啟動Padrino應用服務器的時候了!用內建的Padrino任務來做其實非常簡單,只要在終端里執行下面這條命令:

sample_blog $ padrino start

不出意外你應該從終端看到如下輸出:

=> Located unlocked Gemfile for development
=> Padrino/0.10.2 has taken the stage development on port 3000
>> Thin web server (v1.2.7 codename This Is Not A Web Server)
>> Maximum connections set to 1024
>> Listening on localhost:3000, CTRL+C to stop

要想了解操作Padrino的終端命令,那就閱讀《開發與終端命令》指南。

你的程序現在已經在http://localhost:3000(樓主:Mac和Linux用戶可以無比優越地直接簡寫為0:3000)恭候你的大駕光臨了。在瀏覽器中訪問該網址,你可以看到著名的“Hello World!”我們還可以通過下面這行網址進入管理界面:

http://localhost:3000/admin

當然需要登錄啰,還記得在執行rake seed命令時寫的登錄郵箱和密碼吧。登錄后,你可以盡情探索Padrino的后臺管理功能,不過我們將晚一點兒再來介紹更詳細的信息。如果你想獲取更多關于這方面的資料,可以閱讀《管理面板指南》

順便說一下,Padrino在開發模式中完全支持代碼重裝。啥,你問這是啥?這就是說你可以讓Padrino服務器一邊跑一邊修改源代碼,只需要刷新一下瀏覽器,光彩立現!建議你專門開一個終端程序來跑Padrino服務器程序。

創建博文

好,程序OK了、布局也定好了,現在我們來實現創建和展示博文的功能。

首先在應用目錄中生成模型。和版本0.10.0一樣,模型將默認生成到項目的models目錄下。如果你覺得不爽,可以用-a參數來自定義你想要存儲模型的子目錄。

sample_blog $ padrino g model post title:string body:text -a app
=> Located unlocked Gemfile for development
create  app/models/post.rb
create  test/models/post_test.rb
create  db/migrate/002_create_posts.rb

然后在遷移中給博文模型增加一個時間戳:

# db/migrate/002_create_posts.rb
class CreatePosts < ActiveRecord::Migration
  def self.up
    create_table :posts do |t|
      t.string :title
      t.text :body
      t.timestamps
    end
  end

  def self.down
    drop_table :posts
  end
end

然后遷移到數據庫:

sample_blog $ padrino rake ar:migrate
=> Executing Rake ar:migrate ...
==  CreatePosts: migrating ====================================================
-- create_table("posts", {})
==  CreatePosts: migrated (0.0016s) ===========================================

博文模型便創建好了。然后來創建提供基本展示功能的控制器:

sample_blog $ padrino g controller posts get:index get:show
=> Located unlocked Gemfile for development
create  app/controllers/posts.rb
create  app/helpers/posts_helper.rb
create  app/views/posts
create  test/controllers/posts_controller_test.rb

我們再來添加一些標準路由到控制器里面,比如:index和:show神馬的:

# app/controllers/posts.rb
SampleBlog.controllers :posts do
  get :index do
    @posts = Post.all(:order => 'created_at desc')
    render 'posts/index'
  end
  
  get :show, :with => :id do
    @post = Post.find_by_id(params[:id])
    render 'posts/show'
  end
end

上面這個控制器定義了可以通過我們的應用來訪問的路由。聲明以Http方法get開始,接上一個符號表示動作(Action),放置在一個保存了獲取必要對象的變量以及輸出視圖模板的代碼塊當中。看上去跟Rails和Sinatra沒啥兩樣,是吧?(博主:好像是吧……)

下一步,為index和show控制器動作分別創建視圖:

# app/views/posts/index.haml
- @title = "Welcome"

#posts= partial 'posts/post', :collection => @posts
# app/views/posts/_post.haml
.post
  .title= link_to post.title, url_for(:posts, :show, :id => post)
  .date= time_ago_in_words(post.created_at || Time.now) + '以前'
  .body= simple_format(post.body)
# app/views/posts/show.haml
- @title = @post.title
#show
  .post
    .title= @post.title
    .date= time_ago_in_words(@post.created_at || Time.now) + '以前'
    .body= simple_format(@post.body)    
%p= link_to '顯式全部博文', url_for(:posts, :index)

Padrino管理系統使得數據記錄的增刪改查相當簡便自動。通過Padrino管理系統管理博文,只需輸入下面這行命令:

sample_blog $ padrino g admin_page post
=> Located unlocked Gemfile for development
create  admin/controllers/posts.rb
create  admin/views/posts/_form.haml
create  admin/views/posts/edit.haml
create  admin/views/posts/index.haml
create  admin/views/posts/new.haml
inject  admin/app.rb

你沒關Padrino服務器吧(CTRL + C)?沒關就好,來看看管理界面。

用你之前輸入的郵箱和密碼登錄http://localhost:3000/admin

你可以看到有兩個Tab,一個是博文,另一個是賬戶。點擊博文那個分頁。

只需輕輕點擊一下“New”,你便可以開始創建新的記錄,頁面會羅列出你先前在創建博文模型時設置的所有字段。

注意:確保在創建模型和遷移后運行padrino g admin_page命令。

現在你已經通過管理界面添加了一些博文,訪問http://localhost:3000/posts并注意到你創建的博文都會在index動作中顯示出來。

你可以通過padrino rake routes命令來顯示當前所有定義過的路由:

$ padrino rake routes
    URL                 REQUEST  PATH
    (:about)              GET    /about_us
    (:posts, :index)      GET    /posts
    (:posts, :show)       GET    /posts/show/:id

這對理解控制器和url之間的映射關系很有幫助哦!

在博文中添加賬戶信息

至此,博文還沒有關聯上作者信息,這像什么話,不行不行!再來看看博文模型,我們將開始通過增加新的遷移來將作者賬戶添加到博文中:

sample_blog $ padrino g migration AddAccountToPost account_id:integer
=> Located unlocked Gemfile for development
create  db/migrate/003_add_account_to_post.rb

上述指令創建了一個包含了期望字段的遷移,將account_id附加到博文中。

修改一下遷移文件,將現有博文都指派給系統的第一位用戶(現在也就一個用戶噻):

# db/migrate/003_add_account_to_post.rb
class AddAccountToPost < ActiveRecord::Migration
  def self.up
    change_table :posts do |t|
      t.integer :account_id
    end
    # and assigns a user to all existing posts
    first_account = Account.first
    Post.all.each { |p| p.update_attribute(:account, first_account) }
  end 
  # ...
end

現在,我們回到博文模型來創建賬戶關聯并增加點兒驗證:

# app/models/post.rb
class Post < ActiveRecord::Base
  belongs_to :account
  validates_presence_of :title
  validates_presence_of :body
end

親,每次修改數據庫都要記得遷移人家哦:

sample_blog $ padrino rake ar:migrate
==  AddAccountToPost: migrating ===============================================
-- change_table(:posts)
==  AddAccountToPost: migrated (0.0009s) ====================================== 7:04
=> Executing Rake ar:migrate ...

我們的博文現在已經有了適當的關聯和驗證,接下來我們需要進入Padrino管理系統做一點兒改動來包含賬戶和博文。

直奔admin/controllers/posts.rb,將current_account添加到新博文的創建中:

# admin/controllers/posts.rb
Admin.controllers :posts do
# ...
  post :create do
    @post = Post.new(params[:post])
    @post.account = current_account
    if @post.save
      flash[:notice] = '恭喜,博文已成功創建!'
      redirect url(:posts, :edit, :id => @post.id)
    else
      render 'posts/new'
    end
  end
# ...
end

同時還要更新博文的視圖來顯示作者信息和其它改動:

# app/views/posts/show.haml
- @title = @post.title
#show
  .post
    .title= @post.title
    .date= time_ago_in_words(@post.created_at || Time.now) + ' ago'
    .body= simple_format(@post.body)
    .details
      .author Posted by #{@post.account.email}
%p= link_to '查看全部博文', url_for(:posts, :index)
# app/views/posts/_post.haml
.post
  .title= link_to post.title, url_for(:posts, :show, :id => post)
  .date= time_ago_in_words(post.created_at || Time.now) + ' ago'
  .body= simple_format(post.body)
  .details
    .author 由#{post.account.email}發布

現在來增加一個新用戶。到http://localhost:3000/admin,切換到Account分頁并創建一條新的賬戶記錄。一旦你有了新的賬戶,嘗試用它登錄并添加一些新的博文。猜猜這樣會發生什么?這樣你就有了多個用戶和多篇博文:D

http://localhost:3000/posts看看效果,博文和作者分別全都鏈接上了。

站點布局

現在,應用已經正確配置并且服務器也跑起來了,我們繼續來創建一些基本的樣式和布局。

首先,我們為應用創建一個布局。布局是在其路由上扮演內容模板容器角色的文件,它會被用來為應用創建各個結構一致的頁面。要想創建布局,只需要簡單地想app/views/layouts目錄添加文件:

# app/views/layouts/application.haml
!!! Strict
%html
  %head
    %title= [@title, "Padrino 示例博客"].compact.join(" | ")
    = stylesheet_link_tag 'reset', 'application'
    = javascript_include_tag 'jquery', 'application'
    = yield_content :include
  %body
    #header
      %h1 Sample Padrino Blog
      %ul.menu
        %li= link_to '博客', url_for(:posts, :index)
        %li= link_to '關于', url_for(:about)
    #container
      #main= yield
      #sidebar
        - form_tag url_for(:posts, :index), :method => 'get'  do
          Search for:
          = text_field_tag 'query', :value => params[:query]
          = submit_tag 'Search'
        %p Recent Posts
        %ul.bulleted
          %li Item 1 - Lorem ipsum dolorum itsum estem
          %li Item 2 - Lorem ipsum dolorum itsum estem
          %li Item 3 - Lorem ipsum dolorum itsum estem
        %p Categories
        %ul.bulleted
          %li Item 1 - Lorem ipsum dolorum itsum estem
          %li Item 2 - Lorem ipsum dolorum itsum estem
          %li Item 3 - Lorem ipsum dolorum itsum estem
        %p Latest Comments
        %ul.bulleted
          %li Item 1 - Lorem ipsum dolorum itsum estem
          %li Item 2 - Lorem ipsum dolorum itsum estem
          %li Item 3 - Lorem ipsum dolorum itsum estem
    #footer
      Copyright (c) 2009-2013 Padrino

這個布局為博客創建了一個基本結構,并引用了對控制行為和顯示而言必要的樣式表和JavaScript文件。這個布局應該包含一些假元素,比如假的搜索框和列表項。

然后,我們僅僅需要為演示建立兩張樣式表。第一張是被艾里克·邁耶斯(Eric Meyers)重置的通用CSS,可以在示例博客倉庫找到完整的樣式表重置并放到public/stylesheets/reset.css。

第二張是為了博客更酷一點兒的應用樣式表,可以從示例博客倉庫找到該樣式表的完整內容并放置到app/stylesheets/application.sass。

有了布局和樣式表,博客終于拿得出手了!讓我們訪問http://localhost:3000/posts來看看新的界面。

建立RSS訂閱功能

在部署應用以前,是不是還漏了點兒啥?對,RSS和Atom訂閱。只準用戶說他不想看,不準他他看不到!要實現訂閱,我們得在博文控制器中為index塊添加一個provides選項。下面的代碼指定路由需要響應的HTML、RSS和Atom格式:

# app/controllers/posts.rb
SampleBlog.controllers :posts do
...
  get :index, :provides => [:html, :rss, :atom] do
    @posts = Post.all(:order => 'created_at desc')
    render 'posts/index' 
  end
...
end

需要注意的是,這條路由同時也指定渲染引擎(rendering engine)在使用RSS或Atom格式時避免輸出。

回到index.haml文件,我們將采用auto_discovery_link_tag幫助方法來生成RSS訂閱引用創建器(the RSS feed using builder)。

# app/views/posts/index.haml
- @title = "歡迎"

- content_for :include do
  = feed_tag(:rss, url(:posts, :index, :format => :rss),:title => "RSS")
  = feed_tag(:atom, url(:posts, :index, :format => :atom),:title => "ATOM")

#posts= partial 'posts/post', :collection => @posts

然后添加Atom引用創建器模板:

# app/views/posts/index.atom.builder
xml.instruct!
xml.feed "xmlns" => "http://www.w3.org/2005/Atom" do
  xml.title   "Padrino 示例博客"
  xml.link    "rel" => "self", "href" => url_for(:posts, :index)
  xml.id      url_for(:posts, :index)
  xml.updated @posts.first.updated_at.strftime "%Y-%m-%dT%H:%M:%SZ" if @posts.any?
  xml.author  { xml.name "Padrino Team" }

  @posts.each do |post|
    xml.entry do
      xml.title   post.title
      xml.link    "rel" => "alternate", "href" => url_for(:posts, :show, :id => post)
      xml.id      url_for(:posts, :show, :id => post)
      xml.updated post.updated_at.strftime "%Y-%m-%dT%H:%M:%SZ"
      xml.author  { xml.name post.account.email }
      xml.summary post.body
    end
  end
end

還有RSS引用創建器的模板:

# app/views/posts/index.rss.builder
xml.instruct!
xml.rss "version" => "2.0", "xmlns:dc" => "http://purl.org/dc/elements/1.1/" do
  xml.channel do
    xml.title "Padrino Blog"
    xml.description "The fantastic padrino sample blog"
    xml.link url_for(:posts, :index)

    for post in @posts
      xml.item do
        xml.title post.title
        xml.description post.body
        xml.pubDate post.created_at.to_s(:rfc822)
        xml.link url_for(:posts, :show, :id => post)
      end
    end
  end
end

檢查一下改動,看看http://localhost:3000/posts是不是已經提供了RSS和Atom訂閱。是的,對吧?那就可以開張啦!

部署

丑媳婦終于要見公婆了!用Heroku服務神馬的來部署Padrino應用最簡單老。

參照《Heroku快速入門指南》,確認你此時已經安裝了Git并建立了Heroku賬戶以及安裝了Heroku gem

要部署到Heroku,需要先將應用創建為Git倉庫:

sample_blog $ git init
sample_blog $ git add .
sample_blog $ git commit -m "initial commit for app"

以上命令是在初始化Git倉庫,并將所有內容都提交進去。然后將應用創建到Heroku:

sample-blog $ heroku create --stack bamboo-ree-1.8.7
sample-blog $ git push heroku master

歐了,你的應用現在就運行在Heroku上了!

運行heroku open命令可以在你的系統默認瀏覽器里打開網站。

眼目前兒,Padrino默認使用SQLite,但Heroku只認PostgreSQL,咋整?只能將pg添加為依賴項啰:

# Gemfile
group :production do
 gem 'pg'
end

執行下面的命令可以避免在你本地計算機上安裝pg gem:

sample-blog $ bundle install --without production

而且有必要為生產配置一下config/database.rb:

# config/database.rb
postgres = URI.parse(ENV['DATABASE_URL'] || '')

ActiveRecord::Base.configurations[:production] = {
  :adapter  => 'postgresql',
  :encoding => 'utf8',
  :database => postgres.path[1..-1], 
  :username => postgres.user,
  :password => postgres.password,
  :host     => postgres.host
}

由于沒有shell可以訪問padrino rake,我們還得創建一個Rakefile,不過僅需要使用Rakefile生成器:

$ padrino rake gen

自動生成的Rakefile看起來大概是下面這幅樣兒:

# Rakefile
require File.dirname(__FILE__) + '/config/boot.rb'
require 'thor'
require 'padrino-core/cli/rake'

PadrinoTasks.init

最后還得調整一下seed.rb:

# db/seeds.rb
email     = "info@padrinorb.com"
password  = "admin"

shell.say ""

account = Account.create(:email => email, 
                         :name => "Foo", 
                         :surname => "Bar", 
                         :password => password, 
                         :password_confirmation => password, 
                         :role => "admin")

if account.valid?
  shell.say "================================================================="
  shell.say "Account has been successfully created, now you can login with:"
  shell.say "================================================================="
  shell.say "   email: #{email}"
  shell.say "   password: #{password}"
  shell.say "================================================================="
else
  shell.say "Sorry but some thing went worng!"
  shell.say ""
  account.errors.full_messages.each { |m| shell.say "   - #{m}" }
end

shell.say ""

上面seed的值你想咋改就咋改,誰也攔不住的。

然后在終端中運行下面的命令:

sample_blog $ git add .
sample_blog $ git commit -m "Added Postgres support"
sample_blog $ git push heroku master

再執行migrations/seeds:

sample_blog $ heroku rake ar:migrate
sample_blog $ heroku rake seed

當當當當,你就看到了:

sample_blog $ heroku rake ar:migrate
(in /disk1/home/slugs/151491_a295681_03f1/mnt)
=> Located locked Gemfile for production
==  CreateAccounts: migrating =================================================
-- create_table("accounts", {})
   -> 0.0185s
==  CreateAccounts: migrated (0.0229s) ========================================

==  CreatePosts: migrating ====================================================
-- create_table("posts", {})
   -> 0.0178s
==  CreatePosts: migrated (0.0218s) ===========================================

==  AddAccountToPost: migrating ===============================================
-- change_table(:posts)
   -> 0.0026s
==  AddAccountToPost: migrated (0.0028s) ======================================

MacBook:sample_blog DAddYE$ heroku rake seed
(in /disk1/home/slugs/151491_7576c59_03f1/mnt)
=> Located locked Gemfile for production

=================================================================
Account has been successfully created, now you can login with:
=================================================================
   email: info@padrinorb.com
   password: admin
=================================================================

然后就可以打開我們部署的應用了:

sample_blog $ heroku open

走起!


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()