Showing posts with label Client side rendering. Show all posts
Showing posts with label Client side rendering. Show all posts

Friday, September 18, 2015

Localize web part titles via client object model in Sharepoint

Starting with 2010 version Sharepoint has Multilingual UI feature which allows to dynamically switch language used for UI elements on the site (depending on settings this language may be determined by language preferences set in user profile or language http header configured in browser). This feature is also supported in Sharepoint 2013 and Sharepoint Online. Programmatically you may add different translations using special properties. E.g. if you need to localize site title you need to use SPWeb.TitleResource property.

The problem is that client object model has limited support of localizations UI elements. E.g. Microsoft.SharePoint.Client.dll of 15.0.0.0 version (on-premise) doesn’t have these properties at all. The same assembly, but of 16.0.0.0 vesion (online) has the following properties:

  • Web.TitleResource
  • List.TitleResource
  • Field.TitleResource
  • ContentType.NameResource

These properties can be used for adding localizations to appropriate Sharepoint objects. Of course in order to take effect you need to enable MUI on your site. It can be done in Site settings > Language settings:

image

In this example we enabled alternate Finnish language (language id = 1035) for our site.

The problem however that there is no similar property for web part title. However in Sharepoint in most cases web parts are most often seen by end users than other elements. So it would be good to have a mechanism for localizing web part titles. It can be done by the following PowerShell script:

   1: $localeId = 1035
   2:  
   3: function ProcessWebParts($context, $page) {
   4:   $manager = $page.GetLimitedWebPartManager(
   5: [Microsoft.SharePoint.Client.WebParts.PersonalizationScope]::Shared)
   6:   $pageWebParts = $manager.WebParts
   7:   $context.Load($pageWebParts)
   8:   ExecuteLocalizedQuery $context $localeId
   9:  
  10:   $pageWebParts | foreach {
  11:     $properties = $_.WebPart.Properties
  12:     $context.Load($properties)
  13:     ExecuteLocalizedQuery $context $localeId
  14:     
  15:     $properties["Title"] = $properties["Title"] + $localeId.ToString()
  16:     $_.SaveWebPartChanges()
  17:   }
  18: } 
  19:     
  20: function ExecuteLocalizedQuery($context, $localeid) {
  21:     $context.PendingRequest.RequestExecutor.WebRequest.Headers["Accept-Language"] =
  22: (new-object System.Globalization.CultureInfo($localeid)).Name
  23:     $context.ExecuteQuery()
  24: }
  25:  
  26:  
  27: $currentDir = Convert-Path(Get-Location)
  28: $dllsDir = resolve-path($currentDir + "\dlls")
  29:  
  30: [System.Reflection.Assembly]::LoadFile([System.IO.Path]::Combine($dllsDir,
  31: "Microsoft.SharePoint.Client.dll"))
  32: [System.Reflection.Assembly]::LoadFile([System.IO.Path]::Combine($dllsDir,
  33: "Microsoft.SharePoint.Client.Runtime.dll"))
  34: [System.Reflection.Assembly]::LoadFile([System.IO.Path]::Combine($dllsDir,
  35: "Microsoft.SharePoint.Client.Taxonomy.dll"))
  36: [System.Reflection.Assembly]::LoadFile([System.IO.Path]::Combine($dllsDir,
  37: "Microsoft.Online.SharePoint.Client.Tenant.dll"))
  38:  
  39: $siteURL = "http://example.com"
  40: $context = New-Object Microsoft.SharePoint.Client.ClientContext($siteURL)    
  41: $web = $context.Web
  42: $site = $context.Site
  43: $context.Load($web)
  44: $context.Load($site)
  45: ExecuteLocalizedQuery $context $localeId
  46:  
  47: $page = $web.GetFileByServerRelativeUrl("/Pages/default.aspx")
  48: $context.Load($page)
  49: ExecuteLocalizedQuery $context $localeId
  50:  
  51: ProcessWebParts $context $page

The key element here is ExecuteLocalizedQuery function (lines 20-24). In this function we pass locale id to ClientContext.PendingRequest.RequestExecutor.WebRequest.Headers[“Accept-Language”]. As result our code is executed as it would be called from UI with used Finnish language. Now if we open site with Finnish language all web parts on default.aspx page will have titles with “1035” suffix. But when we will switch to default English language they will have initial values. The only problem which I found at the moment is that if we will use this script with default English language (language id = 1033), it will override also all other translations regardless of the fact that in Site settings > Language settings Overwrite translations setting is set to No (see above). But this is not a big problem because this script is needed first of all for adding translations for alternate languages.

Hope that this information will be helpful.

Monday, August 24, 2015

Hide toolbar of XsltListViewWebPart in Sharepoint Online using client side rendering

When you add OTB XsltListView web part on the page by default it shos toolbar over the list content:

image

Of course you may remove this toolbar manually by going to web part properties and setting Toolbar Type to “No toolbar”. But what to do if we need to set it automatically during provisioning without manual work?

If you worked with XslListViewWebPart in Sharepoint 2010 then you probably know that even with server object model it is possible to remove toolbar only using reflection, e.g. like shown here:

   1: try
   2: {
   3:   MethodInfo ensureViewMethod = lvwp.GetType().GetMethod("EnsureView",
   4:         BindingFlags.Instance | BindingFlags.NonPublic);
   5:   object[] ensureViewParams = { };
   6:   ensureViewMethod.Invoke(lvwp, ensureViewParams);
   7:   FieldInfo viewFieldInfo = lvwp.GetType().GetField("view",
   8:     BindingFlags.NonPublic | BindingFlags.Instance);
   9:   SPView view = viewFieldInfo.GetValue(lvwp) as SPView;
  10:   Type[] toolbarMethodParamTypes = { Type.GetType("System.String") };
  11:   MethodInfo setToolbarTypeMethod = view.GetType().GetMethod("SetToolbarType",
  12:     BindingFlags.Instance | BindingFlags.NonPublic, null, toolbarMethodParamTypes, null);
  13:   object[] setToolbarParam = { "None" }; //set the type here
  14:   setToolbarTypeMethod.Invoke(view, setToolbarParam);
  15:   view.Update();
  16: }
  17: catch { }

But how to do the same in Sharepoint Online where we don’t even have server object model (not even mention reflection)? People on the forums tried to do it via client side object model (CSOM), but without luck, because setting View.Toolbar property to <Toolbar Type='None'/> is ignored: see Hiding the toolbar of a Listview webpart through CSOM.

Fortunately in Sharepoint 2013 there is another powerful mechanism which can be used for hiding toolbar of XsltListViewWebPart: client side rendering. Of course it can be used for other purposes as well, but in this article we will use it for hiding toolbar.

First of all we need to define template override in separate js file and upload this file to the Sharepoint doclib:

   1: (function () {
   2:     var overrideCtx = {};
   3:     overrideCtx.Templates = {};
   4:  
   5:     overrideCtx.BaseViewID = 1;
   6:     overrideCtx.ListTemplateType = 100;
   7:     overrideCtx.OnPostRender = postRenderHandler;
   8:  
   9:     SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideCtx);
  10: })();
  11:  
  12: function postRenderHandler(ctx) {
  13:     jQuery("td.ms-list-addnew").hide();
  14: }

After that we need to set JSLink property of web part pointing to this file. E.g if our file is uploaded to Site assets link will be the following;

   1: <property name='JSLink' type='string'>~site/Site assets/crs-list-view.js</property>

In example above we defined override template with custom post render handler. In the handler we hide DOM element which contains toolbar. After that XsltListViewWebPart will look like this:

image

Hope that this information will help you.