Forum How do I...?

Generated content and source ordering

whittaker007
Hi,

I'm just getting started with Prince and paged media CSS. My interest is to author content with reasonably complex layout that can be reformatted with media specific stylesheets.

Generating headers and footers only with content style attributes allows plain text to be inserted, but without the ability to insert rich XML content, the headers and footers can ony be simply styled. Using flow to divert content from the page body to the header and footer area is an ingenious solution and combining these two techniques offers some interesting possibilities.

My test page has a fairly standard web divisions of Header, Content and Footer. The content has been broken into Sections, Subsections and paragraphs. With the print stylesheet I have associated Sections with a page type of Chapter, set page breaks after each, and diverted the contents of the Header and Footer divs into the header and footer margin area to appear on every page. The structure is something like this:

<header>

<content>
   <section>
      <subsection>
      ...
   </section>
   ...
   <section>
      <subsection>
      ...
   </section>
</content>

<footer>


So here's the first problem: the Footer only appears on the last page. I presume that Prince lays out pages as the DOM is parsed, so the footer content is not available until the last page (since it is the last div in the source). Moving the footer from the bottom of the page source to in front of the content results in the footer appearing on every page as desired. Of course having the footer appear before the content is not just a presentational issue (I can use CSS to position the footer back at the bottom of the page), it is also semantically flawed.

I encountered a similar and more problematic issue when I tried inserting some generated content into the header. I set a custom string (chapter-name) to the contents of an h3 element directly following a Section div. If I insert this value into a named span in the header like this:

#header h3 #chapterName { content: ":: " string(chapter-name) " ::"; }


I get ":: ::" in the #chapterName span, which tells me that the span is being targeted correctly, but the string is not being evaluated. If I use this style instead:

@page chapter {
    @top-right {
        content: ":: " string(chapter-name) "::";
    }
}


the generated content is evaluated and inserted correctly, but it's not a complete solution since I have little control over it's appearance and it breaks the header layout.

Has anyone successfully mixed generated content with richly styled headers and footers?

Finally, the background colour for pages doesn't seem to work. I have set some styles on the base page including size, margins, padding, border and background color. All style the page as expected except the page background is always white (or transparent) no matter what I set the background colour to be:

@page { 
	size: A4; margin: 40mm 15mm 20mm; padding: 2em 0;
	background: yellow; border: 1px solid black; 
	@top    { content: flow(header); vertical-align: bottom; }
	@bottom { content: flow(footer); vertical-align: top; }
}


If I can find workarounds to address these issues I will definitely be using Prince for an upcoming project.

Thanks!

Scott
mikeday
Generating headers and footers only with content style attributes allows plain text to be inserted, but without the ability to insert rich XML content, the headers and footers can ony be simply styled. Using flow to divert content from the page body to the header and footer area is an ingenious solution and combining these two techniques offers some interesting possibilities.

As you can see, there are still aspects of headers/footers that need further work. The generated content method is nice, but can't insert text with complex styles, which is a major limitation. Flowing content from the document is handy, but can require modifying the document. One workaround for this might be if the content could be taken from a different document, for situations when the document to be printed can't be easily modified.

So here's the first problem: the Footer only appears on the last page. I presume that Prince lays out pages as the DOM is parsed, so the footer content is not available until the last page (since it is the last div in the source). Moving the footer from the bottom of the page source to in front of the content results in the footer appearing on every page as desired. Of course having the footer appear before the content is not just a presentational issue (I can use CSS to position the footer back at the bottom of the page), it is also semantically flawed.

I wouldn't go so far as to say it was semantically flawed; the XHTML table <thead> and <tfoot> elements may both occur before the <tbody> elements, which is quite a similar situation to page headers and footers.

However, we did implement a solution for this at one point, where you can add an extra value to the flow in order to say that it should be taken back to the start of the document, not just from the current page:
flow: static(header, start)

Regarding page backgrounds, that is rather strange; they should work fine. Do you perhaps have a background set on the root element of the document as well? Perhaps try making a very simple document that just specifies a page background, and it should work.
whittaker007
Flowing content from the document is handy, but can require modifying the document. One workaround for this might be if the content could be taken from a different document, for situations when the document to be printed can't be easily modified.

Another possibility would be creation of header/footer content after the normal flow content has been created. This should be possible since the header and footer occupy predetermined margin space. Then generated content in the header or footer would have access to variables expressed in the body.

Yet another would be to process markup inserted in the content: attribute into DOM elements the same way as javascript's .innerHTML property. This would probably require an additional proprietary tag to set the evaluation mode to text or xml (default being text):
#footer {
   content: "Page <span>" counter(page) " of " counter(pages) "</span>;
   content-type: xml;
}

Finally, though it wouldn't give us the flexibility of the other solutions, you could allow elements inserted and positioned with the @top and other margin positions to be offset with relative or absolute positioning within that block. For example I have my header content diverted to @top, where it fills the available horizontal space just like a block level element. If I then add generated content to @top-right, the @top content no longer spans the whole width (even if I give it a width of 100%) and the layout gets broken. If you could position @top-right content to occupy the same space of the @top content, it would provide more possibilities for layout.
I wouldn't go so far as to say it was semantically flawed; the XHTML table <thead> and <tfoot> elements may both occur before the <tbody> elements, which is quite a similar situation to page headers and footers.

I guess so, but source ordering usability proponents would argue that the most important content should come first in the document source, in which case the content should usually come first, (sometimes even before the header), followed by sub-content, navigation, and finally footer. But in the state of web authoring today, practicality is king and we must accept anything that works as a blessing.
Regarding page backgrounds, that is rather strange; they should work fine. Do you perhaps have a background set on the root element of the document as well?

Ah, yes, I had the body background set to white. So the body element is rendered over the page element. I guess that makes sense.

Thanks,

Scott