Display Template and Current Item Index

A little while ago we had request where we were spouse to build a content lift up that displays the latest news pages. Very common and nothing new. The solution should be done with SharePoint OOTB features (be Office 365 compatible), so I decided to use a search and search web parts like I have done a multiple times before. What customer wanted was something like in this wireframe.

(Again here’s the link to source code used in this example: GitHub Mikko Koskinen)

The news post should be listed from newest to oldest. The most recent one should have a title, some text and image when others should show only title and short text from the news body. Because I wanted to keep things light from performance point of view I wanted to accomplish this with one web part only. You could do this with two separated web part for sure.

But if we think of the concept of search web part and display templates we know that we have two elements in template; a control display templates and item display templates. This concept is explained nice in Paul Matthews display template series where the following image can be found. If the concept of display templates and using them is new to you please read Matthews posts first.

searchTempaltesControltem

Same item template is used to every single item that is returned to us from the index. If so how can we style the first item element differently than others?

After going through basically every single value from ctx.CurrentItem I finally found the answers. The detail I need is not in CurrentItme but in context it self. There is a value for current item id found and we can use that to solve our small problem.

Only thing we need to do is to check what is the idx value of the current item in display template and change the styling based on that.


var shortText = String.format('<div class="ms-noWrap newsBody" title="{0}" id="{1}" >{2}...</div>',
				$htmlEncode(line2.defaultValueRenderer(line2)), line2Id, line2.toString().substring(0,100));


var index = ctx.CurrentItemIdx;

if (index == 0){
_#-->
	<div class="mainNews" id="_#= containerId =#_" data-displaytemplate="_#= $htmlEncode(dataDisplayTemplateTitle) =#_">
			<div class="newsImage" id="_#= pictureContainerId =#_">
				<!--#_
				if(!linkURL.isEmpty)
				{
				_#-->
				<a href="_#= linkURL =#_" title="_#= $htmlEncode(line1.defaultValueRenderer(line1)) =#_" id="_#= pictureLinkId =#_">
				<!--#_
				}
				_#-->
					_#= pictureMarkup =#_
				<!--#_
				if(!linkURL.isEmpty)
				{
				_#-->
				</a>
				<!--#_
				}
				_#-->
			</div>
			<div class="newsTitle" id="_#= dataContainerId =#_">
				<!--#_
				if(!linkURL.isEmpty)
				{
				_#-->
					<a href="_#= linkURL =#_" title="_#= $htmlEncode(line1.defaultValueRenderer(line1)) =#_" id="_#= line1LinkId =#_">
				<!--#_
				}
				_#-->
					<h2 class="ms-noWrap" id="_#= line1Id =#_"> _#= line1 =#_</h2>
				<!--#_
				if(!linkURL.isEmpty)
				{
				_#-->
					</a>
				<!--#_
				}
				_#-->
			
				<div class="newsBody" title="_#= $htmlEncode(line2.defaultValueRenderer(line2)) =#_" id="_#= line2Id =#_" > _#= line2 =#_</div>
			</div>
		</div>
<!--#_	
}
else{
_#-->
	<div id="_#= containerId =#_" data-displaytemplate="_#= $htmlEncode(dataDisplayTemplateTitle) =#_">
			<div class="newsTitle" id="_#= dataContainerId =#_">
				<!--#_
				if(!linkURL.isEmpty)
				{
				_#-->
					<a href="_#= linkURL =#_" title="_#= $htmlEncode(line1.defaultValueRenderer(line1)) =#_" id="_#= line1LinkId =#_">
				<!--#_
				}
				_#-->
					<h2 class="ms-noWrap" id="_#= line1Id =#_"> _#= line1 =#_</h2>
				<!--#_
				if(!linkURL.isEmpty)
				{
				_#-->
					</a>
				<!--#_
				}
				_#-->
			
				_#= shortText =#_
			</div>
		</div>
<!--#_	
}
_#-->

