Saturday, February 1, 2014

Cross-Site Publishing in SharePoint 2013


Overview

Cross-site publishing is a publishing method. It lets you create and maintain content in one or more authoring site collections, and publish this content across one or more publishing site collections by using Search Web Parts. Cross-site publishing will make life easy for you as it: 
  • Can be used across site collections.
  • Separates content authoring from branding and rendering, meaning how you author content has nothing to do with how it is displayed to users.
  • Allows you to mix pages and catalog content.

Why XSP?

In previous versions of SharePoint one of the commonly experienced limitations was the lack of support for content reuse within an organization. In SharePoint 2007 and 2010 the only way to reuse content across different sites was to use Content Deployment and have that content copied along with all its assets to all the different sites where it was supposed to be published. Using Content Deployment for content reuse not only results in content duplication but also enforces some governance policies, not to mention the fact that it lacks flexibility as to which content you want to reuse and how it should be published.

Glossary

  • An authoring site is where authors go to create and host content; think of it as the source in XSP. This is where a list that is marked as a catalog lives.
  • A catalog is an attribute that you can add to a list or a library in the authoring site. Marking a list or a library as a catalog makes the content easily accessible to other site collections.
  • Search is the engine that connects your catalog to a publishing site.
  • The term store holds metadata terms that are used to organize content for publishing on target sites.
  • A publishing site is where visitors go to see and read content. 

An introduction to cross-site publishing

Cross-site publishing uses search technology to retrieve content. Here's how it works in five simple steps:


Figure 1: Cross-site publishing overview
  1. You create content in lists and libraries. Site columns are used to store values, or in other words information, about each item in a list or library. On these lists and libraries, you select a setting that enables them as catalogs.
  2. The content in your catalogs is crawled. During crawl, site columns and the site column values are added to the search index.
  3. In the search index, site columns are “transformed” into managed properties. Site column values are “transformed” into managed property values.
  4. You add one or more Search Web Parts to the site collections where you want to display your catalog content. The Search Web Parts use display templates that specify which managed property values should be displayed.
  5. When visitors view a page, the Search Web Parts automatically issue queries to the search index. Query results are returned from the search index, and shown in the Search Web Parts.
When you change content in a catalog on the authoring site collection, the changes are shown across all publishing site collections that are using that content.


Figure 2: Basic cross-site publishing environment

Prerequisite features

Here’s an overview of the site collection features that you’ll need: 

Authoring site
Feature
Why you need this feature
How you can activate it
Cross-Site Collection Publishing
To enable libraries and lists as catalogs
Activate the Cross-Site Publishing feature
SharePoint Server Publishing Infrastructure
To create and share term sets in the site collection
Enable publishing features 
Note: this feature is activated on the site collection level

Publishing site
Feature
Why you need this feature
How you can activate it
SharePoint Server Publishing Infrastructure
To be able to activate the SharePoint Server Publishing feature
Enable publishing features 
Note: this feature is activated on the site collection level
SharePoint Server Publishing
To connect to a catalog
Enable publishing features 
Note: this feature is activated on the site level

Logical architecture example for cross-site publishing



