2011-06-10 63 views
2

動機和問題鏈子樣式的HTML標記

有用於使用紅寶石(ERB,HAML,建設者,引入markaby,tagz,...)HTML標記串幾個庫,但我有任何不滿意其中。原因在於,除了erb外,他們採用嵌套式而不是鏈式。而erb是一種在html中嵌入ruby而不是用ruby生成html的方法。

據我瞭解,紅寶石的一個美麗在於鼓勵使用鏈風格:

receiver.method1(args1).method2(args2). ... method_n(args_n) 

,而不是做一個嵌套的風格:

method_n(...method2(method1(receiver, args1), args2), ... args_n) 

但上面提到的庫(除了ERB )採取嵌套樣式(有時在塊參數的幫助下)。

我的想法

對於我自己而言,我寫了一個方法dom,這樣我可以在一個鏈條式的做HTML標記。當施加到一個字符串,這個例子

"This is a link to SO".dom(:a, href: "http://stackoverflow.com").dom(:body).dom(:html) 

將生成:

<html><body><a href="http://stackoverflow.com";>This is a link to SO</a></body></html> 

當應用於陣列,這樣的:

[ 
    ["a".dom(:td), "b".dom(:td)].dom(:tr), 
    ["c".dom(:td), "d".dom(:td)].dom(:tr) 
].dom(:table, border: 1) 

將生成

<table border="1";> 
    <tr> 
    <td>"a"</td> 
    <td>"b"</td> 
    </tr> 
    <tr> 
    <td>"c"</td> 
    <td>"d"</td> 
    </tr> 
<table> 

而,如果沒有明確的重新應用所有與只有一個方法dom完成ceiver(字符串和數組的結構域之外),

dom(:img, src: "picture.jpg", width: 48, height: 48) 

會產生

<img src="picture.jpg";width="48";height="48";/> 

注意。這比使用其他庫要簡單得多。它也很靈活,它不受html標籤庫存變化的影響;您只需使用符號參數指定。在其他庫中,每個標籤都有類和/或方法。更有甚者,不像erb,它是純粹的紅寶石。這不是需要轉換的DSL。

我實現

實現如下:

class Hash 
    def attribute 
     map{|k, v| %Q{#{k}#{ 
      case v 
      when TrueClass; '' 
      when Hash;  %Q{="#{v.subattribute}"} 
      else    %Q{="#{v}"} 
      end 
     ;}}}.join 
    end 
    def subattribute 
     map{|k, v| %Q{#{k}:#{v};}}.join 
    end 
end 

class Array 
    def dom type, hash = {} 
     "<#{type} #{hash.attribute}>\n#{join("\n").gsub(/^/, " ")}\n</#{type}>" 
    end 
end 

class String 
    def dom type, hash = {} 
     "<#{type} #{hash.attribute}>#{self}</#{type}>" 
    end 
end 

class Object 
    def dom type, hash = {} 
     "<#{type} #{hash.attribute}/>" 
    end 
end 

問題

  • 是否有已經是做了類似的事情,穩定的庫?
  • 這種方法會有什麼潛在的問題(特別是對於我的實施或以鏈式方法來做到這一點)?
  • 某些屬性採用布爾值,通常會鼓勵忽略它們。例如,<input type="text";readonly>而不是<input type="text";readonly="true">。在我目前的實現中,我可以通過傳遞true(最終不會使用它)作爲像dom(:input, type: "text", readonly: true)這樣的屬性的值,但這似乎是多餘的,也是我在代碼中有case語句的原因的一部分,使其變慢。有一個更好的方法嗎?
  • 實施有任何可能的改進嗎?

回答

1

haml和大多數其他嵌套的東西的主要原因是,它基本上很容易看你的HTML如何嵌套。我假設這個,但你真的編碼HTML或你做更多的後端的東西?其理由是,在嵌套的風格,你會看到你的元素是如何嵌套(這是對你很重要,如果你也寫樣式)

雖然這是寫

.dom(:body).dom(:html) 

很容易很難爲設計師看到HTML沒有映射如何流動,並試圖在他的頭,可視化,而:

%html 
    %body 

確實已經用一個眼神。

拿不出較長的例子:

"This is a link to SO".dom(:a, href: "http://stackoverflow.com").dom(:body).dom(:html) 

想,如果說客戶端它會容易些,或者你需要一個可點擊的圖片添加到鏈接?你會如何做到這一點?在HAML很容易爲:

%html 
    %body 
    %a{:href => "blah"} 
     = image_tag("image.png") 

另外,IMHO,對於每個HTML標籤寫入dom(:)是一樣乏味作爲寫入它的結束標記(其HAML和其他固定的)

同樣,這些只是我的意見從一個XHTML/CSS程序員(而不是一個紅寶石程序員的觀點)

最後,我也會認爲這可以變成一個社區維基或某事,因爲這不值得一個確切的答案並可能會產生許多像這樣的主觀因素。

+0

感謝您的回答。所以這個問題主要是偏好,而且沒有特別的性能問題?我可能會把它變成一個社區wiki,正如你所建議的那樣。我不做廣泛的HTML編碼。只是爲了我個人的事情。對我而言,鏈式比嵌套式更容易看到。如果結構複雜,我將使用一個數組,我將縮進它以使結構清晰。區別在於您是在開始處還是在結尾處創建嵌套標記的堆棧。我覺得後者對我自己來說更容易。 – sawa 2011-06-10 08:13:08

+0

(順便說一句,我還覺得逆轉波蘭符號比中綴或波蘭更舒服)。對於具有可點擊圖片的示例,我發現使用'image_tag(「image.png」)'替換最初的字符串沒有任何困難。我背後的一般想法是,標籤和屬性是修飾符,而不是主角。擁有主要字符串更自然,並且一步一步地修改它。對於「dom」很乏味的建議,我可以考慮一個較短的方法名稱。 – sawa 2011-06-10 08:13:38

+0

嗯,我想這將是一個有效的論點。但是,是的,如果你更喜歡反向波蘭符號,那更多的是我的偏好。 HTML編碼器通常需要找到嵌套,所以如果我反過來,我自己會丟失。我還想指出並問你將如何編碼子div,還是lis?你如何處理表格? – corroded 2011-06-10 08:19:52