在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ Ruby/ 3.4 模板引擎的使用
寫在后面
寫在前面
第六章 Rails 的配置及部署
第四章 Rails 中的模型
4.4 模型中的校驗(Validates)
1.3 用戶界面(UI)設計
6.5 生產(chǎn)環(huán)境部署
3.2 表單
4.3 模型中的關聯(lián)關系(Relations)
4.5 模型中的回調(Callback)
第五章 Rails 中的控制器
4.2 深入模型查詢
5.2 控制器中的方法
6.2 緩存
3.4 模板引擎的使用
6.4 I18n
第一章 Ruby on Rails 概述
6.6 常用 Gem
1.2 Rails 文件簡介
2.2 REST 架構
2.3 深入路由(routes)
第三章 Rails 中的視圖
6.3 異步任務及郵件發(fā)送
第二章 Rails 中的資源
3.3 視圖中的 AJAX 交互

3.4 模板引擎的使用

概要:

本課時結合商品頁面,講解如何使用簡潔安全的模板引擎,以及如何更改郵件模板。

知識點:

  1. haml
  2. slim
  3. liquid
  4. 郵件模板

正文

3.4.1 haml

前面的章節(jié)里,我們一直使用 erb 作為視圖模板,erb 可以讓我們在 html 中簽入 Ruby 代碼。這樣做的好處是,我們拿到的頁面和設計師提供的頁面幾乎無任何差別,可以直接增加上我們用 Ruby 寫的的邏輯。稍微不好的一點是,html 太多了,稍微處理不好,會缺失標簽,而且不易察覺。

這時我們可以使用其他一些方案,haml 是比較常用的一個。

我們在 Gemfile 中安裝 haml:

gem 'haml'

我們看一下用 haml 寫的代碼:

%section.container
  %h1= post.title
  %h2= post.subtitle
  .content
    = post.content

下面是 erb 的寫法。

<section class=”container”>
  <h1><%= post.title %></h1>
  <h2><%= post.subtitle %></h2>
  <div class=”content”>
    <%= post.content %>
  </div>
</section>

可見 haml 節(jié)省了我們大量的代碼,而且更接近 Ruby 語法。我們看幾個 haml 常用的寫法:

.title= "I am Title"
#title= "I am Title"

它會輸出為:

 <div class="title">I am Title</div>
 <div id="title">I am Title</div>

下面是顯示 ul 列表,注意,haml 的縮進是2個空格:

%ul
  %li Salt
  %li Pepper

這是循環(huán)的例子:

- (42...47).each do |i|
  %p= i
%p See, I can count!

我們?nèi)绻朐陧椖坷锸褂?haml 文件,只需要創(chuàng)建一個 xxx.html.haml 文件即可,這是一個完整的 haml 例子:

!!!
%html{html_attrs}
  %head
    %title Hampton Catlin Is Totally Awesome
    %meta{"http-equiv" => "Content-Type", :content => "text/html; charset=utf-8"}
  %body
    %h1
      This is very much like the standard template,
      except that it has some ActionView-specific stuff.
      It's only used for benchmarking.
    .crazy_partials= render :partial => 'templates/av_partial_1'
    / You're In my house now!
    .header
      Yes, ladies and gentileman. He is just that egotistical.
      Fantastic! This should be multi-line output
      The question is if this would translate! Ahah!
      = 1 + 9 + 8 + 2 #numbers should work and this should be ignored
    #body= " Quotes should be loved! Just like people!"
    - 120.times do |number|
      - number
    Wow.|
    %p
      = "Holy cow        " + |
        "multiline       " + |
        "tags!           " + |
        "A pipe (|) even!"   |
      = [1, 2, 3].collect { |n| "PipesIgnored|" }
      = [1, 2, 3].collect { |n|     |
          n.to_s                    |
        }.join("|")                 |
    %div.silent
      - foo = String.new
      - foo << "this"
      - foo << " shouldn't"
      - foo << " evaluate"
      = foo + " but now it should!"
      -# Woah crap a comment!

    -# That was a line that shouldn't close everything.
    %ul.really.cool
      - ('a'..'f').each do |a|
        %li= a
    #combo.of_divs_with_underscore= @should_eval = "with this text"
    = [ 104, 101, 108, 108, 111 ].map do |byte|
      - byte.chr
    .footer
      %strong.shout= "This is a really long ruby quote. It should be loved and wrapped because its more than 50 characters. This value may change in the future and this test may look stupid. \nSo, I'm just making it *really* long. God, I hope this works"

