मैं पटरियों में एक अलग प्रारूप के एक आंशिक कैसे प्रस्तुत करूं?


114

मैं एक JSON प्रतिक्रिया उत्पन्न करने की कोशिश कर रहा हूं जिसमें कुछ HTML शामिल हैं। इस प्रकार, मेरे पास है /app/views/foo/bar.json.erb:

{
  someKey: 'some value',
  someHTML: "<%= h render(:partial => '/foo/baz') -%>"
}

मैं इसे रेंडर करना चाहता हूं /app/views/foo/_baz.html.erb, लेकिन यह केवल रेंडर करेगा /app/views/foo/_baz.json.erb। पासिंग :format => 'html'मदद नहीं करता है।


जेम्स की विशेष समस्या की तुलना में प्रश्न शीर्षक बहुत अधिक सामान्य है। यदि आप अन्य समाधानों की तलाश कर रहे हैं, तो यहां एक नज़र डालें: stackoverflow.com/questions/7616097/…
miguelsan

जवाबों:


100

रल्स 3.2.3 से शुरुआत करते हुए, रेंडर करते समय: आंशिक (केवल respond_toब्लॉक के बाहर काम करता है )।

render formats: [ :html ]

के बजाय

render format: 'html'

मुझे लगता है कि संदर्भ के आधार पर अलग-अलग "सर्वश्रेष्ठ" उत्तर हो सकते हैं, इसलिए इस प्रश्न पर सार्थक रूप से उत्थान करना कठिन है, लेकिन इसने आरजेएस के भीतर से HTML टेम्पलेट को आसानी से प्रदान करने की मेरी आवश्यकता को एक ही नाम से एक के बाद एक उम्मीद है कि एक :formatविकल्प होगा काम। धन्यवाद!
चेस

1
यह रेल 5.0.2 के लिए भी काम करता है। हालाँकि, ध्यान दें कि आपको :content_typeकुछ मामलों में विकल्प को निर्दिष्ट करने की आवश्यकता हो सकती है - जैसे कि एक format.pdfब्लॉक के अंदर से HTML टेम्पलेट प्रदान करना केवल इसके साथ किया जा सकता है render "template", formats: [:html], content_type: "text/html"। मुझे इसकी आवश्यकता है क्योंकि मैं अपनी पुस्तकों के नमूनों को अपनी ईमेल सूची के सदस्यों के लिए सीधे डाउनलोड करने की अनुमति देता हूं - नियमित आगंतुकों को इसके बजाय साइनअप फॉर्म मिलता है।
माइकल ट्रोजनेक

64

क्या गलत है

render :partial => '/foo/baz.html.erb'

? मैंने सिर्फ एक एटम बिल्डर टेम्पलेट के अंदर से एक HTML ईआरबी आंशिक रेंडर करने के लिए यह कोशिश की और यह ठीक काम किया। वैश्विक चर के साथ कोई गड़बड़ करने की आवश्यकता नहीं है (हाँ, मुझे पता है कि उनके सामने "@" है, लेकिन यही वे हैं)।

आपका with_format &blockदृष्टिकोण हालांकि शांत है, और इसका फायदा है कि आप केवल प्रारूप को निर्दिष्ट करते हैं, जबकि सरल दृष्टिकोण टेम्पलेट इंजन (ईआरबी / बिल्डर / आदि) को भी निर्दिष्ट करता है।


26
इसका केवल नकारात्मक पक्ष यह है कि यदि आपका आंशिक अन्य धारावाहिक प्रस्तुत करता है तो यह तब तक विफल रहेगा जब तक आप उसके नाम पर ".html.erb" को शामिल करने के लिए अपने सभी रेंडर आंशिक कॉल को बदल नहीं देते।
क्रिसब्रेल ने

4
इस कार्य के लिए आपको अस्थायी इंजन को निर्दिष्ट करने की आवश्यकता नहीं है। (कम से कम रेल की तरह 3)। निम्नलिखित ठीक काम करता है: रेंडर (: आंशिक => "baz.html")
टिम हार्पर

