Showing posts with label social. Show all posts
Showing posts with label social. Show all posts

Saturday, May 5, 2012

Add Blog and Discusssion Board tabs programmatically in Newsgator Social Sites 2010

Newsgator Social Sites 2010 is a great social add-on for SharePoint 2010 with a lot of features (IMHO maybe too many) and an extensive API to manage programmatically the Activity Stream, the creation of Communities, the Followers of a Community… they have a great support community (https://engage.newsgator.com) where, if you are a partner, you can register yourself to ask the real experts and access special documentation.

In my current project I needed to create a SiteDefintion with several default Newsgator tabs. It seems really easy to go to the Setup page and create a new Blog or Discussion Board using the UI, but to be honest it was really hard to find any kind of documentation about how to do it programmatically (in fact it was impossible).

image

My idea was to provide a SPWebEventReceiver event handler and add in the WebProvisioned event the tabs creation (they have special names, special webparts inside…). Within the following code and guessing what was Newsgator internally doing to add the tabs in the UI (like creating a new “blog” or creating a new “calendar” list), I was able to add them.

/// 
/// A site was provisioned.
///

public override void WebProvisioned(SPWebEventProperties properties)
{
base.WebProvisioned(properties);
SPWeb web = properties.Web;
if (web.WebTemplate.Equals("mySiteDefinition", StringComparison.InvariantCultureIgnoreCase))
{
// Blog
SPWeb blog = web.Webs.Add("news", "News", "News description", 1033, "BLOG#0", false, false);

var tabs = new List();
tabs.Add(new CommunityTab()
{
Id = 0,
CapabilityType = CapabilityType.Overview,
Name = "Home",
Enabled = true,
DisplayType = ServerUI.OverviewTab,
TabIndex = 0
});
tabs.Add(new CommunityTab()
{
Id = 1,
CapabilityType = CapabilityType.List,
Name = "Calendar",
Enabled = true,
DisplayType = "Calendar",
TabIndex = 1,
TemplateType = SPListTemplateType.Events
});
tabs.Add(new CommunityTab()
{
Id = 2,
CapabilityType = CapabilityType.DiscussionBoards,
Name = "Forums",
Enabled = true,
DisplayType = ServerUI.CommunityTabType_DiscussionBoards,
TabIndex = 2,
});
tabs.Add(new CommunityTab()
{
Id = 3,
CapabilityType = CapabilityType.Web,
Name = "News",
Enabled = true,
TabIndex = 3,
DisplayType = ServerUI.CommunityTabType_Blog,
SubWebId = blog.ID
});

SocialGroupPrivacyLevel privacyLevel = SocialGroupPrivacyLevel.Private;

CommunitySetup newsgatorSetup = new CommunitySetup();
newsgatorSetup.SaveSetupConfiguration(web.Site, web, tabs, web.Title, true, privacyLevel, false);

web.Features.Add(CommunityGlobals.WebCommunityFeature, true); // Convert to community before add blog
web.Features.Add(CommunityGlobals.WebScopedSkinningFeature, true); // Skin for NG communities

web.Dispose();
}
}

Anyway, with this code I had 2 serious problems:



  • the blog linked to the “News” tab didn’t have the top Newsgator navigation menu… it seemed like it was an isolated blog, and that was not what I wanted (maybe I needed a NG feature?)
  • the discussions board didn’t show up… and the “boards.aspx” page that it’s deployed using the UI was simply not there… (maybe again I needed a NG feature?)

Because of that lack of documentation, I was “forced” to glimpse the DLLs using ILSpy (great application when you are in trouble) and I realized I needed to change the code a little bit:



  • activate the NewsGator.Communities_NewsGator.Community.Context feature in the blog to enable the top navigation menu.
  • activate the NewsGator.Communities.BoardsPage feature in my site, which deploys the boards.aspx page.
  • add the LinkUrl property in the Discussions Boards page to “boards.aspx

At the end, my successful code looked like:

/// 
/// A site was provisioned.
///

public override void WebProvisioned(SPWebEventProperties properties)
{
base.WebProvisioned(properties);
SPWeb web = properties.Web;
if (web.WebTemplate.Equals("mySiteDefinition", StringComparison.InvariantCultureIgnoreCase))
{
// Blog
SPWeb blog = web.Webs.Add("news", "News", "News description", 1033, "BLOG#0", false, false);

var tabs = new List();
tabs.Add(new CommunityTab()
{
Id = 0,
CapabilityType = CapabilityType.Overview,
Name = "Home",
Enabled = true,
DisplayType = ServerUI.OverviewTab,
TabIndex = 0
});
tabs.Add(new CommunityTab()
{
Id = 1,
CapabilityType = CapabilityType.List,
Name = "Calendar",
Enabled = true,
DisplayType = "Calendar",
TabIndex = 1,
TemplateType = SPListTemplateType.Events
});
tabs.Add(new CommunityTab()
{
Id = 2,
CapabilityType = CapabilityType.DiscussionBoards,
Name = "Forums",
Enabled = true,
DisplayType = ServerUI.CommunityTabType_DiscussionBoards,
TabIndex = 2,
LinkUrl = "boards.aspx"
});
tabs.Add(new CommunityTab()
{
Id = 3,
CapabilityType = CapabilityType.Web,
Name = "News",
Enabled = true,
TabIndex = 3,
DisplayType = ServerUI.CommunityTabType_Blog,
SubWebId = blog.ID
});

SocialGroupPrivacyLevel privacyLevel = SocialGroupPrivacyLevel.Private;

CommunitySetup newsgatorSetup = new CommunitySetup();
newsgatorSetup.SaveSetupConfiguration(web.Site, web, tabs, web.Title, true, privacyLevel, false);

blog.Features.Add(new Guid("b084760c-452e-419d-8639-babb5c0a4283"), true); // NewsGator.Communities_NewsGator.Community.Context feature

web.Features.Add(CommunityGlobals.WebCommunityFeature, true); // Convert to community before add blog
web.Features.Add(CommunityGlobals.WebScopedSkinningFeature, true); // Skin for NG communities
web.Features.Add(new Guid("62ab07ce-3f9f-441a-80ce-b14beae97dd4"), true); // NewsGator.Communities.BoardsPage feature

blog.Dispose();
web.Dispose();
}
}

And it added the wished tabs, working properly.


image


Hope this helps someone!

Friday, January 13, 2012

Attributes of a socially optimized business

Lately I have worked in several projects where I had to develop some kind of social plugins for SharePoint, or integrate any of the available products to “socialize” SharePoint, or identify the real needs of the client and the better solution for them. It seems that more and more companies realize that a good relationship between their co-workers means better performance and better results.

Anyway, I still find a lot of managers (especially in Germany) that are not able to see the benefits of this approach. They are stuck in the e-mail age. They think that this is just a waste of time and of course, a waste of money –as these solutions are not especially cheap-.

For those people, I found this nice infographic signed by Dachis Group. There are a lot of new/old ideas… I especially like the massive shift from “me” to “we” sentence and the impact on the global workforce.


Sunday, September 4, 2011

Custom MySites TopLinkBar placed in a not-MySites site

It is hard to describe in only one line what I have been doing last week. Sorry about that, but I guess the problem is quite common between customers that want to integrate several different kind of SharePoint 2010 templates with the nice look & feel that MySites offers.

In short, I was asked to keep the same TopLinkBar from MySites in an intranet Team site and in a Basic Search Center site. They 3 were running obviously in 3 different web applications, and they should use the same links.

image

My first idea: add the control

<SharePoint:DelegateControl runat="server" ControlId="GlobalNavigation"/>

to the v4.master (for the TeamSite) and the minimal.master (for the SearchCenter) pages. Then just modify through the SiteSettings the Top Link Bar links in each of the Site Collections. The problem is that this kind of configuration is specifically for MySite based templates, and this will not work in any other type of templates. So although you can see now the TopLinkBar in your site, it is in fact a useless dummy bar that contains links to nowhere…


My second idea: create an own TopLinkBar, using a copy of the User Control TopNavBar.ascx located in CONTROLTEMPLATES which is the control rendered when you place the


<SharePoint:DelegateControl runat="server" ControlId="GlobalNavigation"/>

in the master pages. We can set this new control to our solution in a Module, adding this to the elements.xml


<Control Id="GlobalNavigation" Sequence="10" ControlSrc="~/_CONTROLTEMPLATES/CustomTemplates/CustomTopNavigation.ascx" />

Then, inherit from the class MySiteDataSource, which is being used to set the links in the navigation bar, and modify programmatically the navigation to set my own links. Here again there is a problem, which is the sentence in the MSDN article: This class and its members are reserved for internal use and are not intended to be used in your code. So no, I could not access these methods…


My third and final idea: it is pretty much the second one (create an own CustomTopNavigation.ascx control, add it to the master pages, blablabla) BUT, create my own SiteMapDataSource in my CustomTopNavigation control that I will set to the TopNavigationMenu itself in the DataSourceID parameter.


<SharePoint:AspMenu
     ID="MySiteTopNavigationMenu"
     Runat="server"
     EnableViewState="false"
     DataSourceID="MySiteTopNavDS"
     AccessKey="<%$Resources:wss,navigation_accesskey%>"
     UseSimpleRendering="true"
     UseSeparateCss="false"
     Orientation="Horizontal"
     StaticDisplayLevels="1"
     MaximumDynamicDisplayLevels="1"
     PopOutImageUrl=""
     SkipLinkText=""
     CssClass="s4-mysitetn">
  </SharePoint:AspMenu>
  <asp:SiteMapDataSource runat="server" id="MySiteTopNavDS"  SiteMapProvider="MySiteMapProvider" ShowStartingNode="false" />

Then, create somewhere in the code a custom SiteMap provider and set my links.


public class CustomNavigation : PortalSiteMapProvider
    {
        public override SiteMapNodeCollection GetChildNodes(System.Web.SiteMapNode node)
        {
            PortalSiteMapNode pNode = node as PortalSiteMapNode;
            if (pNode != null)
            {
                if (pNode.Type == NodeTypes.Area)
                {
                    SiteMapNodeCollection nodeColl = base.GetChildNodes(pNode);
                            SiteMapNode childNode = new SiteMapNode(…, "My Newsfeed");
                            SiteMapNode childNode1 = new SiteMapNode(..., "My Content");
                            SiteMapNode childNode2 = new SiteMapNode(…, "My Profile");
                            SiteMapNode childNode3 = new SiteMapNode(…, "New Link");
                            nodeColl.Add(childNode);
                            nodeColl.Add(childNode1);
                            nodeColl.Add(childNode2);
                            nodeColl.Add(childNode3);

                    return nodeColl;
                }
                else
                    return base.GetChildNodes(pNode);
            }
            else
                return new SiteMapNodeCollection();
        }
    }


And then, finally, modify in the web.config files of the web applications we want to change (not for MySites web application, obviously) the entry for the SiteMap provider. That means, replace


<add name="MySiteMapProvider" description="MySite provider that returns areas and based on the current user context" type="Microsoft.SharePoint.Portal.MySiteMapProvider, Microsoft.SharePoint.Portal, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />

with


<add name="MySiteMapProvider" type="[namespace].CustomNavigation, […]" NavigationType="Global" /> 

I know it is not the cleanest way to modify this TopLinkBar, so if anyone has made it with another (and easier) method, I would really apprecciate this info Smiley.


Cheers!