這個文件來自 這里,你可以在這里找到它的源碼。

這里 還有一份文檔。

如果打算把現(xiàn)有的 erb 轉成 haml,可以使用 haml 提供的一個命令行工具 html2haml,我們在 Gemfile 里安裝臺:

gem 'html2haml'

在命令行里,直接使用它:

% html2haml -e index.erb index.haml

-e 參數(shù),可以把 erb 模板轉成 haml。

這里有一個 網(wǎng)站,是在線把 html/erb 轉成 haml。如果需要把 haml 轉回 erb 模板,可是試試 這個網(wǎng)站。

為了方便的使用 haml,尤其在使用 scaffold 或者 generate 創(chuàng)建文件的時候,自動創(chuàng)建 haml,而不是 erb,可以安裝 haml-rails

gem "haml-rails"

它為我們提供了一個快速轉換的工具:

rake haml:erb2haml

它可以把所有 views 文件夾下的 erb 模板,轉成 haml。

3.4.2 slim

和 haml 類似,slim 更加的簡潔,從它的官網(wǎng)首頁可以看到它的代碼風格,而且比 haml 又少了一些分隔符。

doctype html
html
  head
    title Slim Examples
    meta name="keywords" content="template language"
    meta name="author" content=author
    javascript:
      alert('Slim supports embedded javascript!')

  body
    h1 Markup examples

    #content
      p This example shows you how a basic Slim file looks like.

      == yield

      - unless items.empty?
        table
          - for item in items do
            tr
              td.name = item.name
              td.price = item.price
      - else
        p
         | No items found.  Please add some inventory.
           Thank you!

    div id="footer"
      = render 'footer'
      | Copyright ? #{year} #{author}

這是官網(wǎng)首頁給出的代碼示例,這里有它詳盡的使用手冊。

slim 為我們提供了兩個工具:html2slim 可以把 html/erb 轉換成 slim,haml2slim 把 haml 轉成 slim。

和 haml-rails 一樣,slim-rails 可以默認生成 slim 模板。

在這里,有一個 在線工具,把 html 轉換成 slim。

3.4.3 liquid

上面兩個模板引擎(template engine)是針對開發(fā)者的,因為我們編寫的代碼是不會交付給使用者的,但是,如果我們需要把頁面開放給使用者隨意編輯,以上提到的 erb,haml,slim 是絕對不可以的,因為使用者可以在頁面里這么寫:

<%= User.destroy_all %>

那么,如何給使用者一個安全的模板來自由編輯呢? liquid 是一個很好的方案。liquid 是著名的電商網(wǎng)站 Shopify 設計并開源的安全模板引擎。

liquid 不允許執(zhí)行危險的代碼,所以可以隨意交給使用者編輯并且直接渲染成頁面,它還可以保存到數(shù)據(jù)里,這樣可以實現(xiàn)在線編輯模板,它將邏輯代碼和表現(xiàn)代碼分開,如果你熟悉 php 的 smarty 模板,那么你會發(fā)現(xiàn) liquid 就是 Ruby 版的 smarty。

我們看一個例子:

 <ul id="products">
   {% for product in products %}
     <li>
       <h2>{{ product.name }}</h2>
       Only {{ product.price | price }}
       {{ product.description | prettyprint | paragraph }}
     </li>
   {% endfor %}
 </ul>

這是我們的 liquid 模板,我們把 Product 的 Model 也改寫一下,讓 liquid 可以讀取它的屬性:

class Product < ActiveRecord::Base
  def to_liquid
    {
      "name" => name,  [1] 這里要用 string 的寫法,不要使用 symbol。
      "price" => price
    }
  end
end

我們來渲染(Render)這個模板:

