Haml

Haml（HTML Abstraction Markup Language，HTML抽象標記語言）是一種模板系統，它可以避免在Web文檔中內嵌代碼，使HTML更簡易和乾淨。Haml為HTML中提供了一些動態內容的靈活性。類似其他Web語言（如PHP、ASP、JSP）和模板系統（如eRuby），Haml也嵌入一些在運行時執行的代碼並生成HTML代碼，從而提供一些動態內容。為運行Haml代碼，文件需要採用.haml擴展名。這些文件類似.erb或eRuby文件，這有助於在開發網路應用程式時嵌入Ruby代碼。在解析代碼注釋時，Haml採用與Ruby 1.9或之後版本相同的規則。Haml只能理解兼容ASCII的編碼（例如UTF-8），而不能理解不兼容ASCII的UTF-16與UTF-32。Haml可以在命令行界面中使用，也可以作為一個單獨的Ruby模塊或在一個Ruby on Rails應用程式中使用，這使Haml可用於廣泛的應用程式。

## 歷史

Haml最早由Hampton Catlin於2006年發布，它的成果領先於其他幾個人。他的動機是使HTML更簡單、清晰和易於使用。自2006年以來，它已隨新版本發布而多次修訂。2012年4月，Haml的維護由Norman Clarke接手。Natalie Weizenbaum致力於使Haml可以在Ruby應用程式中使用，而品牌與設計則由Nick Walsh完成。目前的維護團隊中還有Matt Wildig、Akira Matsuda和Tee Parham。

## 特性

Haml的發展有四項原則。

### 使用者友好的標記

置標語言如果遵循下列特徵，那麼它則使用者友好：

- 語言能輕鬆理解
- 使用便捷（其實現）

### DRY

標記語言應堅持不重複自身（DRY）原則。它應該：

- 避免不必要的重複
- 專注於乾淨的代碼

### 精巧縮進

有良好縮進的標記語言可以改善外觀、使閱讀器易於讀取，並有助確定元素的開始與結束位置。

### 清晰結構

有清晰結構的標記語言有助於代碼維護和理解最終結果的邏輯。Haml在這方面是否提供了有差異的優勢，這點尚不清晰。

## 例子

Haml標記在語法上類似CSS。例如，Haml同樣使用`.`（點）表示CSS的類，使開發人員可以輕鬆使用這種標記。

### Hello, World例子

Haml的最簡單的Hello World實現像是這樣：

#### Haml作為命令行工具

```haml
%p{:class => "sample", :id => "welcome"} Hello, World!
```

得到這樣的HTML代碼：

```html
<p class="sample" id="welcome">Hello, World!</p>
```

為運行Haml代碼，必須已安裝，如使用下列命令 `Haml`以gem安裝：

```
gem install haml
```

Haml代碼若以`Hello.haml`為文件名保存，則可以這樣運行：

```
haml Hello.haml
```

#### Haml作為Ruby on Rails附加項

要用Ruby使用Haml，Ruby的`Gemfile`應該包含此行：

```
gem 'haml'
```

類似eRuby，Haml也可以訪問局部變量（在同一個文件中以Ruby代碼聲明）。此例子使用一個Ruby控制器文件為例。

- file: app/controllers/messages_controller.rb

```ruby
class MessagesController < ApplicationController
  def index
    @message = "Hello, World!"
  end
end
```

- file: app/views/messages/index.html.haml

```haml
#welcome
    %p= @message
```

將得到：

```html
<div id="welcome">
    <p>Hello, World!</p>
</div>
```

#### Haml作為Ruby模塊

要獨立於Rails和 ActionView使用Haml，安裝`haml` gem，在`Gemfile`中包含它，然後簡單的在Ruby腳本中導入`[Usage: require 'haml']`，或者以`-rubygems`標誌調用Ruby直譯器。

```ruby
welcome = Haml::Engine.new("%p Hello, World!")
welcome.render
```

輸出：

```html
<p>Hello, World!</p>
```

Haml::Engine是一個Haml類。

### 基本例子

Haml使用空格縮進（兩個空格）來表示標籤的嵌套和識別給定標籤的範圍。這取代打開、閉合的標籤對系統，從而符合DRY並使其看上去更清晰（容易閱讀）。下列例子展示了Haml與eRuby（嵌入式Ruby）的差異。

Haml｜ERB

```Haml
%div.category
    %div.recipes
        %h1= recipe.name
        %h3= recipe.category
    %div
        %h4= recipe.description
```

