2012-03-05 12 views
4

複数のオプションのトークンがパラメータとして渡される場合、Rubyで書かれたカスタムLiquidタグをネストできますか?この質問は、関連する例を提示せずに説明することはむしろ困難です。この質問があまりにも特定のユースケースであるように見える場合は、私を許してください。オプションのパラメータを持つ2つのカスタムLiquidタグを入れ子にする

タグを解析するカスタムLiquidタグを作成するOctopress(jekyll fork)のソースである以下のルビコードが与えられています。

# Title: Simple Image tag for Jekyll 
# Authors: Brandon Mathis http://brandonmathis.com 
#   Felix Schäfer, Frederic Hemberger 
# Description: Easily output images with optional class names, width, height, title and alt attributes 
# 
# Syntax {% img [class name(s)] [http[s]:/]/path/to/image [width [height]] [title text | "title text" ["alt text"]] %} 
# 
# Examples: 
# {% img /images/ninja.png Ninja Attack! %} 
# {% img left half http://site.com/images/ninja.png Ninja Attack! %} 
# {% img left half http://site.com/images/ninja.png 150 150 "Ninja Attack!" "Ninja in attack posture" %} 
# 
# Output: 
# <img src="/images/ninja.png"> 
# <img class="left half" src="http://site.com/images/ninja.png" title="Ninja Attack!" alt="Ninja Attack!"> 
# <img class="left half" src="http://site.com/images/ninja.png" width="150" height="150" title="Ninja Attack!" alt="Ninja in attack posture"> 
# 

module Jekyll 

class ImageTag < Liquid::Tag 
    @img = nil 

    def initialize(tag_name, markup, tokens) 
    attributes = ['class', 'src', 'width', 'height', 'title'] 

    if markup =~ /(?<class>\S.*\s+)?(?<src>(?:https?:\/\/|\/|\S+\/)\S+)(?:\s+(?<width>\d+))?(?:\s+(?<height>\d+))?(?<title>\s+.+)?/i 
     @img = attributes.reduce({}) { |img, attr| img[attr] = $~[attr].strip if $~[attr]; img } 
     if /(?:"|')(?<title>[^"']+)?(?:"|')\s+(?:"|')(?<alt>[^"']+)?(?:"|')/ =~ @img['title'] 
     @img['title'] = title 
     @img['alt'] = alt 
     else 
     @img['alt'] = @img['title'].gsub!(/"/, '&#34;') if @img['title'] 
     end 
     @img['class'].gsub!(/"/, '') if @img['class'] 
    end 
    super 
    end 

    def render(context) 
    if @img 
     "<img #{@img.collect {|k,v| "#{k}=\"#{v}\"" if v}.join(" ")}>" 
    else 
     "Error processing input, expected syntax: {% img [class name(s)] [http[s]:/]/path/to/image [width [height]] [title text | \"title text\" [\"alt text\"]] %}" 
    end 
    end 
end 
end 
Liquid::Template.register_tag('img', Jekyll::ImageTag) 

何[<img>]要素のために同じ機能を発揮するために別のカスタムタグを作成するための最良の方法ですが、[<figure>]要素内にネストされ、おそらくのような画像ALTの説明や追加のトークンを表示します[<figcaption>]潜在的にそれ自身のリンクを含む可能性のある要素?あるいは、それが中心に置かれるべきかどうかを言う要素の一連のクラス名さえあるかもしれません。

<figure class=center> 
    <img src="/contra.jpg" alt="One of the greatest nintendo games of all time"> 
    <figcaption>Up Up Down Down Left Right Left Right B A B A <a href="http://www.youtube.com/contramoves/">Watch on Youtube</a></figcaption> 
</figure> 

が、それは巣にカスタムリキッドタグ可能であると仮定して、私が間違っている:

は、言い換えれば、私は、出力は次のようになりたいのでしょうか?私は、既存のコードをもう一度書き直して、[<figcaption>]の追加属性を扱うためにわずかに修正することができたと確信していますが、これはむしろ冗長でDRYの原則と思われます。現在のように、私は、既存のクラスがオプションのトークンそれ自体を取るとすれば、可能な追加のトークンをどのように考慮することができるかについてむしろ混乱しています。

+0

誰もそれに亀裂を入れたくない場合は、誰かが質問をより明確にする方法についてアドバイスできますか?とても有難い! – saneshark

答えて

4

私がする必要があったのは、液体タグではなく、液体ブロックを作成することでした。この解決策は、[<figure>]タグに対して正確に予想されるものである図の範囲内で、他の液体タグおよび理論上の他の液体ブロックを入れ子にすることを可能にする。

Markdownは現在HTML5をサポートしていないので、このLiquidベースのソリューションは素晴らしい妥協点です。

# Example: 
# 
# {% fig This is my caption! http://site.com/link.html Link Caption %} 
# {% img center http://site.com/images/mylinks.png A collection of my favorite links %} 
# {% endfig %} 
# 
# Output: 
# 
# <figure class='center'> 
# <img class="center" src="http://site.com/images/mylinks.png" title="A collection of my favorite links" > 
# <figcaption>This is my caption!<a href='http://site.com/link.html'>Link Caption </a></figcaption> 
#</figure> 
# 
# 

module Jekyll 

    class FigureTag < Liquid::Block 
    include TemplateWrapper 
    CaptionUrl = /(\S[\S\s]*)\s+(https?:\/\/\S+)\s+(.+)/i 
    Caption = /(\S[\S\s]*)/ 
    def initialize(tag_name, markup, tokens) 
     @title = nil 
     @caption = nil 
     if markup =~ CaptionUrl 
     @caption = "\n\t\t<figcaption>#{$1}<a href='#{$2}'>#{$3}</a></figcaption>\n\t" 
     elsif markup =~ Caption 
     @caption = "\n\t\t<figcaption>#{$1}</figcaption>\n\t" 
     end 
     super 
    end 

    def render(context) 
     output = super 
     fig = super.join 
     source = "\t<figure class='center'>\n\t\t" 
     markdown = RDiscount.new(fig.lstrip).to_html[/<p>(.+)<\/p>/i] 
     source += $1 
     source += @caption if @caption 
     source += "</figure>" 
     source = safe_wrap(source) 
     source 
    end 
    end 
end 

Liquid::Template.register_tag('fig', Jekyll::FigureTag) 
関連する問題