PDFkit doesn't display pictures in PDF - ruby-on-rails

Rails 2, PDFkit 0.5.0
Im generating a PDF from a View in Rails 2 with PDFkit and everything works fine. The only thing which doesn't work is displaying pictures in the pdf.
When I look at the View in the Browser, the picture is there but its missing in the PDF. There is only a placeholder existing in the PDF.
The image_tag is looking like this:
<%= image_tag('plus.gif') %>
I also tried to realize it with a css-file but it doesn't work either.
Any ideas?

Because of the way that wkhtmltopdf works you need to specify the full path to any assets (JS, CSS, images etc), including the domain name.
This won't work:
<img src="/images/foo.png" />
This will:
<img src="http://example.com/images/foo.png" />
One workaround is to set an explicit asset host, even if it's the same server as your app is running on (see the AssetTagHelper documentation for details). Another would be to specify the hostname in the image_tag.

Instead of putting the full path each time, you can add a base tag to the head section.
<base href="http://mydomain.com" target="_blank" />

Related

How to add a background image using an absolute path in markup

So I am using pdfkit gem, to make a pdf. The following is the typical syntax to make it work
<%= image_tag("#{Rails.root}/public/images/signature-white.png", class: "signature", alt: "signature")%>
It requires us to give the absolute paths of where the images, also the images are to be in public
Now I have to add a background image dynamically in the markup
I came up with this
<div style="background-image: url('/images/background.png')">
</div>
This is fine, if it had been a web page. However this pdfkit requires the path to be absolute, and I am clueless about how to use the url helper to access the image in public/images/background.png using absolute path
You need to use the file scheme as in file:///home/gregnavis/images/background.png.

Image not loading in dynamic page of Ruby on Rails app

I've done the assets pipeline for my rails project and everything is working fine, except on the dynamic posts page, like http://localhost:3000/posts/2, where images doesn't load. Everywhere else it works fine.
In console I get this error:
ActionController::RoutingError (No route matches [GET]
"/posts/assets/logo.png")
But I used src="assets/m1.jpg in image tag but in the console error the link is different!
What am I missing?
If the image tag has the following exact image path specified:
<img src="assets/m1.jpg" etc="etc">
...then the browser will treat that as a relative URL and try to look it up relative to the URL of the current page, which is http://localhost:3000/posts/2.
As a result, the browser will look for an image with this URL: http://localhost:3000/posts/assets/m1.jpg, which is exactly what's happening in your case.
Try using the image_tag helper instead:
<%= image_tag "m1.jpg" %>
Links that don't start with a / look within the same "folder" you're currently in. Thus when you're on localhost:3000/posts/2 you're in the posts 'folder' and so it looks for localhost:3000/posts/assets/m1.jpg.
If your start a link with a / it'll look from the top of the current site localhost:3000, thus /assets/m1.jpg will look for localhost:3000/assets/m1.jpg which is where you want it to be looking.
In your code you, can use the image_tag helper instead of manually writing out your image tags:
image_tag('m1.jpg') # <img alt="M1" src="/assets/m1.jpg" />
You should use the helper <%= image_tag('m1.jpg') %> and put your image in the assets/images/ directory.
The helper will generate the correct path to the image

How to use svg 'use' statement with Rails sprockets asset helpers?

I have an svg in an external file that I want to reference with a use statement in Rails.
If I do:
%svg
%use{"xlink:href" => "assets/icon.svg#test"}
which generates the html:
<svg>
<use xlink:href="assets/icon.svg#test"></use>
</svg>
Everything works as expected.
However I want this to be able to work with sprockets asset versioning in a similar way to how image_tag works.
I tried to do:
%svg
%use{"xlink:href" => image_url("icon.svg#test")}
This generates the html:
<svg>
<use xlink:href="http://0.0.0.0:5000/assets/icon.svg#test"></use>
</svg>
The asset certainly exists at http://0.0.0.0:5000/assets/icon.svg, but the icon does not show.
What am I doing wrong? How do I use sprockets asset helpers with svg use statements?
Asset cannot exist at 0.0.0.0, it is not a real ip, you need to set config.action_controller.asset_host
In development 127.0.0.1(loopback ip) will do
Seems to be a cross origin browser security issue.
Google chrome actually gives a message that helps with this. (I was previously using firefox so didn't notice this...)
Unsafe attempt to load URL http://0.0.0.0:5000/assets/icon.svg from frame with URL http://localhost:5000/. Domains, protocols and ports must match.
The domain names much match for it to work.
In my opinion, this can be fixed by using image_path instead of image_url. That way you should get a relative link to the SVG file, i.e. precisely the same output as in your raw HTML, possibly with just the asset hash added to the file name.

No pics in my PDF created with PdfKit on heroku

I've an app which works fine in development and on my current production server.
I want to move it to FREE heroku (basic config: 1 dyno, 1 worker).
Unfortunately, the pdf generation (using PdfKit) is ok BUT without the pictures defined in my CSS.
I've followed a lot of tips including:
http://blog.mattgornick.com/using-pdfkit-on-heroku
http://jguimont.com/post/2627758108/pdfkit-and-its-middleware-on-heroku
http://code-fu.pl/blog/2011/05/17/pdfkit-heroku
Thoughts?
Found a workaround but I am still eager to know a better option:
I duplicated my view: one dedicated for html, another for pdf.
I removed all css using pics and put it in a separate file, included only in the view dedicated for html
finally, I inserted the css in the view dedicated to the pdf:
.foo { background-image:url(<%= Rails.root %>/public/images/bar.png) }
Very Ugly but works so please tell me if you've better
It's probably an issue with the way the url's are specified in the css. As I recall, they should be file system absolute paths. What does your css look like?
Here is how I answered my needs with:
Just one single view file
Just one css file
The trick was to pass the proper base_url to the css file dynamically, given I expected a pdf or html.
I decided to use LESS. Style compiles css in a different manner, given the base-url I provide in the DOM. This base-url is generated by a helper.
Here were my steps:
changed my style.css to style.less
Added to my view:
<%= stylesheet_link_tag "style.less", :rel => "stylesheet/less" %>
<script id="base_url" type="text/javascript" data="<%= assets_path %>"></script>
<%= javascript_include_tag "less.min.js" %>
In my helper:
def assets_path
if request.fullpath.include? ".pdf"
"#{Rails.root.join('public',"images","pictos")}"
else
"#{request.protocol}#{request.host_with_port}/images/pictos"
end
end
and in my style.less:
#base_url: `document.getElementById('base_url').getAttribute('data')`;
.foo { background-image:~"url(#{base_url}/bar.png)" }

Why isn't my image tag working?

What is the different with
<images src="http://localhost:3000/images/logo_general.png">
and
<%= image_tag("logo_general.png") %>
Why am I having problems loading images using the first way?
Probably because the correct tag to use is
<img>
And not
<images>
There are several differences:
The image_tag generates the HTML <img> tag, not <images>
The source path is based on your asset host and asset path, so images don't break if they change. The default is relative to root, e.g. /images/
image_tag gives you an alt attribute for proper accessibility.
In development mode, it adds a random number to the image as a convenience to prevent the browser from using a cached image in case you change it.
image_tag properly closes the tag. with />.
You can try it out in the Rails Console.
image_tag("logo_general.png")
=> <img alt="Logo_general" src="/images/logo_general.png?1230601161" />

Resources