Feeds:
Posts
Comments

Posts Tagged ‘SharePoint’

Introduction

Language packs only translate the default SharePoint functionality. Your own lists, content types, fields, etc.. are not translated. Since SharePoint 2010 there is an option in SharePoint to translate elements in the user interface and export them. This export can then be imported again on another server. In my case this is mainly between development, test and production machines (DEV, TST, PRD)

The following items can be translated

  • Website title and description
  • List title and description
  • Contenttype name and description
  • Field name and description
    • field names are also used in the columns of your lists

How to enable?

  • First you need to install the SharePoint Server language packs for the desired language(s)
    • Note: since SharePoint 2013 you do not need to install the “Foundation language packs”  anymore on a SharePoint Server
  • After the language pack is installed. Go to site (Site Settings -> Language Settings)
    lang01
  • Enable the desired languages (in my sample: French and Dutch)
    lang02
  • To translate, sign-in with a user with the correct language set and start changing the titles, descriptions by using the default SharePoint interface.
    • you can set the user language by simply setting the browser language
    • or overrule the browser setting by editing the language settings in the user profile (User Profile is the new name of the “mySite”)
  • When all the translations are done go to Site Settings- > “Export Translations”  (or  ”Import Translations”)
    lang01
  • Select the desired options to create an export file (which is actually an XML based resource file (.resx))
    lang03
  • Save the file on your harddrive
  • Repeat the above step on your target server but now you select “Import Translations”

Note:  for easier testing/validating I always use 2 users with a different language setting. One user I sign-in while using the Google Chrome browser. With the other user I sign-in while using IE browser.

It’s all about the ids!

It’s important to know that the  translation seems to work with the ID of your SharePoint elements. This means that if you want to use this translations functionality, the id’s of your lists , websites, contentypes, fields, etc.. on both environments (source and target) must be the same!

So what will not work?
If you create your SharePoint elements manually in both ( source and target) environments. All the elements will have different id’s. The translation will not happen.

What will work.

  • If you have deployed your content types and fields with a SharePoint solution.  On every server where you deploy this solution the id’s of the content types and fields will be the same. You can translate them on one server and bring the translation over to another server.
  • If you build your sites on one server, create a content backup of this and restore the backup on another server.
    • The restore will use the same id’s on the target server.
    • Note: If you delete for example a list on the target server and manually recreate it it will not be translated anymore since the new list has a new id (even if you used the same name etc..)

How do I use it?

I always deploy my content types and fields with a SharePoint solution. This way all the ids stay the same on every server (DEV, TST, PRD) where the solution is installed. I do not bother with translating them in my (Visual Studio) SharePoint solution.

Why do I do this? Two main reasons:  my experience is that names of content types and fields get changed a lot during the development process. Often even the day before going live.  The other reason is that I find it too complex to manage resource files for n amount of languages in Visual Studio. I prefer that the content editors do the translations for me.

We simply build the other items (lists, websites, ….) on a dedicated web application and do a backup / restore from this to DEV, TST and even PRD. This is very workable in a development situation. When your solution is alive and kicking in PRD, the restore to PRD is not an option anymore of course.

Read Full Post »

The problem

How do you add a custom control to your master page (or page layout) using the Design manager? In my first attempts I continuously got ‘Unknown server tag ‘uc1:FeedbackControl’

Quick introduction

Using the new way of creating and deploying your branding with the Design Manager needs some getting used to. The idea is:

  1. You start with a plain html page
  2. SharePoint automatically converts it to a master page (or layout page)
  3. You only edit the html page. SharePoint pushes your changes to the master page
  4. Most of the SharePoint controls and web parts can be configured and added by copy + pasting snippets into your html
  5. .NET server controls can also be placed on your page by using snippets.

In fact snippets is nothing more than a special kind of mark-up to put server controls in your html page.

But how to you add a custom control?
I created my branding with the Design Manager. I also have a Visual Studio 2012 solution with custom web parts and custom user controls.
After deploying the Visual Studio solution to my server I tried to add some of my custom user controls to the master page.  All attempts I made resulted in “Unknown server tag”

Defining your control.
<!--SPM:<%@ Register Src="~/_controltemplates/15/AmToPm.Client.Intranet/FeedbackControl.ascx" TagPrefix="uc1" TagName="FeedbackControl" %>-->
Putting your control on your page.
<!--CS: Start Create Snippets From Custom ASP.NET Markup Snippet-->
<!--SPM:<uc1:FeedbackControl runat="server" id="FeedbackControl" />-->
<!--CE: End Create Snippets From Custom ASP.NET Markup Snippet-->

The solution

