RoR - Dynamic body (part) in mailer - ruby-on-rails

My goal is to retrieve the a mailer's body from db.
I created a model that store the body in db, with simple text, html tag and variable (as in the original static mailer's body) and changed the piece of body in mailer's view.
I tried with <%= raw #body_db.html.html_safe %> , the text is correctly imported from db, but when i receive the mail there isn't variables's substitution.
Example:
if in DB template i have
Cliente: <%= #nome_cliente %>, in my mail i receive Cliente: <%= #nome_cliente %> but i want Cliente: Jon Doe
P.S. :
All variables are ok using 'static' text
Can someone help me?
Thanks

Great !!!
I found solution!
Without using partial, I used this in my view, so i can include ERB in DB !!
<%= render :inline => #body_db.html.html_safe, :layout => false %>
Thanks to all !

Related

Rails Action Mailer Issue

Im trying to send HTML code as a variable using ActionMailer's ( Ruby on Rails default mailer ).
I have an example bellow with an easy variable ( thats also HTML code )
def newsletter // ==> my method to send
#template = "<h1>wait what ?</h1>"
mail(to: "email#test.com", subject: "test de newsletter")
end
newsletter.html.erb // ==> my html.erb file
<%= #template %>
<h1>wait what ?</h1>
the result I get is :
<h 1 > wait what ? </ h 1> // ==> cannot write h1 here tho
<b>wait what ?</b>
// ==> in the terminal the mail looks like this
<body>
<h1>wait what ?;/h1>
<h1>wait what ? </h1>
</body>
Maybe I can upload an entire file as template ?
How can I write HTML code in my variable ?
Maybe I can upload an entire file as template ?
Yes, you can use an entire file as the template. It is called a view. See reference below.
How can I write HTML code in my variable ?
Use the raw method:
<%= raw #template %>
You may want to try this ActionMailer walkthrough.
Reference: Create a Mailer View
In your view file(newsletter.html.erb) mark the string as trusted safe.
<%= #template.html_safe %>
Use raw if there are chances that the string will be nil.
<%= raw(#template) %>

How to interpolate ruby inside of an interpolated bit of ruby in ERB

I'm trying to create a situation where one user makes message templates and another one can plug in values. I'm using the best_in_place gem, which will allow a user to edit the message on the show page.
The problem is this. When I call the message, with the required erb to make the gem work, it treats all of this as a regular string, not as ruby.
This is unclear, I'm sorry.
Here's the code.
#announcement.content = "The <%= best_in_place #announcement, :train %> is arriving in five minutes."
/show.html.erb
<%= #announcement.content %>
I want it to put "The click to set train is arriving in five minutes." and if the user clicks where it says "click to set train," a text field will open for them to edit (this is something the best-in-place gem does).
Instead, it puts "The <%= best_in_place #announcement, :train %> is arriving in five minutes."
I understand why it is doing this, but I don't know how to make it instead interpret the ruby I'm trying to pass in.
Ideas?
Use regular old string interpolation:
#announcement.content = "The #{best_in_place #announcement, :train} is arriving in five minutes."
You can use ERB to render any ERB template string. In this case something like:
<%= ERB.new(#announcement.content).result %>
Although you likely won't have access to all your Rails helpers, etc.
The Rails way to do this:
#announcement.content_type = :arriving
Later:
<%= render(partial: #announcement.content_type)
In _arriving.erb:
The <%= best_in_place #announcement, :train %> is arriving in five minutes.
TL;DR: ERB is not Ruby, and Rails uses both at different times.
You want simple Ruby string interpolation here:
#announcement.content = "The #{best_in_place #announcement, :train} is arriving in five minutes."
This is unclear, I'm sorry.
Not to worry, the Rails framework throws so many different new concepts at you it can be frustrating for newcomers.
Start from this: the Ruby framework builds the answer to the user's browser from a collection of resources Each file is evaluated by an interpreter for its own language. The trick is: look at the extension.
Files ending in .coffee will be compiled into javascript, files ending in .scss will become CSS, and in the same way files ending in .erb will yield HTML.
ERB is a language composed of mostly HTML already, plus a tag that allows you to interpolate Ruby. ERB stands for Embedded Ruby.
What about files ending in .rb, like the file in which you (surely) are evaluating #announcement.content = "The <%= best_in_place[...]" (a controller, I guess)?
Well, that's just pure Ruby :) that's why the ERB interpolation syntax <%= ... > is not recognized.
What you want to do in the controller, is (as you're trying to do) preparing the data for the view. The ruby in the <%= ... > tag in ERB will have access to the controller's instance variables, i.e. the variables with an # in front defined in the controller. But to define those, inside the controller, you should rely on Ruby alone.
Take-home message:
Be aware of which language you are writing in at each moment. For example:
# show.html.erb
<p>Here is ERB, which will be interpreted straight into HTML</p>
<% "Inside the '<% ...' tag is Ruby, but results won't show up in the HTML because there's no '<%='."%>
<% which_language = "Ruby" # Even variable assignments, and comments, do work %>
<%= "Inside the '<%=' tag, you're writing and interpolating #{which_language} :)" %>
I think the fact that I wasn't clear made it hard to answer this question.
What I'm doing is transforming user-inputted text (using a method in the model, called by the controller) to replace certain keywords with erb tags that call the best_in_place plugin. In my view, when presenting this content to another user, I wanted to call this content, which is saved as an attribute in the database, in such a way that it would render correctly for the other user to have the best_in_place functionality active.
Here's what I ended up doing. It is working, but if you have better ideas, please let me know.
In the announcements#create view, the user creates an announcement with certain pre-defined blocks of bracketed text as well as free-input text. For example, they might write "[train] is leaving from [platform] in [time] minutes."
When they hit save, the controller's create action calls the construct_message method from the model. It looks like this:
def construct_message(msg)
msg.gsub! '[train]', '<%= best_in_place #announcement, :train_id, :as => :select, collection: Train::list_trains, place_holder: "Click here to set train." %>' #note: list_trains and list_platforms are methods on the model, not really important...
msg.gsub! '[platform]', '<%= best_in_place #announcement, :platform_id, :as => select, collection: Platform::list_platforms, placeholder: "Click here to set platform." %>'
msg.gsub! '[time]', '<%= best_in_place #announcement, :number_of_minutes, placeholder: "Click here to set." %>'
end
Then, when I want to show that attribute in my view, I'm using render :inline, like this.
on announcements/:id
<p id="notice"><%= notice %></p>
<p>
<strong>Content:</strong>
<% announcement = #announcement %>
<%= render :inline => announcement.content, locals: { :announcement => announcement } %>
</p>
This allows the erb call that I wrote into the attribute to be functional.
Also note that I'm choosing to use a local rather than instance variable here; this is because in announcements#index, I also render this text and the table there uses local variables.

html_safe, raw, h have all failed to render links in text

I happen to be passing a url within the message body in my model_class. The link renders out well in views but it is unclickable (as a user has to manually copy it). Below is how i am passing the link in model class.
class Something < ActiveRecord::Base
messsage_body = "Hi! Follow this link to say hi! #{Rails.application.routes.url_helpers.user_say_hi_url(#user, :host => "localhost:3000")
end
Try calling it in my view with following:
<%= #something.message_body.html_safe %>
<%= raw #something.message_body %>
<%= h #something.message_body %>
And the link still remains un-clickable.
Hope mt explanation was clear enough thanks...
The link is unclickable because you are not actually making it a link using rails' link_to helpers or creating a HTML anchor tag manually or any other method. You are just printing out a URL.

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)

rails3 + liquid parse question

I have a question in using luquid. My question is like this,
I have a model called 'Page' (with is an ActiveRecord::Base
inherited) , and it has a column called 'content' which will store
the html page content.
I have a code to display it as follows
<%#template = Liquid::Template.parse(page_content) %>
<%= #template.render('page_content' => yield) %>
where 'page_content' has implemented in application helper as follows
def current_site_layout
Page.find(1). content
end
but my problem is if I have content as follows
<h1>This is a test</h1>
It will display in the page as
<h1>This is a test</h1> (with <h1></ h1> tags)
where as I want it to print like This is a test (formatting
applied as h1)
what am I missing here , and I think I will have to use liquid_methods
or something like that. But since I'm new to liquid I'm not sure which
method to use.. can someone help me
I'm on rails3 and using gem 'liquid 2.2.2', from 'github.com/GnomesLab/
liquid.git'
thanks in advance
cheers
sameera
In rails 3, strings are escaped by default. To display unescaped strings, you need to call raw method explicitly.
<%#template = Liquid::Template.parse(page_content) %>
<%= raw #template.render('page_content' => yield) %>

Resources