How to render raw erb content on rails - ruby-on-rails

I've been trying to render a underscore.js template, that is just like ERB on some haml content.
But as the templates grow I dont want to do more like this
%script{:type => "text/template", :id => "my_template"}
:plain
<div><%= my_js_value %></div>
.....(other content)...
and instead of that I want to use partials to render inside it I wish to do something like:
%script{:type => "text/template", :id => "my_template"}
=render :file => "mytemplate.txt"
But that rendering tried to bind the ERB on it, and I've got errors for my_js_value
The only way I get to do this rendering is through that way:
%script{:type => "text/template", :id => "my_template"}
=render :text => File.read("#{Rails.root}/app/views/mycontroller/mytemplate.txt")
The last one worked for me, but I was looking for something better than that.
What do you suggest me to do instead of reading a file? Isn't there a "raw" option for render?
BTW this is on a rails 2.3.14 app

I don't know HAML to well yet but there is a raw option for rails. You can find the details at the link below:
<%= raw #user.name %>
http://api.rubyonrails.org/classes/ActionView/Helpers/OutputSafetyHelper.html

Related

How to store HTML tags into DB

I'm using Tiny Mce Editor 4.0.5 in Rails 2.
new.html
<% form_for #custom, :url=>"create" do |c| -%>
<%= c.text_area 'description' %>
<%= c.submit %>
<% end %>
Create Action:
CustomReport.create(params[:custom_report][:description])
After submission of form I get
undefined method `stringify_keys!'
Along that I tried
CustomReport.create(:description => params[:custom_report][:description])
But it doesn't store any HTML tags, so how I can store tags along to my DB?
Using xss_terminate plugin
And in my model CustomReport
xss_terminate :except => [:description]
easy and simple.
CustomReport.create(:description => params[:custom_report][:description])
should do the job for you, but Rails would naturally escape html tags, to stop rails from doing that you would need to call:
[html_safe](http://apidock.com/rails/String/html_safe)
or
raw
in your view on the string with the html tags (This is not safe practice, you should be sure the string is sincerely safe before considering this, as it can expose your app to attacks)

How do I render a string in Rails 3.2.1 (like render :partial - but everything but the filesystem)

I've made a small gist of it but basically what I'd like to do is
<%= render "this is a #{ I18n.translate(:a_string) }" %>
Saving snippets and/or entire views_templates (like views/mailers/some_model/regards.haml) in a database will allow me to building hierakies of templated views entirely from the web-interface - and saving the designers the round-trip to uploading files to the server, or in less pompous circumstances, having users edit minor screw-ups in templates themselves.
The above example does in no way portray the size of the problem - but point to the heart of it: how to render a template usually sitting in the filesystem, now being a text attribute on a Template model in the database.
You could render a partial for a generic template:
<%= render :partial => 'shared/string' %>
Then the partial template does the string rendering:
In shared/_string:
<%= "this is a #{ I18n.translate(:a_string) }" %>
Or you could have the database lookup for stored string done in the render call, and pass it in as a parameter:
<%= render :partial => 'shared/string', :locals => {:a_string => String.find(:string_id)} %>
In shared/_string:
<%= a_string %>
Or if your string contains ERB that needs to be executed try:
<%= ERB.new(a_string).result %>
Rendering a partial like this shouldn't cause the DoubleRender error.
The answer - at least to my question - is rather convoluted, and requires a great deal of digging into the innards of the Rails stack! I'm merely copy-cat'ing here: go see the complete answer in José Valím's book, Crafting Rails Applications!
With Rails 3.2.1 (possibly even before) templates (as in eg. app/views/posts/show.haml) are 'found' by something called a Resolver, and it is possible to add ones own Resolver - which I did :)
I added a
class ViewTemplate < ActiveRecord::Base
class Resolver < ActionView::Resolver
def find_templates(name, prefix, partial, details)
conditions = {
:path => normalize_path(name, prefix),
:locale => normalize_array(details[:locale]).first,
:display_format => normalize_array(details[:formats]).first,
:handler => normalize_array(details[:handlers]),
:partial => partial || false
}
ViewTemplate.where(conditions).map do |record|
initialize_template(record)
end
end
end
end
and then I told my ApplicationController to look at my own path first:
class ApplicationController < ActionController::Base
append_view_path ViewTemplate::Resolver.new
end
and finally I added a record to my ViewTemplate with
ViewTemplate.create( content: '=render "form"', path: 'posts/edit', display_format: 'html', handler: 'haml' )
and replaced the contents of my views/layouts/application.haml with:
= render 'posts/edit'
and huzzah :)
(well, more or less - there are of cause issues like variables, and scopes - but hey, nothing is perfect)

Trouble on using the i18n gem with partial template files

I am using Ruby on Rails 3.1 and I would like to know how to correctly handle internationalization related to partial template files. That is, ...
... in my app/views/users/flag.html.erb file I have:
<%= t('.test_key1') %>
<%= render :partial => "/users/flag_form" %>
... in my app/views/users/_flag_form.html.erb file I have:
<%= t('.test_key2') %>
If in my config/locales/views/users/en.yml file (note: I am organizing files as stated in the official RoR guide) I use
en:
users:
flag:
test_key1: Test 1 text
test_key2: Test 2 text
the Test 1 text is displayed in the "main" template (app/views/users/flag.html.erb) but the Test 2 text isn't for the partial template (app/views/users/_flag_form.html.erb). How could\should I solve this issue so to properly display the Test 2 text?
config/locales/en.yml
en:
users:
flag:
test_key1: Test 1 text
flag_form:
test_key2: Test 2 text
app/views/users/flag.html.erb
<%= t('.test_key1') %>
<%= render :partial => "/users/flag_form" %>
app/views/users/_flag_form.html.erb
<%= t('.test_key2') %>
NB:
Rails path to the view must match YAML path to the symbol. You need to create an entry at YAML file that matches the name of the view. Omit the trailing underscore since it's a partial.
Read more about lazy lookups
One way would be to using scope, instead of "lazy loading" using the full stop.
Something like this should work:
I18n.t :test_key2, :scope => 'users.flag'
or use:
I18n.t "users.flag.test_key2"
Lastly, you could even pass it to the partial as in
<%= render :partial => "/users/flag_form", :locals => { :test_key => t('.test_key1') } %>
You should also checkout the appendix section on this website as it might be listing something that I am missing:
https://web.archive.org/web/20120619002316/http://www.unixgods.org/~tilo/Rails/where_is_Rails_trying_to_lookup_L10N_strings.html
I wrote this. What do you think about it?
def translate_for_partials key, *args
I18n.t("#{params[:controller].gsub('/', '.')}.#{params[:action]}.#{key}", *args)
end
Is that bad to make such a method ?

Render a partial in rails using jquery

I am trying to setup a navigation bar on my home page that loads a partial into a div element when the user clicks on the links. I have followed the steps in this post and modified them as I thought I needed:
Rails 3 - link_to to call partial using jquery ajax
My code:
views/pages/home.html.erb:
<%= link_to "Files", :action => 'load_upload_partial', :remote => true %>
.
.
.
<div id="main_frame"></div>
pages_controller:
def load_upload_partial
respond_to do | format |
format.js {render :layout => false}
end
end
/views/uploads/load_upload_partial.js.erb:
$("#main_frame").html( "<%= escape_javascript( render( :partial => "/upload/upload_form" ) %>" );
The partial in this example is just a form. When I click on the link I get a blank page with this is the address bar:
http://localhost:3000/load_upload_partial?remote=true
This makes me think that link is not triggering an ajax GET request (if that's the correct terminology). If that is the case is there anything I need to be adding to my application.js file? I followed the railscast #136 on rails and jquery but couldn't figure out which bits of the application.js code applied to my case.
Any thoughts are much appreciated. Thanks. Tom
I now tend to avoid using RJS like you're intending to. I prefer creating js templates with tools like handlebars.
I only use ajax to get raw data and then recreate the partial client side. It's much better for server load and data transfer.
I think you have to change your link_to to:
<%= link_to "Files", {:action => 'load_upload_partial' }, remote => true %>
The problem is related to the method signature of link_to.
ran into this same problem - the hint was in the malformed html produced - take a look at the value of the href attribute of the tag produced by your code. I bet it looks funky. Here's the correct code:
<%= link_to "Files", your_path, action: 'load_upload_partial', remote: true %>
have you tried using .load() instead of .html()?
Also, try using this line instead:
$("#main_frame").html( "<%= escape_javascript( render( :partial => '/upload/upload_form' ) %>" );

Image tag generation in Rails

If working in Rails, what's the best way to define a helper function that generates many image tags? This function would then be called from a .erb file, producing a view.
In other words, something like
def build_view; image_tag("seg-433.png", :alt => "Shit don't work", :class => "round"); end
but that returns many tags.
Feel free to suggest a more idiomatic approach, I just started riding the Rails train, like, yesterday.
If you have an image model you could create a helper like this:
/app/helpers/my_controller_helper.rb
module MyControllerHelper
def bunch_of_image_tags
images = []
Image.all.each do |image|
images << image_tag(image.path, :alt => image.alt, :class => image.class)
end
images.join("<br/>")
end
end
You could also get a list of files from the file system, but I'm not sure what you would use for the alt tag in that case. Also look at paper_clip - https://github.com/thoughtbot/paperclip
You could render a collection of partials which contains everything you need for your image tag.
render :partial => "image", :collection => #images
the partial "image" being the one containing the image tag.
More at api.rubyonrails.org.

Resources