The trick is easy. Instead of registering your control on top of the html together with all the default SharePoint controls. You need to put the @Register statement and your code together

<!--SPM:<%@ Register Src="~/_controltemplates/15/AmToPm.Client.Intranet/FeedbackControl.ascx" TagPrefix="uc1" TagName="FeedbackControl" %>-->
<!--CS: Start Create Snippets From Custom ASP.NET Markup Snippet-->
<!--SPM:<uc1:FeedbackControl runat="server" id="FeedbackControl" />-->
<!--CE: End Create Snippets From Custom ASP.NET Markup Snippet-->

So you do NOT place the @Register-statement before the DOCTYPE declaration. Embed it directly into your html page together with your snippet.

One other tip.

I had some problems / errors with defining multiple controls with the same tag prefix. If you have multiple controls on a page give them all a different TagPrefix and you will be fine.

<!--SPM:<%@ Register Src="~/_controltemplates/15/AmToPm.Client.Intranet/FeedbackControl.ascx" TagPrefix="uc1" TagName="FeedbackControl" %>-->
<!--SPM:<%@ Register Src="~/_controltemplates/15/AmToPm.Client.Intranet/Notification.ascx" TagPrefix="uc2" TagName="Notification" %>-->
<!--SPM:<%@ Register Src="~/_controltemplates/15/AmToPm.Client.Intranet/DisplayStatus.ascx" TagPrefix="uc3" TagName="DisplayStatus" %>-->
<!--CS: Start Create Snippets From Custom ASP.NET Markup Snippet-->
<!--SPM:<uc1:FeedbackControl runat="server" id="FeedbackControl1" />-->
<!--SPM:<uc2:Notification runat="server" id="Notification1" />-->
<!--SPM:<uc3:DisplayStatus runat="server" id="DisplayStatus1" />-->
<!--CE: End Create Snippets From Custom ASP.NET Markup Snippet-->

 

Read Full Post »

I use the Visual Studio CKSDEV plugin so much that I almost forgot it’s not standard Visual Studio functionality. It’s no doubt the number one tool when creating SharePoint solutions with Visual Studio.

Unfortunately the plugin is not yet updated for Visual Studio 2012 / SharePoint 2013.  But the people at Mavention have created a small tool that mimics the “Copy to GAC” functionality. So it takes at least some of the pain away.

Read all the details on Weldak’s blog:
http://blog.mastykarz.nl/quickly-deploying-sharepoint-2013-projects-mavention-quick-deploy/

Download the tool here:
Mavention Quick Deploy

Update:
As Gary pointed out in the comments below. There is a new kid in town called Fishbone. The reviews, functionality and screenshots look promising. Let’s find out!
http://visualstudiogallery.msdn.microsoft.com/4784e790-32f4-455f-9228-53f537c03787

Read Full Post »

