Creating a printer friendly version of your MCMS postings
Introduction
At some point, your site visitors are going to want to print a copy of the MCMS 2002 posting (page) that they are viewing. They often demand that the information be presented in a readable format without the navigation controls, graphics and banner ads. How do you do this?
One way to achieve this is to use a print stylesheet as suggested in this MCMS 2002 Newsgroup thread. For more information on this type of implementation, check out this article from css-discuss Wiki. Also make sure to see the CSS2 specification for Paged Media.
Another way to accomplish this would be to use connected templates and postings. Connected templates are template objects that share placeholder definitions, but which may refer to different template files, and have different layouts and placeholder controls. Connected postings are pages that use connected templates and reference the same content source. Connected pages can be used to display a page on a multilingual site, to display the same information in more than one area of your site, or even to create a printer friendly version of your content.
For more information on connected templates and connected postings, see "Page Processing with Connected Templates" in the MCMS 2002 Help File.
The approach I am going to take will be a file based ASP.NET Web Form used in conjunction with an ASP.NET User Control. The User Control will consist of a Hyperlink that passes the current postings Guid to the web form. The web form will then loop through the placeholder collection, gather the content, and render it in a printer friendly version without the navigation controls.
Let’s get started!
Creating the User Control
In this section, we will create the user control that renders the hyperlink for the Print Friendly page.
In Visual Studio.NET, open your MCMS application.
Create a new User control and name it PrintFriendly.ascx.
Drag a HyperLink control from the Web Forms toolbox.
Set the Text property of the HyperLink control to "Print Friendly Version".
Set the ID property of the HyperLink Control to "lnkPrintFriendly".
Switch to your code view and add the following using directives
using Microsoft.ContentManagement.Publishing;
using Microsoft.ContentManagement.Common;In the Page_Load Event, add the following code:
Posting curPosting = CmsHttpContext.Current.Posting;
if(CmsHttpContext.Current.Mode == PublishingMode.Published)
{
lnkPrintFriendly.Visible = true;
lnkPrintFriendly.NavigateUrl = "PrintFriendly.aspx?" + curPosting.Guid;
lnkPrintFriendly.Target = "_Blank";
}
else
{
lnkPrintFriendly.Visible = false;
}Click Save.
The code above grabs the Guid of the current posting and generates a link to the Print Friendly page (which we create in the next section). This link opens a new browser window and will only be visible if we are in published mode.
Creating the Web Form
In this section, we will create the ASP.NET web form that renders only the content for that posting and breaks out of your site's navigation structure and the look and feel. This page will be very generic with just a table that shows the posting's display name and the content. It will be up to you to design the print page to suit your needs.
In Visual Studio.NET, open your MCMS application.
Create a new web form and name it PrintFriendly.aspx.
Create a table that is 650 pixels wide and centered on the page.
Drag a Label Control inside the table and name it "lblPostingDisplayName". This control will render the posting's Display Name property.
Drag a Literal Control inside the table and name it "litPostingContent". This control will render the content of the placeholders.
Your HTML Code should look something like this:
<%@ Page language="c#" Codebehind="PrintFriendly.aspx.cs" AutoEventWireup="false" Inherits="CMSPrintFriendly.PrintFriendly" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
<HEAD>
<title>PrintFriendly</title>
<meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">
<meta name="CODE_LANGUAGE" Content="C#">
<meta name="vs_defaultClientScript" content="JavaScript">
<meta name="vs_targetSchema" content="https://schemas.microsoft.com/intellisense/ie5">
</HEAD>
<body>
<form id="frmPrintFriendly" method="post" runat="server">
<P>
<TABLE align="center" id="tblContent" cellSpacing="1" cellPadding="1" width="650" border="0">
<TR>
<TD>
<P>
<asp:Label id="lblPostingDisplayName" runat="server" Font-Names="Verdana" Font-Size="Small"
Font-Bold="True"></asp:Label></P>
<P><FONT face="Verdana" size="2">
<asp:Literal id="litPostingContent" runat="server"></asp:Literal></FONT></P>
</TD>
</TR>
</TABLE>
</P>
</form>
</body>
</HTML>Switch to your code view and add the following using directives:
using Microsoft.ContentManagement.Publishing;
using Microsoft.ContentManagement.Common;In the Page_Load Event, add the following code:
try
{
// Retrieve the Posting Display Name
string strGuid = Request.QueryString[0].ToString();
Posting curPosting = (Posting)CmsHttpContext.Current.Searches.GetByGuid(strGuid);
lblPostingDisplayName.Text = curPosting.DisplayName;// Retrieve placeholder data for every placeholder (seperated with HTML breaks).
PlaceholderCollection colPlaceholders = curPosting.Placeholders;foreach(Placeholder pH in colPlaceholders)
{
litPostingContent.Text = pH.Datasource.RawContent.ToString();
litPostingContent.Text += "<br><br>";
}
}
catch
{
// Generate a generic error message if it fails
litPostingContent.Text = "Error: There was a problem obtaining the content for this page.";
}Rebuild your solution.
Implementing the Control
The last thing to do will be to implement the control.
- Open an existing MCMS template for your MCMS application.
- Drag the PrintFriendly User Control on to your template file.
- Save this template.
At this point, you can now go view a posting (or create a new one) and click on the link which will generate a printer friendly version in a new browser window.
This posting is provided "AS IS" with no warranties, and confers no rights.
Comments
- Anonymous
March 26, 2004
I always make a point of reading Luke Nyswonger (MCMS Support Engineer) emails ... - Anonymous
March 26, 2004
A much better solution than plain CSS/Javascript for printable versions of postings. This could easily be 'tweaked' to provide a text only site for accessability requirements. - Anonymous
March 28, 2004
Content of a page may have static content (in template) in addition to placeholder content. This method will not be suitable then. - Anonymous
March 29, 2004
Yes this concept will not work in all instances. If you chose this method you could build a separate printer friendly web form based on all of your templates. Depending on your sites complexity this may not be an option. You could also just as easily include code logic within this one web form to render other template data (content, images, etc.) based on the current postings template. - Anonymous
April 09, 2004
Great work Luke!
One thing I encountered on my first test is that I have an image placeholder and 2 text placeholders. The print-friendly output only shows the display name and image placeholder. It does not seem to continue on through the two HTML placeholders.
I am working through the code to see if I can get it to render properly.
Any thoughts or ideas as to why this might happen? - Anonymous
April 12, 2004
Hey Rick,
I had the same problem. I was able to get it to work with the code below. I added a placeholder control to have the literal control run through.
foreach(Placeholder pH in colPlaceholders)
{
litPostingContent = new Literal();
litPostingContent.Text = pH.Datasource.RawContent.ToString();
litPostingContent.Text += "<br><br>";
PlaceHolder2.Controls.Add(litPostingContent);
}
I do have one problem. How do you order the cms placeholders? I have a title placeholder coming after my body placeholder, but I need it to come before the body placeholder.
Any help is appreciated. - Anonymous
April 12, 2004
My placeholders tend to be 1) Header then 2) Body. The image PH that I have on the page is a user-specified brand image that is in our navigation area. This code tends to read it first on the page, then continues on to the Header and Body. - Anonymous
April 12, 2004
You could retrieve the content from the placeholder in the order that you want them displayed by gettings its name and then doing it that way. Do you know if they are being returned by the alpha order of the Placeholder Defintions for that template? You could change that I believe as well. I have not tested that. - Anonymous
April 12, 2004
Got it to work with Dwaynes tweak although the order of the placeholders is reversed on the PrintFriendly output browser (Body first, then Header.)
I think the order is being determined by how the controls appear in the collection. If you check the class browser for your project and analyze the source template for your post, you may notice that the order there determines how the collection will output the placeholder content.
Checking to see how to specify a particular order for the output. - Anonymous
April 12, 2004
Hi Luke,
Correct, the placeholders are being output in alpha order. I just created a new template with definitions of ph1 and ph2. The PrintFriendly.aspx then outputs them in the proper order.
When I tested this on an existing test template and changed my .aspx placeholder control names to ph1 and ph2, there was no effect.
So it is definitely using the ph definitions.
Thanks! - Anonymous
April 23, 2004
The comment has been removed - Anonymous
May 04, 2004
Has anyone been able to get this to pull information out of a ProductPropertyDataSetPlaceholder for an MSIB site? Any help would be much appreciated.
Thanks. - Anonymous
May 17, 2004
Hi Matt,
I'm not experienced with MSIB and couldn't speculate why its not able to grab it from RawContent. I'd suggest posting to the cms and commerce discussion groups to get a wider audience. - Anonymous
May 09, 2007
Hello! Very interesting. Thank you.