2010-02-23 11 views
8

ich eine Zeichenfolge Vorlage haben, wie untenAuswertung Ketten-Templates

template = '<p class="foo">#{content}</p>' 

gezeigt möchte ich die Vorlage bewerten die auf den gegenwärtigen Wert der Variablen content genannt.

html = my_eval(template, "Hello World") 

Dies ist mein aktueller Ansatz für dieses Problem:

def my_eval template, content 
    "\"#{template.gsub('"', '\"')}\"" # gsub to escape the quotes 
end 

Gibt es einen besseren Ansatz zur Lösung dieses Problems?

EDIT

habe ich in dem Beispielcode HTML-Fragment über mein Szenario zu demonstrieren. Mein reales Szenario hat XPATH Vorlagen in einer Konfigurationsdatei festgelegt. Die Bindevariablen in der Vorlage werden ersetzt, um eine gültige XPATH-Zeichenfolge zu erhalten.

Ich habe über die Verwendung von ERB nachgedacht, entschied mich aber dagegen, da es ein Overkill sein könnte.

Antwort

11

Sie können eine Zeichenfolge so rendern, als ob es sich um eine erb-Vorlage handeln würde. Wenn Sie dies in einer Rake-Aufgabe verwenden, ist es besser, Erb.new zu verwenden.

template = '<p class="foo"><%=content%></p>' 
html = Erb.new(template).result(binding) 

Mit der Action Methoden ursprünglich vorgeschlagen, beinhaltet das Instanziieren eine Action :: Base Objekt und machen oder render_to_string senden.

+0

habe ich in der Vorlage HTML-Fragment, um das Szenario zu demonstrieren. Ich habe mehrere XPATH-Zeichenfolgen, die ersetzt werden müssen. Ich hatte über ERB nachgedacht, aber ich wollte etwas Leichtes. –

+0

Ich muss sagen, das ist eine faszinierende Lösung. Ich muss meinen Code in einer Rake-Aufgabe ausführen. Also muss diese Lösung vielleicht etwas optimiert werden. –

+0

Wenn Sie über eine Rake-Aufgabe sprechen, verwenden Sie besser Erb.new anstelle von ActionController # render. Die Lösung wurde aktualisiert, um dies zu berücksichtigen. – EmFi

3

Ich kann nicht sagen, dass ich wirklich einen dieser Ansätze empfehle. Dies ist, was Bibliotheken wie Erb sind, und sie wurden gründlich für alle Randfälle getestet, an die Sie noch nicht gedacht haben. Und alle anderen, die Ihren Code berühren müssen, werden es Ihnen danken. Wenn Sie jedoch keine externe Bibliothek verwenden möchten, habe ich einige Empfehlungen hinzugefügt.

Die Methode my_eval, die Sie einbezogen haben, funktionierte nicht für mich. Versuchen Sie so etwas wie dieses stattdessen:

template = '<p class="foo">#{content}</p>' 

def my_eval(template, content) 
    eval %Q{"#{template.gsub(/"/, '\"')}"} 
end 

Wenn Sie dies verallgemeinern wollen, dass diese so können Sie Vorlagen verwenden, die andere Variablen als content haben, können Sie es so etwas wie diese erweitern:

def my_eval(template, locals) 
    locals.each_pair{ |var, value| eval "#{var} = #{value.inspect}" } 
    eval %Q{"#{template.gsub(/"/, '\"')}"} 
end 

Diese Methode würde so genannt werden

my_eval('<p class="foo">#{content}</p>', :content => 'value of content') 

Aber wieder würde ich davon abraten, in diesem Fall Ihre eigenen zu rollen.

19

Sie können tun, was Sie mit String nativen Methode wollen '%':

> template = "<p class='foo'>%s</p>" 
> content = 'value of content' 
> output = template % content 
> puts output 
=> "<p class='foo'>value of content</p>" 

Siehe http://ruby-doc.org/core/classes/String.html#M000770

+0

Mind_completely_blown.gif – Trip

+1

Dies ist die bessere Antwort. – WattsInABox

+1

Es könnte sich lohnen, hinzuzufügen, dass Sie mit dieser Methode 'benannte Platzhalter' haben können, d. H. '" Profil:% {Name},% {Alter} "% {Name: 'John', Alter: 25}' – mrt

0

Dies ist auch eine nette Geschichte:

template = "Price of the %s is Rs. %f." 
# %s - string, %f - float and %d - integer 

p template % ["apple", 70.00] 
# prints Price of the apple is Rs. 70.000000. 

more here

0

Zu spät, aber ich denke, ein besserer Weg ist wie ruby-style-guide:

template  = '<p class="foo">%<content>s</p>' 
content_text = 'Text inside p' 
output = format(template , content: content_text)