Upland OL User community

Change last sheet background based on page count?


I have an overflow duplex page template, that creates pages dynamically and adds a blank page when its odd.

Is it possible to change the last sheet background (front and back) depending on pages generated?

Eg: If my content overflows to 3 pages, 3rd page contains no header(with footer), 4th page of course remains blank
But when my content overflows to 4th pages. I want the 3rd page to contain a header(with footer). Now the 4th page to contain no header with a footer.


FYI: Already sent OL support but I thought to post it here for other people as they might have experience doing this sheet config.

Kind regards,

Dear edanting,

You can achieve this with a control Script. here a link on how to acheive that.

Hi robert,

Appreciate the response but Im not after the page numbering here. Not sure how you came about with this response.

Thank you
Kind regards

Hi @edanting,

As of Connect 2020.1 you should be able to change the sheet config conditionally through a post pagination script. Something like this should work:

if (...) {
    merge.section.sheetConfig.positions.last.masterFront = ...
    merge.section.sheetConfig.positions.last.masterBack = ...

The paginate() call makes sure the sheet config changes are applied.

For the selector you can use html, or html[section=...] if you want to target a specific section.

Hi Sander,

Thanks for the response. I did not think that you can do that in post pagination script…
As this documentation is under control script (but if you say it that you can do that in post pagination. Then thats great!)

Plus paginate() is buggy at the moment, referring to posts below:

But apparently fixed on the next release.

Then theres an issue of getting page count without including the empty page on duplex template.

I tested it before posting :wink:

Yes, it is unfortunate that merge.section.paginate() can have unwanted side effects when the section contains a dynamic table. I can confirm that this will be fixed in 2023.2.

In a post pagination script you can get the content page count (i.e. excluding the last blank page if the section is duplex) with:

query("body > :last-child").info().pageNo

If you need that information at a later point in your workflow you can attach it to the contentitem object. You can add arbitrary metadata (key-value pairs) for each record, and this gets stored in the database.

I agree that there should be an easier way.

That’s great, Thanks Sander. Yep, paginate() is the most crucial part of this solution. Otherwise it cant be done.

Thank you

Hi Sander,

Just an update on this merge.section.paginate() function.

This is still not fixed on this new release 2023.2 despite few internals have confirmed.

My dynamic table content set up is like this:

var content = `<table border=1  width="100%" data-detail data-expander="2019">
			<th>Heading1 </th>
			<th>Heading2 </th>

for(var n=0 ; n < 100; n++){
	content += `
	<tr data-breakable="">

content += `</tbody></table>`

So this still hasnt been fixed. All I did is call the function and see what will happen. And still adding an extra table at the bottom with no rows.

Is this intentional, or perhaps I need to add some kind of option to avoid this side effect, are you able to shed some light on this please?

Thank you
Kind regards

Hi @edanting,

Apparently the fix for merge.section.paginate in 2023.2 only applies to dynamic tables. I was not aware of that distinction, I expected it to be fixed for all table types.

In order for a table to be considered dynamic the table element must either be a static part of the DOM or added through loadhtml.

If you add the table element through replaceWith the table is not considered dynamic. This means the data-detail and data-expander attributes have no effect, and we use an older mechanism to split the table across pages.

Aside from including the table element in the DOM or adding it through loadhtml, a simple workaround would be to have your script add data-splitter=2019. That forces the engine to use the new mechanism to split the table across tables, and then merge.section.paginate should work as expected.

1 Like

Hi Sander,

Thank you for the prompt response, as usual!

You are a champ! Setting my html table to

<table border=1 width="100%" data-detail data-splitter="2019">

have removed the extra empty table as expected!

Very much appreciate all the help Sander!

Kind regards,

Hi Sander,

I have run to another issue which I forgot to disclose (as I have seen it happened), regarding merge.section.paginate() , every time I call this function any element in the DOM with style "page-break-before:always" to always start on new page, suddenly stop working.

Are you able to shed a light here, why paginate() causing this unintended side effects again?

Not sure if this only happens with content containing dynamic tables as well, not sure if its intended.

Thank you in advanced.
Kind regards,

Hi @edanting,

We fixed several issues related to forced page breaks recently (internal refs: SHARED-90932, SHARED-91365), but unfortunately neither of these fixes made it into 2023.2. They should be in 2024.1.

Are you talking about the fact that page-break-before:always stops working after switching to preview mode and back to design mode? I haven’t been able to find a workaround for that yet. I’ll spend more time on this tomorrow and keep you updated.

If you’re referring to something else, can you perhaps create and attach a minimal example?

Hi Sander,

I seem to be getting issues after issues whenever I progress with paginate() being the center of it all. Here are the things I noticed:

  • When have a simple element <div id="newPage" style="page-break-before: always"> , this works on preview. And creates a new page. But as soon as I call paginate() , the behaviour of creating a new page fails on this element. What I found works is to set the page-break-before in post script. Like so query("#newPage#).css("page-break-before", "always"); merge.section.paginate(); then as you can see I call paginate() after.

  • Another issue Im having that maybe connected to cloning happening in my control script.

noticeCount   = record.detail.length;
originSection = merge.template.contexts.PRINT.sections["Main Section"];
for(var n = 0; n < noticeCount; n++){
// Clone 

var newClone= originSection.clone();
newClone.name = "Main Section " + n;
newClone.enabled = true;
clones[newClone.name]  = {index: n, pages: 0 };



originSection.enabled = false;

whenever I tried doing some manipulation to targeted elements in my post script before triggering paginate() dont work. For eg in my postscript:

Selector: HTML
var element1FromMasterPage = query(".element1");
var element2FromMasterPage = query(".element2");
var newPage = query(".newPageThatNeedsToBreakPage");

element1FromMasterPage.css(“background”, “white”);
element2FromMasterPage.html(“This contains the total page”);
newPage.css(“page-break-before”, “always”);
merge.section.sheetConfig.positions.last.masterBack = “Blank”


page-break-before works here, but other manipulation like updating html value or changing background of an element in current master page dont work.

There seems to be a disconnect repaginating the document/ and updating values, applying css to current element.

All these inconsistencies seems to revolve around paginate() and potentially with cloning.

Maybe theres a mechanism at play. That Im missing regarding how paginate works.

Hopefully this all make sense.

Thank you in advanced.

Kind regards,

UPDATE: It looks like , I can do away with all the content manipulation, so long as I can assign different media/master pages to specific sheet! I am so close! :slight_smile:


Finally managed to do the sheet configuration I wanted with some workaround!

Important notes I learned:

  • When creating dynamic table by hand, set your table like so (version 2023.2):
    <table data-detail="" data-splitter="2019"> <thead>.... <tbody><tr data-breakable="">

  • You can dynamically change media/master pages in Post pagination script by using merge.section.sheetConfig.positions.[first | middle | last ..etc].media and
    merge.section.sheetConfig.positions.[first | middle | last ..etc].MasterFront | MasterBack

  • Use query(“selector”).info() to get element placements, which page your element is rendered.

  • Do pagination action(any manipulation that would cause your document to change page counts or media/master pages) before merge.section.paginate() and only do content manipulation (changing background/values) after paginate()

  • Currently if you have an existing “page-break-before/after” css applied on your document, this will stop working after calling paginate(), you need to do all your intended page break in Post script, this is atm the only way that worked for me. (This could be unintended bug)

As for the bug last point, hopefully theres just something Im doing incorrectly or needed to add to make the page break work natively after calling paginate().

Hi @edanting,

Glad to see the progress you made!

I can reproduce the issue with page-break-before in combination with merge.section.paginate, and I verified that it has been fixed in 2024.1.

It is caused by incorrect logic in the code that processes forced page breaks. The code will not honor a forced page break if a neighboring element has the page_break_before or page_break_after class. These classes are added automatically as part of the pagination process, and the logic breaks if we are paginating twice.

You should be able to work around the issue in 2023.2 by removing those classes before calling merge.section.paginate:

query(".page_break_before, .page_break_after")
    .removeClass("page_break_before page_break_after");

1 Like