2010-08-29 12 views
6

में मॉडल उदाहरण विधियों के लिए वेरिएबल्स पास करना मैं इस सप्ताह के अंत में तरल टेम्पलेटिंग इंजन के साथ खेल रहा हूं, और मुझे आश्चर्य है कि निम्नलिखित संभव है या नहीं।तरल टेम्पलेट्स

मैं एक Blog मॉडल है, जो मैं नवीनतम एन पदों प्राप्त करने के लिए एक पूर्णांक पारित कर सकते हैं में एक latest_posts विधि है कहो। क्या एक विधि को तरल टेम्पलेट में उपयोग करना संभव है?

उदाहरण के लिए:

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 

ऊपर सरल उदाहरण में, मेरा तरल टेम्पलेट्स में मैं blog.all_posts और blog.last_post, का उपयोग लेकिन पता नहीं कैसे मैं blog.latest_posts: 10 की तरह कुछ भी कर हो सकता है।

क्या कोई मुझे सही दिशा में इंगित कर सकता है?

एक विचार मैंने सोचा था कि एक तरल फ़िल्टर बनाना था और ब्लॉग ऑब्जेक्ट और उसमें एक पूर्णांक दोनों को पास करना था। की तरह कुछ:

{% for post in blog | latest_posts(10) %} 
  • लेकिन प्रयास नहीं किया है कि अभी तक लग रहा है के रूप में की तरह मैं अंधेरे कुछ ही देर में चारों ओर चोट पहुंचा रहा हूँ। अधिक अनुभवी तरल उपयोगकर्ताओं से कुछ मदद की सराहना करेंगे।

उत्तर

9

यहाँ मेरे अपने प्रश्न का उत्तर देना, मैं एक समाधान Liquid groups pages में दस्तावेज मिल गया।

अनिवार्य रूप से, मुझे नवीनतम पोस्ट के लिए एक बूंद बनाने की आवश्यकता है - LatestPostsDrop - और before_method विधि का उपयोग करके एक चर को पास करने के लिए हैक की तरह।यहाँ पूर्ण समाधान है:

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 

ऊपर कर, आप की तरह कुछ का उपयोग कर नवीनतम पोस्ट के किसी भी संख्या के माध्यम से चीज़ों को दोहरा सकते:

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

यह एक सा hacky लगता है, लेकिन यह काम करता है :)

+1

पहले_method पर जानकारी के लिए धन्यवाद। मैं मानता हूं कि यह थोड़ा हैकी है लेकिन याद रखें कि तरल पदार्थ के लिए फोकस टेम्पलेट है, न कि टेम्पलेट के पीछे मशीनरी। इसका इरादा लोगों के अन्य सेटों को सुरक्षित तरीके से डेटा के उपयोगी/परिष्कृत दृश्य बनाने के लिए केवल टेम्पलेट भाषा का उपयोग करने के लिए सक्षम करना है। मुझे लगता है कि इसके लिए यह बहुत अच्छा है - मेरे ग्राहक और उनके ठेकेदार दोनों मेरे एसएएएस डेटा के साथ तरल टेम्पलेट का उपयोग करते हैं। –

5

मुझे लगता है कि तरल एक शानदार टेम्पलेट सिस्टम है। जांच/इसका उपयोग करने पर बधाई।

डिफ़ॉल्ट रूप से, तरल टेम्पलेट में मॉडल के किसी भी तरीके उपलब्ध नहीं हैं। यह एक अच्छी बात है। फिर आप निर्दिष्ट करें कि कौन सी विधियां उपलब्ध होंगी। (एक सफेद सूची।)

मैं मेलिंग सूची पर भेजा गया मॉड्यूल के लिए एक एक्सटेंशन का उपयोग करता हूं। पूरा विस्तार नीचे है। यह कक्षाओं और मॉड्यूल के लिए एक सरल #liquid_methods विधि जोड़कर आपके लिए तरल :: ड्रॉप निर्माण को संभालता है।

फिर, अपने मॉडल में, बस कार्य करें:

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 

मुझे यकीन है कि इसी समय कैसे/तुम एक बूंद में पैरामीटर पारित कर सकते हैं, तो नहीं कर रहा हूँ। तरल मेलिंग सूची पर पूछें। मै सोचता हूँ तुम कर सकते हो।

जोड़ा गया: मैं अब अपने प्रश्न को फिर से पढ़ सकते हैं और देखते हैं कि आप वास्तव में विधि है कि परम में भेजना चाहते हैं। आप तरल फ़िल्टर में एक से अधिक तर्क/पैरामीटर भेज सकते हैं। तो तुम एक फिल्टर हो सकता है:

# 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. 

इस उदाहरण में, यह भी याद रखें कि आप भी पोस्ट कक्षा में तरल तरीकों घोषित करने के लिए की आवश्यकता होगी।

यहां मॉड्यूल एक्सटेंशन है।

# 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

हाय लैरी, आपके इनपुट के लिए धन्यवाद। मैंने आपके अतिरिक्त सुझाव के साथ कोशिश की लेकिन इसे संतोषजनक तरीके से काम नहीं कर सका। '{{ब्लॉग | latest_posts: 10}} 'वास्तव में नवीनतम 10 पोस्ट वापस कर देगा। हालांकि, मैं उनके माध्यम से पुन: प्रयास करने के लिए काम नहीं कर सका: '{% | पोस्ट में नवीनतम पदों के लिए {ब्लॉग | नवीनतम_पोस्ट: 10)%} '(या उस विषय के साथ विविधताएं) सिर्फ पोस्ट के माध्यम से पुनरावृत्त नहीं हुईं। हालांकि, मुझे एक [समाधान यहां] मिला है (http://groups.google.com/group/liquid-templates/browse_thread/thread/90ae684e754b6de5/1b080bcff95ed59d?lnk=gst&q=pass+variable+to+drop#1b080bcff95ed59d) कि मैं नीचे एक जवाब डालूंगा ... – aaronrussell

+0

मुझे पता चला कि मुझे फ़िल्टर के परिणामों को एक चर में स्टोर करने की आवश्यकता है और फिर मैं चर पर फिर से चला सकता हूं: '{% असाइन नवीनतम_ब्लॉग_पोस्ट्स = ब्लॉग | नवीनतम_पोस्ट: 10%} 'फिर' {% नवीनतम_ब्लॉग_पोस्ट%} में पोस्ट के लिए ... ' –

संबंधित मुद्दे