'How to conditionally set header and footer of pages?

It's my first time using reportlab to generate pdfs, it's VERY hard for me to understand how it works (it took me a day to even put a sized SVG image :D)

I want to achieve a very basic pdf:

As you can see in the images: 1 cover page, then 2 pages with header and footer BUT header with text is only on the first page...

Text is not static at all, it can break up to 4-5 pages, in the future there could be another section with title with different text.

Also I think what is very hard is to set text's Frame.topPadding to be variable based on header height... I can't even imagine how to do this xD

cover page1 page2

This is my code right now

I've achieved to do the first page, it was pretty easy, but when it came to Frames, PageTemplates and other, my head blew up...

    def _header(self, canvas, doc, title=None):
        # Save the state of our canvas so we can draw on it
        canvas.saveState()

        y_pad = 50
        header_height = (y_pad * 2) + (self.styles['heading'].leading if text else 0)
        header_frame = Frame(
            x1=0,
            y1=self.height - header_height,
            width=self.width,
            height=header_height,
            topPadding=y_pad,
            bottomPadding=y_pad
        )

        canvas.setFillColor(DARKGRAY)
        canvas.rect(0, self.height - header_height, self.width, header_height, fill=1)
        if text:
            header_frame.addFromList([
                Paragraph(text, self.styles['heading'])
            ], canvas)

        # Release the canvas
        canvas.restoreState()

    def _dark_page(self, canvas, doc):
        canvas.saveState()

        canvas.setFillColor(DARKGRAY)
        canvas.rect(0, 0, self.width, self.height, fill=1)

        canvas.restoreState()

    def _create(self):
        doc = SimpleDocTemplate(
            self.buffer,
            topMargin=0,
            rightMargin=0,
            leftMargin=0,
            bottomMargin=0,
            pagesize=A4
        )

        story = []

        # cover page template with dark background set by self._dark_page
        main_page_template = PageTemplate(id='main', frames=[
            Frame(0, 0, self.width, self.height, 0, 100, 0, 100)
        ], onPage=self._dark_page)

        # basic page template for any further text about product
        body_page_template = PageTemplate(id='body', frames=[
            Frame(0, 0, self.width, self.height, 80, 120, 80, 120, showBoundary=1)
        ], onPage=lambda c,d: self._header(c, d, title='title title title title')

        doc.addPageTemplates([main_page_template, body_page_template])


        story.append(NextPageTemplate('main'))

        logo = svg2rlg(LOGO_PATH)
        logo.width = logo.minWidth() * 0.4
        logo.height = logo.height * 0.4
        logo.scale(0.4, 0.4)
        # logo._showBoundary = 1
        logo.hAlign = 'CENTER'
        story.append(logo)

        story.append(Spacer(width=0, height=80))
        # maybe there's a way to position the image in the center between elements,
        # like justify-content: between in css...
        image = Image(self._get_product_image_path(), 320, 320)
        story.append(image)
        story.append(Spacer(width=0, height=80))

        title = Paragraph(self.product.title, self.styles['heading'])
        story.append(title)
        if self.product.breed.name_latin:
            story += [
                Spacer(width=0, height=10),
                Paragraph(self.product.breed.name_latin, self.styles['subheading'])
            ]


        story.append(NextPageTemplate('body'))
        story.append(PageBreak())

        # actual text
        story.append(Paragraph(text*4, self.styles['body']))

        doc.build(story)

So the question is

How do I set header and footer on the page, and if page breaks, next page with same header and footer, but header without title until the last page of the PageTemplate?

I've tried to get page numbers in self._header doc argument, but it's returning the first page number of the PageTemplate, not every page, maybe there's a way to get a page number from 0(first page used by some template) to the last page used by this template?

THANKS in advance! It already took me 3 days to try to achieve this...



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source