7

I'm currently building a web application using Flask. My supervisor requested that one feature should be to save the current page as a PDF (for printing). To this end I'm using pdfkit. Before anyone proposes to use weasyprint instead: I tried installing it for 2 hours to no avail, so I've abandoned that. I'm using the Bootstrap css and its JavaScript to make the application a bit more pleasant to look upon.

I'm using the below file structure (as proposed by a tutorial to Flask)

+-- name_of_app
|   +-- static
|       +-- css
|           +-- css files
|       +-- js
|           +-- javascript files
|   +-- templates
|       +-- .html templates
|   +-- __init__.py
|   +-- config.py
|   +-- forms.py
|   +-- views.py
+-- run.py

To just try pdfkit out, I generate PDFs every time I generate a page, i.e. in all of the functions which are routed in views.py. All the pages are based on the following template

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <link href="static\css\bootstrap.css" rel="stylesheet" media="screen">
        <link href="static\css\bootstrap-theme.css" rel="stylesheet">
        <script src="http://code.jquery.com/jquery-latest.js"></script>
        <script src="static\js\bootstrap.js"></script>
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        {% if title %}
        <title>{{ title }} - Timeseries Project</title>
        {% else %}
        <title>Welcome to the Timeseries Project</title>
        {% endif %}
    </head>
    <body>
        <div class="navbar navbar-default">
            <div class="navbar-inner">
                <a class="navbar-brand active" href="/">Home</a>
                <a class="navbar-brand" href="/">Save as PDF</a>
            </div>
        </div>
        {% block content %}{% endblock %}
    </body>
</html>

The web pages load beautifully using the provided css and JS files. However, pdfkit outputs the following warnings

Warning: Failed to load file:///C:/Users/my_user/AppData/Local/Temp/static/css/bootstrap.css (ignore)
Warning: Failed to load file:///C:/Users/my_user/AppData/Local/Temp/static/css/bootstrap-theme.css (ignore)
Warning: Failed to load file:///C:/Users/my_user/AppData/Local/Temp/static/js/bootstrap.js (ignore)

The issue I'm trying to resolve is therefore: How do I get pdfkit to look for static in the folder where one of its methods was executed (i.e. views.py), and not in AppData?

Tingiskhan
  • 1,305
  • 3
  • 16
  • 29

2 Answers2

7

To generate URLs for static files, use the special 'static' endpoint name: http://flask.pocoo.org/docs/0.10/quickstart/#static-files

<link href="{{ url_for('static', filename='css/bootstrap.css') }}" rel="stylesheet" >
<link href="{{ url_for('static', filename='css/bootstrap-theme.css') }}" rel="stylesheet">

Update: Using _external=True may also fix the issue by providing an absolute url. eg:

<link href="{{ url_for('static', filename='css/bootstrap.css', _external=True) }}" rel="stylesheet" >
benh
  • 194
  • 1
  • 9
r-m-n
  • 14,192
  • 4
  • 69
  • 68
  • 1
    Wow, if it's this simple I'm going to lay down and cry. Thank you so much for the answer, will try it out when I'm at the office tomorrow and get back to you – Tingiskhan Nov 02 '15 at 16:47
  • Hmm, I tried implementing this, however I now get the same warnings but for path `Failed to load file:///static/css/bootstrap-theme.css` – Tingiskhan Nov 03 '15 at 07:40
  • 3
    try with absolute URL: `url_for('static', filename='css/bootstrap.css', _external=True)` – r-m-n Nov 03 '15 at 08:44
  • Now it finds it correctly, thanks! However, the issue is now that `pdfkit` won't save the file... Probably has something to with it being locally hosted... – Tingiskhan Nov 03 '15 at 10:24
  • This was the solution, thank you. And also to ditch `pdfkit` and use `wkhtmltopdf-wrapper` instead. – Tingiskhan Nov 03 '15 at 11:10
1

I was able to get this to work using pdfkit by including the full path in my jinja2 template:

<link rel="stylesheet" href="file:///Users/paul/code/pdfmaker/templates/css/styles.css">
PaulMest
  • 12,925
  • 7
  • 53
  • 50