Ran into this helpful tool on Codeplex today. The SharePoint language pack downloader (http://sp2010dl.codeplex.com)

Manually downloading all the needed language packs from the Microsoft site can be handful. You have to download an extra pack when you have the SharePoint Server version installed. Multiply the amount of packs by 2 if you have a service pack installed. And you have to do this for all the required languages.

This can be confusing and if you don’t pay attention it’s easy to make mistakes. Luckily this tool downloads all packs automatically. A real time saver.

Read Full Post »

We often get Excel files with content to import into SharePoint. Most of the time I fire up Visual Studio and write a small console application to import the Excel data. However with SharePoint 2010 I got the error “The ‘Microsoft.Jet.OLEDB.4.0′ provider is not registered on the local machine”.

The idea

When I need to import content into SharePoint using the oledb data is far the easiest way to read Excel files without having to install office on your SharePoint server.

You simply add an OleDbConnection , an OleDbCommand, an OleDbDataAdapter and a correctly formulated select statement.

            string ConnectionString = @"Provider=Microsoft.Jet.OLEDB.4.0; Data Source=c:\Import\Sample.xslx; Extended Properties=""Excel 8.0;HDR=Yes"";";
            string CommandText = "SELECT * FROM [Services$]";

            OleDbConnection connection = new OleDbConnection(ConnectionString);
            OleDbCommand command = new OleDbCommand(CommandText, connection);
            connection.Open();

            OleDbDataAdapter adapter = new OleDbDataAdapter(command);

            DataSet dataset = new DataSet();
            adapter.Fill(dataset, "Excel");

The cause

SharePoint 2010 is 64 bit so you need to compile your custom SharePoint code as a 64-bit applications. However the default Jet Library does not support 64-bit applications and thus results in the following error:

The ‘Microsoft.Jet.OLEDB.4.0′ provider is not registered on the local machine.

Solution

Luckily Micosoft has released a solution in the form of the Microsoft Access Database Engine 2010 Redistributable

  1. Download the Microsoft Access Database Engine 2010 Redistributable
  2. Install the package on your development machine
  3. Modify your OleDb Connection string from:
    Provider=Microsoft.Jet.OLEDB.4.0; ….
    to
    Provider=Microsoft.ACE.OLEDB.12.0;….
  4. rebuild your application
    note
    : make sure your application is set to compile as a 64 bit application

Don’t forget to install this redistibutable on your SharePoint server as well.

Read Full Post »

While programming in SharePoint, did you ever needed to work your way back to the parent website?

Probably the easiest, but not the recommended, way to do this is:

SPWeb web = SPContext.Current.Web;
while (web != null)
{
   // Do your code here
   web = web.ParentWeb;
}

The problem with this approach is that you are not disposing your SPWeb and SPSite objects. You should correctly dispose you SharePoint objects to avoid memory leaks in your SharePoint customizations.

A better approach that disposes all the objects correctly is this:


private void SomeMethod()
{
   SPSite site = new SPSite(SPContext.Current.Site.ID);
   SPWeb web = site.OpenWeb(SPContext.Current.Web.ID);

   IterateThroughParentsAndStoreInfo(web);

   web.Dispose();
   site.Dispose();
}

private void IterateThroughParentsAndStoreInfo(SPWeb web)
{
   // Do your code for the 'web' variable here.

   if (web.ParentWeb != null)
   {
      using (SPWeb parentweb = web.ParentWeb)
      {
         IterateThroughParentsAndStoreInfo(parentweb);
      }
   }
}

Best practices in SharePoint programing dictate that you have to dispose your SharePoint objects. You can download the free tool SPDisposeCheck that integrates in your Visual Studio and checks if you properly disposed your objects. If not it will give you errors like:

‘Disposable type not disposed: Microsoft.SharePoint.SPWeb’

More information about disposing your objects can be found here.
Hope it helps.

Read Full Post »

Adding a box or rounded corners around a SharePoint web part can be challenging due to the way that SharePoint renders it’s web parts in a <table> layout. This article explains how to add extra <div> elements around the SharePoint web parts. Then by using the ‘sliding doors’ css technique we can add a flexible box arround the SharePoint web part and even include rounded corners.
This tutorial already assumes that you know what SharePoint master pages are and how to work with css and JavaScript files.

Problem.

The HTML code of a SharePoint web part is made out of tables. Depending on the web part options you selected extra  tables and css classes can be added, removed or nested.

The basic HTML markup of a SharePoint web part looks like this

    <table cellspacing="0" cellpadding="0" border="0" width="100%" class="s4-wpTopTable">
        <tbody>
          <tr>
            <td>
            <table cellspacing="0" cellpadding="0" border="0" width="100%">
                <tbody>
                    <tr class="ms-WPHeader">
                    <!-- web part title and menu goes here -->
                   </tr>
                </tbody>
            </table>
            </td>
          </tr>
          <tr>
            <!-- actual web part content goes here -->
          </tr>
        </tbody>
    </table>

This table layout does not leave much room to add a flexible box layout.

The solution.

By using jQuery we can add extra <div> elements to each web part on the SharePoint page. We will use these extra <div> elements  to create a box arround the web part.

For simplicity sake I have put all the needed files together in a folder “boxdemo”. I simply copied these files to the ‘_layouts\styles\’ folder of my SharePoint hive.

Note: putting your files in a folder on the SharePoint server harddrive is not best practice! But for tutorial purposes this will do :-) .  Always use a SharePoint feature when deploying files to a SharePoint server.

The actual box around the web part will be created by simple images. You can use this website to generate the desired images.

For this solution we will need 6 images

  1. l.png   (left image)
  2. r.png (right image)
  3. t.png (top image)
  4. b.png (bottom image)
  5. tl.png   (top left image)
  6. bl.png  (bottom left image)

And also 2 extra files. A stylesheet and a javascript file. you can already create these and leave them empty for now.

  1. style.css
  2. boxing.js

We will add code to these empty files later on.

Adjust your master page

In order to make the boxing work we need to add 3 links to our master page. These links points to the jQuery library, our styling file and our JavaScript file.

Open your master page and add the following links to the <HEAD> section of your master page:

    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js" type="text/javascript"></script>
    <script src="/_layouts/Styles/boxdemo/boxing.js" type="text/javascript"></script>
    <link rel="stylesheet" type="text/css" href="/_layouts/Styles/boxdemo/style.css" media="screen" />

