Monday, November 19, 2018

Page Layouts button was disabled for a publishing SharePoint page

 Issue: While trying to update the page layout for any page in SharePoint, I realized that Page Layouts button was disabled!

Reason: There can be many reasons for this, but here are the first things to check
1. SharePoint Server Publishing Infrastructure feature should be activated at site collection level.
2. SharePoint server publishing feature should be activated at site level.
You should now be able to see that button in top ribbon under Page Actions tab.

But, if you are like me and working in SharePoint 2010 and if you see the option after publishing feature is enabled, but if it is DISABLED, try this –

Click on ‘Save and Keep Editing’
  
It’s available now.

Thank you very much

          Fahadullah Karimi

         SharePoint Specialist




How to Save Site as Template in Publishing Site Template in SharePoint 2013 Power shell to delete SharePoint Group

Monday, February 5, 2018

How to Save Site as Template in Publishing Site Template in SharePoint 2013

Missing “Save Site As Template” Option in Sites with Publishing feature enabled.

One of the old and well known workarounds for this was to directly navigate to “_layouts/savetmpl.aspx” application page and save the site Template. This workaround however does not work as expected in SharePoint 2013 sites.

In a Typical SharePoint 2013 Publishing Site, if you try to navigate to “_layouts/savetmpl.aspx” you would get the below error –

“The “Save site as template” action is not supported on this site.”


something went wrong

The url “_layouts/savetmpl.aspx” failed on the Publishing site because by default, in at Typical Publishing Site in SharePoint 2013, “SaveSiteAsTemplateEnabled” is set as “false”. Setting this switch as true would re-enable us to use “_layouts/savetmpl.aspx” to save a Typical Publishing Site in SharePoint 2013.

The easiest way to set SaveSiteAsTemplateEnabled as true is by using Site options in SharePoint Designer 2013.

Lets look the Steps –

1. Open you Team Site in SharePoint Designer 2013.

2. In SharePoint Designer, under Sites tab select “Site Options” (see screen below)


SiteOptions

3. Find “SaveSiteAsTemplateEnabled” in Site Properties (see below).

Save Site As Template Enabled

4. Next change this setting to “true”.

Set as True

             

Apply the Setting once done.

5. Now in your Publishing site navigate to “http://sitename/_layouts/15/savetmpl.aspx” and you would see the old Save Site as Template Page as expected.


                             Save as Template
     

   

Thank you very much

          Fahadullah Karimi

         SharePoint Specialist


Best Practice for disposing objects in SharePoint Development Page Layouts button was disabled for a publishing SharePoint page

Tuesday, January 30, 2018

Best Practice for disposing objects in SharePoint Development

 Using clause use to dispose common SharePoint objects like SPWeb and SPSite. This is an important issue for production environments, since not correctly disposing objects will result in excessive memory and resource usage, while over-disposing can lead to error spamming in the SharePoint log files.

Following are some of the best Practice for disposing objects in SharePoint Development


Best Practice #1: Use the Using Clause for all Sharepoint objects that implement the IDisposable interface

Example C# Coding

String str;

using(SPSite oSPsite = new SPSite("http://server"))

{

using(SPWeb oSPWeb = oSPSite.OpenWeb())

{

    str = oSPWeb.Title;

    str = oSPWeb.Url;

}

}

Best Practice #2: Use the try/catch/finally blocks. When you use try blocks, it is important to add a finally block to ensure that all objects are disposed off properly:

Example C# Coding

String str;

SPSite oSPSite = null;

SPWeb oSPWeb = null;

try

{

oSPSite = new SPSite("http://server");

oSPWeb = oSPSite.OpenWeb(..);

str = oSPWeb.Title;

}

catch(Exception e)

{

}

finally

{

if (oSPWeb != null)

  oSPWeb.Dispose();

 

if (oSPSite != null)

   oSPSite.Dispose();

}

Best Practice #3: Using Response.Redirect in the try block will never execute the finally block, so it is important, to dispose off all objects before the redirection occurs:

Example C# Coding

String str;

SPSite oSPSite = null;

SPWeb oSPWeb = null;

bool bDoRedirection = true;

try

{

oSPSite = new SPSite("http://server");

oSPWeb = oSPSite.OpenWeb(..);

str = oSPWeb.Title;

if(bDoRedirection)

{

    if (oSPWeb != null)

       oSPWeb.Dispose();

    if (oSPSite != null)

       oSPSite.Dispose();

    Response.Redirect("newpage.aspx");

}

}

catch(Exception e)

{

}

finally

{

if (oSPWeb != null)

  oSPWeb.Dispose();

if (oSPSite != null)

   oSPSite.Dispose();

}

