Make printing easy, using a PrintController
Posted on 24/9/06 by Felix Geisendörfer
Deprecated post
The authors of this post have marked it as deprecated. This means the information displayed is most likely outdated, inaccurate, boring or a combination of all three.
Policy: We never delete deprecated posts, but they are not listed in our categories or show up in the search anymore.
Comments: You can continue to leave comments on this post, but please consult Google or our search first if you want to get an answer ; ).
The web site I currently work on is going to be for the hotel where my step father is the manager of. It's a beautiful little hotel in the Ore Mountains and close to Dresden, so in case you ever plan to visit the area of Germany where I live, make sure to spent a couple nights there. However, their current web site was the first big site I ever did in php (about 3-4 years ago), and is in bad need for a complete relaunch *cough*.
One of the things that is going to be an important 'feature' for the site, is to make it printer friendly. Their guests are usally no computer geeks and like to print stuff, so they can show their familiy more information about their destination.
Since the new site has a very clean markup, I thought about simply creating an additonal style sheet for the media type "print", hide the menu & other unneccessary items with it, and don't worry much about printing at all.
However, after thinking about it a little bit more today, I came to to the conclusion that I'm dealing with WYSIWYG visitors. If there are tons of graphics and a background color on the site, those people will expect to get exactly that if they hit the print button in their browser. I don't think they would mind if the printer then prints out a nice light weight CSS-free design, but I suspect them to be more likely to print things out when they know this up front.
So I decided to get a little fancier, and to create a PrintController, which would output printable versions of any site requested by /print/*. The advantage here is that you can link people to a printable version of the site, instead of telling them to trust you and your mighty CSS skills (which they wouldn't understand anyway) about not wasting their printer ink.
Ok, here is how this PrintController I came up with looks like:
{
var $name = "Print";
var $uses = array();
function index()
{
$this->autoRender = false;
$args = func_get_args();
$url = '/'.join('/', $args);
$Dispatcher =& new Dispatcher();
$Dispatcher->dispatch($url, array('layout' => 'print'));
}
}
I tried to use requestAction, but I couldn't get it to return a rendered action with a given layout, so I decided to call the Dispatcher instead. In case I'm missing something, let me know.
And here a 1.1 compatible 1.2 Route to make sure /print/* works as expected.
One of the cool aspects of this method is that you can serve a different layout for your printable pages, allowing you to remove useless divities and all CSS style sheets relyably. And you can even put statements like this in your action views to optimize things even further:
Again, nothing to see here that couldn't be done with CSS, but personally I think it makes for a better User experience to actually see what you are going to print, even if your browser doesn't offer print preview or such.
Oh and if you are looking for a little example, here is a normal layout vs a print layout screenshot from the site I'm doing right now (and yes, the icons on the left will change again ^^).
Update:
One thing I forgot to mention: If you come from SEO-land and you are afraid google could detect duplicated content, add a robots.txt to your /app/webroot/ and put this in there:
User-agent: *
Disallow: /print
Personally I also have a "Disallow: /admin" in there - just in case ; ).
--Felix Geisendörfer aka the_undefined
You can skip to the end and add a comment.
You could do the same without the PrintController at all, just with routing and a beforeFilter in your app_controller.php
routes.php:
$Route->connect('/print/:controller/:action/*', array('printable' => '1'));
app_controller.php
function beforeFilter()
{
if ( @$this->params['printable'] == '1' ){
// ... whatever you want to change when printing
}
}
Grant Cox: I thought about this, but what happens is that this would break all my other custom routes that I rely on, that's why I use an entire controller for it ; ).
Felix Geisendörfer's Blog: Make printing easy, using a PrintController...
...
That looks like a great option. I often wonder the same about CSS Print stylesheets. I know they are great and really prepare the page for print (getting rid of underlined links, forms, colored images, menus, etc) - but I just don't think many people realize that if they print a colored page - they will get a printer friendly version (just from past experiences). This is why I think it is still important to make it known that there is a printer friendly version.
Looks very nice. The more I read your stuff, the more interested I am in playing with Cake.
I do something similar like this:
i have a LayoutController, and I catch urls like '/light/*' ,'/print/', '/blue/*' etc, and send them to the LayoutController passing light, print , blue etc as layout
Btw ad7six, i think that by saying 'wysiwyg visitors' felix meant that people prefer to have the printer print the same thing as they see on the page (which is prefferably the eye-candy less page using the print.css stylesheet)
I don't think this is related to wysiwyg _editors_ ;-)
Dieter@be,
I guess drinking and blogging/comment aren't that good an idea after all :)
AD7six
Nate: I can't believe you haven't played around with CakePHP so far, I know your job is to maintain a self-made system (right?), but man, you are missing out on some great stuff ; ).
Regarding printing: Yes, even I am one of the people that doesn't intuitivly realize that. Because even if a site is done via CSS, you don't know if the media types have been assigned correctly and for some reason I dislike the print preview when it comes to printing of the web. Basically I just want to klick print, see what I'll get, confirm, and be done with it. If it takes me more then those 3 steps my user experience drops significantly.
I must be doing something wrong. I can see the "layout" going into the params array, but I don't see it actually changing the layout. Is there something I'm missing?
Found what I was missing -- this is for cake 1.2 and I had cake 1.1
This post is too old. We do not allow comments here anymore in order to fight spam. If you have real feedback or questions for the post, please contact us.
Hi Felix,
Regarding requestAction, you could pass the $url variable to the view, set the layout, and put the requestAction call in your /app/views/print/index.thtml.
You could switch pages styles by providing an alternate css in the head of your document for generating a print preview, which would save some time and bandwidth. For semi-tech-savy users, they could switch styles to see what it will look like; for the wholey un-tech-savy user a button using something like this: http://alistapart.com/stories/alternate could achieve the same thing. That is, if they are afraid of the print-preview button of their browser that is - which seems surprisingly common.
I'm not sure it's such a good idea to include logic on whether to include content depending on the layout used, I know you said you were considering WYSIWYG editors, but why not include display:none; in the relavent section of the css used for printing? Try the "plain" page style for my personal site for an example (which uses the same css as if you print).
An thought provoking post as always ;), I wonder if there is any value in knowing which/how many of your visitors print (which) pages..
Cheers,
AD7six
ps. Thanks for the blogroll entries. Both of them :).