1
यदि आप अलग अलग स्थानों के लिए अलग partials (जैसे है काम नहीं करता है baz.en.html.erb, baz.fr.html.erb) और आप चाहते हैं render :partial(, फ़ॉलबैक साथ आदि) सही एक को चुनने के लिए तर्क है।
जॉन

1
3.2.3 रेल के रूप में, मैं इस समाधान का उपयोग करते समय निम्नलिखित चेतावनी देख रहा हूं:DEPRECATION WARNING: Passing a template handler in the template name is deprecated. You can simply remove the handler name or pass render :handlers => [:erb] instead.
YWCA Hello

3
इस दृष्टिकोण का एक नकारात्मक पहलू यह है कि स्थानीयकरण foo.baz.html.[your_string]इसके बजाय देखेंगे foo.baz.[your_string]। zgchurc का उत्तर एक बेहतर समाधान है।
mbillard

32

रेल 3 के लिए, with_format ब्लॉक काम करता है, लेकिन यह थोड़ा अलग है:

  def with_format(format, &block)
    old_formats = formats
    self.formats = [format]
    block.call
    self.formats = old_formats
    nil
  end

रेल के साथ काम करता है 3.2.0 भी :)
गुच्ची

32

रेल 4 आपको एक प्रारूप पैरामीटर पारित करने की अनुमति देगा। तो आप कर सकते हैं

render(:partial => 'form', :formats => [:html])} 

ध्यान दें कि आप रेल 3 में भी कुछ ऐसा ही कर सकते हैं, लेकिन यह उस प्रारूप को किसी भी उप भाग में नहीं भेजेगा (यदि प्रपत्र अन्य भाग को कहता है)।

आपके पास रेल 3 की क्षमता हो सकती है रेलिंग 3 में कॉन्फिगरेशन / इनिशियलाइज़र / रेंडरर .rb:

class ActionView::PartialRenderer
  private
  def setup_with_formats(context, options, block)
    formats = Array(options[:formats])
    @lookup_context.formats = formats | @lookup_context.formats
    setup_without_formats(context, options, block)
  end

  alias_method_chain :setup, :formats
end

Http://railsguides.net/2012/08/29/rails3-does-not-render-partial-for-specific-format/ देखें


अजीब है, मुझे आश्चर्य है कि यह मेरे लिए एक रेल 3.2.19 ऐप में काम क्यों नहीं कर रहा है, आश्चर्य है कि मेरे ऐप में क्या अंतर है। ActionView रेंडर नहीं कर सकता: सम्मान करने के लिए आंशिक: arg, इस पैच के साथ भी कोई अंतर नहीं पड़ता है।
ज्रोचाइंड

29

रौनक की प्रतिक्रिया पर बिल्डिंग , मुझे निम्नलिखित होने का सबसे अच्छा समाधान मिला है:

in /app/helpers/application.rb:

def with_format(format, &block)
  old_format = @template_format
  @template_format = format
  result = block.call
  @template_format = old_format
  return result
end

/App/views/foo/bar.json में:

<% with_format('html') do %>
  <%= h render(:partial => '/foo/baz') %>
<% end %>

एक वैकल्पिक समाधान renderएक :formatपैरामीटर को स्वीकार करने के लिए फिर से परिभाषित करना होगा ।

मैं render :fileस्थानीय लोगों के साथ और बिना किसी रास्ते की जीत के काम नहीं कर सकता था ।


8
मेरे स्वाद के लिए भी हैक। संपूर्ण एक्सटेंशन निर्दिष्ट करने के लिए बेहतर है।
टिम हार्पर

1
रेल के लिए 3 zgchurch का उत्तर देखें।
lillq

25

रेल 3 में, व्यू में एक फॉर्मेट सरणी होती है, जिसका अर्थ है कि आप इसे [: मोबाइल,: html] देखने के लिए सेट कर सकते हैं। मोबाइल टेम्प्लेट खोजने के लिए डिफ़ॉल्ट रूप से सेट करना, लेकिन वापस जाना: html टेम्प्लेट। इसे स्थापित करने का प्रभाव आंतरिक भाग में कम हो जाएगा।