I use the jQuery hosted at googleapis.com. In corporate environments this domain is sometimes blocked. If this is the case you should download the jQuery library and put it in the _layouts\styles folder together with the other files.

Javascript

To dynamically add the extra <div> elements arround your webparts we will need a piece of javascript.

Open the (empty) boxing.js file you created earlier and add the following code

/* Add extra div arround webparts so they can be styled with a box. */
$(document).ready(
    function RoundWebPartHeader() {
        $(".s4-wpTopTable").each(function () {
            $(this).addClass("wp-head-round")
            .wrap('<div class=\"box-wp-dialog\">')
            .wrap('<div class=\"box-wp-content\">')
            .wrap(' <div class=\"innerbox\">')
            .parents("div:first").parents("div:first").parents("div:first").prepend('<div class=\"top\"><span>&nbsp;</span></div>')
            .append('<div class=\"bottom\"><span>&nbsp;</span></div>')
        });
    }
);

This JavaScript uses jQuery to find all HTML elements with the css class “s4-wpTopTable”.  By default this css class is assigned  to every web part on the page by SharePoint.

For each HTML element with css class “s4-wpTopTable” the code does the following :

  • adds a css class “wp-head-round”
  • wraps the web part in a <div> with class “box-wp-dialog”
  • wraps the web part again with a <div> with class “box-wp-content”
  • inside the <div> with class “box-wp-dialog”, a new <div class”top”> is added
  • inside the <div> with class “box-wp-dialog”, a new <div class”bottom”> is added

When this is done the SharePoint web part will be encapsulated by various <div> elements.
And the HTML will look like this

<div class="box-wp-dialog">
  <div class="top">
     <span>&nbsp;</span>
  </div>
  <div class="box-wp-content">
    <div class="innerbox">
      <! -- The webpart table HTML is included here -->
      <table cellspacing="0" cellpadding="0" border="0" width="100%" class="s4-wpTopTable">
      </table>
    </div>
  </div>
  <div class="bottom">
    <span>&nbsp;</span>
  </div>
</div>

Go ahead and try it out. Visually there will be no changes (yet). But the extra <div> should be there in the HTML. Keep in mind that the extra HTML elements  are added dynamically on the client side. You will not see these new HTML elements in the source of the page. You need to inspect the HTML with FireBug or with the “Internet Explorer Developer Tools” (F12)

Styling

So now that you have the (extra) <div> elements in our HTML, we can focus on actually styling and creating the box. The last step in our tutorial.

Open the (empty) style.css file and add the following css code.

.box-wp-dialog .top
{
  background-image:url(/_layouts/Styles/boxdemo/tl.png);
  background-repeat: no-repeat;
  background-position: left top;
  height: 12px;padding: 0px 0px 0px 10px;
}
.box-wp-dialog .top span
{
  background-image:url(/_layouts/Styles/boxdemo/t.png);
  background-repeat: no-repeat;
  background-position: right top;
  width: 100%;height: 12px;float:  left;
}

.box-wp-dialog .bottom
{
  background:url(/_layouts/Styles/boxdemo/bl.png) no-repeat left bottom;
  height: 10px;
  padding-left:15px;
}

.box-wp-dialog .bottom span
{
  background:url(/_layouts/Styles/boxdemo/b.png) no-repeat right bottom;
  height: 10px;
  display:block;
}

.box-wp-dialog  .box-wp-content
{
  background: url(/_layouts/Styles/boxdemo/l.png) repeat-y top left;
  padding-left: 2px;
}

.box-wp-dialog  .box-wp-content .innerbox
{
  background: url(/_layouts/Styles/boxdemo/r.png) repeat-y top right;
  background-color: #FFFFFF;
  padding: 5px 5px 0px 10px;
}

This CSS code simply defines the correct background images on our web part to create the illusion of a box.  Save the file and reload your page. Make sure your browser is not using a cached copy.

You should see something similar to this

 

You can change the images to the desired color. Play around with the height, padding, etc…

Happy coding…

Read Full Post »

I always get a little nervous when I see a “Service not found” on my development machine instead of the desired website.

Most of the time it can be resolved by doing:

or any combination of the above.
But today it turned out to be “Url reservation”. I probably changed my IIS7 settings a few months back when I was reading a book about WCF.

I finally found that the command “netsh http delete urlacl” did solve my issue and I got my website (on port 80800) working again.

More info about netsh command here , here and here

Read Full Post »

When adding a List View web part in a custom Site Definition  be careful to define the url correctly. If not, SharePoint returns the following error when creating a site based upon the Site Definition.

Cannot complete this action.

