thoughts on page templates

>From discussions at TPAC, I have a few thoughts on how to make page templates work and how to unify that with page view & overflow:paged.

Note that this is brainstorming, these ideas may not be new or good. There is a lot of overlap with Peter's proposal [1], there is no intent to compete with that - Peter's proposal is both broader and more detailed, this is trying to find the minimum required functionality for pagination setup and define it in CSS-friendly way. Any outcome of this needs to converge with [1].


1.       Element-per-region

Peter's template design [1] relies on region functionality where a region consumes exactly one element from flow. This is close to what would have happen if there was a forced break after each element, but region auto sizing doesn't work that way now.

I think this calls for a special kind of region, and it will work better than manipulating with forced breaks.

How about this:

     region-type: page | column | box | slot | frame | auto
     (initial: auto)

Region types have this meaning:
                page - paginate the flow ("region-overflow:break"); "break-*:page" treats region as a page
                column - same as page, but "break-*:column" moves to next region and content can be balanced (TBD how to tell which columns are on same page)
                box - consuming one element at a time from the flow. No pagination, layout works as if the element from flow was the only child of the region
                slot - same as 'box' but the element from flow replaces the region. Useful for incompatible containers (e.g. region is <p> and element is <div>). TBD how region and content properties are merged.
                frame - consume all of the flow content, layout as if it was actual content
                auto - page (if content doesn't fit) or frame (if it does) - as defined currently for "region-overflow:auto"

This would replace 'region-overflow' property.


1.1. 'flow-into': element vs. content

The issue of nested containers in regions ("region-type:box" vs. "region-type:slot") can also be addressed by named flow source element sending its content to the flow, e.g. like this:



     <div style="flow-into:title; display:content">Lorem Revisited</div>

Then if template has a region for "title" flow

     <h1 style="flow-from:title; region-type: box"></h1>

it will not get an extra div in the heading.

This can solve other issues of regions adding hierarchy that gets in the way:


*         Combine multiple <OL> elements in a flow and merge numbering

*         Remove semantic grouping elements which don't have rendering (and allow content to be laid out by parent layout, e.g. grid)

Note that "display:content" can have effect when applied to any element (not necessarily related with flows and regions) -- it has the same effect as if the element would be replaced in the DOM tree with its content.

And of course this is a way to solve the problem of <iframe> special behavior:

     <iframe style="flow-into:article; "> -- iframe is named flow
     <iframe style="flow-into:article; display:content"> -- iframe content is named flow
     <iframe style="display:content"> -- similar to "seamless" iframe, but not transparent for dom and styles.


Effect on replaced elements is undefined, but at least should reset any non-default properties.


2.       Template from named flow

This should work without any new features:

<div style="flow-into:template">
     <div style="flow-from:header; region-type:frame;"></div>
     <div style="flow-from:page; region-type:page;"></div>
     <div style="flow-from:footer; region-type:frame;"></div>
</div>

Since regions and flow content are in the same document, nested flows must work (but for iframe-based flow it would not work without allowing flows to be shared across documents).

Note: this style of headers/footers require that "region-type:frame" can render multiple copies of the flow.


3.       Page view with generated pages

There may be many ways to generate pages from templates, but the outcome is reasonable to expect to be something like this:

<div id="page-view">
     <!-- custom UI for page fiew -->
     <div id="page-container">
           <!-- generated pages, may or may not be in DOM -->
           <div id="page1"></div>
           <div id="page2"></div>
           ...
           <div id="pageN"></div>
     </div>
</div>


3.1. GC option - pages as generated content

There could be a construct like this:

     Div#page-container { content:pages }

where content of the pages doesn't need to be specified, templates are picked based on flows globally available in the DOM and pages are generated until the process runs out of content or runs out of templates.

Or it could be something more specific

     Div#page-container { content:pages(first-template-flow-name) }

or even something more advanced, perhaps matching actual flows with flow placeholders in templates.

Generated pages are not visible in DOM, but selectors should work:

     #page-container * { border: 1px solid black; }
     #page-container::nth-child(even) { position:relative; left:<page-width> }

Selectors will work, but dynamically changing page properties from script needs something better than tweaking stylesheet. Perhaps R/W access to style of generated content elements via selector. Or perhaps a generic way to access content in "shadow dom".


3.2. Script option - pages in DOM

Generating pages by script doesn't need any new statndards. Not sure if there is middle ground of generating pages with some kind of databinding and then leaving in dom for scrip to modify if needed. To be explored.


4.       Selecting page templates

4.1. Automatic template selection

Peter's page templates proposal [1] describes in detail one way of matching position in multi-stream content to the most appropriate next template. Formalizing such algorithm belongs to a much longer discussion, but in general the idea is to describe what a template can handle and match a template to available content.

The template properties could be defined like this:

     @page-template cover {
min-width:600px;
max-width:1200px;
flows:author title subtitle publisher;
flow-from:cover-page-template;
}

Then at every new page currently available flows are matched with a template that can display some or all of the flows.


4.2. Event for page template selection

It is very likely that advanced applications will require custom logic for content selection. That logic would need to be invoked when a new page is created.

Could be like this:

     function onNewPage(e) {
           if (e.pageNumber == 1) {
                e.pageTemplate = "template-cover";
           } else {
                e.pageTemplate = "template-two-column";
}
                }


5.       Integration with "overflow:paged"

Built-in page view ("overflow:paged") could be defined as a set of paged generated from default empty template, binding to default flow (there is no such thing as "default flow" currently but it would make sense for such purpose).


6.       Wiki?

There is  a lot of options in all of the above. If any of the above sounds promising I can put it on wiki and see if it can evolve into something implementable.

Alex

[1] http://epub-revision.googlecode.com/svn/trunk/src/proposals/css_page_templates/csspgt-doc.xhtml

Received on Saturday, 5 November 2011 17:43:29 UTC