Best Practice #4: Whenever you create an object with a new operation, the creating application must dispose it off

Example C# Coding

SPSite oSPSite = new SPSite("http://server");

... do some task ...

oSPSite.Dispose();

Or  by using clause

using(SPSite oSPSite = new SPSite("http://server"))

{

... do some task ...

}

Best Practice #5: For Site.OpenWeb method, you need to dispose it off explicitly.

Example C# Coding

String str;

SPSite oSPSite = new SPSite("http://server");

SPWeb oSPWeb = oSPSite.OpenWeb();

str = oSPWeb.Title;

str = oSPWeb.Url;

... do some task ...

oSPWeb.Dispose();

oSPSite.Dispose();

Or  by using clause

String str;

using(SPSite oSPSite = new SPSite("http://server"))

{

using(SPWeb oSPWeb = oSPSite.OpenWeb())

{

    str = oSPWeb.Title;

    str = oSPWeb.Url;

... do some task ...

}

}

Best Practice #6: An exception to the rule is that One should not explicitly dispose SPSite.RootWeb, as it is automatically disposed off.

Similarly one should not explicitly dispose SPContext.Current.Site and SPContext.Current.Web as they are handles automatically by Sharepoint and .NET framework.

Example C# bad Coding Practice

void SPContextBADPractice()

{

 SPSite siteCollection = SPContext.Current.Site;

 siteCollection.Dispose();  // DO NOT DO THIS

 SPWeb web = SPContext.Current.Web;

 web.Dispose();   // DO NOT DO THIS

}

Example C# good Coding Practice

void SPContextBestPractice()

{

 SPSite siteCollection = SPContext.Current.Site;

 SPWeb web = SPContext.Current.Web;

 // Do NOT call Dispose()

}

Best Practice #7: SPControl.GetContextSite(Context) and GetContextWeb(Context) return SPSite and SPWeb respectively, they do not need an explicit call to Dispose(), they will be disposed automatically

Example C# bad Coding Practice

void SPControlBADPractice()

{

 SPSite siteCollection = SPControl.GetContextSite(Context);

 siteCollection.Dispose();   // DO NOT DO THIS

 SPWeb web = SPControl.GetContextWeb(Context);

 web.Dispose();  // DO NOT DO THIS

}

Example C# good Coding Practice

void SPControlBestPractice()

{

 SPSite siteCollection = SPControl.GetContextSite(Context);

 SPWeb web = SPControl.GetContextWeb(Context);

 // Do NOT call Dispose()

}

Best Practice #8: SPWeb.ParentWeb  returns SPWeb, and needs to be disposed off explicitly using either Dispose() or the using clause

Example C# bad Coding Practice

void ParentWebLeak()

{

 using (SPSite siteCollection = new SPSite("http://moss"))

 {

     using (SPWeb outerWeb = siteCollection.OpenWeb())

     {

         SPWeb parentWeb = outerWeb.ParentWeb; // Internal reference to SPWeb parentWeb

         string sTitle = parentWeb.Title;

         string sUrl = parentWeb.Url;

         // SPWeb object parentWeb leaked

     } // SPWeb object outerWeb.Dispose() automatically called

 }  // SPSite object siteCollection.Dispose() automatically called

}

Example C# good Coding Practice

void ParentWebBestPractice()

{

 using (SPSite siteCollection = new SPSite("http://moss"))

 {

     using (SPWeb outerWeb = siteCollection.OpenWeb())

     {

         using (SPWeb parentWeb = outerWeb.ParentWeb) // Internal reference to SPWeb parentWeb

         {

             string sTitle = parentWeb.Title;

             string sUrl = parentWeb.Url;

         } // SPWeb object parentWeb.Dispose() automatically called

     } // SPWeb object outerWeb.Dispose() automatically called

 }  // SPSite object siteCollection.Dispose() automatically called

}

Best Practice #9: SPWeb.Webs returns an SPWeb object, practically used in drilling down sub-sites within a Site

Example C# bad Coding Practice

void WebsLeak()

{

 using (SPSite siteCollection = new SPSite("http://moss"))

 {

     using (SPWeb outerWeb = siteCollection.OpenWeb())

     {

         foreach (SPWeb innerWeb in outerWeb.Webs)

         {

             // SPWeb innerWeb leak

         }

     } // SPWeb object outerWeb.Dispose() automatically called

 }  // SPSite object siteCollection.Dispose() automatically called

}

Example C# good Coding Practice

void WebsBestPractice()