Please try again.   at Microsoft.SharePoint.Library.SPRequestInternalClass.ApplyWebTemplate(String bstrUrl, String& bstrWebTemplate, Int32& plWebTemplateId)
at Microsoft.SharePoint.Library.SPRequest.ApplyWebTemplate(String bstrUrl, String& bstrWebTemplate, Int32& plWebTemplateId)

It took me a whole afternoon looking for a solution.

Detailed description

I created a feature with a new Site Definition. To this Site Definition I added a custom task list with display name “Qrm reminders”. The list is a custom list that is deployed as a feature ( 2849AF43-E405-481c-9803-09F55785C214) on the server.

For your reference I also included the definition of a default task list.

   1:  <List FeatureId="00BFEA71-A83E-497E-9BA0-7A5C597D0107" Type="107"


2:                Title="$Resources:core,taskList;"
   3:                Url="$Resources:core,lists_Folder;/$Resources:core,tasks_Folder;"

   4:                QuickLaunchUrl="$Resources:core,lists_Folder;/$Resources:core,tasks_Folder;/AllItems.aspx" />
   5:  


   6:          <List FeatureId="2849AF43-E405-481c-9803-09F55785C214" Type="10002"
   7:                Title="QRM Reminders"
   
8:                Url="$Resources:core,lists_Folder;/QrmTasks"
   
9:                QuickLaunchUrl="$Resources:core,lists_Folder;/QrmTasks/AllItems.aspx" >

As you can see in the above code, the list “QRM Reminders” is added. It is based on custom type  10002.  I also replaced the resource that defines the name for the list  ‘QRMTasks’

Further down in the Site Definition I add a List View web part on the default.aspx page. This List View web part points to the custom list QRMTasks (display name = Qrm Reminders)

   1:          <View List="Lists/QrmTasks" BaseViewID="1" WebPartZoneID="Right" WebPartOrder="3" />

When creating a site based on this site definition with the List View web part, it returns the following error.

Cannot complete this action.Please try again.   at Microsoft.SharePoint.Library.SPRequestInternalClass.ApplyWebTemplate(String bstrUrl, String& bstrWebTemplate, Int32& plWebTemplateId)

Some error information from the SharePoint logs :

Creating list “QRM Reminders” in web “http://wind2003entr2:1100/sites/demoSiteFail&#8221; at URL “Lists/QrmTasks”,

Creating default modules at URL “http://wind2003entr2:1100/sites/demoSiteFail&#8221; Not enough information to determine a list for module “Default”. Assuming no list for this module.

Failed to find a suitable list for tag in module for file ‘default.aspx’ given List attribute ‘QrmTasks’.

Failed to apply template “ProjectSite#0″ to web at URL “http://wind2003entr2:1100/sites/demoSiteFail&#8221;.
Failed to apply template “ProjectSite#0″ to web at URL “http://wind2003entr2:1100/sites/demoSiteFail&#8221;, error 0×80004005

Without the List View web part definition, the site and the QrmTasks list are created successfully.

Solution.

It took me a whole afternoon to figure it out. It turned out the  url attribute was improperly set.
I specified the list url as: Url=”$Resources:core,lists_Folder;/QrmTasks”. So it would result in Lists/QrmTasks

For some reason the List View web part could not find the “QrmTasks” list on this location. So I simplified the url and deleted the folder ‘Lists’ from the url

   1:  <List FeatureId="2849AF43-E405-481c-9803-09F55785C214" Type="10002"
   2:                Title="QRM Reminders"
   3:                Url="QrmTasks"
   4:                QuickLaunchUrl="$Resources:core,lists_Folder;/QrmTasks/AllItems.aspx" >
      7:  ...
     6:  <View List="QrmTasks" BaseViewID="1" WebPartZoneID="Right" WebPartOrder="3" />

Note: the url attribute of the list definition now only contains QrmTasks.

Basically the list ‘folder’ is removed from the url. After this the Site Definition worked as expected and the List View web part was correctly provisioned on the page.

Read Full Post »

I recently ran into a problem where my web part, that uses jQuery, didn’t work anymore on the SharePoint production server. After some investigation it became clear that it was caused by another  SharePoint feature that was enabled on the site.

This SharePoint feature used it’s own JavaScript framework that conflicted with jQuery. jQuery uses some keywords and expressions in a fashion that does not match with other libraries. jQuery Has foreseen this and has functionality in place to resolve this.  More information on how to solve this can be found here.
After applying these changes the two frameworks were working happily together.

For more detailed information about the issue I encountered see here.

Hope it helps.

Read Full Post »

Older Posts »

Follow

Get every new post delivered to your Inbox.