Thursday, April 5, 2012

Sharepoint XML world...

I have used XML in a variety of my earlier projects and find it very interesting concept.

In one of my recent projects, To Read an XML file from Layouts folder to display a Megamenu which is audience targetted based on a userprofile property was pretty challenging for me... so I am sharing this with my fellow SP developement team for reference!

Define the string constant for the path to XML file
 public const string XMLFILEPATH = "Template/Layouts/Banfield.Portal/MyFile.xml";  
Let's say the XML is in the below format

<?xml version="1.0" encoding="UTF-8"?>
<Menu>
  <Tab Title="Tab 1">
    <Audience>Audience1,Audience2</Audience>
    <Content>
      <![CDATA[
      <ul> <!-- ul for the tab -->
        <li> <!-- li per column in the tab -->
          <ul> <!-- ul for the column -->
            <li> <!-- li per group in the column -->
              <h3>Tab One, Column One, Group One</h3>
              <ul> <!-- ul for the group -->
                <li> <!-- li per link -->
                  <a href="something">Tab One, Column One, Group One, Link One</a>
                </li>
                <li>
                  <a href="something else">Tab One, Column One, Group One, Link Two</a>
                </li>
              </ul>
            </li>
            <li>
              <h3>Tab One, Column One, Group Two</h3>
              <ul>...</ul> <!-- ul for the group, with li's per link -->
            </li>
          </ul>
        </li>
        <li>

      ]]>
    </Content>
  </Tab>
  <Tab Title="Tab 2">
    <Audience>Audience1,Audience3</Audience>
    <Content>
      <![CDATA[<ul> <!-- ul for the tab -->
        <li> <!-- li per column in the tab -->
          <ul> <!-- ul for the column -->
            <li> <!-- li per group in the column -->
              <h3>Tab 2, Column One, Group One</h3>
              <ul> <!-- ul for the group -->
                <li> <!-- li per link -->
                  <a href="something">Tab 2, Column One, Group One, Link One</a>
                </li>
                <li>
                  <a href="something else">Tab 2, Column One, Group One, Link Two</a>
                </li>
              </ul>
            </li>
            <li>
              <h3>Tab 2, Column One, Group Two</h3>
              <ul>...</ul> <!-- ul for the group, with li's per link -->
            </li>
          </ul>
        </li>
        <li>
      ]]>
    </Content>
  </Tab>
  <Tab Title="Tab 3">
    <Audience>Audience1,Audience2,Audience3</Audience>
    <Content>
      <![CDATA[<ul> <!-- ul for the tab -->
        <li> <!-- li per column in the tab -->
          <ul> <!-- ul for the column -->
            <li> <!-- li per group in the column -->
              <h3>Tab 3, Column One, Group One</h3>
              <ul> <!-- ul for the group -->
                <li> <!-- li per link -->
                  <a href="something">Tab 3, Column One, Group One, Link One</a>
                </li>
                <li>
                  <a href="something else">Tab 3, Column One, Group One, Link Two</a>
                </li>
              </ul>
            </li>
            <li>
              <h3>Tab 3, Column One, Group Two</h3>
              <ul>...</ul> <!-- ul for the group, with li's per link -->
            </li>
          </ul>
        </li>
        <li>
      ]]>
    </Content>
  </Tab>
</Menu>

In CreateChildControls - using System.LinQ we will try to retrieve the data of the XML

  System.Xml.Linq.XDocument doc = XDocument.Load(Microsoft.SharePoint.Utilities.SPUtility.GetGenericSetupPath(XMLFILEPATH));
  

Now we can safely start the process of data retrieval for the megamenu elements for the user's departrment ( this is specified as a user profile property.)

  
  XElement navElement = doc.Element("Menu");
  
         using (SPSite siteCollection = new SPSite(SPContext.Current.Web.Url))
  
         {
  
             
           var AudienceCategory = GetUserProfile.GetUserProperty(SPContext.Current.Site, loginName, GetUserProfile.AudienceCategory);
  
           var newElement = from el in navElement.Descendants("TopNode")
    
                   where el.Element("Audience").Value.Contains(strDepartment)
  
                    select new
  
                      {
  
                        TopNodeTitle = el.Attribute("Title").Value,
  
                        TopNodeContent = el.Element("Content").Value 
  
                      };
  
           if (newElement != null)
  
           {
  
             // Prepare for the rendering of megamenu classes, UL and Li's
  
             StringBuilder sb = new StringBuilder();
  
             foreach (var c in newElement)
  
             {
  
               RenderTopNodeContents(c.TopNodeTitle.ToString(), c.TopNodeContent.ToString(), sb);
  
             }
  
             MegaMenuUl.InnerHtml = sb.ToString();
  
           }
  
         }  
HTML for the usercontrol

 <div class="Menu" runat="server" >
  
 <ul id="MenuUl" runat="server">
 </ul>
  
 </div>  

RenderTabContents function :

  private void RenderTabContents(string strTabTitle, string strContent, StringBuilder sb)
  
     {
  
       sb.Append("<li>"); // Begin Li for each Tab
  
       sb.Append("<h2>"); // H2 for the Menu name
  
       sb.Append(strTabTitle);
  
       sb.Append("</h2>"); // End for H2
  
       sb.Append(strContent); // This should have the UL and Li embedded in the content from XML
  
       sb.Append("</li>"); //End Li for each tab
  
     }  

No comments:

Post a Comment