After this we can have nice one web part solution with OOTB tools to our problem. You can find the full source from my GitHub (link at the beginning the post).

Change the display value of list column

Every now and then my customers are asking me to hide some list column from different views. Because every time I have to think that what is the best way to fulfill this requirement I decided to write this post that basically tells the different options. There are ways x to hide the column in different list views. And by views here I mean DisplayForm, EditForm and NewForm.

  • With list level setting
  • With JavaScript or actually JQuery here

As you can see I left out the options for doing this with server side code or declaratively during the wsp installation for example. These solution can be used to make the change in existing environment and especially these are working in Office 365. Actually the examples have been developed in my Office 365 test tenant. For these examples I created an OOTB announcement list and added one new column called “Hide Me”.

Change the list level setting

This shouldn’t be a new thing to you but just for reference. You can change the list column visibility from list settings. But this setting will change the visibility in all forms. There is no form level setting available through UI.

  1. Go to list setting from the ribbon
  2. Activate the content type management if necessary
  3. Open the content type that holds the field
  4. Click the field you would like to hide
  5. Select Hidden from column settings

Here’s a video that shows you the steps if needed.

Hide the column with JavaScript

This method is for maybe more advantage users because you need to insert some script to the pages. With this method you can hide the column form any list form separately.

  1. You can find the list form edition option from the ribbon. Open one you want to edit. I use display form here because that’s the most common form one have to edit.

  2. This will open the form (or actually a page). The form is opened in edit mode.
  3. Add a Script Editor web part to main zone.

  4. Click the Edit Snipped link and add the code below to editor.
  5. Remember to change the “Hide Me” text to match your field title.
  6. Click Stop Editing to save the changes.
  7. Your field should now been hidden in display view.

I decided to use JQuery in my script because this way it’s more flexible to search the right HTML element from the page. The code below includes a link to JQuery but you can leave it away if that is already loaded on your environment.

In the page the list columns are actually shown in table format. What we will do here is that we will find the title of our field that we want to hide. Then we will get the closest row and hide it. This will hide both the title and value columns. To get field back simply delete the script editor web part from the form. There is one small draw back when you use this method. For a blink of an eye it’s possible that users are actually seeing the field when they load the form. This is because the scripts in editor web part are run only after the form has been fully loaded.

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js" />
<script type="text/javascript" language="javascript">
$(document).ready(function() { $('h3:contains("Hide Me")').closest('tr').hide(); });
</script>

Using PowerShell

Because of the delay there I decided to seek still one option. If you know there is actually SetShowIn setting for field. This setting is available only through object model or you can set it declaratively in field xml settings. Because we already had the environment running and we are using Office 365 those options wasn’t available to us. For me PowerShell is the tool make this kind of coding necessary operations.

You can actually use SharePoint client side code with power shell also. I won’t go through the requirements and basics of that because a link original source for how to do it is a lot easier. Thanks for Chirs O’Brien for posting this tip http://www.sharepointnutsandbolts.com/2013/12/Using-CSOM-in-PowerShell-scripts-with-Office365.html

  1. Make sure you have the SharePoint client dll available on the machine you are running the PowerShell script.
    1. If you don’t have SharePoint server available from where you can get them, you have to download and install SharePoint Server 2013 Client Components SDK.
    2. http://www.microsoft.com/en-us/download/details.aspx?id=35585
    3. The path in my script is showing the place where you can find these dll:s in SharePoint server or after you have installed the SDK
  2. Change the path of the dll files to the script if needed.

  3. You can run this code from basic Windows PowerShell command prompt. You should run the command prompt as administrator.
  4. Navigate in the folder where the script is and run it with the following parameter.
  5. .\ChangeColumnFormVisibility.ps1 -Url “https://tenant.sharepoint.com/sites/spdevsamples/&#8221; -ListName “Events” -FieldName “Hide Me” -ListView “DisplayForm” -ShowInForm:$False
    1. Url = Url of the site where the list is
    2. ListName = Title of your list
    3. FieldName = Title or internal name of your field
    4. ListView = form which view you want to edit. This value has to be DisplayForm or NewForm or EditForm
    5. ShowInForm = Boolean ($true or $false) value that tells should the field be hidden or shown
  6. The script will prompt and ask you for credential during the run.
  7. The details of the changes are shown after the changes are done.

