Community Server 2007: Extend user profile to add Twitter account and auto-tweet

I've learned how to extend Community Server's user profile fields to add additional ones for storing a Twitter account data and auto-posting when publishing new content.

In this post I will show you how to do it, but first of all I want to thank Jon for his fantastic post about how to extend user profiles. It avoided me a lot of work searching for what and where to change :)

Database modifications

  1. Modify the table cs_users, and add two text fields for the account username and password (remember to make them nullable!)
  2. Modify the stored procedure cs_user_CreateUpdateDelete:
    · Add two new arguments:
    @TwitterUsername nvarchar (60) = null,
    @TwitterPassword nvarchar (60) = null,

    · And modify the INSERT INTO cs_Users and UPDATE cs_Users to include the two new arguments.
  3. Modify the view cs_vw_Users_FullUser to obtain the two new table fields:
    U.TwitterUsername,U.TwitterPassword,

Community Server components modifications

  1. Modify CommunityServer.Components.User to add new properties:
    string twitterUsername;string twitterPassword;
    public string TwitterUsername{    get    {        return twitterUsername;    }    set    {        twitterUsername = value;    }}public string TwitterPassword{    get    {        return twitterPassword;    }    set    {        twitterPassword = value;    }}
  2. Modify CommunityServer.Data.SqlCommonDataProvider to send the new fields to the DB when creating or updating a user:
    public override User CreateUpdateDeleteUser( [...] ) 
    {
    [...]
        myCommand.Parameters.Add("@TwitterUsername", SqlDbType.VarChar, 60).Value = 
    upm.CurrentUser.TwitterUsername; myCommand.Parameters.Add("@TwitterPassword", SqlDbType.VarChar, 60).Value =
    upm.CurrentUser.TwitterPassword;



  3. Modify CommunityServer.Components.CommonDataProvider to retrieve the new fields and store them in the User class:
    public static User PopulateUserFromIDataReader( [...] ) 
    {
    [...]
        user.TwitterUsername = dr["TwitterUsername"] as string;    user.TwitterPassword = dr["TwitterPassword"] as string;
  4. Modify CommunityServer.Controls.EditUserForm to add the logic for populating textboxes and saving their values whenever editing an existing user:
    TextBox TwitterUsernameTextBox;TextBox TwitterPasswordTextBox;


    public string
    TwitterUsernameTextBoxId{ get { return (string)ViewState["TwitterUsernameTextBoxId"] ?? string.Empty; } set { ViewState["TwitterUsernameTextBoxId"] = value; }}
    public string TwitterPasswordTextBoxId{    get    {        return (string)ViewState["TwitterPasswordTextBoxId"] ?? string.Empty;    }    set    {        ViewState["TwitterPasswordTextBoxId"] = value;    }}
    protected override void  AttachChildControls(){
    [...]
        TwitterUsernameTextBox = 
    CSControlUtility.Instance().FindControl(this, TwitterUsernameTextBoxId) as TextBox; TwitterPasswordTextBox =
    CSControlUtility.Instance().FindControl(this, TwitterPasswordTextBoxId) as TextBox;

    [...]

    }
    public override void DataBind()
    {
    [...]
        if (!Page.IsPostBack)    {
    [...]
            if (TwitterUsernameTextBox != null)            TwitterUsernameTextBox.Text = userToEdit.TwitterUsername;        if (TwitterPasswordTextBox != null)            TwitterPasswordTextBox.Text = userToEdit.TwitterPassword;

    [...]
    }

    [...]
    }
    void  SubmitButton_Click(object sender, EventArgs e){
    [...]
        if (TwitterUsernameTextBox != null)        userToEdit.TwitterUsername = TwitterUsernameTextBox.Text;    if (TwitterPasswordTextBox != null)        userToEdit.TwitterPassword = TwitterPasswordTextBox.Text;


    [...]
    }

Community Server Web modifications

  1. Modify the /Themes/xxxxx/User/EditUser.aspx to add a new tab, textboxes and mapping of them to the components form previously modified:
    · Add a new tab with the desired layout to the TabbedPanes:
    <TWC:TabbedPanes id="ProfileTabs" runat="server"    PanesCssClass="CommonPane"    TabSetCssClass="CommonPaneTabSet"    TabCssClasses="CommonPaneTab,CommonPaneTab1,CommonPaneTab2"    TabSelectedCssClasses="CommonPaneTabSelected,CommonPaneTabSelected1,CommonPaneTabSelected2"    TabHoverCssClasses="CommonPaneTabHover,CommonPaneTabHover1,CommonPaneTabHover2">      [...]    <TWC:TabbedPane runat="server">        <Tab>Twitter Account</Tab>        <Content>             <h3 class="CommonSubTitle">Twitter Account data</h3>             <table>             <tr>                 <td class="CommonFormFieldName">                     Account/Username:                 </td>                 <td class="CommonFormField">                     <asp:Textbox id="TwitterUsername" Columns="30" MaxLength="60" runat="server" />                 </td>             </tr>             <tr>                 <td class="CommonFormFieldName">                     Password:                 </td>                 <td class="CommonFormField">                     asp:Textbox id="TwitterPassword" Columns="30" MaxLength="60" runat="server" />                 </td>             </tr>                                     </table>         </Content>     </TWC:TabbedPane>      [...]

    · Add the textboxes mapping to the EditUserForm control:
    <CSControl:EditUserForm runat="server"     RssFeedUrlsTextBoxId="rssFeeds"    EnableUserAvatarsCheckBoxId="enableUserAvtars"     TimeZoneDropDownListId="Timezone"    NameTextBoxId="CommonName"    [...]    
    TwitterUsernameTextBoxId="TwitterUsername" TwitterPasswordTextBoxId="TwitterPassword" [...]
  2. Download the Kartones.Net CS2007 Addon Pack (just updated today), and add to the CommunityServer.Config file CSModules section the new module I've created to auto-tweet if the post author has a Twitter account configured:
    <add name = "UserTwitterAccountPostingAddon" applications="Weblog" 
    type="KartonesNet.Modules.UserTwitterAccountPostingAddon, KartonesNet" />


And finally we're done!

This is how the new tab appears on the edit profile page:


And this is a sample auto-tweet:

Enjoy!

Note: As you might have noticed, I haven't touched the new user creation page. As an exercise I'll leave that to you.

Comments?

Posted by Kartones on 2009-01-29