Thursday, 14 June 2012

Add Connection String to webconfig.xml

You know you should never modify the webconfig.xml file manually, so lets talk about how to add a connection string through XML. Now keep in mind that this technique can be used to add or remove anything to your webconfig.

First thing you need to do is map the config folder to your project:
  • right click on your project in the solution explore
  • scroll over Add
  • Click on SharePoint Mapped Folder
The "Add SharePoint Mapped Folder" dialogue should pop up, select the config folder.
Once you click OK, the mapped folder should appear in your solution explorer

 
 With the CONFIG mapped folder press ctrl+shift+a to add a new item.
  • in the left hand pane select Data
  • in the middle pane select XML File
  • at the bottom make sure to name your file webconfig.*.xml; it is imperative that you follow this naming format. (webconfig.addConnections.xml)
Once you click the add button you will get an empty xml file to add webconfig modification to
 
add the following to your xml file

<actions>
  <add id ="{BE573280-EDD2-4E9D-9C53-2B943A118F63}" path = "configuration" >
    <connectionStrings />
  </add>
  
  <add id ="{6B92AB06-90B9-4464-BEF5-C0F5B14FABA6}" path = "configuration/connectionStrings" >
    <add name="ConnectionStringName" 
         connectionString="Data Source=myServer;Initial Catalog=INTERNET;User ID=userID;password=Password;" />
  </add>
</actions> 
 
Make sure to use unique id's for your actions otherwise you'll get multiple entries everytime you update your webconfig.
  1. With your XML ready to go, deploy the project.
  2. Once you've deployed your project successfully open up windows powershell (not the ISE) and run the command "stsadm -o copyappbincontent"
 

Presto, all should be well

But if it's not continue to read.

Should you get an error that says "expression must evaluate to a node-set"
that means that you didn't build the path correctly, notice:
first i add the connectionStrings element
  <add id ="{BE573280-EDD2-4E9D-9C53-2B943A118F63}" path = "configuration" >
    <connectionStrings />
  </add>
Second I add the connection string to the the connectionStrings element
  <add id ="{6B92AB06-90B9-4464-BEF5-C0F5B14FABA6}" path = "configuration/connectionStrings" >
    <add name="ConnectionStringName" 
         connectionString="Data Source=myServer;Initial Catalog=INTERNET;User ID=userID;password=Password;" />
  </add>
 
 Finnally if you see this
 
Somewhere there is a duplication, it doesn't necessarily have to be what you did, it could have been someone else breaking the number one law of webconfigs: Thou Shalt Not Manually Edit.

Wednesday, 13 June 2012

DateTimeField custom date format

Before you get your hopes all up there is no straightforward way to do this; though three possible workarounds come to mind:
  • use jQuery on page load to format your date however you please
  • add a codebehind to your pagelayout/masterpage
  • Utilize a calculated column
I proceed with the third option:
First create your site columns

<?xml version="1.0" encoding="utf-8"?>
 
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <Field ID ="{FD53DB35-0C02-45D8-9737-7C32A4184B86}"
         Group ="Portals Columns"
         Name ="Cust_EffectiveDate"
         DisplayName ="Effective Date"
         Type ="DateTime"
         Required="FALSE"
         Format="DateOnly" />
  <Field ID ="{8E90C71A-C8C1-4CD9-A0BC-37482F03EF8E}"
         Name ="Cust_EffectiveDate_Display"
         DisplayName="Published Effective Date"
         Group="Portals Columns"
         Type="Calculated"
         ResultType="Text" 
         ReadOnly="TRUE" 
         Required="FALSE">
    <Formula>=TEXT([Effective Date],"MMMM dd, yyyy")</Formula>
  </Field>
</Elements>

With your site columns deployed the next step is to make your content type, make sure to inherit from page

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <!-- Parent ContentType: Page (0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF39) -->
  <ContentType ID="0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF3900a689672336e64278beb708d5d4807b7f"
               Name="PolicyProcedureType"
               Group="CCW Portals Content Types"
               Description="Custom content type for Policy or Procedure pages"
               Inherits="TRUE"
               Version="0">
    <FieldRefs>
      <FieldRef ID ="{FD53DB35-0C02-45D8-9737-7C32A4184B86}" Name ="cust_EffectiveDate" />
      <FieldRef ID ="{8E90C71A-C8C1-4CD9-A0BC-37482F03EF8E}" Name ="cust_EffectiveDate_Display"/>
    </FieldRefs>
  </ContentType>
