【說明】本系列博文是依據 Emmet 官方文檔翻譯的,原文地址為:http://docs.emmet.io/,部分內容已經在博主之前的博文中節選過,為方便已經收藏過之前博文的朋友,沒有刪除這些博文,僅將其完整的收錄於本系列中。
過濾器
過濾器是在將縮寫展開輸出到編輯前進行編輯的特殊的提交處理器。為了更好地理解示過濾器如何工作,我們製作了一個簡單的教程。
下面的編輯器中輸入並展開了:#content>p.title
正像所期望的那樣,展開的結果是如下的 HTML 程式碼:
<div id="content"> <p class="title"></p></div>
現在,再來看展開: #content>p.title|e
。將得到稍有不同的結果:
<div id="content"> <p class="title"></p></div>
只是通過在標籤名添加管道符應用了 e
(轉碼) 過濾器。這個過濾器在 Emmet 將輸出傳遞給編輯器前,將所有的非 XML 安全的符號轉碼為實體符號。如果展開:#content>p.title|e|e,將得到:
&lt;div id="content"&gt; &lt;p class="title"&gt;&lt;/p&gt;&lt;/div&gt;
這是一段雙轉碼的代碼 (例如,應用了兩次 e
過濾器)。正如所展示的那樣,我們可以按我們想要的次數在縮寫上應用多個我們想要使用的過濾器。
還有更多有趣的事可做。嘗試編寫: #content>p.title|haml
#content %p.title
是不是漂亮? 竟然可以按照 HAML 模板展開縮寫!
如上所示,過濾器是 Emmet 的關鍵概念。用瀏覽器的 DOM 模型打個比方,每次展開縮寫,首先要做的是是擷取轉換成的樹,然後逐步過慮每個樹結點並編輯輸出結果。過濾器能夠做任何事:從為 CSS 規則末尾添加空格到輸出高文法的輸出結果等複雜任務。甚至將 HTML 輸出定義成 html
過濾器。
隱式調用過濾器
通過向縮寫後附加管道符,可以顯式地為縮寫應用過濾器。但過濾器也可以隱式調用,這依賴於當前編輯的文檔的類型。是否不想每次都在 HAML 文檔中的縮寫後添加 |haml?
預設的過濾器定義在 snippets.json 檔案中每個文法的 filters
一節:
{ ... "html": { ... "filters": "html" }}
如果沒有這一節,預設應用 html
過濾器。如果想要在預設情況下應用多個過濾器,可以在 filters
一節為寫下以逗號或管理符間隔的過濾器列表:
{ ... "html": { ... "filters": "html, e" }}
現在,在 HTML 文檔中,每次展開縮寫,html
和 e
過濾器都將被應用。
小心! snippets.json
檔案中,必須將 html
或 haml 文法過濾器放在預設過濾器的第一位,否則,就會得到空白的輸出,這是因為文法過濾器被定義為主輸出結果。
可用的過濾器HAML 文法:
haml
HAML 文法過濾器:按 HAML 模板輸出縮寫。它是 HAML 檔案的預設過濾器。
HTML 文法:
html
HTML 文法過濾器:按 HTML/XML 標籤輸出縮寫。除了 HAML 檔案以外所有地方的預設過濾器。
轉碼:
e
對非 XML 安全的字元進行轉碼,如: <
、 >
和 &。
例如: div#header|e
將展開成 <div id="header"></div>
。這個過濾器對技術部落格/技術作家極為有用,因為他們想要在 web 網站中展示程式碼片段(當然,需要在 CMS 中添加 Emmet 支援)。
注釋標籤:
c
為重要的標籤添加環繞注釋。預設的, “重要標籤” 是指那些帶有 id
和/或 class 屬性的標籤。
div>div#page>p.title+p|c
將展開為:
<div> <div id="page"> <p class="title"></p> <!-- /.title --> <p></p> </div> <!-- /#page --></div>
這個過濾器有幾個可以重定義的選項:
filter.commentTrigger:可以觸發注釋輸出的屬性。預設是
id、class。
filter.commentAfter:
: 即將被放在“重要標籤”後面的 ERB-模板風格 的註解。預設值是 \n<!-- /<%= attr("id", "#") %><%= attr("class", ".") %> -->
filter.commentBefore:即將被放在“重要標籤”前面的
ERB-模板 風格的註解。預設為空白。
XSL 調整:
xsl
這個過濾器在 <xsl:variable>
和 <xsl:with-param>
標籤包含子節點時從中刪除 select
屬性。例如:
ap>wp
將展開成:
<xsl:apply-templates select="" mode=""> <xsl:with-param name="" select=""/></xsl:apply-templates>
而
ap>wp>call
將輸出
<xsl:apply-templates select="" mode=""> <xsl:with-param name=""> <xsl:call-template name=""/> </xsl:with-param></xsl:apply-templates>
預設應用於 XSL 檔案。
單行:
s
將縮寫展開成單選代碼。在 JavaScript、Python、Ruby 等程式設計語言中編寫模板字串時有用。例如:
ul>li*4|s
將展開成:
<ul><li></li><li></li><li></li><li></li></ul>
刪除行標記:t
僅在包圍縮寫中有用:從被包圍的行中刪除行標記,參見 “Wrap with Abbreviation” 動作。
Yandex BEM/OOCSS
如果以特定的 OOCSS-風格、 Yandex’s BEM 風格編寫 HTML 和 CSS 代碼,就肯定會喜歡這個過濾器。它提供了一些別名,並且自動在 class 中插入註解區塊和注釋名。
簡言之,BEM 引入了三種類型的 CSS class:塊、元素和修飾符。塊是是 HTML 頁中語言部分的命名空間,例如 search-form
。元素是其中的一段,例如 serch-form__query-string
。修飾符定義了塊變數和元素變數: search-form_wide
或 search-form_narrow
。class 名中的元素使用 __
(兩個底線)分隔,修飾符用 _
(一個底線分隔)。
BEM/OOCSS 是維護和複用 CSS 的好辦法。即使在 Emmet 縮寫的協助下,在普通的 HTML 中編寫這些類名仍然可能很乏味。必須在每個縮寫元素中重複書寫相同的塊和元素名:
form.search-form.search-form_wide>input.search-form__query-string+input:s.search-form__btn.search-form__btn_large
bem
過濾器允許製造一個縮寫分揀器:
form.search-form._wide>input.-query-string+input:s.-btn_large|bem
它是如何工作的呢?
BEM 過濾器引入了幾個 class 名首碼的概念類型: __
或 -
作為元素首碼,而 _
則是修飾符首碼。任何時候遇到帶有這些首碼的類名,過濾器都將處理如下的事情:
- 如果 class 名帶有元素首碼,過濾器將從從父節點中解析塊名;
- 如果 class 名帶有修飾符首碼,過濾器將從當前節點或父節點中解析塊名、元素名;
- 如果同時帶有塊和修飾符首碼,過濾器將從父節點中解析塊名,並輸出元素上的所有 “未修飾的” 和 “已修飾的” class;
- 如果使用多個元素修飾,過濾器將從 nth 父節點中解析塊名。
下面是幾個樣本:
Abbreviation |
Output |
.b_m |
<div class="b b_m"></div>
|
.b_m1._m2 |
<div class="b b_m1 b_m2"></div>
|
.b>._m |
<div class="b"> <div class="b b_m"></div></div>
|
.b1>.b2_m1>.-e1+.--e2_m2 |
<div class="b1"> <div class="b2 b2_m1"> <div class="b2__e1"></div> <div class="b1__e2 b1__e2_m2"></div> </div></div>
|
記住,要讓 bem
過濾器總是 HTML 文法過濾器的第一個。