{

 using (SPSite siteCollection = new SPSite("http://moss"))

 {

     using (SPWeb outerWeb = siteCollection.OpenWeb())

     {

         foreach (SPWeb innerWeb in outerWeb.Webs)

         {

             innerWeb.Dispose();

         }

     } // SPWeb object outerWeb.Dispose() automatically called

 }  // SPSite object siteCollection.Dispose() automatically called

}

Best Practice #10: AllWebs[] Indexer returns SPWeb

object that needs to be disposed to avoid aggregation of memory which

can lead to memory pressure when running on a site collection with

large number of sub sites. Practically used in Enumerating or iterating all webs in a site collection.

 

Example C# bad Coding Practice

void AllWebsForEachLeakBestPractices()

{

 using (SPSite siteCollection = new SPSite("http://moss"))

 {

     using (SPWeb outerWeb = siteCollection.OpenWeb())

     {

         foreach (SPWeb innerWeb in siteCollection.AllWebs)

         {

              // Explicit Dispose must be called to avoid aggregation of memory

         }

     } // SPWeb object outerWeb.Dispose() automatically called

 }  // SPSite object siteCollection.Dispose() automatically called

}

Example C# good Coding Practice

void AllWebsForEachLeakBestPractices()

{

 using (SPSite siteCollection = new SPSite("http://moss"))

 {

     using (SPWeb outerWeb = siteCollection.OpenWeb())

     {

         foreach (SPWeb innerWeb in siteCollection.AllWebs)

         {

             innerWeb.Dispose();   // Explicit Dispose must be called to avoid aggregation of memory

         }

     } // SPWeb object outerWeb.Dispose() automatically called

 }  // SPSite object siteCollection.Dispose() automatically called

}

 

Example C# bad Coding Practice

void AllWebsIndexerLeak()

{

 using (SPSite siteCollection = new SPSite("http://moss"))

 {

     SPWeb web = siteCollection.AllWebs[0];

     // SPWeb web leaked

 }  // SPSite object siteCollection.Dispose() automatically called

}

Example C# good Coding Practice

void AllWebsIndexerBestPractice()

{

 using (SPSite siteCollection = new SPSite("http://moss"))

 {

     using (SPWeb web = siteCollection.AllWebs[0])

     {

     } // SPWeb object web.Dispose() automatically called

 }  // SPSite object siteCollection.Dispose() automatically called

}

Best Practice #11: AllWebs.Add() returns a instance of SPWeb object which needs to be disposed.

Example C# bad Coding Practice

void AllWebsAddLeak()

{

 using (SPSite siteCollection = new SPSite("http://moss"))

 {

     SPWeb web = siteCollection.AllWebs.Add("site-relative URL");

     // SPWeb web Leaked

 }  // SPSite object siteCollection.Dispose() automatically called

}

Example C# good Coding Practice

void AllWebsAddBestPractice()

{

 using (SPSite siteCollection = new SPSite("http://moss"))

 {

     using (SPWeb web = siteCollection.AllWebs.Add("site-relative URL"))

     {

     } // SPWeb object web.Dispose() automatically called

 }  // SPSite object siteCollection.Dispose() automatically called

}

Best Practice #12: OpenWeb() returns a SPWeb object which needs to be disposed.

Example C# bad Coding Practice

void OpenWebLeak()

{

 using (SPWeb web = new SPSite(SPContext.Current.Web.Url).OpenWeb())

 {

     // SPSite leaked !

 } // SPWeb object web.Dispose() automatically called

}

Example C# good Coding Practice

void OpenWebBestPractice()

{

 using (SPSite siteCollection = new SPSite("http://moss"))

 {

     using (SPWeb web = siteCollection.OpenWeb())

     {

     } // SPWeb object web.Dispose() automatically called

 }  // SPSite object siteCollection.Dispose() automatically called

}

Best Practice #13:new SPSite() - Instantiating SPSite objects with the new operator needs to be disposed.

Example C# bad Coding Practice

void CreatingSPSiteLeak()

{

 SPSite siteCollection = new SPSite("http://moss");

 // siteCollection leaked

}

Example C# good Coding Practice

void CreatingSPSiteExplicitDisposeBestPractice()

{

 SPSite siteCollection = new SPSite("http://moss");

 siteCollection.Dispose();

}

void CreatingSPSiteWithAutomaticDisposeBestPractice()

{

 using (SPSite siteCollection = new SPSite("http://moss"))

 {

 } // SPSite object siteCollection.Dispose() automatically called

}


Thank you very much

          Fahadullah Karimi

         SharePoint Specialist


List of all web parts used on SharePoint 2013 pages using PowerShell How to Save Site as Template in Publishing Site Template in SharePoint 2013