```HTML+ERB
<div class="category">
    <div class="recipes">
        <h1><%= recipe.name %></h1>
        <h3><%= recipe.category %></h3>
    </div>
    <div>
        <h4><%= recipe.description %></h4>
    </div>
</div>
```

由上述代碼示例呈現的HTML代碼如下所示：

```HTML
<div class="category">
    <div class="recipes">
        <h1>Cookie</h1>
        <h3>Desserts</h3>
    </div>
    <div>
        <h4>Made from dough and sugar. Usually circular in shape and has about 400 calories.</h4>
    </div>
</div>
```

兩者的關鍵差異是：

- Haml不像eRuby那樣，每個元素都有開始與結束
- eRuby語法看上去很像、更像HTML，而Haml更像CSS。
- Haml使用縮進來嵌套標籤元素，而eRuby使用與HTML相同的表示法
- 在Haml屬性中，`class`、`id`可以用`.`和`#`表示`class`和`id`關鍵字。Haml使用`%`標示一個HTML元素，而eRuby中使用`<>`。

### 嵌入Ruby代碼的例子

注意：這是一個簡單的預覽示例，可能不能體現此語言的目前版本。

```haml

%html{ :xmlns => "http://www.w3.org/1999/xhtml", :lang => "en", "xml:lang" => "en"}
  %head
    %title BoBlog
    %meta{"http-equiv" => "Content-Type", :content => "text/html; charset=utf-8"}
    %link{"rel" => "stylesheet", "href" => "main.css", "type" => "text/css"}
  %body
    #header
      %h1 BoBlog
      %h2 Bob's Blog
    #content
      - @entries.each do |entry|
        .entry
          %h3.title= entry.title
          %p.date= entry.posted.strftime("%A, %B %d, %Y")
          %p.body= entry.body
    #footer
      %p
        All content copyright © Bob
```

上述Haml產生這個XHTML：

```html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang='en' xml:lang='en' xmlns='http://www.w3.org/1999/xhtml'>
  <head>
    <title>BoBlog</title>
    <meta content='text/html; charset=utf-8' http-equiv='Content-Type' />
    <link href="/stylesheets/main.css" media="screen" rel="Stylesheet" type="text/css" />
  </head>
  <body>
    <div id='header'>
      <h1>BoBlog</h1>
      <h2>Bob's Blog</h2>
    </div>
    <div id='content'>
      <div class='entry'>
        <h3 class='title'>Halloween</h3>
        <p class='date'>Tuesday, October 31, 2006</p>
        <p class='body'>
          Happy Halloween, glorious readers! I'm going to a party this evening... I'm very excited.
        </p>
      </div>
      <div class='entry'>
        <h3 class='title'>New Rails Templating Engine</h3>
        <p class='date'>Friday, August 11, 2006</p>
        <p class='body'>
          There's a very cool new Templating Engine out for Ruby on Rails. It's called Haml.
        </p>
      </div>
    </div>
    <div id='footer'>
      <p>
        All content copyright © Bob
      </p>
    </div>
  </body>
</html>
```

## 實現

Haml的官方實現已經以Ruby插件形式內置在Ruby on Rails和Merb中，該Ruby實現也能夠獨立使用。Haml可以輕鬆配合其他語言使用。下列是各種語言對Haml的實現：

- hamlit (Ruby)
- HamlPy (Python)
- LuaHaml (Lua)
- MonoRail NHaml (ASP.NET)
- NHaml (.NET)
- Fammel (PHP)
- HAML-TO-PHP (PHP5)
- pHAML (PHP)
- phamlp (PHP)
- phpHaml (PHP5)
- Multi target HAML (PHP5.3)
- haml-js (JavaScript)
- Text::Haml (Perl)
- Scalate (Scala)
- JHaml (Java)
- Hart (Dart)
- cl-haml (Common Lisp)

## 外部連結

- Haml tutorial
- Learn Haml (basic)
- haml/haml
- phpHaml，面向PHP的Haml實現
- Haml Google討論組
- Haml 1.0，Ruby on Rails部落格上的公告

## 基本資料

- 著名校友： Natalie Weizenbaum、Hampton Catlin
- 設計者： Nick Walsh
- 開發者： Norman Clarke、 Matt Wildig、 Akira Matsuda、 Tee Parham、 Natalie Weizenbaum
- 實作語言：Ruby
- 軟體版本週期：5.2.1
- 軟體版本週期：2020年11月30日
- 作業系統：跨平台
- 許可證： MIT許可證、 Unspace Interactive
- 文件擴展名：.haml