सबसे अच्छा, लेकिन अभी भी त्रुटिपूर्ण तरीका है, जो मुझे यह निर्धारित करने के लिए मिल सकता है कि इस लाइन को प्रत्येक पूर्ण मोबाइल टेम्पलेट के शीर्ष पर रखा जाए (लेकिन भाग नहीं)।

<% self.formats = [:mobile, :html] %>

दोष यह है कि आपको उस लाइन को कई टेम्पलेट्स में जोड़ना होगा। अगर किसी को application_controller.rb से एक बार इसे सेट करने का तरीका पता है, तो मुझे यह जानना अच्छा लगेगा। दुर्भाग्य से, यह आपके मोबाइल लेआउट में उस लाइन को जोड़ने के लिए काम नहीं करता है, क्योंकि लेआउट से पहले टेम्प्लेट प्रस्तुत किए जाते हैं।


यह समझाने के लिए धन्यवाद। मैंने इसे अन्यत्र उपयोग करके समाप्त कर दिया: stackoverflow.com/questions/47459724/…
जोशुआ पिंटर

16

ज़चर्च ने क्या लिखा, इस पर विस्तार से:

  • अपवादों को ध्यान में रखते हुए
  • तथाकथित ब्लॉक का परिणाम लौटाता है

सोचा कि यह उपयोगी हो सकता है।

def with_format(format, &block)
  old_formats = formats
  begin
    self.formats = [format]
    return block.call
  ensure
    self.formats = old_formats
  end
end

10

आपके पास दो विकल्प हैं:

1) का उपयोग करें render :file

render :file => "foo/_baz.json.erb"

2) @template_format वैरिएबल सेट करके html में टेम्प्लेट प्रारूप बदलें

<% @template_format = "html" %>
<%= h render(:partial => '/foo/baz') %>

1
<% @template_format = "html"%> ने मेरे लिए काम किया, क्योंकि मेरे आंशिक रूप से लोड किए गए अन्य धारावाहिकों में मुझे श्रृंखला के नीचे अन्य रेंडर अपडेट करने की आवश्यकता नहीं थी।
पेजेट्रिबे

5

मेरे पास 'api / item.rabl' नाम की एक फाइल थी और मैं इसे एक HTML दृश्य से रेंडर करना चाहता था, इसलिए मुझे इसका उपयोग करना पड़ा:

render file: 'api/item', formats: [:json]

( fileक्योंकि फ़ाइल के नाम में कोई अंडरस्कोर formatsनहीं है , और नहीं format(और पास और सरणी))


2

ऐसा लगता है कि एक formatsविकल्प पास करना नए रेल संस्करण में इसे ठीक से प्रस्तुत करना होगा, कम से कम 3.2:

{
  someKey: 'some value',
  someHTML: "<%= h render('baz', formats: :html) -%>"
}

1

मैं इस धागे के पार आया था जब मैं एक XML को दूसरे xml.builder दृश्य फ़ाइल में आंशिक रूप से रेंडर करने की कोशिश कर रहा था। निम्नलिखित यह करने का एक अच्छा तरीका है

xml.items :type => "array" do
    @items.each do |item|
        xml << render(:partial => 'shared/partial.xml.builder', :locals => { :item => item })
    end
end

और हाँ ... पूर्ण फ़ाइल नाम यहाँ भी काम करता है ...


यह उसी आंतरिक-आंशिक-समस्या से ग्रस्त है जिसका उल्लेख @chrisrbailey ने एक अन्य उत्तर में किया है: यदि आप जिसे पूर्ण फ़ाइल नाम से पुकारते हैं, वह स्वयं ही पूर्णांक (प्रत्येक के लिए पूर्ण फ़ाइल नाम निर्दिष्ट किए बिना) का उपयोग करता है, तो वह विफल हो जाएगा।
जेम्स ए। रोसेन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.