2010-08-29 27 views
6

Bu hafta sonu Sıvı şablonlama motoruyla uğraşıyorum ve aşağıdakilerin mümkün olup olmadığını merak ediyorum.Sıvı şablonlarında örnek örnek yöntemlerine geçirme değişkenleri

Blog modelinde latest_posts yöntemini varsa, en son N yayınlarını almak için bir tamsayı geçebiliyorum. Bu yöntemi sıvı bir şablonda kullanmak mümkün mü? Örneğin

: Yukarıdaki basitleştirilmiş örnekte

class Blog 

    has_many :posts 

    def latest_posts(n) 
    posts.latest(n) # using a named scope 
    end 

    def to_liquid(*args) 
    { 
     'all_posts' => posts.all, # allows me to use {% for posts in blog.all_posts %} 
     'last_post' => post.last, # allows me to use {% assign recent = blog.last_post %} 
     'latest_posts' => posts.latest_posts(args[0]) # how do I pass variables to this? 
    } 
    end 

end 

, benim sıvı şablonlarında ben blog.all_posts ve blog.last_post, kullanın ama blog.latest_posts: 10 böyle bir şey yapacağını nasıl hiçbir fikir sahibi olabilirsiniz.

Kimse doğru yöne işaret edebilir mi?

Düşündüğüm bir fikir, bir Sıvı filtresi oluşturmak ve hem Blog nesnesini hem de bunun tam sayısını iletmekti. şöyle birşey:

{% for post in blog | latest_posts(10) %} 
  • ama denemedim bu henüz hissi gibi karanlık biraz etrafında bıçaklama gibiyim. Daha deneyimli Sıvı kullanıcılardan bazı yardımlar için teşekkür ederiz.

cevap

9

, ben Liquid groups pages belgelenen bir çözüm buldu. Bir LatestPostsDrop - -

Esasen, ben en son gönderileri için bir damla oluşturmak için gerekli ve tür before_method yöntemini kullanarak kendisine bir değişken geçirmeden kesmek.İşte tam çözüm:

class Blog 

    has_many :posts 

    def latest_posts 
    LatestPostsDrop.new(posts) 
    end 

    def to_liquid 
    { 
     'all_posts' => posts.all, 
     'last_post' => post.last, 
     'latest_posts' => latest_posts 
    } 
    end 

end 

class LatestPostsDrop < Liquid::Drop 

    def initialize(posts) 
    @posts = posts 
    end 

    def before_method(num) 
    @posts.latest(num) # Post.latest is a named scope 
    end 

end 

yukarıdaki yaparak, gibi bir şey kullanarak son yayınların herhangi bir sayı arasında yineleme sağlar:

{% for post in blog.latest_posts.10 %} # the last attribute can be any integer 
    <p>{{ post.title }}</p> 
{% endfor %} 

Biraz hacky görünüyor ama işe yarıyor :)

+1

before_method hakkında bilgi için teşekkürler. Bunun biraz hacky olduğunu kabul ediyorum, ancak sıvının odaklanmasının şablonun arkasındaki makineler değil, şablon olduğunu unutmayın. Buradaki amaç, diğer insan gruplarının, verilerin yararlı/sofistike görüntülerini güvenli bir şekilde yapmak için sadece şablon dilini kullanmasını sağlamaktır. Bunun için çok iyi olduğunu düşünüyorum - hem müşterilerim hem de müteahhitlerimiz Sıvı şablonlarını SAAS verilerimle kullanıyorlar. –

5

Bence sıvı fantastik bir şablon sistemidir. Tebrik etmek/kullanmak için tebrikler.

Varsayılan olarak, modelin yöntemlerinin hiçbiri sıvı şablonunda mevcut değildir. Bu iyi birşey. Daha sonra hangi metotların kullanılacağını belirtin. (A beyaz liste.)

Posta listesinde gönderilen Modül için bir uzantı kullanırım. Tam uzantı aşağıda. Sınıflara ve modüllere basit bir #liquid_methods yöntemi ekleyerek sizin için Liquid :: Drop oluşturma işlemlerini gerçekleştirir.

