none
What are some different ways to customize the display of an SPUser field on a list via Xslt on an XsltListViewWebPart

    Question

  • -Scenario-


    I have a list with a single field on it of Type user, and it is set to "Display Picture With Details".  I have a requirement to show much more information for that field on the ListView of the list.


    --Currently--


    1.  I create a new XSLT file that includes main.xsl


    2. I overrode the FreeForm Template to add a new button for another requirement next to "Add New Item"


    3. I also overwrode the FieldRef_User_body template, which I can comment out and the field's content disappears so I'm pretty sure that's the right template to override.


    The xsl for that template, is this


      <xsl:template name="FieldRef_User_body" ddwrt:dvt_mode="body" match="FieldRef" mode="User_body">
        <xsl:param name="thisNode" select="."/>
        <xsl:variable name="idField" select="concat(current()/@Name, '.id')" />
        <xsl:value-of disable-output-escaping="yes" select="$thisNode/@*[name()=current()/@Name]" />
      </xsl:template>


    The xml on the page has encoded HTML on it representing the display of the user field, the above template simple gets it and unencodes it and writes it to the output in the transformation.


    I don't see any real way to customize that unless I could somehow load that html to a variable and treat it like XML I can transform (not sure if that's possible).  Secondly I don't see any needed variables or parameters for acquiring the account name of the user so I can't just use the ddwrt profile extensions (that I know of).


    I don't see much documentation on the process either.


    --Options I'm aware of--


    1. Create a custom field type that inherits user and override the rendering with a new BaseControl, ascx etc.


    2. Create a custom control and register it via this method http://www.portalsolutions.net/Blog/Lists/Posts/Post.aspx?List=1fef67f0-70ca-4263-b683-f10c1958687a&ID=115&Web=2a4e9897-6530-44a1-80b5-4fac295c2c26






    --Desired option--


    I really want to find a way to do this by creating a new xslt sheet that inherits main.xsl, basically what I've done already without having to register a control in the web.config.  Are there any xslt extensions in sharepoint I can use to process a control without registering it in the web.config?  Can I call a webservice that returns xml and transform it (not efficient)? 


    Is there any way to get the user account name for a user field so I can look up the profile and do all the rendering right in xslt?  Optionally, is there any way to add xml to the List View before the transformation takes place?

    My Blog: http://www.thesug.org/Blogs/ryan_mann1/default.aspx Website: Under Construction

    Friday, March 02, 2012 7:54 PM