After the script is run you can go and see the changes in your list view.

 

 

 

 

 

 

 

The code is actually quite simple. First we connect to the site. After that we have to get the right list and it’s fields. We have to load the field collection before we can make the necessary changes. After that we can get the right field based the given name. Then we have to check what form value user wants to change and make the right changes and update the field settings.

	# connect/authenticate to SharePoint Online and get ClientContext object..
	$credential = Get-Credential
	$clientContext = New-Object Microsoft.SharePoint.Client.ClientContext($Url)
	$credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($credential.UserName, $credential.Password)
	$clientContext.Credentials = $credentials

	if (!$clientContext.ServerObjectIsNull.Value)
	{
		#This gets Microsoft.SharePoint.Client.List
		$oList = $clientContext.Web.Lists.GetByTitle($ListName);
		#This gets Microsoft.SharePoint.Client.FieldCollection
		$fieldColl = $oList.Fields;

		$clientContext.Load($fieldColl);
		$clientContext.ExecuteQuery();

		$field = $fieldColl.GetByInternalNameOrTitle($FieldName);

		$clientContext.Load($field);
		$clientContext.ExecuteQuery();

		switch ($listView) {
			"DisplayForm"
			{
				$field.SetShowInDisplayForm($ShowInForm);
				$clientContext.ExecuteQuery();

				$message = "Fields '" + $field.Title + "' DisplayForm visibility changed to: " + $ShowInForm
				write-Host $message -ForegroundColor Green
				break
			}
			"NewForm"
			{
				$field.SetShowInNewForm($ShowInForm);
				$clientContext.ExecuteQuery();

				$message = "Fields '" + $field.Title + "' NewForm visibility changed to: " + $ShowInForm
				write-Host $message -ForegroundColor Green
				break
			}
			"EditForm"
			{
				$field.SetShowInEditForm($ShowInForm);
				$clientContext.ExecuteQuery();

				$message = "Fields '" + $field.Title + "' EditForm visibility changed to: " + $ShowInForm
				write-Host $message -ForegroundColor Green
				break
			}
		}
	}

	

You can find the whole script from my GitHub:

GitHub Mikko Koskinen

New-SPConfigurationDatabase – system error 5 (Access is denied.)

This not something very fancy and the solution is actually very clear and something I should have understood right from the error message. But because it took me a while to figure it out and googling with error message didn’t give that much help, maybe this helps someone else also.

I was installing SharePoint 2010 in very typical three tiers environment. SQL Server was installed as it should be based on best practice recommendations. This means that log and data files were also separated to different drivers. SharePoint was also meant to be installed based on least privilege practices. I was using power shell script to make the SharePoint installation but the same error is given to you with wizard also.

So on the stage where Configuration database is created I get the following error
message:

New-SPConfigurationDatabase : CREATE FILE encountered operating system error 5(Access is denied.) while attempting to open or create the physical file ‘R:\Log\Config_log.ldf’. CREATE DATABASE failed. Some file names listed could not be created. Check related errors.

And now what?

I know that my setup account has all the necessary privileges to SQL Server. First I thought that my setup account should have access privileges to Log folder (where all the database log files are created) and I tried that with no help. After some googling, wondering and discussion with my colleague I figured it out.

The SQL server instance is driven with service account. Even though I’m using a setup account to operate in SQL server the actual creation of database is done with service account. I checked the SQL Server Services log on account with Sql Server Configuration Manager and gave this account read/write access to Log –folder.


And that solved the problem and the installation process was over quite quickly.

SharePoint 2013 and Search-Driven Content