</Elements> 
 
Now that your Custom content type is created go ahead and create a custom page layout that inherits from your content type.

Then in your page layout to display the DateTimeField in edit mode and the CalculatedField in display mode.


<PublishingWebControls:EditModePanel ID="DateEditModePanel" runat="server">
    <SharePoint:DateTimeField ID="EffectiveDateField" FieldName="Cust_EffectiveDate" runat="server" />
</PublishingWebControls:EditModePanel>
 
<PublishingWebControls:EditModePanel ID="DatePublishModePanel" PageDisplayMode="Display" runat="server">
    <SharePoint:CalculatedField ID="CalculatedDateField" FieldName="Cust_PublishedEffectiveDate_Display" runat="server" />
</PublishingWebControls:EditModePanel>

Retrieving the PublicKeyToken

Simplest way to get the public key Token which is sometimes needed when you build your assembly tag
 <%@ Assembly Name="Mobile.MasterPage, Version=1.0.0.0, Culture=neutral, PublicKeyToken=8173e6146926d073" %>
 
Inside of Visual studio 2010 click on tools in your menu and select "External Tools..." from the drop down.

with The External Tools Dialogue open click the Add button on the right hand side and fill in the details specified:
  • Title: Get Public Token
  • Command: The Path to sn.exe (C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\sn.exe)
    if that's not the path for you just search your hard drive.
  • Arguments: -Tp $(TargetPath)
  • Initial Directory: (Leave it blank)
Make Sure to Check off: Use Output Window
and it should now appear in the tools drop down menu.

Monday, 4 June 2012

Custom Page Layout with Content Type

How to Create a Custom Page Layout with it's own Content Type while displaying the Meta Data as Page Content.

First Step Create some site columns that you're going to use inside your content type:
<?xml version="1.0" encoding="utf-8"?>
<!-- Custom Site Columns -->
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <Field ID ="{F8B5DA47-CC24-498B-8D80-8B2AC7774AB2}"
       Name ="Custom_EffectiveDate"
       DisplayName ="Effective Date"
       Type ="DateTime"
       Required="FALSE"
       Group="Custom Site Columns"
       Format="DateOnly" />
  <Field ID="{B18BC51D-3ADF-4EBD-8AE7-924EF70252CA}"
       Name ="Custom_Opinion"
       DisplayName="Opinion"
       Type="Note"
       Required="TRUE"
       Group="Custom Site Columns"/>
  <Field ID ="{57C17546-3D1E-485B-9F8F-9B61E1544245}"
       Name ="Custom_Priority"
       DisplayName ="Priority"
       Type="Choice"
       Required="TRUE"
       Group="Custom Site Columns">
    <CHOICES>
      <CHOICE>High</CHOICE>
      <CHOICE>Medium</CHOICE>
      <CHOICE>Low</CHOICE>
    </CHOICES>
  </Field>
</Elements> 
 
Once you have your Site Columns set up, it's time to create your content type:
 
 
Make sure you inherit from type Page.
With your content type created, just add your Custom FieldRefs from your custom site columns:
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <!-- Parent ContentType: Page (0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF39) -->
  <ContentType ID="0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF3900d1ea0c66dfaf42bc9ae1d6475d2e5161"
               Name="CustomType"
               Group="Custom Content Types"
               Description="My Content Type"
               Inherits="TRUE"
               Version="0">
    <FieldRefs>
      <FieldRef ID ="{F8B5DA47-CC24-498B-8D80-8B2AC7774AB2}" Name ="Custom_EffectiveDate"/>
      <FieldRef ID ="{B18BC51D-3ADF-4EBD-8AE7-924EF70252CA}" Name ="Custom_Opinion"/>
      <FieldRef ID ="{57C17546-3D1E-485B-9F8F-9B61E1544245}" Name ="Custom_Priority"/>
    </FieldRefs>
  </ContentType>
</Elements> 
 
With your custom content type ready it's time to make your page layout, this is more or less a three part effort
  • add a module
  • change sample.txt to pagelayout.aspx
  • provision the page with the elements file 
To get started lets add a module, navigate in your solution explorer to where you want to add your page layout and hit (ctrl+shift+A)
make sure you have SharePoint 2010 selected in the left hand pane, Module selected in the middle Pane, then give your page layout a unique yet descriptive name; finally hit the add button.

Inside your module you should have an elements.xml and a sample.txt file.
First open the sample.txt file and paste the following code over top the sample text