Answers

  • Due to the replication pains, waiting for timer jobs to run to update the site users info list, and the non portability of customizing the site users info list, I opted for a custom field type.

    So what I did,

    1.  Create a Custom Field Type that inherits from SPFieldText.

    2.  Create a Custom Field Editor control IFieldEditor interface to allow users to configure what user profile properties the field renders.

    3.  Used the same Edit Rendering Template as the UserField BaseFieldControl from sharepoint the templates ID is "UserField", this gives me a people picker selector just like an OOTB user field.

    4.  Created a FieldControl class for my new Custom Field type that allows users to select a single user from the People Picker.  It saves the users Account Name (Encoded claim string if claims is enabled) as the value of the field.

    5.  Create a Value class and set it to the FieldValueType in the Field class and enable HTML rendering.  The value class outputs the field as HTML.

    The end result, I have a field that renders a users Profile Picture, their account name linked to UserDisp.aspx (which redirects to person.aspx if MySite feature is enable, which I override so it redirects to Profile.aspx in my case).  And I can customize what user profile properties get rendered by the field by editing the field on the list settings page via the IFieldControl interface.

    Then it gets transformed with this xsl,

    <xsl:stylesheet xmlns:x="http://www.w3.org/2001/XMLSchema" xmlns:d="http://schemas.microsoft.com/sharepoint/dsp" version="1.0" exclude-result-prefixes="xsl msxsl ddwrt" xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime" xmlns:asp="http://schemas.microsoft.com/ASPNET/20" xmlns:__designer="http://schemas.microsoft.com/WebParts/v2/DataView/designer" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:SharePoint="Microsoft.SharePoint.WebControls" xmlns:ddwrt2="urn:frontpage:internal">
      <xsl:template match="FieldRef[@FieldType='AccountNameWithProfile']" mode="Text_body">
        <xsl:param name="thisNode" select="."/>
        <xsl:value-of select="$thisNode/@*[name()=current()/@Name]" disable-output-escaping ="yes"/>
      </xsl:template>
    </xsl:stylesheet>

    That outputs the value of my field by FieldType by outputting it as unescaped HTML (so it will process every field of that type, the MSDN documentation for this shows it using InternalName, which isn't ideal because it will only render that fields name, no all fields of that type).


    My Blog: http://www.thesug.org/Blogs/ryan_mann1/default.aspx Website: Under Construction


    • Marked as answer by Ryan T Mann Thursday, March 08, 2012 2:50 PM
    • Edited by Ryan T Mann Thursday, March 08, 2012 2:51 PM
    Thursday, March 08, 2012 2:50 PM

All replies

  • Well, I managed to figure out that the the User Field's show field property is actually the lookup field it uses to display.  The user field, by default, is tied to the SiteUsersInfoList (hidden user list at /_Catalogs/Users).  On that list is a filed called "PictureWithNameAndDetails".  When you set the show field drop down to that it simply displays that field in a list view.  That field is a computed field that renders Picture, Department, Job Title, First Name, LastName.

    It would appear that I can change my field to point to my list and build my own computed field.  But I want the field to pull properties from the user profile.

    I can set up my user profile properties to replicate to the site users info list which creates new columns on the list for them, and then possiblly edit one of the computed fields to include additional fields in it's lookup value, but this solution is not very portable as I would have to edit the calculated column on 1 to XXX web apps (up to 500+).  It needs to be deployable and easily portable via a wsp.

    I'm not sure if this is possible, but if I can create a Calculated column that renders an aspx control, I could put that on my list and point the field to that.  I could also create a custom field definition that does nothing but render user profile properties.


    My Blog: http://www.thesug.org/Blogs/ryan_mann1/default.aspx Website: Under Construction

    Saturday, March 03, 2012 11:28 PM
  • Due to the replication pains, waiting for timer jobs to run to update the site users info list, and the non portability of customizing the site users info list, I opted for a custom field type.

    So what I did,

    1.  Create a Custom Field Type that inherits from SPFieldText.

    2.  Create a Custom Field Editor control IFieldEditor interface to allow users to configure what user profile properties the field renders.

    3.  Used the same Edit Rendering Template as the UserField BaseFieldControl from sharepoint the templates ID is "UserField", this gives me a people picker selector just like an OOTB user field.

    4.  Created a FieldControl class for my new Custom Field type that allows users to select a single user from the People Picker.  It saves the users Account Name (Encoded claim string if claims is enabled) as the value of the field.

    5.  Create a Value class and set it to the FieldValueType in the Field class and enable HTML rendering.  The value class outputs the field as HTML.

    The end result, I have a field that renders a users Profile Picture, their account name linked to UserDisp.aspx (which redirects to person.aspx if MySite feature is enable, which I override so it redirects to Profile.aspx in my case).  And I can customize what user profile properties get rendered by the field by editing the field on the list settings page via the IFieldControl interface.

    Then it gets transformed with this xsl,

    <xsl:stylesheet xmlns:x="http://www.w3.org/2001/XMLSchema" xmlns:d="http://schemas.microsoft.com/sharepoint/dsp" version="1.0" exclude-result-prefixes="xsl msxsl ddwrt" xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime" xmlns:asp="http://schemas.microsoft.com/ASPNET/20" xmlns:__designer="http://schemas.microsoft.com/WebParts/v2/DataView/designer" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:SharePoint="Microsoft.SharePoint.WebControls" xmlns:ddwrt2="urn:frontpage:internal">
      <xsl:template match="FieldRef[@FieldType='AccountNameWithProfile']" mode="Text_body">
        <xsl:param name="thisNode" select="."/>
        <xsl:value-of select="$thisNode/@*[name()=current()/@Name]" disable-output-escaping ="yes"/>
      </xsl:template>
    </xsl:stylesheet>

    That outputs the value of my field by FieldType by outputting it as unescaped HTML (so it will process every field of that type, the MSDN documentation for this shows it using InternalName, which isn't ideal because it will only render that fields name, no all fields of that type).


    My Blog: http://www.thesug.org/Blogs/ryan_mann1/default.aspx Website: Under Construction


    • Marked as answer by Ryan T Mann Thursday, March 08, 2012 2:50 PM
    • Edited by Ryan T Mann Thursday, March 08, 2012 2:51 PM
    Thursday, March 08, 2012 2:50 PM
  • Also, because I'm outputing the account name, it seems to resolve properly if I try to send an email to it with NintexWorkflows Send Notification or SPUtility.SendEmail

    My Blog: http://www.thesug.org/Blogs/ryan_mann1/default.aspx Website: Under Construction

    Thursday, March 08, 2012 2:52 PM