For the last year I have done a lot of concept and architecture design together with development in cases where SharePoint is used as organization internal communication, news, announcement and general information channel. Basically I mean traditional Intranet with news pages, announcements lists, blogs, HR content sites, department sites etc. For this reason I have spent my time looking the new SharePoint 2013 Preview (SP2013 on this point of view. There is so much to look into and learn that you better start from something you are familiar with. I have tried to find out what there is new for my customers that are using SharePoint with Publishing Portal features inside their company. So few upcoming posts, including this one, will include my thoughts and findings on this point of view.

Here is how the Publishing Portal looks in right after creation

Search-Driven Content web parts

First big thing that you should notice are new web parts related to search. They are called Search-Driven Content web parts. When showing something like announcements in page on SharePoint 2010 (SP2010) you basically had four options 1. List View web part 2. Content Query web part 3. Search Result web part 4. Custom web part. In all of these there are pros and cons and you can still use them.

But SP2013 introduced a whole set of new search-driven web part. It seems that Microsoft really wants us to use search index when fetching and publishing content on the site. And I don’t claim them from doing so. Search index is very efficient and safe way to do it.

Content query web part is create but there is a possibility that your site is slowing down if you get content from a large site. That is why search is a create option. Only problem in SP2010 is that Search Result web part isn’t very useful way to do things and you are able to use List View web part only on that site where the list is located (without some SharePoint Designer hacks). So I have to say that in quite many occasion we went to road of making custom web part for some needed components on the site. Now I think that we can change this thinking at least in quite many occasion.

Available web parts

  1. Content Search – Web Part will allow you to show items that are results of a search query you specify.
  2. Articles – Web Part will show any items that are derived from the Article Page content type.
  3. Catalog – Item Reuse Web Part to reuse or republish the content of an item from a catalog.
  4. Items from a Catalog – Web Part will show items from a catalog configured for this site.
  5. Items Matching a Tag – Web Part will show items that are tagged with a term.
  6. Pictures – Web Part will show any items that are derived from the Picture or Image content type.
  7. Popular Items – Web Part will show items that have been recently viewed by many users.
  8. Recently Changed Items – Web Part will show items that have been modified recently.
  9. Recommended Items – Web Part will show content recommendations based on usage patterns for the current page.
  10. Videos – Web Part will show any items that are derived from the Video content type.
  11. Web Pages – Web Part will show any items that are derived from the Page content type.
  12. Wiki Pages – Web Part will show any items that are derived from the Wiki Page content type.

All of these web parts can fetch, except Recommended Items and Catalog-Item Reuse that have special features, data from current site, current site collection, specified URL or whole index (=Don’t restrict results by location). You are able to control this with query builder in web part properties. I will tell you more about this later. This really means that you fetch and show items from almost every possible location. This is why using index in these web parts is so powerful.

Use cases that customers wants

As you can see there are a lot of good and useful web parts for your intranet site. Something like popular items, articles (news pages) or recently changed items are something that customers ask almost every time. I can really see that these will be used a lot when people learn how to use them and can recommend those to customers. You can also create extra value in you intranet with these web parts because you can focus content more closely to users in different places regardless where the content is actually created and saved.

You can for example show department related news or blog post in department community site with Items Matching a Tag web part. Only thing you have to do is create necessary managed metadata and use those when publishing different kind of content. I really think that if organizations start to use these web parts effectively we will see good and really useful intranets in the feature. Laura Rogers has written a good overall look to Content Search web part that you should take a look at: SharePoint 2013 Web Part: Content Search

Something like popular items, articles (news pages) or recently changed items are something that customers ask almost every time.

And just as a site note Content Query Web Part has also this new Query builder that I like already. Catalog mentioned on some web parts, by the way, is a new thing is SP2013. Catalogs are used in cross-site collection publishing. MVP Liam Cleary gives a nice example of using catalogs and search-drive web parts here: SharePoint 2013 – Cross Site Collection Publishing Part 1. More information from cross-site collection publishing can be found here: What’s new in web content management for SharePoint 2013 Preview publishing sites.

Plan the metadata and search!

Of course using these web parts means that you have to plan, maintain and implement your search and metadata model well. Otherwise you can’t take a really advantages from these web part. I have notice that even though many people sees that metadata and terms are important it’s not that easy to implement and adapt them to organization. Now is the real time you start to think about these things and start to discuss about metadata. Remember that that metadata is not about technical issues, it’s about real life artefacts and content. You can create metadata model without SharePoint and IT department J. We can make many nice technical solutions but if people don’t tell what kind of items they save to SharePoint we can’t take full advantages from the possibilities.

Continuous crawl

Other important thing to release here is that index is not real time. You have to tell this to your customers and make clear that they understand this limitation. Corey Roth has written a create post about search in new SP2013: Search is Everywhere! What you need to know about Search in SharePoint 2013 Preview. One basic thing is to master and schedule your content sources. SP2013 introduced a new thing called continuous crawl.


Here is what Corey he says about continuous crawl:

“This crawls your content source continuously (every 15 minutes by default). However, there is some magic that occurs now and new items can appear in the index within seconds.”.

I think that in the environment that we are talking about you should definitely use this crawling option.

I wrote down a little more about continuous crawl and configuration about it in a separated post Using and Configuring Continuous Crawl.

So everything is perfect now?

Well as you can guess from the topic I think there are still things that could have done differently. One of mine top ranked wishes for the new SP was easier handling of xsl files in content query web part. This didn’t unfortunately come true. The same thing concerns also these search-driven web parts. Styling is done is xsl file. You still have to open/copy the xsl file, make the changes and save them back to styles library. Of course you can use SharePoint Designer or Visual Studio to make the changes. And if you want to link the web part to another style sheet than OOTB one you still need to take the road of SPD or Visual Studio solution. What I was expecting was xsl editor in web part level, or minimum of possibility to link you own custom xsl file like in List View Web Part. But this didn’t come, at least not in this preview version.

One of mine top ranked wishes for the new SP was easier handling of xsl files in content query web part. This didn’t unfortunately come true.

Other missing thing in these search-driven web parts is that you are not able to create personalized views or behavior to them. For example there is no possibility to filter the search results based on user profile value like department. You can only give the department value as static property. For sure you can use target audience and but multiple web part to the site but is always a maintenance hazel. Ok, to accomplish there should be some kind of scripting possibility on the query builder.


Luckily there is always my favorite framework solution MatchPoint that can handle these two issues. MatchPoint has web part called Composite Web Part. This web part can be connect to different data sources, you can modify the query with easy to use editor and you also have an editor to handle the styling. Composite also have a special expression framework that you can use to make dynamic queries during the load time. With this web part we have made solutions where we have fetched data from different sources based on user profile values and styled them with xsl. Here’s basic information about Composite web part but I will post more details of MatchPoint Composite web part little later: MatchPoint Composite Web Part

Using Search-Driven Web Parts – Example

I think that let’s stop this novel writing and let’s look something practical example. Here is on example of using search-driven web parts in communicational Intranet – SharePoint 2013 and Search-Driven Content – Articles Web Part.

SharePoint Application Configuration part 1 – Property Bag

Property bags are power full and good way to store properties and static details that is used in SharePoint. Earlier the most common way was to store for example some URL information in web-config. And still web.config is a good place to store information. Only administrators are able to modify web.config so the information is saved in quite save way. One disadvantage (a big one even) there is with web.config. If you have multi server farm you have to make web.config changes to every server so that everything would work.

However property bags are handles through code or xml file and application server is handling the information so that information is always reachable. You can store information in many different level and object like SPFarm, SPServer, SPWebApplication, SPContentDatabase, SPWeb, SPFolder, SPListItem, SPFile. “Each property bag allows you to store a collection of key/value pairs, each key is unique, and the value has to be a string. If you need more advanced capabilities, you could choose to store complex data in the string using serialization.[1]” Property bag are available both on server solutions and sandbox solutions (from site collection level and below). Even external application can use them if they connect to SharePoint environment through API.

Advantages to use property bags

· There are provided to you out of the box.

· They are saved straight to SharePoint databases.

· There is good and simple API to use them.

Disadvantages

· No out of the box UI to modify them. But there is an good farm level solution found from Codeplex http://pbs2010.codeplex.com/

How to use property bag?

But let’s have an example of how you can use property bag in our solutions. This example is light version from real life case. Our customer wanted to have web part that can be used in multiple sites and multiple times in a site. The request also was that they want to make multiple predefined style themes from which site administrators can choose from. This meant that on a site there could be multiple web parts but all of them have different style layout (font color etc.).

On this post I will leave the creating of visual web part with editor part out. But you can download the source code from the link below and there are a lot of examples found with Google of course.

Our web part fulfilled the requirements in a following way.

a) Make the web part based on visual web part and add custom style classes to every control on the page.