Figure 3: Many-to-many (n:n) authoring-to-publishing site architecture
The authoring and publishing site collections are located in separate web applications. The Authored content web application uses AD DS for authentication of content authors, whereas the Published Internet sites web application uses forms-based authentication for designers and is also configured to allow anonymous access for external users. The authoring site (http://authoring) contains a single Pages library. The product catalog site collection (http://products) contains a list of product data. All libraries and lists are shared as catalogs. The catalog content appears in two separate publishing site collections, one named http://www.contoso.com and one named http://www.fabrikam.com. Different content and products are shown on the publishing sites based on the associated brand.

Because the publishing site collections are outside the firewall, the asset library is located in a separate site collection in the same web application as the publishing site collections so that users on the publishing sites have read access to those assets. Internal users such as designers and other content authors have Contribute permission level to add, update, and delete items in the asset library. The asset library is added to the Suggested Content Browser Locations list for the authoring and product catalog site collections so that content authors can use those assets in their content.

The search system indexes content from the authoring site and the product catalog site collection. When a user views a page on one of the publishing sites, queries from Search Web Parts on that page are sent to the search index. Results are returned from the search index, and shown in the Search Web Parts on the page.

Limitations in XSP

One of the consequences of using the SharePoint 2013 search-based publishing model is that it only applies to the content that can be indexed. All other assets such as images or files are not included in the search index and therefore it is still your responsibility to ensure that they are available everywhere where the content from a catalog might be published.

Wednesday, September 4, 2013

SharePoint Custom Field - Regex Validator

Finally!!.. I have published my first project on codeplex. Here is a brief about that project:

Project Description
This is a SharePoint 2010 custom field type project that provides Regex (regular expression) validation on a text field.

In few words
This field provides some inbuilt validation options like Email, SSN, Phone no., IP Address and Alphanumeric. Besides this, it also provides an option to specify your own regular expression with an error message.

DecodingSharePoint_Regex_Field.jpg

When a user will try to add/edit list item, this custom field will check if the value matches the regular expression and it will throw an error, if not matched.

validation screenshot.jpg

How to add custom regex options
If you want to add some more inbuilt regex options like Email or SSN then you can make changes to the following files as described below :
  • In ControlTemplates\DS_Regex_FieldEditor.ascx
    • Add new item in "rbnRegexType" RadioButtonList control
      • e.g. <asp:ListItem Text="Alphanumeric XXX" Value="Alphanumeric"></asp:ListItem>
  • In DS.Regex.Common.cs
    • Create a new string and its value must be equal to the value specified in the previous step i.e. in DS_Regex_FieldEditor.ascx file
      • e.g. : public static string Alphanumeric = "Alphanumeric";
  • In DS.Regex.ValidationRule.cs
    • Add regex in StandardRegularExpressions Dictionary using the constant defined in DS.Regex.Common.cs file.
      • { DS_Regex_Common.RegexType.Alphanumeric, @"^\w+$"}
    • Add error message in StandardErrorMessage Dictionary using the constant defined in DS.Regex.Common.cs file.
      • { DS_Regex_Common.RegexType.Alphanumeric, "Please enter valid input"}

Installation
  • Add-SPSolution -LiteralPath <Path>\DecodingSharePoint_Regex_Field_Type.wsp
  • Install-SPSolution -Identity DecodingSharePoint_Regex_Field_Type.wsp -GACDeployment

You can download the source code and deployment package from here :
https://spregexfield.codeplex.com/

Saturday, August 24, 2013

Insert Item in SharePoint list with specific ID

I recently came across with a problem that someone deleted an item from a list and then cleared the recycle bin. Now that item was previously referred in many lists as lookup field, so they all became null referenced lookup and as a result of that, site got crashed.

So I had 3 choices to correct this :
1) To correct all references in all lists by building a utility or do it manually (time consuming process)
2) To correct the code to handle these type of issues (time consuming process)
3) To insert the item with that specific id.

I tried to find the solution to 3rd option, but had no luck. So, I dig little deeper and came up with this solution. Although it is not a very good idea to set internal fields of sharepoint explicitly. But sometimes we have to do it. :)

Here is the solution :

private static void InsertItemWithSpecificID(int itemID)
{
    string siteUrl = "http://www.contoso.com";
    string listName = "Employee";
    SPSecurity.RunWithElevatedPrivileges(delegate()
    {    
        using (SPSite site = new SPSite(siteUrl))
        {
            using (SPWeb web = site.OpenWeb())
            {
                SPList list = web.Lists.TryGetList(listName);

                if (list != null)
                {
                    // The ID field is readonly field, set to to read and write mode.
                    list.Fields[SPBuiltInFieldId.ID].ReadOnlyField = false;
                    list.Update();

                    SPListItem item = list.AddItem();
                    item["Title"] = "This item Id's is not auto-generated by SharePoint, it is specified explicitly.";
                    item[SPBuiltInFieldId.ID] = itemID; //item[SPBuiltInFieldId.ID] = 3;
                    item.Update();
                    list.Fields[SPBuiltInFieldId.ID].ReadOnlyField = true;
                    list.Update();
                }
            }
        }
    });
}