Rendering ERB in models: "no implicit conversion of ERB into String" - ruby-on-rails

I am rendering an ASCII map that looks like the following:.
I want the asterisk in the map, which represents a character, to be red. Right now this characters asterisk is being assigned to its location as follows:
def mark_character_coordinates
WORLD.terrain[#character.y_coordinate][#character.x_coordinate][0][0] = "*"
end
I want my characters location on the map (the asterisk) to render as red. My idea is to try to wrap the asterisk in a span and give it an id. Then go into my CSS and make ID color red. My problem is I am not sure how to insert ERB into the model and have it render as such in the view. After reading similar problems on stackoverflow, this is the closest I got:
def mark_character_coordinates
WORLD.terrain[#character.y_coordinate][#character.x_coordinate][0][0]
= ERB.new("<span>*</span>")
end
What should I do? How do I insert ERB into a variable in the model and have it render accordingly in the view?

The best and easiest way to do this is to use JQuery. First, put the ASCII map inside a div with id="ascii-map" in your template. Then switch to the front-end. Once the DOM is fully loaded, you can parse the ASCII map, look for the asterisk, and then wrap it in a span element that has red color defined for its font.
In your CSS:
.red-font {
color: red;
}
Then, some JQuery:
$(document).ready(function() {
var text = $('#ascii-map').html();
var textWithRed = text.replace("*", "<span class='red-font'>*</span>");
$('#ascii-map').html(textWithRed);
});
I test this and confirmed that it works.

Well... you're breaking MVC pretty badly, so that's one thing. Other than that though, do you need ERB for this? You're not embedding ruby at all. Why not just have it as a string?
i.e
def mark_character_coordinates
WORLD.terrain[#character.y_coordinate][#character.x_coordinate][0][0] = "<span>*</span>"
end

Related

Rendering markdown with Slim/Rails from an instance var

I'm having trouble getting Slim to render my markdown:
div.container
div.row
div.col-md-8.job_description
markdown:
= #listing.job_description
That just renders the string
This is an h1 ## h2 ### h3 > this is a quote * hello * goodbye foo
No line breaks or anything (which are contained in the actual string)
How do I get this to render properly? Thanks!
I gave up on using markdown: in slim, had tried everything.
I ended up creating this helper, place it in just any file in app/helpers
def markdown(content)
return '' if content.blank?
markdown = Redcarpet::Markdown.new(Redcarpet::Render::XHTML, autolink: true, space_after_headers: true)
sanitize(markdown.render(content)).html_safe
end
And then in a view
= markdown #listing.job_description
You will of course have to install the redcarpet gem.
gem 'redcarpet'
Rendering Markdown out of a variable in this way isn't possible, as Slim first renders the Markdown (or any other embedded engine language) and only after that interpolates the variable contents.
It makes sense that it would work this way as Slim's embedded engine tags are intended as a way of including different languages in-line so you can read them there. If the markdown isn't included in literal form in the template, there's no advantage to using the embedded engine over simply rendering the Markdown before you pass it to Slim (as HTML, and using '==' to prevent further processing by Slim).
I think, also, that it's set up like this because it's intended to provide and easy way for interpolating text into Markdown - which doesn't itself have a means of interpolation - within the same template as everything else.
The helper Iceman suggests is a nice way to do it. I'd probably call it outside of the template, but that's just because it's my personal preference to do as little as possible inside the template.
Looks like your markdown content is not indented under markdown:, so it won't be processed by markdown.
It should look more like this:
div.col-md-8.job_description
markdown:
= #listing.job_description
See this section of the docs for more information.

ruby JSON.pretty_generate() doesn't work

I'm trying to print JSON data in a view in a 'pretty' human readable format. I have a controller:
def show
h = JSON.parse(RestClient.get("http://link_to_get_json"))
#json = JSON.pretty_generate(h)
end
and a simple view:
= #json
But all I see, when I load the page, is the same JSON I've got, not formatted. What do I do wrong?
JSON.pretty_generate inserts whitespace into the returned string.
If your'e dumping the string into an HTML document, all whitespace (such as newlines) is ignored, and rendered as a single space. In order to preserve whitespace, you need add a white-space: pre CSS style, or wrap the content in a <pre> tag.
I think you were using <p>. wrap it up in <pre>.

Searching for contents between two specified tags

I installed Nokogiri into a Rails project and it can currently run "Nokogiri HTML Parser Example" with no issues.
I'm trying to create a Rails project that will parse a movie script from IMDB, conduct a word count, then display the most occurring words from that section. I've identified that the scripts are kept in a "table":
<table width=100% border=0 cellpadding=5 class=scrtext><tr><td class=scrtext><pre><html><head></head><body>
<b>PERSON1</b>
They say some dialogue
<b>PERSON2</b>
They say some more
</pre></table>
I would like to exclude the text within the <b>/<b> brackets as well.
I've been setting this up like the example above in the controller, and have gotten as far as taking in the URL:
#Save as a temp. file
tmp_file = open('http://www.imsdb.com/scripts/Authors-Anonymous.html')
#Parse the temp. file
doc = Nokogiri::HTML(tmp_file)
I'm having difficulty understanding how to set the CSS constraints to grab this table. I understand that it's between those <pre>/<pre> tags, and I've followed a number of tutorials for this but I still don't understand how to set up those constraints.
I feel that the code following this should be something like this, but I'm not awfully sure:
doc.search("//pre")
How do I set up Nokogiri's CSS constraints to pull the content between two tags such as <pre></pre>, and then filter out irrelevant tags such as <b></b> that will occur within the output?
You can use the css method selector: doc.css('pre b') which will get every <b> tag(s) inside every <pre> tag(s):
doc.css('pre b').each do |b_tag|
# b_tag will be a String containg like `<b>this text is bold</b>`
end
It might not be the most elegant solution but it did the trick for me.
In the controller, I defined the following:`
def index
page = [THE_URL]
doc = Nokogiri::HTML(open(page))
#content = doc.css('b').remove
#content = doc.css('pre')
puts #content
end
and then in the View;
<%=#content %>

Raw and simple_form...neither is perfect

I have this in one of my models:
def rank_match_2
...
...
array = [start, finish, [words]]
results = field.insert(start, "<mark>") and field.insert(finish, "</mark>")
...
end
Now I know I shouldn't be adding view logic in the model, but I am building a search app that has quite a bit of logic built into how the results are rendered. At this point I don't see how to get around including it in the model, so I that's what I am doing.
My problem is this:
On the view, I have this:
<%=raw #parse.rank_match_2 %>
This effectively handles the html "mark" tags inserted in the model logic and DOES highlight the correct text, but DOES NOT include line breaks etc.
However, this:
<%= simple_form(#parse.rank_match_2).html_safe %>
does not handle the 'mark' tags and therefore DOES NOT highlight the correct text, but DOES correctly format the line breaks as expected.
I want to do both: highlight the correct text by inserting the 'mark' tags into the model object (which seems to work with 'raw'), AND render correctly formatted html with line breaks etc.
Any idea what I am missing. I am trying Draper gem but I don't think it is suitable for exactly what I want.

Why does the simple_format helper seem to ignore double new lines in ruby on rails?

I have a micropost feature and was testing the way it formats text that has been posted when displaying back to the user.
I pasted the following text like this:
and this was displayed back to me:
I'm using "simple_format h(content)". When I remove the helper the text is displayed with out a new line from the word "In". It displays as one big paragraph so I assume the helper is working but for some reason my double new lines are being ignored.
Any idea what is going on? Am I missing something?
By seeing it back, do you mean inside a textarea, or on the page? If it's on the page, all whitespace is compressed to one space each. If it's the latter, simply use the css rule:
white-space:pre;
On the proper selector.
However, if it is in a textarea (which preserves whitespace by default), there must be something stripping the extra space when you save it into the database. You might want to debug down your stack in the model & controller, to see where this might be happening. I have to admit i haven't used the the simple_format method.
Thanks to chrome developer tools as per usual. I realised that each text separated by 2 new lines were wrapped with p tags so I just added a bottom margin of 5px using css to p. Works perfectly.

Resources