Category Archives: Tip

SharePoint document templates: A solution to the one-template-per-content-type problem?

One of our customers was upgrading their intranet from SP2010 to 2013, and wanted help improving their document management solution simultaneously. Their current solution already had a lot of document templates, and since we wanted to merge some of the libraries having different templates, we were looking at a situation of having libraries with perhaps 30-50 templates, which in SharePoint means 30-50 content types. Not only would this be a pain to maintain, it also makes it much harder for users to use the templates. And let’s face it, managing document templates in SharePoint is already an awful experience, even with just a few templates to manage. In this case, as in most, the metadata from SharePoint had to be visible in the documents created using the templates as well. That meant having quick parts in the templates with a connection to the fields in the SharePoint library. So, in a conversation with the customer, one of them asked if we couldn’t simply put the templates in Word instead. My immediate reaction was “Hmm… no… i don’t think so. I don’t think the connection to SharePoint will be maintained”. But then I thought about it and figured it just might work. If the template was stored in a SharePoint library, the correct quick parts could perhaps be added and work anyway. So I did some searching and came up with the following solution:

  1. Put the documents that should be used as templates in a document library in SharePoint
  2. Set the Workgroup templates property in MS Word to the address of the SharePoint template library

In other words, new documents aren’t created from the SharePoint library at all. Instead the user can create new documents directly from word, which is an improvement in my opinion (though I would prefer if you could still create documents from SP as well). The Workgroup templates property in Word allows users to point to a folder, making all the documents in that folder appear as custom templates in Word. The problem was that you’re not allowed to set the Workgroup templates property to a web address. I did some searching, and found a few posts on how to work around this. What you need to do is:

  1. Map a network drive to the address of the SharePoint library
  2. Set the Workgroup templates property in MS Word to another network drive (not the one you just created)
  3. Open regedit and modify the property to point to your own network drive

After performing these steps, the files stored in the SharePoint library can be used as templates in word, with working quick parts, and you won’t even need to open SharePoint to create documents anymore. Note: This works in both SharePoint on-premises, and SharePoint Online!

Ok, so how do we do this?

1. Map a network drive to a SharePoint library

There are plenty of examples out there on how to do this. Here is the MS one: https://support.microsoft.com/en-us/kb/2616712?wa=wsignin1.0

  • Make sure the site with the document library is added to your list of Trusted Sites.
  • If using SharePoint Online, log into your tenancy, and make sure to remember the credentials.
  • Right-click Computer and choose “Map network drive…” in the menu.
  • In the Map Network Drive dialog, enter the following. Drive: Choose a Drive to map it to. I like S: as in SharePoint. =) Folder: Paste the URL to the document library
  • Click Finish

Windows explorer should now be opened automatically, showing you the contents of the library. MappedDrive

2. Set the Workgroup templates property in MS Word

The next thing we need to do is set the Workgroup templates property in MS Word. This will make the given location be used as a folder for custom document templates. I am using Word 2013 in this example. But it should work for 2007 and 2010 as well, even if the paths may vary.

  • Open MS Word
  • Go to File –> Options –> Advanced (scroll to the bottom) and click the “File Locations…” button.
  • Modify the Workgroup templates property and set it to a non-web address location. I set it to D: for example (see image) WordWorkgroupTemplates
  • Confirm all the dialogs and close Word.

3. Open regedit and modify the property

  • Open up the registry editor (press the windows key, type “regedit”, press enter)
  • Go to HKEY_CURRENT_USER/Software/Microsoft/Office/15.0/Common/General Note: Replace “15.0” with your current office version.
  • Modify the “SharedTemplates” property and set it to the drive of your SharePoint library, in my case S: regedit
  • Confirm the dialog and close the registry editor.

4. Create a new document using your new template

And now you are done, ready to use the documents stored in the library as templates!

  • Open Word and go to the New screen
  • Click the Custom tab, and you will see a folder named “S:” (or whichever drive you mapped the library to) newDocument
  • Open the S: folder to see all the documents stored in the library. Just click the one you want to use as a template. newDocument2
  • Word will now copy the document from SharePoint and create a new file for you, with SharePoint field references working perfectly. newDocument3