<%@ Assembly Name="$SharePoint.Project.AssemblyFullName$" %>
<%@ Import Namespace="Microsoft.SharePoint" %>
<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" 
             Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> 
<%@ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" 
             Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> 
<%@ Register Tagprefix="PublishingWebControls" Namespace="Microsoft.SharePoint.Publishing.WebControls" 
             Assembly="Microsoft.SharePoint.Publishing, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> 
<%@ Register Tagprefix="PublishingNavigation" Namespace="Microsoft.SharePoint.Publishing.Navigation" 
             Assembly="Microsoft.SharePoint.Publishing, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
 
<%@ Page language="C#" masterpagefile="~masterurl/custom.master"
         Inherits="Microsoft.SharePoint.Publishing.PublishingLayoutPage,Microsoft.SharePoint.Publishing,Version=14.0.0.0,Culture=neutral,PublicKeyToken=71e9bce111e9429c" %>
 
<asp:Content ContentPlaceholderID="PlaceHolderPageTitle" runat="server">
 <SharePoint:FieldValue id="PageTitle" FieldName="Title" runat="server"/>
</asp:Content>
 
<asp:Content ContentPlaceholderID="PlaceHolderMain" runat="server">
 
</asp:Content>

Now rename your sample.txt file to an .aspx one, I named mine  layout01.aspx.


With your files renamed you are now ready to design your actual Page Layout; Inside the Main Content Place holder add your Layout HTML.

<asp:Content ContentPlaceholderID="PlaceHolderMain" runat="server">
    <div id="PageContent">    
        <table id="DetailsTable">
            <caption>
                <SharePoint:TextField ID="TitleField" FieldName="Title" runat="server" />
                <SharePoint:DropDownChoiceField ID="PolicyProcedureField" FieldName="Custom_Priority" runat="server" />
            </caption>
 
            <tr>
                <td class = "FirstColumn" >Effective Date: </td>
                <td class = "SecondColumn"><SharePoint:DateTimeField ID="Custom_EffectiveDate" 
                    FieldName="Custom_EffectiveDate" runat="server" /></td>
                <td class = "ThirdColumn"><SharePoint:NoteField ID = "DescriptionField" 
                    FieldName="Custom_Opinion" runat = "server" /></td>
            </tr>
        </table>            
 
 <div id="MainContent">
   <PublishingWebControls:RichHtmlField FieldName="PublishingPageContent" PrefixStyleSheet="ccw-" 
                                                      HasInitialFocus="True" MinimumEditHeight="400px" runat="server"/>
        </div>
    </div> 
    <div id = "RelatedColumn">
        <WebPartPages:WebPartZone ID="MainContentWebPart" Title="Web Part Zone" runat="server" FrameType="TitleBarOnly">
 
 </WebPartPages:WebPartZone>
    </div>
</asp:Content>
 
I've created simple layout that consists of an area to fill in your meta data a place to put your content and finally a web part zone if you wanted to add a web part.

Next you have to setup the elemets file to deploy your Page Laout, for this Open the Elemets.xml file
Above is what you should have as default we are going to make the following changes:
<?xml version="1.0" encoding="utf-8"?>
 
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <Module Name="CustomPageLayout" Url="_catalogs/masterpage">
    <File Path="CustomPageLayout\layout01.aspx" Url="layout01.aspx" Type="GhostableInLibrary" IgnoreIfAlreadyExists="TRUE">
      <Property Name="Title" Value="Policy page Layout" />
      <Property Name="MasterPageDescription" Value="This page layout For Policy Pages" />
      <Property Name="ContentType" Value="$Resources:cmscore,contenttype_pagelayout_name;" />
      <Property Name="PublishingPreviewImage" Value="~SiteCollection/_catalogs/masterpage/$Resources:core,Culture;/Preview Images/DefaultPageLayout.png, ~SiteCollection/_catalogs/masterpage/$Resources:core,Culture;/Preview Images/DefaultPageLayout.png" />
      <Property Name="PublishingAssociatedContentType" Value=";#CustomPage;#0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF3900fdd825c8803c43d1bd98bd0306fa8971;#" />
    </File>
  </Module>
</Elements>
Notice that in the Property PublishingAssociatedContentType we get the values from our Custom Content type 
at the start of this post. 
Before you deploy, go into the feature of your project and make sure that you provision:
  • site columns
  • content type
  • page layout 
it should resemble the following

deploy your project and all should be well.