SharePoint 2010 Default Theme Colors

Applies To: SharePoint

I’ve been messing with Branding quite a bit lately and have been trying to find a way to keep it as simple as possible. The easiest choice is to use themes. There are several out of the box and it’s easy enough to create your set of colors using PowerPoint or ThemeBuilder. On a publishing site you can even just specify them right on the site!

But every theme I tried just didn’t look right. I finally decided that I really liked the default theme except for a color or two. Unfortunately, I couldn’t just start with the default and change a couple of colors using the simple themes engine. So I cracked open the corev4.css to see if I could find the default colors. Sure enough, you can see where the Theme Replacement comments are right next to a specified color (default when no theme).

So I started just snooping through the CSS and found some really interesting things. First, the theming engine is really powerful. Not only does it replace element colors on the fly, it can tint images (nice png gradients), and for each color it will actually use shades for various elements allowing you to only have to specify a small number of colors to get a wide palette.

For much more detail about where and how theme colors are used in the CSS check out Eric Schrader’s blog post that includes a pretty awesome Excel file: http://eschrader.com/2010/09/23/sharepoint-2010-%E2%80%93-themes-and-corev4-css-comparison-technique-for-developers/

However, the most interesting thing I found was that when you don’t use a theme (Default) you get many more colors and so the page looks much better. What I mean is that in trying to find the theme color default, I found that each one had several variations which I’ve laid out in a chart below. I expected to find (except in the case of tinting and named variations (lighter, lightest, etc.)) a single color for each theme color. Instead, most had several variations – ALL of which get replaced by a single color. This results in the default theme having a much greater depth than any theme available.

For example, in the CSS file there are even single classes that specify different defaults for the same theme replacement (Lines 2302 & 2304 below):

.ms-siteactionsmenuinner{
/* [ReplaceColor(themeColor:"Dark2")] */ border-color:#21374C;
/* [ReplaceColor(themeColor:"Dark2")] */ border-top-color:#394f63;
/* [RecolorImage(themeColor:"Dark2-Lighter",method:"Filling",includeRectangle:{x:0,y:467,width:1,height:11})] */ background:url("/_layouts/images/bgximg.png") repeat-x -0px -467px;
/* [ReplaceColor(themeColor:"Dark2")] */ background-color:#21374c;
}

Notice the background-color and the border-top-color are defaulting to different colors but both are replaced with the Dark2 theme color.

So what does this mean? Well it means that the default theme (no theme) will always look better than any theme you choose. Looking through the chart below you may even be surprised to see that certain colors are reused in the default theme but are replaced by different theme colors! (The default Hyperlink color #0072BC for instance). If you’d like to achieve the same level of depth you’ll need to create your own CSS file based on corev4.css removing the theme comments and manually specifying your colors. If you’re very serious about Branding, you’re probably already doing this, but those of us looking for a quick solution, this is pretty frustrating.

The themeing engine is very powerful and is still a huge leg up from the themeing available in SharePoint 2007, but it surprises me that they didn’t extend it further to handle all the options they themselves obviously required.

Default Theme Colors

Theme Color Value Example of Color
Light1 #FFFFFF
Dark1 #000000
#003759
#676767
#525252
#6d6f72
#3b4f65
#0072bc
Light2 #f6f6f6
#efefef
#fcfcfc
#F5F6F7
#e7e7e8
#ffffff
#f9f9f9
Dark2 #204d89
#003759
#929fad
#65686b
#0072bc
#161d25
#3b4f65
#5d6878
#003759
#49617a
#21374C
#394f63
#23272c
#666666
#476382
#182738
Accent1 #44aff6
#529dcc
#0072bc
Accent2 #ff0000
#EC008C
#CA0078
Accent3 #003399
#0093CA
#00adee
Accent4 #fd9f08
#ffbb47
#FD9F08
Accent5 #058036
#36B000
Accent6 #FAE032
Hyperlink #0072BC
#0061a0
FollowedHyperlink #b10069

Show Term Store Manager on Site

Applies to: SharePoint

If you’ve ever used the Records Center or one of the other templates that has it, you might wonder how you can get the Term store management link to show up under the Site Administration section of your Site Settings page as shown below.

This is a hidden feature and so can’t be activated from the Site Features. From Powershell, use this command:

Enable-SPFeature -ID "73EF14B1-13A9-416b-A9B5-ECECA2B0604C" -url http://sharepointsite/sites/targetsite

Choose Which Content Database to Create Your Site Collection in

Applies to: SharePoint

If you want to choose which Content Database to use when creating a new Site Collection you will have to use Powershell. There are some crazy solutions out there that tell you to do things like detach all other content databases or adjust the site limits to force SharePoint to pick your Content Database, but in a production environment that is usually not possible – not to mention stupid.

You can do all of this with the stsadm tool in SharePoint 2007, but I won’t be covering that here. But a good reference to figure out what commands match the powershell ones can be found here: http://technet.microsoft.com/en-us/library/ff621081.aspx

If you already have a Content Database you’d like to use, then skip ahead. Otherwise you can create a new Content Database pretty easy in Powershell using this command:

New-SPContentDatabase -Name MyNewSite_Content -WebApplication http://mysharepointsite.com

One of the main irritations with creating a new Site Collection from Powershell rather than the GUI is, although you gain the ability to specify the Content Database, you have to specify the site template by internal name. To get the internal names of all the Site Templates available, use this command:

Get-SPWebTemplate

But for the lazy (me), I’ve put a quick list of most of the templates and their internal names (For English sites – 1033) at the end of this article.

To create the new Site Collection while specifying the Content Database use the following command:

New-SPSite http://mysharepointsite.com/sites/mynewsite -OwnerAlias "MyDomain\MyUser" -ContentDatabase MyNewSite_Content -Name "My New Site!" -Template "STS#0"

That’s it! There’s a bunch of other parameters for the New-SPSite command you can specify (Like Description), but that’s the basic syntax.

Default Installed Templates and their internal Names:

Internal Name Title
GLOBAL#0 Global template
STS#0 Team Site
STS#1 Blank Site
STS#2 Document Workspace
MPS#0 Basic Meeting Workspace
MPS#1 Blank Meeting Workspace
MPS#2 Decision Meeting Workspace
MPS#3 Social Meeting Workspace
MPS#4 Multipage Meeting Workspace
CENTRALADMIN#0 Central Admin Site
WIKI#0 Wiki Site
BLOG#0 Blog
SGS#0 Group Work Site
TENANTADMIN#0 Tenant Admin Site
ACCSRV#0 Access Services Site
ACCSRV#1 Assets Web Database
ACCSRV#3 Charitable Contributions Web Database
ACCSRV#4 Contacts Web Database
ACCSRV#6 Issues Web Database
ACCSRV#5 Projects Web Database
BDR#0 Document Center
BT#0 Bug Database
OFFILE#0 (obsolete) Records Center
OFFILE#1 Records Center
OSRV#0 Shared Services Administration Site
PPSMASite#0 PerformancePoint
BICenterSite#0 Business Intelligence Center
SPS#0 SharePoint Portal Server Site
SPSPERS#0 SharePoint Portal Server Personal Space
SPSMSITE#0 Personalization Site
SPSTOC#0 Contents area Template
SPSTOPIC#0 Topic area template
SPSNEWS#0 News Site
CMSPUBLISHING#0 Publishing Site
BLANKINTERNET#0 Publishing Site
BLANKINTERNET#1 Press Releases Site
BLANKINTERNET#2 Publishing Site with Workflow
SPSNHOME#0 News Site
SPSSITES#0 Site Directory
SPSCOMMU#0 Community area template
SPSREPORTCENTER#0 Report Center
SPSPORTAL#0 Collaboration Portal
SRCHCEN#0 Enterprise Search Center
PROFILES#0 Profiles
BLANKINTERNETCONTAINER#0 Publishing Portal
SPSMSITEHOST#0 My Site Host
ENTERWIKI#0 Enterprise Wiki
SRCHCENTERLITE#0 Basic Search Center
SRCHCENTERLITE#1 Basic Search Center
SRCHCENTERFAST#0 FAST Search Center
visprus#0 Visio Process Repository

Batch Updates with SharePoint Web Services

Applies To: SharePoint

One of the biggest irritations to me coming from a SQL background is trying to do SQL like things in SharePoint 2007. One of those irritations is performing a simple update through the web services.  In SQL, I could write something like:

UPDATE ListTable
    SET FieldName = FieldValue
    WHERE QueryFieldName = QueryFieldValue

In the generic T-SQL above, any row where the QueryFieldName column had a value equal to the QueryFieldValue would have it’s FieldName Column set to FieldValue. Pretty straightforward for anyone with a database background.

With the SharePoint Web Services, however, there isn’t a simple UPDATE command like this. Instead of the one simple command above, we have to make 2 calls to the Web Service and provide some complicated XML parameters. This can be a big hassle the first time you do this, so to hopefully save you some headaches, I’ll provide most of the code required below.

I won’t be showing you how to setup whatever project you are using or how to connect to the web service. The code is in C# and I will assume your service reference (Lists) is called myService.  So let’s get started!

Helper Functions:

I will be using a few helper functions to make generating the XML parameters easier, I’ll go ahead and list these here:

private void AddAttribute(XmlDocument x, ref XmlNode node,
          string attributename, string attributevalue,
          string AttributeNameSpace = "")
{
    XmlNode attnode =
              x.CreateNode(XmlNodeType.Attribute, attributename,
              AttributeNameSpace);
    attnode.Value = attributevalue;
    node.Attributes.Append(attnode);
}

private XmlNode CreateUpdateNode(XmlDocument x, int ID, string RowID)
{
    XmlNode node = x.CreateNode(XmlNodeType.Element, "Method", null);
    AddAttribute(x, node, "ID", ID);
    AddAttribute(x, node, "Cmd", "Update");
    node.AppendChild(CreateFieldNode(x, "ID", RowID));
    return node;
}

private XmlNode CreateFieldNode(XmlDocument x, string Name, string Value)
{
    XmlNode node = x.CreateNode(XmlNodeType.Element, "Field", null);
    AddAttribute(x, node, "Name", Name);
    node.InnerText = Value;
    return node;
}

Retrieve the Items to be Updated:

This is equivalent to the WHERE clause of the example SQL query. You will need to use the GetListItems method of the Lists service.

This method uses the List GUID to reference the target list, I’ll leave it to you to retrieve it and will assume it in the variable ListGUID. You will also need to replace the QueryFieldName, QueryFieldType, and QueryFieldValue variables with appropriate values.

XmlDocument doc = new XmlDocument();
XmlNode queryNode = doc.CreateNode(XmlNodeType.Element, "Query", null);
queryNode.InnerXml =
          string.Format("<Where><Eq><FieldRef Name='{0}' />
                         <Value Type='{1}'>{2}</Value></Eq></Where>",
          QueryFieldName, QueryFieldType, QueryFieldValue);

XmlNode viewNode = doc.CreateNode(XmlNodeType.Element, "ViewFields", null);
viewNode.InnerXml = "<FieldRef Name='ID'/>";

XmlNode resultsNode = myService.GetListItems(ListGUID, null, queryNode,
          viewNode, null,
          doc.CreateNode(XmlNodeType.Element, "QueryOptions", null), null);

 Parse the IDs from the Results:

XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("z", "#RowsetSchema");
XmlNodeList rowNodes = resultsNode.SelectNodes(".//z:row", nsmgr);
List<int> IDs = new List<int>();
foreach (XmlNode rowNode in rowNodes) {
    XmlAttribute result = rowNode.Attributes("ows_ID");
    IDs.Add(int.Parse(result.Value));
}

Perform the Update:

This is equivalent to the SET portion of the example SQL query. You will need to use the UpdateListItems method of the Lists service.

Again, this method uses the List GUID to reference the target list, I’ll leave it to you to retrieve it and will assume it in the variable ListGUID. You will also need to replace the FieldName and FieldValue variables with appropriate values.

<pre>XmlDocument doc2 = new XmlDocument();
XmlNode node = doc2.CreateNode(XmlNodeType.Element, "Batch", null);
AddAttribute(doc2, node, "OnError", "Continue");

int itemCount = 1;
foreach (int i in IDs) {
    XmlNode updateNode = CreateUpdateNode(doc2, itemCount, i);
    updateNode.AppendChild(CreateFieldNode(doc2, FieldName, FieldValue));
    //Append More children here to update multiple fields
    node.AppendChild(updateNode);
    itemCount += 1;
}

myService.UpdateListItems(ListGUID, node);

That’s it. To review, we created a CAML query and retrieved the IDs of the matching rows using the GetListItems method. We parsed the XML result and put all of those IDs in a List<int>. We then added each row ID to a batch update XML parameter which we used in the UpdateListItems method.

As you can see, this is way more complicated and not nearly as obvious as a SQL UPDATE command, but you can take the above code and create a pretty generic wrapper to make your web service updates nearly as easy. Let me know how it works out for you or if you have any questions!

Originally Published on WireBear.com/blog on February 11, 2011

WP7 Accent Shapes

Applies To: Windows Phone 7

The new Windows Phone 7 (WP7) introduces Microsoft’s Metro style (Okay, it’s not the first Microsoft product to use it but it will probably be the first time many users encounter it).  We’ve gone back and forth on it.  It seems most people (by people I mean developer’s and tech gurus) are convinced of it’s genius.

It is simple and there is a sort of beauty to it when done correctly.  However, it will be interesting to see how main stream consumers who are used to the styles introduced through the iOS and Android devices take to it.  As developers of multiple platforms we’ve struggled with it a bit.  It seems to fit some Apps remarkably well, but others not at all.

If  you have developed apps for other software platforms like iOS it can be tempting to try and port your apps to look and behave as it does on the other platforms.  Admittedly this was our first approach and we found it didn’t work too well.  Ultimately we’ve come to the conclusion that existing apps were made to match the OS they were created for and the same should be true of the various versions we create.

In other words, if the consumer wanted an iOS style app they would have bought an iOS device.  By purchasing a WP7 device the consumer has shown their preference for WP7 styles, which inevitably means Metro.

This isn’t always appropriate and should be decided on an App by App basis.  WP7 style is also a moving target and we shouldn’t hold back on innovation just to match existing patterns.  But there should be an evolution to our innovations so that they don’t clash with those patterns but rather enhance them.

</soapbox>

So now that you are all about Metro, here is at least one technique we use to take advantage of this design pattern. The SDK comes with a variety of StaticResources that map directly to the user’s theme settings. Ironically, these “Static” resources can be used to dynamically match a user’s design preferences.  Using these allows you to match a style your user obviously likes and allows their personalization to carry all the way through the phone into your apps.  This is a powerful and easy way to provide customization to your app for “Free”.

Note – By default your app will be doing this and if you wish to explicitly control your colors you will need to do so on each control.  Be sure to adjust your theme and accent color multiple times during the testing of your app to ensure your app remains readable and reasonably pretty.

This can be done from either ExpressionBlend or directly in the XAML.  The nice thing about doing it in ExpressionBlend is that it allows you to choose the resource from a list:

Doing this with text or built in shapes is pretty simple.  For instance, to create a textblock control that matches a user’s accent color (PhoneAccentBrush) you can just use this XAML:

<TextBlock Text="I'm so Pretty!"
 Foreground="{StaticResource PhoneAccentBrush}"/>

You could also create a Circle filled with the accent color using this XAML:

<Ellipse Fill="{StaticResource PhoneAccentBrush}" Width="25" Height="25"/>

There are some other basic shapes and a lot can be done with these.  But what do you do when you want something a little more complex?  You could draw it from shapes, include an image for each possible theme, or try this technique using an OpacityMask combined with an ImageBrush:

<Rectangle x:Name="Star"
 Fill="{StaticResource PhoneAccentBrush}"
 Width="15" Height="15">
  <Rectangle.OpacityMask>
    <ImageBrush ImageSource="/Images/Star.png"/>
  </Rectangle.OpacityMask>
</Rectangle>

Note – the image used above has it’s Build Action property set to Content.

This allows us to use an image with transparency to determine our shape.  The image itself doesn’t need to be any particular color it just needs to have an alpha layer.  This allows for complex shapes that match a user’s theme without a whole lot of work!

Both of the above screenshots use the same XAML:

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
  <StackPanel HorizontalAlignment="Left" VerticalAlignment="Top" Width="456">
    <TextBlock TextWrapping="Wrap" Text="PhoneForegroundBrush"
     Margin="0,0,-75,0" d:LayoutOverrides="Width"
     Foreground="{StaticResource PhoneForegroundBrush}"/>
    <TextBlock TextWrapping="Wrap" Text="PhoneAccentBrush"
     Margin="0,0,15,0" d:LayoutOverrides="Width"
     Foreground="{StaticResource PhoneAccentBrush}"/>
    <TextBlock TextWrapping="Wrap" Text="PhoneContrastBackgroundBrush"
     Foreground="{StaticResource PhoneContrastBackgroundBrush}"/>
    <TextBlock TextWrapping="Wrap" Text="PhoneDisabledBrush"
     Foreground="{StaticResource PhoneDisabledBrush}"/>
    <TextBlock TextWrapping="Wrap" Text="PhoneSubtleBrush"
     Foreground="{StaticResource PhoneSubtleBrush}"/>
    <TextBlock TextWrapping="Wrap" Text="PhoneBorderBrush"
     Foreground="{StaticResource PhoneBorderBrush}"/>
    <TextBlock TextWrapping="Wrap" Text="PhoneChromeBrush"
     Foreground="{StaticResource PhoneChromeBrush}"/>
    <Line X2="400" StrokeThickness="4" Height="4"
     Stroke="{StaticResource PhoneAccentBrush}" Margin="0,50,0,0"
     HorizontalAlignment="Center"/>
    <Ellipse Fill="{StaticResource PhoneAccentBrush}"
     Width="25" Height="25" Margin="0,50,0,0" HorizontalAlignment="Center"/>
    <Rectangle x:Name="Star" Fill="{StaticResource PhoneAccentBrush}"
     Width="15" Height="15" VerticalAlignment="Center"
     HorizontalAlignment="Center" Margin="0,50,0,0">
      <Rectangle.OpacityMask>
        <ImageBrush ImageSource="/Images/Star.png"/>
      </Rectangle.OpacityMask>
    </Rectangle>
    <StackPanel Orientation="Horizontal" HorizontalAlignment="Center"
     Margin="0,50,0,0">
      <Image Source="/Images/Bear.png" Stretch="Fill"
       Width="63" Height="92" HorizontalAlignment="Center"/>
      <Rectangle x:Name="Bear" Fill="{StaticResource PhoneAccentBrush}"
       Width="63" Height="92" HorizontalAlignment="Center" Margin="50,0,0,0">
        <Rectangle.OpacityMask>
          <ImageBrush ImageSource="/Images/Bear.png"/>
        </Rectangle.OpacityMask>
      </Rectangle>
    </StackPanel>
  </StackPanel>
</Grid>

You can use this technique in all sorts of situations, but our favorite is to combine it with databinding and use a little icon to mark something about the entry (such as unread in an article reader).  This is an easy way to wow your users while maintaining consistency with the Metro style.

Originally Published on WireBear.com/blog on October 29, 2010

LiquidOffice Retry on Exception

Applies To: LiquidOffice

LiquidOffice tasks can fail for a number of reasons. By default, a failed task halts the entire process and you will have to manually skip the task, delete the process or take some other action using Management Console. Sometimes, however, wouldn’t it be nice if the failed task waited a certain amount of time then retried?

We have found this to be especially helpful for web service tasks. Calls to web services can fail if the server has gone offline for a minute, but could recover if tried in 10 minutes or so. So we have added an exception loop to each of our web service tasks that retries indefinitely.

Here is the process:

On this process you can see we have a Form task and then a script task called FailTask. The FailTask is pretty simple, it just throws an exception. Here is the code inside the FailTask:

void enteredActive(State state) {
 Log log = LogFactory.getLog();
 log.info("FAIL");
 thisProcess.setFieldValue("FakeField","panda");
}

So we write a message to the log then try to set the value on a field that doesn’t exist. FAIL! The next task, Other Stuff, will never be reached in this particular example, but is representative of the rest of your process.

The other four tasks are the interesting ones. First is an Exception task. An exception task is just a task that becomes active when the task it is connected to (with a red line) throws an exception – pretty straightforward. After the exception task we have placed a Delay task. This is the task that determines how long the process should wait before retrying.

The most important task is the Reset State script task. Here is the code inside:

void enteredActive(State state) {
  thisProcess.getTaskByName("FailTask").forceToState(State.READY);
}

(This Code can also be placed in the Delay task on the enteringDone event, we have separated it into a separate Script task just to make it easy to understand)

This code retrieves the failed task (whatever task you are attaching the exception loop too) and sets its’ state to READY. This command will fail if the task is not currently at state ABORT, so just make sure to only put this code inside your exception loop.

The last member of this loop is the strangest, the Loop task. The loop task is between the Delay task and the Exception task and does NOT link back to the main process (Fail Task). Resetting the state of the Failed task immediately activates it (which is why we reset AFTER the delay task). The loop is only there to reactivate the exception task so that if the Failed task fails again, the exception loop starts over.

In our example above the process will retry forever until it succeeds. You could easily add conditions to the loop task to determine how often it should run and this will be the equivalent of a retry count (since the exception task will never be reactivated).

Adding these types of loops to your processes can help them to be more robust and keep you from having to intervene on recoverable tasks.

UPDATE: Although the above guide can be greatly improve the reliability of your processes, LiquidOffice isn’t not a very reliable program. Depending on a variety of factors, Exception tasks themselves can have exceptions and there’s really no way to totally prevent these.

Originally published on wirebear.com/blog on January 18, 2011