b) Themes can be made so that there will be necessary CSS styling done and user can change this style to a single web part.

c) Make editor part where users sees drop down box and styles (like Blue Theme, Red Theme) from where to choose from.

d) This list of styles should be centrally defined by administrators.

e) Theme list will be saved in property bag and administrator can update it with pbs2010 tool found from Codeplex.

First we need to create the actual property bag. On this demo we create the properties on site (or web) level.

1. Create an empty module to your visual studio solution.

2. Into element.xml file here is the xml definition we used to list the possible style themes. More information about property bag xml schema can be found here: Property Bag Schema.

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <PropertyBag ParentType="Web">
    <Property Name="pbpost.messageboxstyling" Type="string" Value="Blue Theme, Red Theme" />
  </PropertyBag>
</Elements>

3. Save the element file and create a feature that will install the module to the site.

Getting the property bag information

As I told there is a editor part where we want to show list of possible styles in drop down list. The styles are saved to web property bag with a key pbpost.messageboxstyling. Teams are saved as comma separated string so we also have to decrypt them as single items.

Here is the create CreateChildControl function where we are creating the drop down list and start to fill that with the values from property bag.

protected override void CreateChildControls()
        {
            try
            {
                //Create the Dropdown list
                SelectedNewCssClass = new DropDownList();
                //Add the item from property bag
                addCSSStyles(SelectedNewCssClass);

                Label lblControl = new Label();
                lblControl.Text = "Box Custom CssClass";
                Controls.Add(lblControl);
                Controls.Add(new LiteralControl("<br/>"));
                Controls.Add(SelectedNewCssClass);
                Controls.Add(new LiteralControl("<br/>"));
            }
            catch (Exception ex)
            {
                SPDiagnosticsService.Local.WriteTrace(0,
new SPDiagnosticsCategory("UsingPropertyBag", TraceSeverity.Unexpected,
EventSeverity.Error), TraceSeverity.Unexpected, ex.Message, ex.StackTrace);
            }
        }

And here is the actual function that reads the values from the bag and saves them as items to the drop down list.

private void addCSSStyles(DropDownList CssClass)
        {
            CssClass.Items.Add("");

            if (SPContext.Current.Site.RootWeb.AllProperties.ContainsKey
("pbpost.messageboxstyling"))
            {
                string[] cssValues = SPContext.Current.Site.RootWeb.AllProperties
["pbpost.messageboxstyling"].ToString().Split(',');

                foreach (string value in cssValues)
                {
                    CssClass.Items.Add(value);
                }
            }

So here was the short example and information about SharePoint property bags. You can find the complet Visual Studio 2010 solution from my SkyDrive (zip file names as UsingPropertyBag.zip

References:

[1] Course 10232A: Designing and Developing Microsoft® SharePoint® Server 2010 Applications material

%d bloggers like this: