Tag Archives: SharePoint

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.

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.

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

Unhide a hidden SPField using PowerShell

Another task that’s much harder than it should be. Setting the hidden property of a SPField to false.

First you get the field itself. In this example we change the setting of the field in the library, but it could just as well be done on the site level.

$web = Get-SPWeb http://MyWeb
$list = $web.Lists["MyList"]
$field = $list.Fields.GetFieldByInternalName("MyField")

Then, when you have the actual field, you just need a bit of reflection magic.

$type = $field.GetType()
$mi = $type.GetMethod("SetFieldBoolValue",[System.Reflection.BindingFlags]$([System.Reflection.BindingFlags]::NonPublic -bor [System.Reflection.BindingFlags]::Instance))
$mi.Invoke($field, @("CanToggleHidden",$true))
$field.Hidden=$false
$field.Update()

I don’t know why, but simply setting field.Hidden = $false doesn’t work. But the code above does!

Solution comes from here.

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.

Programmatically move a SPListItem to another folder in the same list

I had a hard time finding a good source for this, and therefore decided to write a short post about it.

First of all, I want to say that I am against the use of folders unless you absolutely need them. They add unnecessary complexity, and you can have the benefits of folders without many of the drawbacks by using metadata instead, for example with managed metadata fields. However, as there are no OOTB (out of the box) way of handling permissions for a group of items based in their metadata, folders MIGHT be useful for that purpose. There are other solutions though.

Now to the task at hand, moving a SPListItem based on it’s metadata, and then moving it to a subfolder in the same list. In my example, I will be moving the item in an event receiver.

What we need to do is to check the SPFileSystemObjectType of the SPListItem. This value will actually be File, even it it’s not a document library. Regular list items will also return object type File. This is only needed if you don’t want to move folders the same way.

This code assumes you have already got your SPListItem:

if (item.FileSystemObjectType == SPFileSystemObjectType.File)
{
 // Put the rest of code here.
}

Then we need to get the file object of the item. The file object will exist even if the list is not a library, and this code will work for documents and list items alike.

SPFile file = item.Web.GetFile(item.Url);

Then we want to build the new destination path were the item will be moved to. The path should follow the pattern: “<web url>/<list rootfolder url>/<subfolder>/<item Id>._000”

string filePath = string.Format("{0}/{1}_.000", "My Folder", item.ID);

And lastly, we simply call the SPFile.MoveTo method on our file object, and add the destination path.

file.MoveTo(filePath);

And that’s it. Put this in an ItemAdded function in an event receiver for a list and items will automatically be moved to the correct folder. Below is my complete example where I also make sure the folder exist before moving the item.

public override void ItemAdded(SPItemEventProperties properties)
{
 var item = properties.ListItem;
 var folderName = item["My Column"].ToString();
 var folderUrl = SPUtility.ConcatUrls(SPUtility.ConcatUrls(item.Web.Url, item.ParentList.RootFolder.Url), folderName);

 EnsureFolder(item.ParentList, folderName, folderUrl);

 MoveItemToFolder(item, folderUrl);
}

private static void EnsureFolder(SPList list, string folderName, string folderUrl)
{
 if (!list.ParentWeb.GetFolder(folderUrl).Exists)
 {
 SPListItem newFolder = list.Items.Add(list.RootFolder.ServerRelativeUrl, SPFileSystemObjectType.Folder, folderName);
 newFolder.Update();
 }
}

private static void MoveItemToFolder(SPListItem item, string folderUrl)
{
 if (item.FileSystemObjectType == SPFileSystemObjectType.File)
 {
 var filePath = string.Format("{0}/{1}_.000", folderUrl, item.ID);
 var file = item.Web.GetFile(item.Url);
 file.MoveTo(filePath);
 }
}

Sources:

http://zhebrun.blogspot.se/2011/06/sharepoint-how-to-move-listitem-or.html

 

Programmatically create, setup and use a custom Site Policy

On a current project I got the task to implement a solution for pushing out Site Policies to team sites. The common way of doing this is by using a Content Type Hub, which there are several blogs and guides available explaining how to do. But in this case this was not an option, and I had to be able to do it programmatically.

Finding examples of how to create a custom Site Policy wasn’t very hard, but what I soon discovered was that hardly any of these actually explained how to setup the schema of the policy the way you wanted. They just explained how to create one and maybe even set it to be used on a given site. And the object model itself isn’t complete enough to let you set everything using code. Eventually I found one single blog post by Dragan Panjkov which showed how to set it up, and managed to get it to work.

Site Policies are actually hidden content types, which you can tell by some parts of the creation process.The creation of the policies are actually pretty simple, and can be done with a few lines of code. First of all, you need reference the InformationPolicy namespace, like so:

using Microsoft.Office.RecordsManagement.InformationPolicy;

The second thing we do is getting the ProjectPolicy content type, which is (according to it’s own description) the “Container content type for Project Policy definitions”.
Note: The code assumes you already have an SPSite object called site.

var projectPolicyContentTypeId = new SPContentTypeId("0x010085EC78BE64F9478aAE3ED069093B9963");
var contentTypes = site.RootWeb.ContentTypes;
var parentContentType = contentTypes[projectPolicyContentTypeId];

The content type id in the code above is always the same, and is the id of the content type “Project Policy”.

Then you can create your own content type using Project Policy as the parent.

var policyContentType = new SPContentType(parentContentType, contentTypes, "My Site Policy");
policyContentType = contentTypes.Add(policyContentType);
policyContentType.Group = parentContentType.Group;
policyContentType.Description = "My Description.";
policyContentType.Hidden = true;
policyContentType.Update();

The next step is to setup the content type with the schema you want to use. For this there is no object model support. You have to write your own xml, which is a real pain. But the great post by Dragan gave a great solution on how to do this.

Setup a Site Policy the way you want it on a site in the browser. Open the site in SharePoint Manager and go to the Content Types collection. There will be a content type with the same name as the policy you just created. Click the content type and scroll down to the XmlDocuments property. Open that collection and copy the value of the <pp:ProjectPolicy> property.

policyschema

You will get an xml string, which you can copy and reuse to create your new policy schema. Doing so is simple. With the same content type object you have created previously, delete the existing project policy XmlDocument using the name from the xml.

policyContentType.XmlDocuments.Delete("http://schemas.microsoft.com/office/server/projectpolicy");

Then load your copied xml string into a new XmlDocument object, and add that to the XmlDocuments collection of your content type, and updated it.

var policySchema = new XmlDocument();
policySchema.LoadXml("Insert policy schema xml here.");
policyContentType.XmlDocuments.Add(policySchema);
policyContentType.Update();

When this is done, all that’s left is to create a Policy, using your content type.

Policy.CreatePolicy(policyContentType, null);

And that’s it. You’ve created your own Site Policy, with a custom schema, and all through code.

To apply the custom policy, simply get the policy object using the ProjectPolicy class, and run the ApplyProjectPolicy method.

var policy = (from projectPolicy in ProjectPolicy.GetProjectPolicies(web)
	where projectPolicy.Name.Equals("My Site Policy")
	select projectPolicy).Single();
ProjectPolicy.ApplyProjectPolicy(web, policy);

I’ve added a simple PolicyService class on GitHub Gist. Feel free to copy and use it if you want. Some tweaks may be necessary. =)

Resources:

http://blog.dragan-panjkov.com/archive/2013/10/27/configuring-site-policy-in-sharepoint-2013-using-server-code.aspx

Thoughts on SPC14

LV2_0001

So I attended the official SharePoint Conference in Las Vegas for the first time last week, and after a few days of contemplation I just want to try and summarize the experience and try to jot down some of the takeaways.

For an even better summary, check out my Colleague Anatoly’s summary over at Chuvash. =)

And while a lot of this may not be news, it’s still the impression I got from the conference. If it’s old news, it might just be a more clear sign that this is indeed the path Microsoft is on when it comes to SharePoint.

SharePoint and Office

So it’s been back and forth with SharePoint and Office since… well like forever. SP 2007 was called MOSS (Microsoft Office SharePoint Server), but then they removed SharePoint as a part of Office in 2010. Now they’re bringing it back, but of course (unless you haven’t noticed yet) as a part of the online version, Office 365 and SharePoint Online. Microsoft is (and this is not new for 2014) betting big on Office 365, and they aim to have SharePoint Online usage exceed SharePoint on premise usage by 2016. I won’t go in to a discussion on why you should or shouldn’t migrate to SharePoint Online, but it’s pretty clear what the Microsoft roadmap looks like. This was extremely obvious during the conference as the word SharePoint hardly appeared without an Office logo next to it, and many sessions were focused to SharePoint AND Office developers. The question is how well (or rather how fast) the SP community and businesses will accept and adopt it. What I do believe is no matter what you may feel about SharePoint Online and Office 365, everyone planning on using or developing SharePoint in the future have better to start learning the differences, and preparing on what a migration might require in the future. That said, there is still a lot happening with the platform, and it will probably have a lot less gaps in it in a year or two, as updates are pretty frequent.

App-solutely! (Oh no he didn’t!)

Bad jokes aside, the (SharePoint) Cloud App Model won’t just be a fluke, passing by if we just keep ignoring it. I know that a lot of developers (including myself) often get stuck on it’s flaws, and argue against using it in favor of our dear old sandboxed and farm solutions. But the planet of the apps is coming, and it’s not Microsofts “fault”. It’s just their version of a shift taking place in the entire space of web and application development. One of the main reasons (I think) for us developers having such trouble adopting it, is due to the fact that we once again have to handle a lot of things that were previously handled for us, like passing authentication tokens across domains and other tedious tasks. In short, it’s more difficult to develop some things using the App Model than using a good old visual webpart for example. But we need to learn how to do it, anyway. It’s not our choice, it’s not Microsofts choice (sort of). It’s just how it is.

AND… The App Model is still pretty new compared to “the good old stuff”, and it’s evolving all the time, as is the body of knowledge possessed by the SP community. It will get better, and easier to work with. For now, we just have to keep improving ourselves and learn all the new techniques and skills needed to be good little SP developers.

SharePoint is getting smaller

So we’ve seen it before. In SP 2013, a few services were cut loose, the recommendation to host them on individual servers. For example Office Web Apps (I know it was a separate product even in SP2010), Workflow Manager or Foundation or what’s it’s name, etc. This goes hand in hand with the architectural mindset of the App Model, and what’s happening in Office 365. Instead of having SharePoint as a big, bulky blob of a system slash platform slash product slash everything, Microsoft is taking the approach of detaching components from one another, having the possibility to connect them to each other instead. While this will require more configuration than before (just look at the Workflow engine), it provides a better architecture, providing better performance, stability, maintainability etc.

Side note: Developers can adopt this same mindset when building functions for their SharePoint portals, using the App Model. Building a function which runs separate from SharePoint, but is still used from within has a lot of benefits, and will go hand in hand with the path Microsoft is taking. So the next time you’re considering making yet another Visual WebPart, just give a few minutes of thought if it might not be better to build it as an app (and add about 500 % of development time to your project plan for learning how to build it, host it and use it).

SharePoint 2015

Yes there will be another SP on premises released in 2015. Will give us some more time to adapt to O365. Yay!

SharePoint Dev = Web Dev

Being a good SharePoint developer is more and more becoming being a good Web developer. While scary for some, it’s not a bad thing. It means that we may benefit from a larger developer community, with all the benefits it brings. Plus, being a web developer is cool. Like… hipster cool (or?).

Microsoft is also getting better at using standards and open source stuff regularly used by the web community. What about an Office 365 SDK for android on GitHub? And sessions this year have even promoted using javascript frameworks such as AngularJS developed by Google. I think our little boy is finally growing up. =)

Conference available for all

So the entire conferences sessions (I think) will be available on Channel 9 for all to see, both videos and presentations. While some (douchebags) whine about spending $$$ plenty on actually attending the conference needlessly, I say HORAY! Knowledge should be free. I like the sharing Microsoft better. =)

Here is a short list of sessions I attended which I think were awesome, or simply informative.

  • Developer audience keynote | What’s new for the Office & SharePoint developer (If you want to see what Microsoft wants)
  • SharePoint Power Hour – New developer APIs and features for Apps for SharePoint
  • Adjust the perspective with responsive designs for SharePoint
  • Build your own REST service with WebAPI 2
  • Apps, BCS, OData, Search and O365…Oh My
  • Site provisioning techniques with SharePoint apps
  • Deep dive: REST and CSOM comparison
  • Best practices for maintaining and updating a SharePoint App

LV1_0038

Programmatically set navigation settings in SharePoint 2013

When working on a project where I needed to set the navigation for newly created sites programmatically, I had a hard time finding the correct properties and methods in the SharePoint object model to change all the navigation settings. After some researching I found that you need no less than 3 different objects representing the navigation of a website to be able to modify all the settings. These examples apply to SharePoint sites with publishing features enabled (navigation options differ on non-publishing sites), and just using the PublishingWeb.Navigation and WebNavigationSettings objects were sufficient for me. Other properties can be found in the SPWeb.Navigation object however.

These are the objects containing navigation properties:

  • web.Navigation (Namespace: Microsoft.SharePoint)
  • publishingWeb.Navigation (Namespace: Microsoft.SharePoint.Publishing)
  • WebNavigationSettings (Namespace: Microsoft.SharePoint.Publishing.Navigation)

Here are examples of how you instantiate these objects:

// Web Navigation
using (var site = new SPSite("http://somesite"))
using (var web= site.OpenWeb())
{
 var navigation = web.Navigation;
}

// PublishingWeb Navigation
var pubWeb = PublishingWeb.GetPublishingWeb(web);

// WebNavigationSettings
var webNavigationSettings = new WebNavigationSettings(web);

Once instantiated, you will be able to modify the navigation using these objects. I will show some examples of how to set different options on the Navigation settings page on a publishing site through code.

Select type of navigation

GlobalAndCurrent

There are two navigations. The Global navigation (also called Top navigation) and the Current navigation (also called left navigation or quicklaunch). Both of these can be set to different to use different sources. They can inherit from their parent (if a subsite only), use managed navigation, or structural navigation. All you need to do is select the webNavigationSettings object, choose which navigation to set, and select a source for that navigation.

webNavigationSettings.GlobalNavigation.Source = StandardNavigationSource.TaxonomyProvider;
webNavigationSettings.GlobalNavigation.Source = StandardNavigationSource.InheritFromParentWeb;
webNavigationSettings.GlobalNavigation.Source = StandardNavigationSource.PortalProvider;
webNavigationSettings.GlobalNavigation.Source = StandardNavigationSource.Unknown;
webNavigationSettings.CurrentNavigation.Source = StandardNavigationSource.Unknown;

TaxonomyProvider is Managed Metadata Navigation, PortalProvider is structural navigation, InheritFromParentWeb is self-explanatory, and Unknown leaves no radiobutton selected.

Show subsites and pages

To change these options you need to use the PublishingWeb object.

ShowSubsitesAndPages2

pubWeb.Navigation.CurrentIncludeSubSites = false;
pubWeb.Navigation.CurrentIncludePages = false;
pubWeb.Navigation.CurrentDynamicChildLimit = 20;

Managed navigation: Page settings

To change the values of these two checkboxes, use the WebNavigationSettings object again.

DefaultPageSettings

webNavigationSettings.AddNewPagesToNavigation = false;
webNavigationSettings.CreateFriendlyUrlsForNewPages = false;

Managed navigation: Term set

To connect to a term set in code you can do something like this.

MetadataNavigation

// Below code has to be used from within a method of course.
var session = new TaxonomySession(web.Site);
if (session.TermStores.Count != 0)
{
    var termStore = session.TermStores["MyTermStoreName"]; // Standard name is "Managed Metadata Service"
    var group = this.GetTermGroupByName(termStore.Groups, "MyTermGroupName");
    var termSet = this.GetTermSetByName(group.TermSets, "MyTermSetName");
    webNavigationSettings.GlobalNavigation.TermStoreId = termStore.Id;
    webNavigationSettings.GlobalNavigation.TermSetId = termSet.Id;
}

// Support methods
private Group GetTermGroupByName(GroupCollection groupCollection, string name)
{
    foreach (var group in groupCollection)
    {
        if (group.Name == name)
        {
            return group;
        }
    }
    return null;
}

private TermSet GetTermSetByName(TermSetCollection setCollection, string name)
{
    foreach (var set in setCollection
    {
        if (set.Name == name)
        {
            return set;
        }
    }
    return null;
}

Structural navigation: Sorting

Use the PublishingWeb.Navigation to set the ordering of the Structural navigation.

Sorting

pubWeb.Navigation.OrderingMethod = OrderingMethod.Automatic;
pubWeb.Navigation.AutomaticSortingMethod = AutomaticSortingMethod.Title;

Update
Finally, don’t forget to update your objects when you are done with them.

webNavigationSettings.Update();
pubWeb.Update();
web.Update();

These examples are not a complete overview of what you can do with the navigation in SP2013, but the objects I have shown contain most of the properties needed to set the navigation. You just have to look at the object model in Visual Studio to find other options, and most are pretty self-explanatory.

How to provision a ContentEditorWebPart (CEWP) with predefined content to a page using a module

I did this a long time ago, then when I recently had to do it again, I couldn’t fid any Resources online describing how to do it. Simply adding text to the <Content> tags of the <AllUsersWebPart> declaration didn’t do it. The reason is simple I Think. The content in a CEWP is html, and you need encoded HTML tags for it to show. Otherwise the content will simply be ignored (This is my own theory at least. I haven’t investigated much).

So knowing that you can add any html content. Here is how you add an image for example:

<Content xmlns="http://schemas.microsoft.com/WebPart/v2/ContentEditor"> 
    ​&lt;img alt=&quot;&quot; src=&quot;/PublishingImages/image-sample.png&quot;&gt;
</Content>

The easiest way to get encoded HTML is to use an Encoder, like this one. Simply paste your html and press encode. Then paste the results inside the <Content> tag for the CEWP. My full code example can be found below. This is to be put inside the File element in a Module:

<AllUsersWebPart WebPartZoneID="Right" WebPartOrder="1">
        <![CDATA[
           <?xml version="1.0" encoding="utf-8"?>
            <WebPart xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.microsoft.com/WebPart/v2">
              <Title>MyTitle</Title>
              <FrameType>None</FrameType>
              <Description>MyDescription</Description>
              <IsIncluded>true</IsIncluded>
              <ZoneID>Right</ZoneID>
              <PartOrder>4</PartOrder>
              <FrameState>Normal</FrameState>
              <Height />
              <Width />
              <AllowRemove>true</AllowRemove>
              <AllowZoneChange>true</AllowZoneChange>
              <AllowMinimize>true</AllowMinimize>
              <AllowConnect>true</AllowConnect>
              <AllowEdit>true</AllowEdit>
              <AllowHide>true</AllowHide>
              <IsVisible>true</IsVisible>
              <DetailLink />
              <HelpLink />
              <HelpMode>Modeless</HelpMode>
              <Dir>Default</Dir>
              <PartImageSmall />
              <MissingAssembly>Det går inte att importera den här webbdelen.</MissingAssembly>
              <PartImageLarge>/_layouts/images/mscontl.gif</PartImageLarge>
              <IsIncludedFilter />
              <Assembly>Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c</Assembly>
              <TypeName>Microsoft.SharePoint.WebPartPages.ContentEditorWebPart</TypeName>
              <ContentLink xmlns="http://schemas.microsoft.com/WebPart/v2/ContentEditor" />
              <Content xmlns="http://schemas.microsoft.com/WebPart/v2/ContentEditor"> 
                ​&lt;img alt=&quot;&quot; src=&quot;/PublishingImages/image-sample.png&quot;&gt;
              </Content>
              <PartStorage xmlns="http://schemas.microsoft.com/WebPart/v2/ContentEditor" />
              </WebPart>
              ]]>

This works in SP2010 and 2013. Just change the assembly version to 14 or 15 depending on which you are using. I presume it works the same in 2007 also, but I haven’t tried.