Sitecore's SPEAK: A Custom Component Part 1 - Foundation

|
Comments
(0)

User Manager V2Months ago around the time “SpeakUI” was introduced, I was asked to create a new “User Manager” for a client, where the client could search by email, name, or username and export the results to a CSV file or enter them into an engagement plan. 

With the latest update and Sitecore 7, the SPEAK concepts introduced then have changed drastically.  Now, there are things called SPEAK Components and integrated Javascript used by Sitecore, which are things that were not seen in this way during the first run of SPEAK. 

For more information on basic ideas of how SPEAK works, I recommend reading Blogs By Anders Laub or watched YouTube videos by The Rocks Guy at Jakob Christensen's YouTube Page. This will give you a general understanding before we get started on this journey with SPEAK.  

After watching the videos and blogs myself, I was ready to start recreating a portion (the specific user search) of the “User Manager” into the new SPEAK.  

First, I had to get the numerous components (text, textbox, checkboxes) ready.  After adding the basic components, the screen looked like this:

SPEAK User Manager Initial

After adding the "ListControl" SPEAK component, I realized I needed a custom DataSource component to communicate to this rendering.  I called this Custom Component the "SearchUserDatabase" Component.  

In this first blog, I will first explain to you the WebAPI calls that will return the list of data objects to SPEAK.  

All access starts with the StartSearch() function.  The Custom Component will post form values such as "emailaddress" and "fullname" (those items will be explained more in Blog 2).  For future use by the download button, the data is also stored in a session variable List<UserData> named "lastSearch."

public List<userdata> StartSearch() {
    var email = Sitecore.Web.WebUtil.GetFormValue("emailaddress");
    var fullname = Sitecore.Web.WebUtil.GetFormValue("fullname");
    var username = Sitecore.Web.WebUtil.GetFormValue("username");
    var sitecoreV = Sitecore.Web.WebUtil.GetFormValue("sitecore") == "true" ? "sitecore" : "";
    var extranetV = Sitecore.Web.WebUtil.GetFormValue("extranet") == "true" ? "extranet" : "";
    var emailcampaignV = Sitecore.Web.WebUtil.GetFormValue("emailcampaign") == "true" ? "Emailcampaign" : "";
    var domains = new List<string>( new [] {sitecoreV, extranetV, emailcampaignV} );
 
    var list = new List<userdata>();
    var usernames = GetUserNames(email, fullname, username, domains);
 
    foreach (var user in usernames)
    {
        list.Add(GetUser(user, "sitecore"));
    }
    HttpContext.Current.Session.Add("lastSearch", list);
    return list;
}

This function first calls the GetUserNames method with the search values to get the usernames that satisfy the search query.  Below is the search method ran against the database to find usernames the fulfill the search.  

public List<string> GetUserNames(string email, string name, string username, List<string> domains )
{
    var usernames = new List<string>();
    foreach (var d in domains)
    {
        if (d != "")
        {
            var domain = DomainManager.GetDomain(d);
            if (domain != null)
            {
                var list = domain.GetUsers().ToList();
                foreach (var u in list)
                {
                    var auser = Sitecore.Security.Accounts.User.FromName(u.Profile.UserName, true);
                    if (username == null || auser.LocalName.ToLower().Contains(username.ToLower()) ||
                        username == "")
                    {
                        UserProfile userprofile = auser.Profile;
                        if (name == null || userprofile.FullName.ToLower().Contains(name.ToLower()) ||
                            name == "")
                        {
                            if (string.IsNullOrEmpty(email) ||
                                userprofile.Email.ToLower().Contains(email.ToLower()))
                                usernames.Add(userprofile.UserName);
                        }
                    }
                }
            }
        }
    }
 
    return usernames;
}

Afterwards, the usernames are used to create the UserData object and are added to the list of results.  The initial method loops through the list of usernames that fulfilled the search, calls the GetUser(username) method to get the UserData object, and adds the UserData object to the list.  

public UserData GetUser(string username)
{
    UserData newUser = null;
    if (username != null)
    {
        MembershipUser user = Membership.GetUser(username);
        var userSitecore = Sitecore.Security.Accounts.User.FromName(username, false);
 
        if (user != null)
        {
            newUser = new UserData();
            newUser.UserName = userSitecore.LocalName;
            newUser.FullName = userSitecore.Profile.FullName;
            newUser.Email = user.Email;
            newUser.Domain = userSitecore.Domain.ToString();
            newUser.Title = userSitecore.Profile.GetCustomProperty("Title");
            var membershipUser = Membership.GetUser(username);
            if (membershipUser != null)
                newUser.CreationDate = membershipUser.CreationDate.ToString("d");
        }
    }
    return newUser;
}

For reference, here is the UserData object used for this example.  It, along with the code above, is a simplified version of the original to focus in on Speak concepts.  

public class UserData
{
    public string UserName { get; set; }
    public string Domain { get; set; }
    public string FullName { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
    public string Title { get; set; }
}

In the next blog (A Custom Component Part 2 - SPEAK Structure), I will explain how SPEAK uses the returned list of UserData object with its own ListControl rendering to create the component.