1

I am using just Ruby (no rails) to make a gem that takes a yaml file as an input an it produces a pdf. I am using pdfKit and Haml. In the haml file I need to render an image. When using pure HTML, PDFKit shows the image, but when using Haml::Engine and the haml file the image doesn't get rendered.

I have put the image, the .module and the haml file under one folder to make sure the issue is not the path.

In my gemspec I have the following . .

gem.add_development_dependency("pdfkit", "0.8.2")
gem.add_development_dependency("wkhtmltopdf-binary")
gem.add_development_dependency("haml")

The HTML that works:

<html>
  <head>
    <title>
      junk
    </title>
  </head>
  <body>
    HI
    <img src="watermark.png"/>
    Bye
  </body>
</html>

Haml version that doesn't work:

%html
  %head
    %title
      junk
  %body
    HI
    = img "watermark.png"
    Bye

module:

require "pdfkit"
require "yaml"
require "haml"
require "pry"
.
.

junk = Haml::Engine.new(File.read("lib/abc/models/junk.haml")).render
kit2 = PDFKit.new(junk)
kit2.to_file("pdf/junk.pdf")

when using the html file, pdf renders the image, however, when I use the haml this is now my pdf looks like

enter image description here

and If I use

%img(src="watermark.png")

I get the following error when pdf is generated Exit with code 1 due to network error: ContentNotFoundError

The PDF still gets generated, but the still looks like the image above.

So I am trying to see without using any rails, and img_tag, image_tag etc.. how would I just use the %img in haml file to render the proper image

Following is the output of junk, when I create @img = "watermark.png"

1 pry(DD)> junk

=> "<html>\n<head>\n<title>\njunk\n</title>\n</head>\n<body>\nHI\n<img src='watermark.png'>\nBye\n</body>\n</html>\n"

Replace the img tag %img(src=@img) still same result

Sarah A
  • 1,185
  • 12
  • 27

2 Answers2

2

I think this is not HAML issue, but wkhtmltopdf thing. Apparently it's not very good at handling relative urls to images. It should work with absolute path, for example:

%img(src="/home/user/junk/watermark.png")
katafrakt
  • 2,438
  • 15
  • 19
  • UH... look at this: if i use %img(src="https://upload.wikimedia.org/wikipedia/commons/thumb/8/83/Internet1.svg/2000px-Internet1.svg.png") it works. https://stackoverflow.com/questions/6108943/pdfkit-doesnt-display-pictures-in-pdf but the question is how do I give it my image. – Sarah A Mar 17 '18 at 22:28
  • So the question is now, since I am not using rails and cannot access RAILS_ROOT... how I find the proper root – Sarah A Mar 17 '18 at 22:32
  • You don't know where the file is on your system? – lacostenycoder Mar 17 '18 at 22:34
  • UH.. the only way to get it to work is to use the path with ```pwd```... sigh.. this should be OK though because in production, I am replacing it with S3 path.. voted up, thank you – Sarah A Mar 17 '18 at 22:42
1

To create an image tag in HAML you will need to use

%img(src="foo.png")
# or
%img{src: "foo.png"}

If you use

= img "watermark.png"

then you are calling the img method (if it exists), passing it "watermark.png" as argument and outputting the return value of that method in the generated HTML.

Honestly i'm not sure how that HTML template should work, when the HAML template that generates the same HTML does not. So I guess you run that script from different directories or so?

Anyways: Problem is, that you will need absolute paths for your files. Otherwise wkhtmltopdf will not be able to resolve your images. You can use File.expand_path (see sample) for this, or write a custom helper.

I tried following:

Created two files:

/tmp/script.rb
/tmp/watermark.png
/tmp/template.haml

Where watermark.png is a screenshot I took from this question, script.rb is:

require "pdfkit"
require "haml"

template = File.read("template.haml")
html = Haml::Engine.new(template).render
File.write("template.html", html)
pdf = PDFKit.new(html)
pdf.to_file("output.pdf")

And template.haml is:

%html
  %head
    %title Something
  %body
    BEFORE
    %img(src="#{File.expand_path(__dir__, "watermark.png")}")
    AFTER

When I run this script like:

ruby-2.5.0 tmp$ ruby script.rb

Then the HTML that is generated is:

<html>
<head>
<title>Something</title>
</head>
<body>
BEFORE
<img src='/tmp/watermark.png'>
AFTER
</body>
</html>

And the generated PDF looks like:

enter image description here

Pascal
  • 8,464
  • 1
  • 20
  • 31