require "liquid"
template = Liquid::Template.parse(template) # template 就是上面的代碼,可以直接從數(shù)據(jù)庫讀取出來。
template.render('products' => Product.all) # 傳入 products 變量,這是由我們控制傳入的,用戶可以在模板中隨意調用。

liquid 的源碼在 https://github.com/Shopify/liquid,在 https://github.com/Shopify/liquid/wiki/Liquid-for-Designers,有非常詳盡的使用方法。

和 haml-rails,slim-rails 一樣,liquid 也有自己的:

gem 'liquid-rails'

它可以方便的使用 Rails 中的 Helper 和 Tag,實現(xiàn) Drop Class,并且編寫 Rspec 測試。

Rails 使用 Tilt 這個 Gem 來處理各種模板引擎,Tilt 是一個接口,支持幾十個模板引擎,我們只是提到了其中較常用的三個。

使用 tilt 方便我們在 Rails 集成各種模板引擎,不過實際開發(fā)的時候,我們要注意他們的效率問題。這里有一份測試數(shù)據(jù):

# Linux + Ruby 1.9.2, 1000 iterations

                      user     system      total        real
(1) erb           0.680000   0.000000   0.680000 (  0.810375)
(1) erubis        0.510000   0.000000   0.510000 (  0.547548)
(1) fast erubis   0.530000   0.000000   0.530000 (  0.583134)
(1) slim          4.330000   0.020000   4.350000 (  4.495633)
(1) haml          4.680000   0.020000   4.700000 (  4.747019)
(1) haml ugly     4.530000   0.020000   4.550000 (  4.592425)

(2) erb           0.240000   0.000000   0.240000 (  0.235896)
(2) erubis        0.180000   0.000000   0.180000 (  0.185349)
(2) fast erubis   0.150000   0.000000   0.150000 (  0.154970)
(2) slim          0.050000   0.000000   0.050000 (  0.046685)
(2) haml          0.490000   0.000000   0.490000 (  0.497864)
(2) haml ugly     0.420000   0.000000   0.420000 (  0.428596)

(3) erb           0.030000   0.000000   0.030000 (  0.033979)
(3) erubis        0.030000   0.000000   0.030000 (  0.030705)
(3) fast erubis   0.040000   0.000000   0.040000 (  0.035229)
(3) slim          0.040000   0.000000   0.040000 (  0.036249)
(3) haml          0.160000   0.000000   0.160000 (  0.165024)
(3) haml ugly     0.150000   0.000000   0.150000 (  0.146130)

(4) erb           0.060000   0.000000   0.060000 (  0.059847)
(4) erubis        0.040000   0.000000   0.040000 (  0.040770)
(4) slim          0.040000   0.000000   0.040000 (  0.047389)
(4) haml          0.190000   0.000000   0.190000 (  0.188837)
(4) haml ugly     0.170000   0.000000   0.170000 (  0.175378)

1. Uncached benchmark. Template is parsed every time.
   Activate this benchmark with slow=1.

2. Cached benchmark. Template is parsed before the benchmark.
   The ruby code generated by the template engine might be evaluated every time.
   This benchmark uses the standard API of the template engine.

3. Compiled benchmark. Template is parsed before the benchmark and
   generated ruby code is compiled into a method.
   This is the fastest evaluation strategy because it benchmarks
   pure execution speed of the generated ruby code.

4. Compiled Tilt benchmark. Template is compiled with Tilt, which gives a more
   accurate result of the performance in production mode in frameworks like
   Sinatra, Ramaze and Camping. (Rails still uses its own template
   compilation.)

該數(shù)據(jù)來自:https://ruby-china.org/topics/634

選擇哪個模板引擎,還是直接使用 erb,需要視情況而定了。

3.4.4 devise 的郵件模板

Devise 除了提供用戶注冊和登錄功能,還可以通過郵件激活用戶。這里,我們可以自己定義郵件模板中的內(nèi)容。

我們修改一下 User 中關于 Devise 的配置:

devise :database_authenticatable, :registerable,
       :recoverable, :rememberable, :trackable, :validatable,
       :confirmable

我們增加了一個新的選項::confirmable。

