Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for page overlays to support non-trivial page headers/footers #14

Closed
doekman opened this issue Sep 7, 2017 · 3 comments
Closed

Comments

@doekman
Copy link
Contributor

doekman commented Sep 7, 2017

Paged media CSS doesn't support more complex page header/footer requirements, like tables. A solution to this is to create a separate page with such a header, and merge this into the PDF on the required pages. A proof of concept was written by pikhovkin in this Gist.

I made a function to use this functionality with WeasyPrint, and would like to create a pull request to include this into Flask-WeayPrint, since it is such a common use-case.

(any comments about my coding is welcome, since I'm new to the Python language and community)


My API is currently like this:

first_page =     lambda page_nr: page_nr==0
not_first_page = lambda page_nr: page_nr!=0
odd_page =       lambda page_nr: page_nr%2==1
even_page =      lambda page_nr: page_nr%2==0

class Overlay(object):
    def __init__(self, template_name_or_list, fn_include_on_page=not_first_page, **kwargs):

def render_pdf_with_overlays(html, *overlays, stylesheets=None, download_filename=None):

#example:
html = flask.render_template('my_report.html')
first_page_overlay = Overlay('first_page_overlay.html', fn_include_on_page=first_page, left='10cm', top='5cm')
default_page_overlay = Overlay('default_page_overlay.html', fn_include_on_page=not_first_page)
pdf_response = render_pdf_with_overlays(HTML(string=html), first_page_overlay, default_page_overlay)

Overlay: Represents one HTML page to be overlaid on a PDF document.

  • template_name_or_list: the name of the HTML template, which is resolved with jinja2's get_or_select_template method.
  • fn_include_on_page: a function that takes a 0-based page number, and returns a boolean that indicates if it needs to be included on that page.
  • kwargs: context used to render the overlay. Can also be used to dynamically position content.

render_pdf_with_overlays renders the PDF like Flask-WeasyPrint's render_pdf, but with overlays.

  • stylesheets are also used to render the Overlay, so if any FontConfiguration is included, it is also included in the Overlays.
  • the overlays templates are rendered to HTML with the supplied context, and this context is extended with the page and pages entries, indicating current 1-based page number and number of pages (CSS page and pages counters don't work with single page overlays)
@liZe
Copy link
Member

liZe commented Sep 7, 2017

Hi @doekman,

Thank you for your comment and for your idea, it looks like a great solution. Next version of WeasyPrint may rely on pdfrw, a library able to edit PDF files. It's opening a large set of new possible solutions like this one, with or without an API in WeasyPrint.

However, your solution doesn't really rely on the Flask part of Flask-WeasyPrint and would be better discussed in Kozea/WeasyPrint#92. Could you please copy your comment in Kozea/WeasyPrint#92?

Thank you!

@liZe liZe closed this as completed Sep 7, 2017
@doekman
Copy link
Contributor Author

doekman commented Sep 7, 2017

My solution does rely on Flask a bit (actually Jinja2) for rendering of the page number (which obviously varies per page). But I get your point, some work should be done in WeasyPrint first.

I added my comment to WeasyPrint, and put my current solution in a gist, so others might use it.

@liZe
Copy link
Member

liZe commented Sep 8, 2017

My solution does rely on Flask a bit (actually Jinja2) for rendering of the page number (which obviously varies per page).

You can use CSS instead of Flask for page numbers 😉.

I added my comment to WeasyPrint, and put my current solution in a gist, so others might use it.

Thanks a lot!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants