Specify full path for image source in Ruby on Rails - ruby-on-rails

I have HTML documents that contain image tags . I need to pick out each image tag's source attribute and specify a full path instead of the relative path already present . That is to append the absolute path .
Current Version :
<img src = '/assets/rails.png' />
After transformation :
<img src = 'http://localhost:3000/assets/rails.png' />
What would be the cleanest and most efficient way to do this in RoR ?
Addition
I am going to use the transformed HTML as a string and pass it to IMgKit gem for transformation into an image .

It's hard to figure out if you mean you have HTML templates, such as HAML or ERB, or real HTML files. If you're trying to manipulate HTML files, you should use Nokogiri to parse and change the src parameters:
require 'nokogiri'
require 'uri'
html = '<html><body><img src="/path/to/image1.jpg"><img src="/path/to/image2.jpg"></body></html>'
doc = Nokogiri.HTML(html)
doc.search('img[src]').each do |img|
img['src'] = URI.join('http://localhost:3000', img['src']).to_s
end
puts doc.to_html
Which outputs:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body>
<img src="http://localhost:3000/path/to/image1.jpg"><img src="http://localhost:3000/path/to/image2.jpg">
</body></html>
You could do the manipulation of the src parameters various ways, but the advantage to using URI, is it's aware of the various twists and turns that URLs need to follow. Rewriting the parameter using gsub or text manipulation requires you to pay attention to all that, and, unexpected encoding problems can creep in.

You can create a helper method so you can use it everywhere
def full_image_path(image)
request.protocol + request.host_with_port + image.url
end

Related

Acquire Asset Path from JavaScript

I need to display images on an HTML5 canvas that are in the Rails asset pipeline, but I need to know the path for the asset from JavaScript. I'm using js-routes for other parts of the application, but it doesn't appear to provide a way to get the path to something in the asset pipeline.
What's the correct way to obtain the path to a Rails asset (e.g., an image) from JavaScript?
In the Rails Asset Pipeline guide, they give an example of coding assets in your stylesheets by preprocessing the stylesheets with ERB. You can use the same technique with JavaScript, assuming you tack an .erb to the end of the filename:
var someAssetPath = "<%= asset_path('some_image.png') %>";
Checkout the js_assets(Javascript helper in rails projects) gem.
I think it is precisely what you need.
From the documentation:
Get the path to the template app/assets/javascripts/rubrics/views/index.html in javascript:
var path = asset_path('rubrics/views/index.html')
Why not add a data attribute for the path inside an element in your .erb file and then retrieve that with JQuery?
inside some_template.html.erb
<%= content_tag(:div, "", id: 'some-id', data:{path_to_asset: asset_path("some_image.png")}) %>
then in some_javascript.js
var assetPath = $("#some-id").data("pathToAsset");
For those using HAML you can do:
:javascript
var assetPath = "#{asset_path('some_image.jpg')}";
I came across the same issue in Rails 4.1 and used referencing rails assets in coffeescript for images. No additional libraries needed.
In my case, I wanted to get the stylesheet path and the hash that rails generates for cache busting made it impossible to hardcode.
What ended up working quite well for me is to assign an ID to the main stylesheet link element in the html (layout) and then use javascript to extract the href. If you want the base asset path, perhaps create a generic element with the data you need as an attribute.
Rendered HTML
<link rel="stylesheet" href="mypath/main.css" type="text/css" id="main-css">
JS
$("#main-css").attr("href"); // "mypath/main.css"

How to correctly state internationalization keys/values in YAML files?

I am using Ruby on Rails 3.1.0 and I would like to know how to correctly state internationalization keys/values in YAML files (I have a couple of questions/doubts...). That is, I have a locale file containing the following code:
en:
# Note the 'style' HTML property and the ':' at the end
test_key_html: <span style='color: #4682B4;'>Test text</span>:
How should I correctly add colon (punctuation) to a YAML file (maybe by using HTML code)?
How should I properly state the HTML 'style' property in the YAML file? What do you advise about?
Those translation files aren't meant to have HTML. I would avoid having the entire HTML string in there, instead just have the string "Test text" and move the html portion back into your template or helper.

Nokogiri unescaped html

I am parsing HTML text using nokogiri and making some changes to that HTML.
doc = Nokogiri::HTML.parse(html_code)
But i am using mustache with that html so the html contains mustache variables which are in enclosed in
curly braces e.g.{{mustache_variable}}.
After tinkering with the nokogiri document, when i do
doc.to_html
These curly braces are escaped and i get something like %7B%7Bmustache_variable%7D%7D
But, not all of the content is escaped, e.g. if i have html as
<label> {{mustache_variable}} </label>
It returns, <label> {{mustache_variable}} </label>
But for html like, <img src='{{mustache_variable}}'>
It returns, <img src='%7B%7Bmustache_variable%7D%7D'>
So, i am currently doing a gsub to replace %7B and %7D with { and } respectively so mustache works.
So, is there a way i can get the exact html from nokogiri or a better solution ???
Probably you need cgi module
require 'cgi'
doc = Nokogiri::HTML.parse(html_code)
CGI.unescapeHTML(doc.to_html)
or you can use htmlentities lib.
And try to use doc.content instead of doc.to_html
I ran into this same problem and ended up using a regular expression to convert the escaped double braces:
html_doc.gsub(/%7B%7B(.+?)%7D%7D/, '{{\1}}')
To make this safer, I'd recommend prefixing each mustache variable with a namespace, just in case some of the HTML does have the escaped double brace pattern intentionally, e.g.
html_doc.gsub(/%7B%7Bnamespace(.+?)%7D%7D/, '{{namespace\1}}')

Rails - strip_tags - Not catching DOCTYPE?

Given an HTML email, I'm using the following to strip down to just the text:
body = body.gsub(/\\r\\n?/, "\n");
body = body.gsub(/\\n\\n?/, "\n");
body = simple_format(body)
body = strip_tags(body)
But I'm now seeing that one tag gets passed this:
<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">
Which outputs like so:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
Any ideas why?
I guess for strip_tags, which looks like it's been deprecated, considers the doctype statement neither a tag, nor a comment. You could strip it out separately:
string.gsub(/<!.*?$/,'')
I ended up using Hpricot to text, worked great
I'd recommend using Nokogiri for your parsing needs. It's very well supported, plenty fast, very flexible, and the basis of a lot of other HTML/XML type gems. It has a Hpricot mode, though I'm not sure why anyone would need that as its syntax is more full-featured.
In particular, to strip tags from HTML, I'd recommend looking into Loofah. It can whitelist tags, and has several layers of cleansing it can do.

Strip Inline CSS and JavaScript in Rails

I'm working on a Rails application and I would like to know what's the best way to strip blocks of CSS or JavaScript.
<style>
...
</style>
-or-
<script>
...
</script>
I'm using the strip_tags helper to take care of most of the HTML, but it leaves a bunch of CSS when the content contains inline CSS. Thanks
Try to use Nokogiri library:
require 'nokogiri'
str = " ... " # some html from user
doc = Nokogiri::HTML(str)
doc.css("style,script").remove # remove all tags with content
new_string = doc.to_s
Nokogiri can much more, but this is what you asked for in questions :-)
The recommended way to do this is using the sanitize method. The strip_tags method is somewhat limited and less secure:
[strip_tags] Strips all HTML tags from the html,
including comments. This uses the
html-scanner tokenizer and so its HTML
parsing ability is limited by that of
html-scanner.
If you use sanitize, you will be much more secure, just come up with a white list of tags you intend to allow first.
If you need user-provided CSS for your application, you can try using http://github.com/courtenay/css_file_sanitize/tree/master as well.

Resources