我們配置下郵件發(fā)送的信息,這里我們只在開發(fā)環(huán)境(development)配置,我們打開 config/environments/development.rb

  config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
  config.action_mailer.delivery_method = :smtp
  config.action_mailer.smtp_settings = {
    address:              'smtp.163.com',
    port:                 25,
    domain:               '...',
    user_name:            '...@163.com',
    password:             '...',
    authentication:       :plain,
    enable_starttls_auto: true
  }

同時,我們還需要修改 user 創(chuàng)建時的 migration 文件,打開 db/migrate/xxxx_devise_create_users.rb,我們?nèi)∠⑨屵@個部分:

## Confirmable
  t.string   :confirmation_token
  t.datetime :confirmed_at
  t.datetime :confirmation_sent_at
  t.string   :unconfirmed_email # Only if using reconfirmable

注意,xxxx 是日期時間戳,表示這個文件創(chuàng)建的日期。devise 已經(jīng)為我們添加了 confirmable 需要的字段,我們不必自己添加。這里有一個問題,我們已經(jīng)運行過數(shù)據(jù)庫文件了,這里是修改舊文件,我們不能直接更新文件,這里我們可以刪掉舊的數(shù)據(jù)庫,其實在開發(fā)環(huán)境,我們可以經(jīng)常重建數(shù)據(jù)庫:

rake db:drop
rake db:create
rake db:migrate
rake db:seed

還記得 db/seeds.rb 這個文件吧,我們可以把一些默認數(shù)據(jù)寫到 seed 里,或者一些測試數(shù)據(jù),比如我們添加50個商品信息,來測試分頁等效果是否正確,或者初始化幾十個商品類別等。這樣,重建數(shù)據(jù)庫時,不必擔心默認數(shù)據(jù)的丟失。

我們再編輯下 devise 的配置文件,它在 config/initializers/devise.rb

config.mailer_sender = '...@163.com'
...
config.mailer = 'Devise::Mailer'

我們重新啟動 Rails 服務,注冊一個賬號,這時我們觀察終端,可以看到郵件發(fā)送的信息:

Sent mail to hi@liwei.me (2468.6ms)
Date: Mon, 02 Mar 2015 14:04:57 +0800
From: master@...
Reply-To: master@...
To: hi@liwei.me
Message-ID: <54f3fd89f0f84_62213ffdf44a34e08208d@macbook.local.mail>
Subject: =?UTF-8?Q?=E6=9D=A5=E8=87=AAezcms=E7=9A=84=E6=B3=A8=E5=86=8C=E7=A1=AE=E8=AE=A4=E9=82=AE=E4=BB=B6?=
Mime-Version: 1.0
Content-Type: text/html;
 charset=UTF-8
Content-Transfer-Encoding: 7bit

 <p>Welcome hi@liwei.me!</p>

 <p>You can confirm your account email through the link below:</p>

 <p><a href="http://localhost:3000/users/confirmation?confirmation_token=FNMGvy_VnNfyhHKz_LKY">Confirm my account</a></p>

我們頁面上,也會得到這樣的提示:

http://wiki.jikexueyuan.com/project/rails-practice/images/chapter_3/11.png" alt="" />

為了讓我們的郵件看起來更友好,我們編輯 app/views/users/mailer/confirmation_instructions.html.erb

 <p>你好 <%= @email %>!</p>

 <p>請點擊下面的確認鏈接,驗證您的郵箱:</p>

 <p><%= link_to "驗證我的郵箱", confirmation_url(@resource, confirmation_token: @token) %></p>

你可以再試試看。不過這種配置可能會被當做垃圾郵件拒收,或者直接被放到垃圾郵件中。在后面的章節(jié)里,我們會介紹其他的方式發(fā)送郵件。

如果你不能通過郵件激活這個用戶,比如那些在 seed 中添加的用戶,沒關系,rails c 進入控制臺:

u = User.last [1]
u.confirm! [2]
  • [1] 找到這個用戶,更多方法在下一章陸續(xù)介紹
  • [2] confirm! 方法激活用戶

更多郵件配置,可以查看 http://guides.rubyonrails.org/configuring.html#configuring-action-mailer