Benefits over regular SharePoint document templates

Easier to update templates. To edit the templates, you just need to edit the documents stored in the template library, rather than edit the template file connected to a content type, saving you a lot time, especially when adding/changing quick parts in the template. Create documents from Word, instead of SharePoint. Word is the program you use to edit documents, so why should I have to go to SharePoint to create a new one? Wouldn’t it be easier if I could create a new document from a template directly in Word? Yes it would. It would simplify the process greatly. Separation between Content Types and Template. Having a 1-to-1 relationship between Content Types and Templates is a system design mistake of epic proportions, and one of the reasons you cannot create a great document management system in SharePoint without customizations. Separating the two is a major win, enabling you to have a great number of templates without adding unnecessary complexity.

Limitations and drawbacks

Single Site Collection. This solution will ONLY WORK ON A SINGLE SITE COLLECTION! The templates will need to be stored on a library on the same site collection were the new documents will be saved. It can be on different web sites, but save it on another site collection and the fields won’t update inside the document, even if the content type is distributed through a content type hub. This means that the users need to know where to save the documents if they should work as expected. This basically means that you cannot have a document management system (DMS) consisting of several site collections, which you shouldn’t want to anyways. But this puts a limit to scalability. You can use archiving to keep your DMS site collection below the recommended levels, but it’s still more limited. There may be a way around this by ensuring that the fields SourceID and internalName attributes are consistant between site collections, but I haven’t tested it yet.   I hope you give this a try. It’s a working (although not great) way of separating Content Types and Templates, which is something MS should have done a looong time ago.

Advertisements

SharePoint two way lookup field, strictly out of the box

Sometimes you forget that SharePoint can do things out of the box, and you immediately start to think about how to customize or buy third party products to solve issues.

I for example, wanted a two way lookup between two lists. In other words, if I added items from List A to a lookup of an item in List B, I would like to be able to see the relationship on items in both lists. When I got the advice to buy a third party product for this, I thought I’d just see if there were any other options, and of course there was!

By following the steps on this blog, all I needed to do was to edit the display form of List B, and insert the related list. To do this, just go to list settings -> Forms Web Parts -> Default Display Form.

formWebParts

You will be redirected to the display form in edit mode. Just click the web part zone and the insert tab will appear. Open it, click Related List and select the list in the drop down.

relatedList

This will add a list view web part to the form, which is pre-connected to the item opened in the display form. Next time you open up an item in the list, you will see the list view of the related items in the form. Of course you can do this on the new, and edit forms as well.

This approach doesn’t look very good however, and you won’t get the related items in a list view. But it’s cheap, and could suit customers who are very cost-aware (a nice way of saying cheap). And with a little JSLink magic you should be able to make it look a lot better with hardly any effort at all.

Generate Guid easily with ReSharper

Sometimes the smallest things make our life a lot easier.

Like this tiny – but great – feature from ReSharper for generating Guids. Simply write nguid in any file, no matter the type, and press tab.

guid1

ReSharper will then generate a new Guid for you, and even let you choose a format.

guid2

Just one of those small, nice things making ReSharper a delight to work with. =)

(Thanks for the tip Villy)

Export SharePoint list data to XML directly from the GUI

The other day I learned of a cool function in SharePoint which can come in handy if you want to export a list to XML. And best of all, no code, script or SharePoint Destroyer… *cough* … Designer needed. What you do is simply to call an OOTB SharePoint service and specify in the query string what it is you want, and in which format:

http://<site url>/_vti_bin/owssvr.dll?Cmd=Display&List=<list guid>&View=<view guid>&Query=*&XMLDATA=TRUE

So what you do is to call the owssvr.dll from the site you want to export from, and in the query string add Cmd=Display. Then you add the List and View you want to export from. If you want all items and fields you simply set Query=*. Mind, you still might have to reference a view, even though it won’t be used when using the query. And in the end, add XMLDATA=TRUE. That’s it! An example of how it might look:

http://myawesomesite/_vti_bin/owssvr.dll?Cmd=Display&List={002A6DE2-7638-4FEF-A7CD-7427D4DECABA}&View={757d5548-eafc-4a5f-8ef4-e0be36d790a3}&Query=*&XMLDATA=TRUE

You can get the guid to the list by simply going to the list settings and copy the guid from the url. Its the guid after “…&List=”. That’s it. =) Some documentation about it and other SharePoint services: http://msdn.microsoft.com/en-us/library/dd588689(v=office.11).aspx

SharePoint 2010 Security Breach: Export to Excel Ignores Security Trimming

I’m currently working on a project where there are lists where permissions are broken and set on the list item level. Basically there are different groups of users, and some should see all items, and some should only be able to view a fiew of them. Now, all of these users have contribute, and can use the ‘Export to Excel’ function, which is very important to them. Now here is the issue I found out just a few days ago. Export to Excel ignores security trimming!

So what does this actually mean? Let me illustrate using a fictional example: I have a list called Accounts, where I store important information about clients and the business I have with them. Some accounts are secret, so I break the permission inheritance on them. Let’s say I have three accounts, A, B and C. Account A is secret, and I’m the only one who has permissions to view it. Now, I have a group of colleagues, who also have access to the Accounts list, and can contribute to it. But when they visit the list, they can’t see Account A, since I have removed their permissions from it. Now what happens when one of my colleagues use the Export to Excel function? You would think that the generated Excel file would only contain accounts B and C. But no! The export function ignores the permissions of the user and only checks if the user has permissions to acces the function itself. The result is the user being able to see account A as well, giving it access to information that should be hidden. In my opinion, this has to be regarded as a bug, because if this is by design, it’s poor design indeed.

EDIT: I tested this in SharePoint 2013, and the bug seems to be fixed. Will try and see if there is a hotfix or CU fixing this issue for SP 2010.

EDIT 2: After installing the July 2014 CU for SharePoint Server 2010, I can confirm that the bug is not fixed. It has to have been fixed for SP 2013 only.

EDIT 3: It seems that security might be trimmed after all, only that it uses the current windows credentials rather than the account logged into SharePoint with. Please read Pierres great comment below. I have personally not tested this though.

Automatic minifying of CSS (and LESS) and javascript using Web Essentials 2013 in Visual Studio 2013

We just recently started upgrading to Visual Studio 2013 in the project I’m currently working on, and with VS 2013 comes Web Essentials 2013, an extension that’s truly essential for web development.

Now, I like to use the LESS framework when writing CSS, and have been using Web Essentials 2012 for some time. One of the nice things about LESS and Web Essentials 2012 was that it automatically generates a minified version of the CSS file for you, and that’s pretty sweet.

Now, one of the first thing we noticed in VS 2013, was that modifying and saving our LESS files no longer generated a minified version of that file.

No mini

At first we thought it might be a bug, but when exploring the toolbar menu for Web Essentials (new to 2013), we found an interresting button:

Toolbar menu

Pressing this created a settings file and added it to the solution. In this file we found a number of awesome stuff. For example, you could turn the automatic generation of CSS files on and off. And even better, there was even an option to do the same for our javascript files!

Settings

Now we were getting our minified CSS files just like before, and also having the same behavior for our javascripts!

Yes mini

Before, we used another VS plugin for generating our minified javascripts, but now we no longer need to. Everything is taken care of using Web Essentials 2013, and modifying the settings file.

Perhaps the best thing about the created settings file is that it is automatically added as a solution file, and picked up by the source controller. So once configurated, we can just check in the file and let everyone in the team get the correct behaviour automatically.

Now, I may be ignorant of what was possible in 2012. Perhaps this settings file was available, and perhaps they had support for minifying javascripts. But since Web Essentials are now more visible than before (having its own toolbar menu), finding these features was easier, and took only a few minutes to figure out, without googling for help or reading any Product Updates info. And to me that’s pretty sweet! =)