Printable View Needs Rethinking
Ever since we started supporting multiple skins and
TWikiApplications seriously and these became used more widely, we have had problems in TWiki with the printable view.
In pre-Dakar days, the printable view was done via a special
print skin. This had the disadvantage, that the same printable view was used for
all skins, making that view rather unattractive looking for some skins. (A relic of this can still be seen in the
SlideShowPlugin, where the print skin is used to render the page, making everything look like classic skin.)
In Dakar, we moved to a scheme where the printable view was relegated to skins. In
PatternSkin, the de facto standard, it is accomplished by a special template,
viewprint.pattern.tmpl, which is loaded when the printable view is invoked.
This approach has the following disadvantages:
- Every skin needs to define its approach to skins, raising the risk of every skin doing it differently.
- Topic-specific templates are ignored when the printable view is invoked, breaking all TWikiApplications that rely on topic-specific templates.
The real problem, I believe is that
the printable view is neither a separate skin nor a template.
Let me try to expand...
First the problem with the Dakar
?template=viewprint approach. The
viewprint.pattern.tmpl is a modification of the
view.pattern.tmpl template making the appropriate adjustments so that only the material is rendered which should be shown in printable mode. This is accomplished by reading the
viewprint.pattern.tmpl whenever the printable mode is invoked, forcing this via the
template URL parameter. However, this conflicts with topic-specific templates in the following way: A topic-specific template also typically modifies the
view template. For example, the following is a subset of a topic-specific template.
%TMPL:INCLUDE{"view"}%
%TMPL:DEF{"beforetext"}%<div class="twikiBeforeText">
%CALC{$IF($EXACT(%WEEKLYONLY%,1), ,See also <img src="%PUBURL%/%TWIKIWEB%/TWikiDocGraphics/home.gif" border="0" alt="Charter">[[%LABEL%Charter][Charter]] <img src="%PUBURL%/%TWIKIWEB%/TWikiDocGraphics/searchtopic.gif" border="0" alt="Summary">[[%LABEL%Summary][Summary]] <img src="%PUBURL%/%TWIKIWEB%/TWikiDocGraphics/statistics.gif" border="0" alt="Dashboard">[[%LABEL%Dashboard][Dashboard]])}%
---++!! %TITLE% Weekly Updates
</div>%TMPL:END%
It uses the
view template, but adds that before the text there is some additional material displayed, in this case a row of links unique to this topic, as well as a header. (Remember, to use this feature, you set the
VIEW_TEMPLATE variable to the name of the topic-specific template.) This works great, until somebody hits "Printable". Then the
viewprint.pattern.tmpl template is used instead, omitting the pretext material. Please, don't get hung up on the specifics of the example. The point is that the topic-specific template might show all kinds of things very different from the standard view template. The printable mode, instead, will show what is rendered by the standard view template, minus the non-printable elements. That may even be nothing, if all the rendering is done by the topic-specific template.
There are two possible dignoses of the problem:
- The topic-specific template is really defining a new skin, so it is a mistake to just modify the
view template. The user should define a skin instead, and then have her own viewprint template.
- The printable mode is not really a skin nor a template, but just an overlay to the existing skin and template, and "subtracts" certain non-printable matter from the template.
I do believe (1) is a non-starter, as this would require that every
TWikiApplication which uses topic specific templates has define a separate skin with a different
viewprint template. In my
TWikiApplications I often have several different topic-specific templates, which would require a different
viewprint template for each. For example, the exerpt above is from a project reporting application, where there are topic-specific templates for the weekly report, the dashboard, the project summary, the project charter, the project report card, and the project slide show. All these would require their own
viewprint template.
I think the right approach is (2). I have not yet worked out the details, but will do so as we go along. Please comment below.
I think there is an additional problem with the printable mode, which has not yet come out. The current approach only eliminates certain aspects, such as the left bar, or the action buttons, etc. However, in the printable view one may also want to remove link indications, other buttons such as the "Edit table" button generated by the various table editing plugins, buttons that enable editing of sections, etc. It would be great if that could be addressed as well. In a sense, what should appear in the printable view is only partially a matter of the skin, but should be consistent across all skins.
Back to the overlay. My current thinking is this: Rather than being a normal template, define the printable template as an addon to an existing template. In other words, do not include any other templates, but just redefine the portions of the view template that need to be changed. Invoke it via a different URL parameter, or alternatively, name it
view.printpattern.tmpl and invoke it via
?cover=printpattern.
I shall do an experiment and report back...
See also
Bugs:Item2771
--
Contributors: ThomasWeigert - 09 Dec 2006
Discussion
Very good overview of the problem and I think you are on the right track.
--
KennethLavrsen - 09 Dec 2006
Turns out the first level solution to this problem appears pretty easy:
- Define an overlay template for the printable view and name it, say,
view.printpattern.tmpl (the name must be view )
- Invoke it with
?cover=printpattern
Theoretically, it would be sufficient to just rename the current
viewprint.pattern.tmpl to
view.printpattern.tmpl. However, there is a bug in the
viewprint.pattern.tmpl in that its definition of
%TMPL:DEF{"content"}% is wrong anyway, in not including
beforetext and
aftertext, as well as always putting attachements and forms at the bottom, contrary to what the view might do. But once you fix that (and examine for any other inconsistencies) this solves the first level problem.
This addresses
- the original issue with the Cairo approach, as every skin can have its own printable view, by choosing appropriate names, e.g.,
view.printclassic.tmpl, view.printpattern.tmpl, etc.
- the issue with topic specific templates, as the print template now modifies the topic specific template as desired rather than eliminating it.
- the issue with plugins using templates and skins, such as SlideShowPlugin.
It might be worth checking whether one can apply, in addition, some rewrites in general which remove anchors, etc., but that can be an enhancement for next release...
--
ThomasWeigert - 09 Dec 2006
This is not so much about print templates as it is about the (impossibility of) stacking templates. I had the same issue this week with an addon that defines a VIEW_TEMPLATE while I have at the same time a pattern skin override for my company. User COVER might be the right direction, I will investigate this as well.
--
ArthurClemens - 10 Dec 2006
Arthur, I think your problem would be solved in the same way. You just have to be make sure that the covering template overrides what you want to change but leaves the VIEW_TEMPLATE to do its work.
The more templates get stacked, the trickier that gets...
--
ThomasWeigert - 10 Dec 2006
What about controlling the printable view using
CSS? Let me explain.
There may be some widgets rendered by the core, some widgets rendered by the skins and some widgets rendered by the plugins that are not suppose to be printed (like the left bar, the
edit button from
EditTablePlugin or the sort arrow of
TablePlugin).
Those elements can be assigned a special class
.twikiNotPrintable, and then the core can inject the proper style for the printable view:
.twikiNotPrintable {
display:none;
}
How to inject it? I can think two options:
- Use a "cover" template that includes the style
- Wire it into the Core.
Comments?
--
RafaelAlvarez - 10 Dec 2006
See
MarkNonPrintableObjects.
--
ArthurClemens - 10 Dec 2006
Something to note:
cover does not keep the current skin setting.
Let's say I have a custom edit template
myskin:
- If I write
%INCLUDE{"edit"}% and I set the url to bla/edit/TheTopic?cover=myskin, nothing is displayed.
- If I write
cover=myskin,pattern, nothing is displayed either
- If I write
cover=pattern,myskin, I cannot override template elements because these are already defined
- The only way it works is to write
%INCLUDE{"edit.pattern"}% and to set the url to bla/edit/TheTopic?cover=myskin. But then I am hardwiring pattern skin. Which is often necessary, after all I am overriding elements from a specified skin, but the notation is not all that intuitive.
--
ArthurClemens - 10 Dec 2006
Hmmm... I will study this but what you describe (assuming I understand it right) should not happen. I have to confess that I have used cover only with view templates, but theoretically that should be the same as with edit templates. Note that I have added some fixes earlier (independent of this issue) for the view script as it was loosing the skin; maybe the same fixes need to be made for the edit script. Could you please check whether your issues are edit script specific or happen with the view script as well?
One issue that I have with your description is that you should use the topic specific template via
EDIT_TEMPLATE, not via cover.
Could you send me your templates for testing?
--
ThomasWeigert - 11 Dec 2006
Sorry, but
why was it that PatternSkin abandoned using
view.print.pattern.tmpl for printing and now uses
viewprint.pattern.tmpl?
Seems so,
this is the reason TWikiApps+PatternSkin using VIEW_TEMPLATES clash. In general it should be
enuf for a topic-template to
%TMPL:INCLUDE{"view"}% and forget about the rest.
- 1. Some skin specific elements need to be hidden. 2. A print stylesheet should be invoked. So setting
?skin=print will not work, its not skin specific. -- ArthurClemens - 11 Dec 2006
- Sorry, I meant
view.print.pattern.tmpl for printing (corrected above). So why was it abandoned for printing? Why is ?skin=print.pattern bad? This avoids at least the VIEW_TEMPLATE issue that exists now. -- MD
--
MichaelDaum - 11 Dec 2006
There never was a
view.print.pattern.tmpl mechanism, as far as I know. The original mechanism was
view.print.tmpl which had the problems that Arthur describes.
But if there were, there would still be the issue that
?skin=print.pattern could not be loaded if one had templates defined as topics. I am hoping to drive towards a unique way of doing printable.
- Erm, why? I make a lot of use of topic templates in TWikiApps and print using
?skin=print.nat and things are just fine. -- MD
- What I meant was that you could not have a template for print defined as topic if the name had to have a "." in it. -- TW
I must say I am surprised that
?skin=print.nat works. Cover, yes, but skin?
- There's zero magic in that. It is just a stripped down version of the skin's normal view. Til now, I have no use for covers. -- MD
- Here is why I am surprised. If you set skin to be "print.nat", then it will look for that skin for all included template snippets, and if that skin does not exist, it will fall back to the default skin. So unless you no further included templates in "print.nat" I cannot see how that would work. I just looked at your "print.nat", and in fact, it only includes one other template, also "defaultjavascript.nat". This template does not reuse other templates and hardwires too many things, e.g., form is always at the bottom, attachements are always at the bottom, topic-specific templates that change display of form or attachements won't work, topic-specific templates that do anything to before and after text, won't work... etc... As I said, I don't think this can work in any generic manner... -- TW
- Admitted, there could be more reusage in
view.print.nat.tmpl but this is all doable and no big issue, and by far not a conceptual problem! Forms are not hardwired to be at the bottom. Most of my TWikiApps hide the form table by overriding the content macro appropriately, which is the same macro used in the normal view. This is all that needs to be guaranteed: that the macro is named the same in view.SKIN.tmpl and view.printSKIN.tmpl, content in this case. It will insert the net data just at the right place. -- MD
I chose the
cover approach as a solution that solves the immediate problem. I don't think it is the final solution, as I would prefer to have the invocation of the printable mode to be independent of which skin you are using. E.g., I would like to have in my topic a button "view in printable mode" which works right no matter what skin you are using, so having the name of the skin embedded in the printable command is not right.
- That's true, but not so much of an issue when the "print" button is part of the skin, so ... -- MD
- In many of my apps I have links where I am showing things in printable mode.
But I suggest that to be a 4.2 issue.
The right way is probably to define a
?printable=on parameter, which will invoke the right printable template, independent of which skin we are using.
--
ThomasWeigert - 11 Dec 2006
Thomas, on the
PrecompileTemplatesForPerformance topic, I've attached a patch that you problably would like for debugging and comparing template evaluation between 4.0 and 4.1 - In templates_postinclude I add a template comment that shows what tmpl file is actually included..
I think i agree with your surprise wrt
?skin=print.nat but like Micha says, theres alot less reuse in skins than perhaps there should be.
In some of my deployed sites, I have SKIN=webpermissions,someother,localpatterncustomisation,pattern and you're right, the correct answer would be to add something like
?templatecover=print , and preffereably have it try to resolve as print.webpermissions, print.someother, print.localpatterncustomisation, print.pattern, print.default
until it finds a match :/
--
SvenDowideit - 11 Dec 2006