Ardından, modellerinde, sadece yapın:

class Blog 
    # id 
    # name 
    has_many :posts 

    def latest_posts(n) 
    posts.latest(n) # using a named scope 
    end 

    def latest_10_posts;latest_posts(10); end 

    liquid_methods :id, :name, :posts, :latest_10_posts 
end 

Sana bir damla içine params'ı geçebilir eğer hazırlıksız nasıl/emin değilim. Sıvı posta listesine sorunuz. Bence yapabilirsin.

Eklendi: Şimdi sorunuzu tekrar okumak ve gerçekten yönteme bu param göndermek istediğiniz görüyoruz. Sıvı filtresine birden fazla argüman/parametre gönderebilirsiniz. Yani bir filtre olabilir:

# Define as a Liquid filter 
def latest_posts(blog, n) 
    blog.latest(n) 
end 

# then call the filter in a template: 
{{ blog2 | latest_posts: 10 }} 
# Note that the second param is after the filter name. 

Bu örnekte, aynı zamanda çok Gönder sınıfında sıvı yöntemler bildirmesine gerektiğini unutmayın.

İşte modül uzantısı. benim kendi soru cevaplama

# By dd -- http://groups.google.com/group/liquid-templates/browse_thread/thread/bf48cfebee9fafd9 
# This extension is usesd in order to expose the object of the implementing class 
# to liquid as it were a Drop. It also limits the liquid-callable methods of the instance 
# to the allowed method passed with the liquid_methods call 
# Example: 
# 
# class SomeClass 
# liquid_methods :an_allowed_method 
# 
# def an_allowed_method 
#  'this comes from an allowed method' 
# end 
# def unallowed_method 
#  'this will never be an output' 
# end 
# end 
# 
# if you want to extend the drop to other methods you can define more methods 
# in the class <YourClass>::LiquidDropClass 
# 
# class SomeClass::LiquidDropClass 
#  def another_allowed_method 
#  'and this is another allowed method' 
#  end 
# end 
# end 
# 
# usage: 
# @something = SomeClass.new 
# 
# template: 
# {{something.an_allowed_method}}{{something.unallowed_method}}{{something.another_allowed_method}} 
# 
# output: 
# 'this comes from an allowed method and this is another allowed method' 
# 
# You can also chain associations, by adding the liquid_method calls in the 
# association models. 
# 
class Module 

    def liquid_methods(*allowed_methods) 
    drop_class = eval "class #{self.to_s}::LiquidDropClass < Liquid::Drop; self; end" 
    define_method :to_liquid do 
     drop_class.new(self) 
    end 

    drop_class.class_eval do 
     allowed_methods.each do |sym| 
     define_method sym do 
      @object.send sym 
     end 
     end 
     def initialize(object) 
     @object = object 
     end 
    end 

    end 
end 
+0

Merhaba Larry, girişiniz için teşekkürler. Eklediğin öneriyle uğraştım ama tatmin edici bir şekilde çalışamam. '{{blog | latest_posts: 10}} 'son 10 yazıyı gerçekten iade ederdi. Ancak, bunların üzerinden nasıl yinelenebileceğiyle ilgili çalışma yapamadım: "(blog | latest_posts: 10)%}' daki (veya bu temadaki varyasyonlar) yayınlar için%, yalnızca gönderiler boyunca yinelenmedi. Ancak, burada bir çözüm buldum (http://groups.google.com/group/liquid-templates/browse_thread/thread/90ae684e754b6de5/1b080bcff95ed59d?lnk=gst&q=pass+variable+to+drop#1b080bcff95ed59d) aşağıda bir cevap koyacağım ... – aaronrussell

+0

Filtrenin sonuçlarını bir değişkende saklamak zorunda olduğumu buldum ve sonra değişken üzerinde yineleyebilirim: '{% assign latest_blog_posts = blog | latest_posts:% 10} '' sonra '% post in son_blog_posts%} ...' –